summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-hid-roccat-kone13
-rw-r--r--Documentation/DocBook/dvb/dvbapi.xml19
-rw-r--r--Documentation/DocBook/dvb/frontend.h.xml1
-rw-r--r--Documentation/DocBook/dvb/frontend.xml10
-rw-r--r--Documentation/DocBook/media-entities.tmpl1
-rw-r--r--Documentation/DocBook/media.tmpl8
-rw-r--r--Documentation/DocBook/stylesheet.xsl1
-rw-r--r--Documentation/DocBook/v4l/lirc_device_interface.xml235
-rw-r--r--Documentation/DocBook/v4l/remote_controllers.xml2
-rw-r--r--Documentation/coccinelle.txt258
-rw-r--r--Documentation/dvb/get_dvb_firmware19
-rw-r--r--Documentation/feature-removal-schedule.txt51
-rw-r--r--Documentation/filesystems/Locking22
-rw-r--r--Documentation/filesystems/nilfs2.txt12
-rw-r--r--Documentation/filesystems/porting45
-rw-r--r--Documentation/hwmon/emc210333
-rw-r--r--Documentation/hwmon/ltc424524
-rw-r--r--Documentation/hwmon/sysfs-interface29
-rw-r--r--Documentation/hwmon/w83627ehf15
-rw-r--r--Documentation/i2c/instantiating-devices2
-rw-r--r--Documentation/kbuild/kbuild.txt8
-rw-r--r--Documentation/kbuild/makefiles.txt100
-rw-r--r--Documentation/kernel-parameters.txt132
-rw-r--r--Documentation/scsi/scsi-parameters.txt139
-rw-r--r--Documentation/video4linux/CARDLIST.cx238856
-rw-r--r--Documentation/video4linux/CARDLIST.saa71343
-rwxr-xr-x[-rw-r--r--]Documentation/video4linux/extract_xc3028.pl0
-rw-r--r--Documentation/video4linux/gspca.txt8
-rw-r--r--Documentation/vm/page-types.c2
-rw-r--r--MAINTAINERS39
-rw-r--r--Makefile24
-rw-r--r--arch/arm/Kconfig102
-rw-r--r--arch/arm/Makefile10
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-l7200.S29
-rw-r--r--arch/arm/common/gic.c46
-rw-r--r--arch/arm/common/sa1111.c5
-rw-r--r--arch/arm/configs/ap4evb_defconfig1268
-rw-r--r--arch/arm/configs/g3evm_defconfig768
-rw-r--r--arch/arm/configs/g4evm_defconfig772
-rw-r--r--arch/arm/configs/lusl7200_defconfig23
-rw-r--r--arch/arm/configs/s5pc110_defconfig66
-rw-r--r--arch/arm/configs/s5pv210_defconfig4
-rw-r--r--arch/arm/configs/tegra_defconfig1095
-rw-r--r--arch/arm/configs/tnetv107x_defconfig1741
-rw-r--r--arch/arm/include/asm/atomic.h132
-rw-r--r--arch/arm/include/asm/elf.h3
-rw-r--r--arch/arm/include/asm/hwcap.h1
-rw-r--r--arch/arm/include/asm/irq.h2
-rw-r--r--arch/arm/include/asm/kexec.h22
-rw-r--r--arch/arm/include/asm/lmb.h16
-rw-r--r--arch/arm/include/asm/mach/arch.h2
-rw-r--r--arch/arm/include/asm/mach/irq.h1
-rw-r--r--arch/arm/include/asm/memory.h67
-rw-r--r--arch/arm/include/asm/mmzone.h30
-rw-r--r--arch/arm/include/asm/ptrace.h36
-rw-r--r--arch/arm/include/asm/setup.h8
-rw-r--r--arch/arm/include/asm/stackprotector.h38
-rw-r--r--arch/arm/include/asm/tls.h46
-rw-r--r--arch/arm/include/asm/vfpmacros.h18
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/asm-offsets.c3
-rw-r--r--arch/arm/kernel/crash_dump.c60
-rw-r--r--arch/arm/kernel/entry-armv.S45
-rw-r--r--arch/arm/kernel/irq.c41
-rw-r--r--arch/arm/kernel/kprobes-decode.c5
-rw-r--r--arch/arm/kernel/machine_kexec.c4
-rw-r--r--arch/arm/kernel/process.c36
-rw-r--r--arch/arm/kernel/ptrace.c96
-rw-r--r--arch/arm/kernel/relocate_kernel.S6
-rw-r--r--arch/arm/kernel/setup.c100
-rw-r--r--arch/arm/kernel/traps.c41
-rw-r--r--arch/arm/lib/Makefile1
-rw-r--r--arch/arm/mach-at91/Kconfig11
-rw-r--r--arch/arm/mach-at91/Makefile3
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c11
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c45
-rw-r--r--arch/arm/mach-at91/board-sam9g20ek.c45
-rw-r--r--arch/arm/mach-at91/board-snapper9260.c189
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9.h2
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h22
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9260.h2
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9261.h2
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h130
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_sdramc.h23
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9rl.h2
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h10
-rw-r--r--arch/arm/mach-at91/include/mach/gpio.h1
-rw-r--r--arch/arm/mach-at91/pm.h49
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S74
-rw-r--r--arch/arm/mach-clps711x/Kconfig1
-rw-r--r--arch/arm/mach-clps711x/clep7312.c1
-rw-r--r--arch/arm/mach-clps711x/edb7211-arch.c10
-rw-r--r--arch/arm/mach-clps711x/fortunet.c1
-rw-r--r--arch/arm/mach-davinci/Kconfig12
-rw-r--r--arch/arm/mach-davinci/Makefile3
-rw-r--r--arch/arm/mach-davinci/board-tnetv107x-evm.c174
-rw-r--r--arch/arm/mach-davinci/devices-tnetv107x.c318
-rw-r--r--arch/arm/mach-davinci/dm365.c4
-rw-r--r--arch/arm/mach-davinci/gpio-tnetv107x.c205
-rw-r--r--arch/arm/mach-davinci/include/mach/debug-macro.S50
-rw-r--r--arch/arm/mach-davinci/include/mach/gpio.h22
-rw-r--r--arch/arm/mach-davinci/include/mach/memory.h9
-rw-r--r--arch/arm/mach-davinci/include/mach/serial.h21
-rw-r--r--arch/arm/mach-davinci/include/mach/tnetv107x.h55
-rw-r--r--arch/arm/mach-davinci/include/mach/uncompress.h87
-rw-r--r--arch/arm/mach-davinci/tnetv107x.c753
-rw-r--r--arch/arm/mach-ep93xx/adssphere.c24
-rw-r--r--arch/arm/mach-ep93xx/core.c46
-rw-r--r--arch/arm/mach-ep93xx/edb93xx.c31
-rw-r--r--arch/arm/mach-ep93xx/gesbc9312.c24
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h3
-rw-r--r--arch/arm/mach-ep93xx/micro9.c37
-rw-r--r--arch/arm/mach-ep93xx/simone.c24
-rw-r--r--arch/arm/mach-ep93xx/ts72xx.c27
-rw-r--r--arch/arm/mach-imx/Kconfig (renamed from arch/arm/mach-mx2/Kconfig)101
-rw-r--r--arch/arm/mach-imx/Makefile (renamed from arch/arm/mach-mx2/Makefile)18
-rw-r--r--arch/arm/mach-imx/Makefile.boot (renamed from arch/arm/mach-mx2/Makefile.boot)4
-rw-r--r--arch/arm/mach-imx/clock-imx1.c (renamed from arch/arm/mach-mx1/clock.c)50
-rw-r--r--arch/arm/mach-imx/clock-imx21.c (renamed from arch/arm/mach-mx2/clock_imx21.c)0
-rw-r--r--arch/arm/mach-imx/clock-imx27.c (renamed from arch/arm/mach-mx2/clock_imx27.c)2
-rw-r--r--arch/arm/mach-imx/cpu-imx27.c (renamed from arch/arm/mach-mx2/cpu_imx27.c)0
-rw-r--r--arch/arm/mach-imx/devices-imx1.h18
-rw-r--r--arch/arm/mach-imx/devices-imx21.h30
-rw-r--r--arch/arm/mach-imx/devices-imx27.h38
-rw-r--r--arch/arm/mach-imx/devices.c (renamed from arch/arm/mach-mx2/devices.c)296
-rw-r--r--arch/arm/mach-imx/devices.h (renamed from arch/arm/mach-mx2/devices.h)32
-rw-r--r--arch/arm/mach-imx/dma-v1.c (renamed from arch/arm/plat-mxc/dma-mx1-mx2.c)4
-rw-r--r--arch/arm/mach-imx/eukrea_mbimx27-baseboard.c (renamed from arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c)197
-rw-r--r--arch/arm/mach-imx/include/mach/dma-mx1-mx2.h10
-rw-r--r--arch/arm/mach-imx/include/mach/dma-v1.h (renamed from arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h)10
-rw-r--r--arch/arm/mach-imx/mach-cpuimx27.c (renamed from arch/arm/mach-mx2/mach-cpuimx27.c)120
-rw-r--r--arch/arm/mach-imx/mach-imx27lite.c (renamed from arch/arm/mach-mx2/mach-imx27lite.c)11
-rw-r--r--arch/arm/mach-imx/mach-mx1ads.c (renamed from arch/arm/mach-mx1/mach-mx1ads.c)34
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c (renamed from arch/arm/mach-mx2/mach-mx21ads.c)58
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c (renamed from arch/arm/mach-mx2/mach-mx27_3ds.c)40
-rw-r--r--arch/arm/mach-imx/mach-mx27ads.c (renamed from arch/arm/mach-mx2/mach-mx27ads.c)76
-rw-r--r--arch/arm/mach-imx/mach-mxt_td60.c (renamed from arch/arm/mach-mx2/mach-mxt_td60.c)36
-rw-r--r--arch/arm/mach-imx/mach-pca100.c (renamed from arch/arm/mach-mx2/mach-pca100.c)114
-rw-r--r--arch/arm/mach-imx/mach-pcm038.c (renamed from arch/arm/mach-mx2/mach-pcm038.c)33
-rw-r--r--arch/arm/mach-imx/mach-scb9328.c (renamed from arch/arm/mach-mx1/mach-scb9328.c)21
-rw-r--r--arch/arm/mach-imx/mm-imx1.c (renamed from arch/arm/mach-mx1/generic.c)23
-rw-r--r--arch/arm/mach-imx/mm-imx21.c (renamed from arch/arm/mach-mx2/mm-imx21.c)5
-rw-r--r--arch/arm/mach-imx/mm-imx27.c (renamed from arch/arm/mach-mx2/mm-imx27.c)5
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq-ksym.c (renamed from arch/arm/mach-mx1/ksym_mx1.c)0
-rw-r--r--arch/arm/mach-imx/mx1-camera-fiq.S (renamed from arch/arm/mach-mx1/mx1_camera_fiq.S)0
-rw-r--r--arch/arm/mach-imx/pcm970-baseboard.c (renamed from arch/arm/mach-mx2/pcm970-baseboard.c)0
-rw-r--r--arch/arm/mach-imx/pm-imx27.c46
-rw-r--r--arch/arm/mach-integrator/common.h1
-rw-r--r--arch/arm/mach-integrator/core.c12
-rw-r--r--arch/arm/mach-integrator/integrator_ap.c3
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c3
-rw-r--r--arch/arm/mach-iop13xx/include/mach/memory.h2
-rw-r--r--arch/arm/mach-ixp4xx/common-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/memory.h6
-rw-r--r--arch/arm/mach-l7200/Makefile11
-rw-r--r--arch/arm/mach-l7200/Makefile.boot2
-rw-r--r--arch/arm/mach-l7200/core.c100
-rw-r--r--arch/arm/mach-l7200/include/mach/aux_reg.h28
-rw-r--r--arch/arm/mach-l7200/include/mach/debug-macro.S40
-rw-r--r--arch/arm/mach-l7200/include/mach/entry-macro.S35
-rw-r--r--arch/arm/mach-l7200/include/mach/gp_timers.h42
-rw-r--r--arch/arm/mach-l7200/include/mach/gpio.h105
-rw-r--r--arch/arm/mach-l7200/include/mach/hardware.h57
-rw-r--r--arch/arm/mach-l7200/include/mach/io.h21
-rw-r--r--arch/arm/mach-l7200/include/mach/irqs.h56
-rw-r--r--arch/arm/mach-l7200/include/mach/memory.h26
-rw-r--r--arch/arm/mach-l7200/include/mach/pmpcon.h46
-rw-r--r--arch/arm/mach-l7200/include/mach/pmu.h125
-rw-r--r--arch/arm/mach-l7200/include/mach/serial.h37
-rw-r--r--arch/arm/mach-l7200/include/mach/serial_l7200.h101
-rw-r--r--arch/arm/mach-l7200/include/mach/sib.h119
-rw-r--r--arch/arm/mach-l7200/include/mach/sys-clock.h67
-rw-r--r--arch/arm/mach-l7200/include/mach/system.h29
-rw-r--r--arch/arm/mach-l7200/include/mach/time.h73
-rw-r--r--arch/arm/mach-l7200/include/mach/timex.h20
-rw-r--r--arch/arm/mach-l7200/include/mach/uncompress.h39
-rw-r--r--arch/arm/mach-l7200/include/mach/vmalloc.h4
-rw-r--r--arch/arm/mach-lh7a40x/include/mach/memory.h44
-rw-r--r--arch/arm/mach-msm/Kconfig7
-rw-r--r--arch/arm/mach-msm/Makefile4
-rw-r--r--arch/arm/mach-msm/acpuclock-arm11.c1
-rw-r--r--arch/arm/mach-msm/board-msm7x30.c28
-rw-r--r--arch/arm/mach-msm/board-qsd8x50.c27
-rw-r--r--arch/arm/mach-msm/board-trout-gpio.c227
-rw-r--r--arch/arm/mach-msm/board-trout-mmc.c189
-rw-r--r--arch/arm/mach-msm/board-trout.c12
-rw-r--r--arch/arm/mach-msm/board-trout.h157
-rw-r--r--arch/arm/mach-msm/clock.c1
-rw-r--r--arch/arm/mach-msm/devices-msm7x30.c21
-rw-r--r--arch/arm/mach-msm/devices-qsd8x50.c21
-rw-r--r--arch/arm/mach-msm/devices.h33
-rw-r--r--arch/arm/mach-msm/gpio_hw-7x30.h100
-rw-r--r--arch/arm/mach-msm/gpio_hw-7xxx.h84
-rw-r--r--arch/arm/mach-msm/gpio_hw-8x50.h100
-rw-r--r--arch/arm/mach-msm/gpio_hw.h35
-rw-r--r--arch/arm/mach-msm/include/mach/gpio.h9
-rw-r--r--arch/arm/mach-msm/msm7200a-gpio.c421
-rw-r--r--arch/arm/mach-msm/msm7200a-gpio.h87
-rw-r--r--arch/arm/mach-mx1/Kconfig19
-rw-r--r--arch/arm/mach-mx1/Makefile15
-rw-r--r--arch/arm/mach-mx1/Makefile.boot4
-rw-r--r--arch/arm/mach-mx1/crm_regs.h55
-rw-r--r--arch/arm/mach-mx1/devices.c242
-rw-r--r--arch/arm/mach-mx1/devices.h7
-rw-r--r--arch/arm/mach-mx2/serial.c141
-rw-r--r--arch/arm/mach-mx25/Kconfig23
-rw-r--r--arch/arm/mach-mx25/Makefile4
-rw-r--r--arch/arm/mach-mx25/clock.c63
-rw-r--r--arch/arm/mach-mx25/devices-imx25.h38
-rw-r--r--arch/arm/mach-mx25/devices.c313
-rw-r--r--arch/arm/mach-mx25/devices.h16
-rw-r--r--arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c261
-rw-r--r--arch/arm/mach-mx25/mach-cpuimx25.c173
-rw-r--r--arch/arm/mach-mx25/mach-mx25_3ds.c (renamed from arch/arm/mach-mx25/mach-mx25pdk.c)58
-rw-r--r--arch/arm/mach-mx25/mm.c7
-rw-r--r--arch/arm/mach-mx3/Kconfig52
-rw-r--r--arch/arm/mach-mx3/Makefile4
-rw-r--r--arch/arm/mach-mx3/clock-imx35.c2
-rw-r--r--arch/arm/mach-mx3/devices-imx31.h38
-rw-r--r--arch/arm/mach-mx3/devices-imx35.h32
-rw-r--r--arch/arm/mach-mx3/devices.c247
-rw-r--r--arch/arm/mach-mx3/devices.h13
-rw-r--r--arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c264
-rw-r--r--arch/arm/mach-mx3/mach-armadillo5x0.c17
-rw-r--r--arch/arm/mach-mx3/mach-cpuimx35.c227
-rw-r--r--arch/arm/mach-mx3/mach-kzm_arm11_01.c31
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c256
-rw-r--r--arch/arm/mach-mx3/mach-mx31ads.c55
-rw-r--r--arch/arm/mach-mx3/mach-mx31lilly.c15
-rw-r--r--arch/arm/mach-mx3/mach-mx31lite.c17
-rw-r--r--arch/arm/mach-mx3/mach-mx31moboard.c50
-rw-r--r--arch/arm/mach-mx3/mach-mx35_3ds.c (renamed from arch/arm/mach-mx3/mach-mx35pdk.c)16
-rw-r--r--arch/arm/mach-mx3/mach-pcm037.c34
-rw-r--r--arch/arm/mach-mx3/mach-pcm037_eet.c7
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c27
-rw-r--r--arch/arm/mach-mx3/mach-qong.c16
-rw-r--r--arch/arm/mach-mx3/mm.c7
-rw-r--r--arch/arm/mach-mx3/mx31lilly-db.c14
-rw-r--r--arch/arm/mach-mx3/mx31lite-db.c15
-rw-r--r--arch/arm/mach-mx3/mx31moboard-devboard.c10
-rw-r--r--arch/arm/mach-mx3/mx31moboard-marxbot.c4
-rw-r--r--arch/arm/mach-mx3/mx31moboard-smartbot.c11
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c28
-rw-r--r--arch/arm/mach-mx5/clock-mx51.c11
-rw-r--r--arch/arm/mach-mx5/devices.c60
-rw-r--r--arch/arm/mach-mx5/devices.h3
-rw-r--r--arch/arm/mach-mx5/mm.c3
-rw-r--r--arch/arm/mach-mxc91231/crm_regs.h5
-rw-r--r--arch/arm/mach-mxc91231/devices.c2
-rw-r--r--arch/arm/mach-mxc91231/mm.c8
-rw-r--r--arch/arm/mach-omap1/Kconfig13
-rw-r--r--arch/arm/mach-omap1/Makefile3
-rw-r--r--arch/arm/mach-omap1/board-ams-delta.c3
-rw-r--r--arch/arm/mach-omap1/board-fsample.c13
-rw-r--r--arch/arm/mach-omap1/board-generic.c5
-rw-r--r--arch/arm/mach-omap1/board-h2.c32
-rw-r--r--arch/arm/mach-omap1/board-h3.c16
-rw-r--r--arch/arm/mach-omap1/board-htcherald.c3
-rw-r--r--arch/arm/mach-omap1/board-innovator.c5
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c137
-rw-r--r--arch/arm/mach-omap1/board-osk.c3
-rw-r--r--arch/arm/mach-omap1/board-palmte.c87
-rw-r--r--arch/arm/mach-omap1/board-palmtt.c3
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c16
-rw-r--r--arch/arm/mach-omap1/board-perseus2.c13
-rw-r--r--arch/arm/mach-omap1/board-sx1.c5
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c3
-rw-r--r--arch/arm/mach-omap1/clock.c22
-rw-r--r--arch/arm/mach-omap1/clock.h2
-rw-r--r--arch/arm/mach-omap1/clock_data.c149
-rw-r--r--arch/arm/mach-omap1/devices.c72
-rw-r--r--arch/arm/mach-omap1/io.c2
-rw-r--r--arch/arm/mach-omap1/mcbsp.c3
-rw-r--r--arch/arm/mach-omap1/mux.c6
-rw-r--r--arch/arm/mach-omap1/serial.c7
-rw-r--r--arch/arm/mach-omap1/usb.c530
-rw-r--r--arch/arm/mach-omap2/Kconfig89
-rw-r--r--arch/arm/mach-omap2/Makefile17
-rw-r--r--arch/arm/mach-omap2/board-2430sdp.c24
-rw-r--r--arch/arm/mach-omap2/board-3430sdp.c9
-rw-r--r--arch/arm/mach-omap2/board-3630sdp.c10
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c71
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c9
-rw-r--r--arch/arm/mach-omap2/board-apollon.c31
-rw-r--r--arch/arm/mach-omap2/board-cm-t35.c9
-rw-r--r--arch/arm/mach-omap2/board-devkit8000.c145
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-h4.c61
-rw-r--r--arch/arm/mach-omap2/board-igep0020.c9
-rw-r--r--arch/arm/mach-omap2/board-ldp.c9
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c14
-rw-r--r--arch/arm/mach-omap2/board-omap3beagle.c9
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c9
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c157
-rw-r--r--arch/arm/mach-omap2/board-omap3stalker.c8
-rw-r--r--arch/arm/mach-omap2/board-omap3touchbook.c9
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c304
-rw-r--r--arch/arm/mach-omap2/board-overo.c51
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c78
-rw-r--r--arch/arm/mach-omap2/board-rx51-video.c1
-rw-r--r--arch/arm/mach-omap2/board-rx51.c3
-rw-r--r--arch/arm/mach-omap2/board-zoom2.c22
-rw-r--r--arch/arm/mach-omap2/board-zoom3.c22
-rw-r--r--arch/arm/mach-omap2/clock3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/cm.c6
-rw-r--r--arch/arm/mach-omap2/devices.c82
-rw-r--r--arch/arm/mach-omap2/i2c.c27
-rw-r--r--arch/arm/mach-omap2/id.c36
-rw-r--r--arch/arm/mach-omap2/include/mach/id.h22
-rw-r--r--arch/arm/mach-omap2/include/mach/omap4-common.h7
-rw-r--r--arch/arm/mach-omap2/io.c16
-rw-r--r--arch/arm/mach-omap2/iommu2.c44
-rw-r--r--arch/arm/mach-omap2/mcbsp.c13
-rw-r--r--arch/arm/mach-omap2/mux.c338
-rw-r--r--arch/arm/mach-omap2/mux.h28
-rw-r--r--arch/arm/mach-omap2/mux2420.c688
-rw-r--r--arch/arm/mach-omap2/mux2420.h282
-rw-r--r--arch/arm/mach-omap2/mux2430.c791
-rw-r--r--arch/arm/mach-omap2/mux2430.h370
-rw-r--r--arch/arm/mach-omap2/mux34xx.c8
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S16
-rw-r--r--arch/arm/mach-omap2/omap-hotplug.c79
-rw-r--r--arch/arm/mach-omap2/omap-iommu.c2
-rw-r--r--arch/arm/mach-omap2/omap-smp.c3
-rw-r--r--arch/arm/mach-omap2/omap44xx-smc.S25
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c106
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2420_data.c79
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_2430_data.c81
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c92
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.c3
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_common_data.h1
-rw-r--r--arch/arm/mach-omap2/pm.c84
-rw-r--r--arch/arm/mach-omap2/pm24xx.c1
-rw-r--r--arch/arm/mach-omap2/pm34xx.c7
-rw-r--r--arch/arm/mach-omap2/pm44xx.c135
-rw-r--r--arch/arm/mach-omap2/serial.c80
-rw-r--r--arch/arm/mach-omap2/usb-ehci.c1
-rw-r--r--arch/arm/mach-omap2/usb-fs.c359
-rw-r--r--arch/arm/mach-omap2/usb-musb.c1
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c14
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c4
-rw-r--r--arch/arm/mach-pxa/corgi.c1
-rw-r--r--arch/arm/mach-pxa/eseries.c1
-rw-r--r--arch/arm/mach-pxa/generic.h3
-rw-r--r--arch/arm/mach-pxa/include/mach/memory.h7
-rw-r--r--arch/arm/mach-pxa/palmt5.c7
-rw-r--r--arch/arm/mach-pxa/palmtreo.c9
-rw-r--r--arch/arm/mach-pxa/poodle.c1
-rw-r--r--arch/arm/mach-pxa/spitz.c1
-rw-r--r--arch/arm/mach-pxa/tosa.c1
-rw-r--r--arch/arm/mach-realview/core.c28
-rw-r--r--arch/arm/mach-realview/include/mach/board-pb1176.h1
-rw-r--r--arch/arm/mach-realview/include/mach/memory.h7
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c14
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c9
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c1
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c1
-rw-r--r--arch/arm/mach-s3c2440/mach-rx1950.c9
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c9
-rw-r--r--arch/arm/mach-s3c64xx/Kconfig7
-rw-r--r--arch/arm/mach-s3c64xx/Makefile1
-rw-r--r--arch/arm/mach-s3c64xx/clock.c6
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/map.h4
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/regs-clock.h5
-rw-r--r--arch/arm/mach-s3c64xx/mach-smdk6410.c8
-rw-r--r--arch/arm/mach-s3c64xx/s3c6410.c6
-rw-r--r--arch/arm/mach-s3c64xx/setup-ide.c46
-rw-r--r--arch/arm/mach-s5p6440/cpu.c3
-rw-r--r--arch/arm/mach-s5pc100/Kconfig11
-rw-r--r--arch/arm/mach-s5pc100/Makefile1
-rw-r--r--arch/arm/mach-s5pc100/cpu.c5
-rw-r--r--arch/arm/mach-s5pc100/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pc100/include/mach/map.h11
-rw-r--r--arch/arm/mach-s5pc100/include/mach/regs-clock.h3
-rw-r--r--arch/arm/mach-s5pc100/mach-smdkc100.c20
-rw-r--r--arch/arm/mach-s5pc100/setup-ide.c70
-rw-r--r--arch/arm/mach-s5pv210/Kconfig41
-rw-r--r--arch/arm/mach-s5pv210/Makefile1
-rw-r--r--arch/arm/mach-s5pv210/cpu.c9
-rw-r--r--arch/arm/mach-s5pv210/gpiolib.c14
-rw-r--r--arch/arm/mach-s5pv210/include/mach/gpio.h12
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-s5pv210/include/mach/map.h3
-rw-r--r--arch/arm/mach-s5pv210/include/mach/memory.h9
-rw-r--r--arch/arm/mach-s5pv210/mach-aquila.c350
-rw-r--r--arch/arm/mach-s5pv210/mach-goni.c375
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkc110.c8
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c8
-rw-r--r--arch/arm/mach-s5pv210/setup-ide.c50
-rw-r--r--arch/arm/mach-sa1100/generic.h3
-rw-r--r--arch/arm/mach-sa1100/include/mach/memory.h6
-rw-r--r--arch/arm/mach-shark/include/mach/memory.h7
-rw-r--r--arch/arm/mach-shmobile/Kconfig13
-rw-r--r--arch/arm/mach-shmobile/Makefile6
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c499
-rw-r--r--arch/arm/mach-shmobile/board-g3evm.c58
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c153
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c357
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c399
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c369
-rw-r--r--arch/arm/mach-shmobile/clock.c44
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h10
-rw-r--r--arch/arm/mach-shmobile/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/memory.h3
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h24
-rw-r--r--arch/arm/mach-shmobile/include/mach/vmalloc.h3
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c178
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c232
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c300
-rw-r--r--arch/arm/mach-shmobile/setup-sh7367.c30
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c391
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c34
-rw-r--r--arch/arm/mach-tegra/Kconfig50
-rw-r--r--arch/arm/mach-tegra/Makefile14
-rw-r--r--arch/arm/mach-tegra/Makefile.boot3
-rw-r--r--arch/arm/mach-tegra/board-harmony-pinmux.c144
-rw-r--r--arch/arm/mach-tegra/board-harmony.c127
-rw-r--r--arch/arm/mach-tegra/board-harmony.h22
-rw-r--r--arch/arm/mach-tegra/board.h32
-rw-r--r--arch/arm/mach-tegra/clock.c488
-rw-r--r--arch/arm/mach-tegra/clock.h147
-rw-r--r--arch/arm/mach-tegra/common.c61
-rw-r--r--arch/arm/mach-tegra/gpio-names.h247
-rw-r--r--arch/arm/mach-tegra/gpio.c348
-rw-r--r--arch/arm/mach-tegra/headsmp.S61
-rw-r--r--arch/arm/mach-tegra/hotplug.c140
-rw-r--r--arch/arm/mach-tegra/include/mach/barriers.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/clk.h26
-rw-r--r--arch/arm/mach-tegra/include/mach/clkdev.h32
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S46
-rw-r--r--arch/arm/mach-tegra/include/mach/entry-macro.S118
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio.h53
-rw-r--r--arch/arm/mach-tegra/include/mach/hardware.h24
-rw-r--r--arch/arm/mach-tegra/include/mach/io.h79
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h203
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h173
-rw-r--r--arch/arm/mach-tegra/include/mach/memory.h28
-rw-r--r--arch/arm/mach-tegra/include/mach/pinmux.h348
-rw-r--r--arch/arm/mach-tegra/include/mach/smp.h30
-rw-r--r--arch/arm/mach-tegra/include/mach/system.h39
-rw-r--r--arch/arm/mach-tegra/include/mach/timex.h26
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h78
-rw-r--r--arch/arm/mach-tegra/include/mach/vmalloc.h28
-rw-r--r--arch/arm/mach-tegra/io.c78
-rw-r--r--arch/arm/mach-tegra/irq.c34
-rw-r--r--arch/arm/mach-tegra/localtimer.c25
-rw-r--r--arch/arm/mach-tegra/pinmux.c945
-rw-r--r--arch/arm/mach-tegra/platsmp.c156
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c1359
-rw-r--r--arch/arm/mach-tegra/timer.c187
-rw-r--r--arch/arm/mach-u300/u300.c17
-rw-r--r--arch/arm/mach-ux500/board-mop500.c28
-rw-r--r--arch/arm/mach-ux500/clock.c2
-rw-r--r--arch/arm/mach-ux500/cpu-db5500.c1
-rw-r--r--arch/arm/mach-ux500/pins-db8500.h742
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c2
-rw-r--r--arch/arm/mach-vexpress/include/mach/ct-ca9x4.h1
-rw-r--r--arch/arm/mm/Kconfig14
-rw-r--r--arch/arm/mm/Makefile1
-rw-r--r--arch/arm/mm/cache-l2x0.c5
-rw-r--r--arch/arm/mm/discontig.c45
-rw-r--r--arch/arm/mm/init.c411
-rw-r--r--arch/arm/mm/ioremap.c6
-rw-r--r--arch/arm/mm/mm.h4
-rw-r--r--arch/arm/mm/mmap.c4
-rw-r--r--arch/arm/mm/mmu.c161
-rw-r--r--arch/arm/mm/nommu.c22
-rw-r--r--arch/arm/mm/proc-v6.S5
-rw-r--r--arch/arm/mm/proc-v7.S2
-rw-r--r--arch/arm/plat-mxc/3ds_debugboard.c202
-rw-r--r--arch/arm/plat-mxc/Kconfig22
-rw-r--r--arch/arm/plat-mxc/Makefile5
-rw-r--r--arch/arm/plat-mxc/audmux-v1.c4
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c19
-rw-r--r--arch/arm/plat-mxc/clock.c37
-rw-r--r--arch/arm/plat-mxc/devices.c33
-rw-r--r--arch/arm/plat-mxc/devices/Kconfig11
-rw-r--r--arch/arm/plat-mxc/devices/Makefile4
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-i2c.c29
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-uart.c60
-rw-r--r--arch/arm/plat-mxc/devices/platform-mxc_nand.c44
-rw-r--r--arch/arm/plat-mxc/devices/platform-spi_imx.c30
-rw-r--r--arch/arm/plat-mxc/ehci.c50
-rw-r--r--arch/arm/plat-mxc/include/mach/3ds_debugboard.h18
-rw-r--r--arch/arm/plat-mxc/include/mach/board-armadillo5x0.h15
-rw-r--r--arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx25.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx35.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/board-kzmarm11.h39
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx21ads.h52
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27ads.h344
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27lite.h14
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx27pdk.h14
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31_3ds.h59
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h117
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lilly.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31lite.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31moboard.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx35pdk.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm037.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm038.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-pcm043.h22
-rw-r--r--arch/arm/plat-mxc/include/mach/board-qong.h17
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h42
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx25.h28
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx51.h553
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mxc91231.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-v3.h15
-rw-r--r--arch/arm/plat-mxc/include/mach/mmc.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/mx1.h28
-rw-r--r--arch/arm/plat-mxc/include/mach/mx25.h38
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mx3_camera.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc91231.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_nand.h10
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/timex.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/vmalloc.h4
-rw-r--r--arch/arm/plat-mxc/irq.c3
-rw-r--r--arch/arm/plat-mxc/system.c4
-rw-r--r--arch/arm/plat-mxc/tzic.c2
-rw-r--r--arch/arm/plat-nomadik/gpio.c316
-rw-r--r--arch/arm/plat-nomadik/include/plat/gpio.h15
-rw-r--r--arch/arm/plat-nomadik/include/plat/mtu.h6
-rw-r--r--arch/arm/plat-nomadik/include/plat/pincfg.h72
-rw-r--r--arch/arm/plat-nomadik/timer.c14
-rw-r--r--arch/arm/plat-omap/Kconfig24
-rw-r--r--arch/arm/plat-omap/Makefile1
-rw-r--r--arch/arm/plat-omap/common.c18
-rw-r--r--arch/arm/plat-omap/debug-leds.c2
-rw-r--r--arch/arm/plat-omap/devices.c124
-rw-r--r--arch/arm/plat-omap/dma.c11
-rw-r--r--arch/arm/plat-omap/fb.c77
-rw-r--r--arch/arm/plat-omap/gpio.c4
-rw-r--r--arch/arm/plat-omap/i2c.c12
-rw-r--r--arch/arm/plat-omap/include/plat/board.h8
-rw-r--r--arch/arm/plat-omap/include/plat/clock.h130
-rw-r--r--arch/arm/plat-omap/include/plat/common.h11
-rw-r--r--arch/arm/plat-omap/include/plat/cpu.h2
-rw-r--r--arch/arm/plat-omap/include/plat/dma.h1
-rw-r--r--arch/arm/plat-omap/include/plat/dsp_common.h40
-rw-r--r--arch/arm/plat-omap/include/plat/iommu.h2
-rw-r--r--arch/arm/plat-omap/include/plat/mux.h224
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h130
-rw-r--r--arch/arm/plat-omap/include/plat/omap_device.h2
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h14
-rw-r--r--arch/arm/plat-omap/include/plat/smp.h1
-rw-r--r--arch/arm/plat-omap/include/plat/uncompress.h6
-rw-r--r--arch/arm/plat-omap/include/plat/usb.h49
-rw-r--r--arch/arm/plat-omap/include/plat/vram.h4
-rw-r--r--arch/arm/plat-omap/iommu.c27
-rw-r--r--arch/arm/plat-omap/iopgtable.h8
-rw-r--r--arch/arm/plat-omap/mux.c2
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c61
-rw-r--r--arch/arm/plat-omap/omap_device.c33
-rw-r--r--arch/arm/plat-omap/usb.c644
-rw-r--r--arch/arm/plat-samsung/Kconfig10
-rw-r--r--arch/arm/plat-samsung/Makefile4
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c72
-rw-r--r--arch/arm/plat-samsung/dev-ide.c44
-rw-r--r--arch/arm/plat-samsung/dev-wdt.c2
-rw-r--r--arch/arm/plat-samsung/include/plat/adc-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/ata-core.h28
-rw-r--r--arch/arm/plat-samsung/include/plat/ata.h36
-rw-r--r--arch/arm/plat-samsung/include/plat/devs.h14
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-ata.h56
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h15
-rw-r--r--arch/arm/plat-samsung/platformdata.c37
-rw-r--r--arch/arm/tools/mach-types152
-rw-r--r--arch/arm/vfp/vfpmodule.c10
-rw-r--r--arch/avr32/include/asm/ioctls.h3
-rw-r--r--arch/avr32/mach-at32ap/include/mach/board.h2
-rw-r--r--arch/blackfin/include/asm/elf.h1
-rw-r--r--arch/blackfin/mach-bf527/include/mach/defBF52x_base.h81
-rw-r--r--arch/blackfin/mach-bf548/include/mach/defBF54x_base.h60
-rw-r--r--arch/ia64/configs/bigsur_defconfig1428
-rw-r--r--arch/ia64/configs/generic_defconfig1788
-rw-r--r--arch/ia64/configs/gensparse_defconfig1493
-rw-r--r--arch/ia64/configs/sim_defconfig756
-rw-r--r--arch/ia64/configs/tiger_defconfig1356
-rw-r--r--arch/ia64/configs/xen_domu_defconfig1678
-rw-r--r--arch/ia64/configs/zx1_defconfig1681
-rw-r--r--arch/ia64/kernel/perfmon.c22
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S362
-rw-r--r--arch/m68k/include/asm/ide.h13
-rw-r--r--arch/m68k/mac/config.c9
-rw-r--r--arch/m68k/mac/misc.c6
-rw-r--r--arch/m68k/sun3/leds.c4
-rw-r--r--arch/microblaze/Kconfig30
-rw-r--r--arch/microblaze/include/asm/cacheflush.h18
-rw-r--r--arch/microblaze/include/asm/dma-mapping.h6
-rw-r--r--arch/microblaze/include/asm/elf.h2
-rw-r--r--arch/microblaze/include/asm/exceptions.h5
-rw-r--r--arch/microblaze/include/asm/page.h12
-rw-r--r--arch/microblaze/include/asm/setup.h2
-rw-r--r--arch/microblaze/include/asm/system.h1
-rw-r--r--arch/microblaze/include/asm/uaccess.h4
-rw-r--r--arch/microblaze/include/asm/unwind.h29
-rw-r--r--arch/microblaze/kernel/Makefile2
-rw-r--r--arch/microblaze/kernel/cpu/mb.c1
-rw-r--r--arch/microblaze/kernel/entry-nommu.S28
-rw-r--r--arch/microblaze/kernel/entry.S41
-rw-r--r--arch/microblaze/kernel/head.S4
-rw-r--r--arch/microblaze/kernel/hw_exception_handler.S4
-rw-r--r--arch/microblaze/kernel/irq.c2
-rw-r--r--arch/microblaze/kernel/misc.S2
-rw-r--r--arch/microblaze/kernel/process.c7
-rw-r--r--arch/microblaze/kernel/ptrace.c17
-rw-r--r--arch/microblaze/kernel/stacktrace.c44
-rw-r--r--arch/microblaze/kernel/timer.c24
-rw-r--r--arch/microblaze/kernel/traps.c91
-rw-r--r--arch/microblaze/kernel/unwind.c318
-rw-r--r--arch/microblaze/kernel/vmlinux.lds.S12
-rw-r--r--arch/microblaze/mm/fault.c1
-rw-r--r--arch/microblaze/mm/init.c7
-rw-r--r--arch/mips/Kbuild15
-rw-r--r--arch/mips/Kbuild.platforms31
-rw-r--r--arch/mips/Makefile519
-rw-r--r--arch/mips/alchemy/Platform109
-rw-r--r--arch/mips/alchemy/common/Makefile2
-rw-r--r--arch/mips/alchemy/common/clocks.c4
-rw-r--r--arch/mips/alchemy/devboards/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/db1200/platform.c8
-rw-r--r--arch/mips/alchemy/devboards/pb1200/Makefile2
-rw-r--r--arch/mips/alchemy/mtx-1/Makefile5
-rw-r--r--arch/mips/alchemy/xxs1500/Makefile4
-rw-r--r--arch/mips/ar7/Makefile1
-rw-r--r--arch/mips/ar7/Platform6
-rw-r--r--arch/mips/ar7/platform.c42
-rw-r--r--arch/mips/bcm47xx/Platform7
-rw-r--r--arch/mips/bcm63xx/Makefile2
-rw-r--r--arch/mips/bcm63xx/Platform7
-rw-r--r--arch/mips/boot/Makefile49
-rw-r--r--arch/mips/boot/compressed/Makefile54
-rw-r--r--arch/mips/cavium-octeon/Makefile3
-rw-r--r--arch/mips/cavium-octeon/Platform11
-rw-r--r--arch/mips/cavium-octeon/cpu.c6
-rw-r--r--arch/mips/cavium-octeon/serial.c4
-rw-r--r--arch/mips/cavium-octeon/setup.c4
-rw-r--r--arch/mips/cobalt/Makefile2
-rw-r--r--arch/mips/cobalt/Platform6
-rw-r--r--arch/mips/configs/powertv_defconfig275
-rw-r--r--arch/mips/dec/Makefile2
-rw-r--r--arch/mips/dec/Platform8
-rw-r--r--arch/mips/dec/promcon.c3
-rw-r--r--arch/mips/emma/Makefile6
-rw-r--r--arch/mips/emma/Platform4
-rw-r--r--arch/mips/emma/markeins/irq.c8
-rw-r--r--arch/mips/include/asm/arch_hweight.h38
-rw-r--r--arch/mips/include/asm/bitops.h5
-rw-r--r--arch/mips/include/asm/cop2.h12
-rw-r--r--arch/mips/include/asm/cpu-features.h3
-rw-r--r--arch/mips/include/asm/emma/emma2rh.h84
-rw-r--r--arch/mips/include/asm/emma/markeins.h37
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h8
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1550.h8
-rw-r--r--arch/mips/include/asm/mach-powertv/asic_reg_map.h2
-rw-r--r--arch/mips/include/asm/mach-powertv/dma-coherence.h8
-rw-r--r--arch/mips/include/asm/mach-powertv/ioremap.h165
-rw-r--r--arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h4
-rw-r--r--arch/mips/jazz/Makefile2
-rw-r--r--arch/mips/jazz/Platform6
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/traps.c7
-rw-r--r--arch/mips/lasat/Makefile2
-rw-r--r--arch/mips/lasat/Platform7
-rw-r--r--arch/mips/loongson/Platform32
-rw-r--r--arch/mips/loongson/common/cs5536/Makefile2
-rw-r--r--arch/mips/loongson/fuloong-2e/Makefile2
-rw-r--r--arch/mips/math-emu/Makefile1
-rw-r--r--arch/mips/math-emu/dp_modf.c2
-rw-r--r--arch/mips/math-emu/dp_tint.c3
-rw-r--r--arch/mips/math-emu/dp_tlong.c3
-rw-r--r--arch/mips/math-emu/sp_modf.c2
-rw-r--r--arch/mips/math-emu/sp_tint.c3
-rw-r--r--arch/mips/math-emu/sp_tlong.c3
-rw-r--r--arch/mips/mipssim/Makefile2
-rw-r--r--arch/mips/mipssim/Platform6
-rw-r--r--arch/mips/mm/Makefile2
-rw-r--r--arch/mips/mm/fault.c1
-rw-r--r--arch/mips/mti-malta/Makefile2
-rw-r--r--arch/mips/mti-malta/Platform7
-rw-r--r--arch/mips/nxp/pnx833x/stb22x/Makefile3
-rw-r--r--arch/mips/nxp/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/nxp/pnx8550/stb810/Makefile4
-rw-r--r--arch/mips/pci/ops-titan-ht.c4
-rw-r--r--arch/mips/pmc-sierra/Platform14
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c11
-rw-r--r--arch/mips/pmc-sierra/yosemite/ht-irq.c13
-rw-r--r--arch/mips/pmc-sierra/yosemite/irq.c4
-rw-r--r--arch/mips/pnx833x/Makefile3
-rw-r--r--arch/mips/pnx833x/Platform5
-rw-r--r--arch/mips/pnx833x/common/Makefile (renamed from arch/mips/nxp/pnx833x/common/Makefile)2
-rw-r--r--arch/mips/pnx833x/common/interrupts.c (renamed from arch/mips/nxp/pnx833x/common/interrupts.c)0
-rw-r--r--arch/mips/pnx833x/common/platform.c (renamed from arch/mips/nxp/pnx833x/common/platform.c)12
-rw-r--r--arch/mips/pnx833x/common/prom.c (renamed from arch/mips/nxp/pnx833x/common/prom.c)0
-rw-r--r--arch/mips/pnx833x/common/reset.c (renamed from arch/mips/nxp/pnx833x/common/reset.c)0
-rw-r--r--arch/mips/pnx833x/common/setup.c (renamed from arch/mips/nxp/pnx833x/common/setup.c)0
-rw-r--r--arch/mips/pnx833x/stb22x/Makefile1
-rw-r--r--arch/mips/pnx833x/stb22x/board.c (renamed from arch/mips/nxp/pnx833x/stb22x/board.c)0
-rw-r--r--arch/mips/pnx8550/Makefile3
-rw-r--r--arch/mips/pnx8550/Platform7
-rw-r--r--arch/mips/pnx8550/common/Makefile (renamed from arch/mips/nxp/pnx8550/common/Makefile)2
-rw-r--r--arch/mips/pnx8550/common/int.c (renamed from arch/mips/nxp/pnx8550/common/int.c)0
-rw-r--r--arch/mips/pnx8550/common/pci.c (renamed from arch/mips/nxp/pnx8550/common/pci.c)0
-rw-r--r--arch/mips/pnx8550/common/platform.c (renamed from arch/mips/nxp/pnx8550/common/platform.c)0
-rw-r--r--arch/mips/pnx8550/common/proc.c (renamed from arch/mips/nxp/pnx8550/common/proc.c)0
-rw-r--r--arch/mips/pnx8550/common/prom.c (renamed from arch/mips/nxp/pnx8550/common/prom.c)0
-rw-r--r--arch/mips/pnx8550/common/reset.c (renamed from arch/mips/nxp/pnx8550/common/reset.c)0
-rw-r--r--arch/mips/pnx8550/common/setup.c (renamed from arch/mips/nxp/pnx8550/common/setup.c)0
-rw-r--r--arch/mips/pnx8550/common/time.c (renamed from arch/mips/nxp/pnx8550/common/time.c)0
-rw-r--r--arch/mips/pnx8550/jbs/Makefile4
-rw-r--r--arch/mips/pnx8550/jbs/board_setup.c (renamed from arch/mips/nxp/pnx8550/jbs/board_setup.c)0
-rw-r--r--arch/mips/pnx8550/jbs/init.c (renamed from arch/mips/nxp/pnx8550/jbs/init.c)0
-rw-r--r--arch/mips/pnx8550/jbs/irqmap.c (renamed from arch/mips/nxp/pnx8550/jbs/irqmap.c)0
-rw-r--r--arch/mips/pnx8550/stb810/Makefile4
-rw-r--r--arch/mips/pnx8550/stb810/board_setup.c (renamed from arch/mips/nxp/pnx8550/stb810/board_setup.c)0
-rw-r--r--arch/mips/pnx8550/stb810/irqmap.c (renamed from arch/mips/nxp/pnx8550/stb810/irqmap.c)0
-rw-r--r--arch/mips/pnx8550/stb810/prom_init.c (renamed from arch/mips/nxp/pnx8550/stb810/prom_init.c)0
-rw-r--r--arch/mips/powertv/Makefile5
-rw-r--r--arch/mips/powertv/Platform7
-rw-r--r--arch/mips/powertv/asic/asic-calliope.c2
-rw-r--r--arch/mips/powertv/asic/asic-cronus.c4
-rw-r--r--arch/mips/powertv/asic/asic-zeus.c2
-rw-r--r--arch/mips/powertv/asic/asic_devices.c24
-rw-r--r--arch/mips/powertv/init.c4
-rw-r--r--arch/mips/powertv/ioremap.c136
-rw-r--r--arch/mips/powertv/memory.c342
-rw-r--r--arch/mips/powertv/powertv_setup.c6
-rw-r--r--arch/mips/rb532/Makefile2
-rw-r--r--arch/mips/rb532/Platform7
-rw-r--r--arch/mips/sgi-ip22/Makefile2
-rw-r--r--arch/mips/sgi-ip22/Platform34
-rw-r--r--arch/mips/sgi-ip27/Makefile2
-rw-r--r--arch/mips/sgi-ip27/Platform19
-rw-r--r--arch/mips/sgi-ip27/ip27-klconfig.c8
-rw-r--r--arch/mips/sgi-ip32/Makefile2
-rw-r--r--arch/mips/sgi-ip32/Platform11
-rw-r--r--arch/mips/sibyte/Makefile27
-rw-r--r--arch/mips/sibyte/Platform43
-rw-r--r--arch/mips/sibyte/bcm1480/Makefile2
-rw-r--r--arch/mips/sibyte/common/Makefile2
-rw-r--r--arch/mips/sibyte/sb1250/Makefile2
-rw-r--r--arch/mips/sni/Makefile2
-rw-r--r--arch/mips/sni/Platform11
-rw-r--r--arch/mips/txx9/Makefile17
-rw-r--r--arch/mips/txx9/Platform10
-rw-r--r--arch/mips/txx9/generic/Makefile2
-rw-r--r--arch/mips/txx9/jmr3927/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4927/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4938/Makefile2
-rw-r--r--arch/mips/txx9/rbtx4939/Makefile2
-rw-r--r--arch/mips/vr41xx/Platform32
-rw-r--r--arch/mips/vr41xx/common/Makefile2
-rw-r--r--arch/mips/wrppmc/Makefile (renamed from arch/mips/gt64120/wrppmc/Makefile)4
-rw-r--r--arch/mips/wrppmc/Platform7
-rw-r--r--arch/mips/wrppmc/irq.c (renamed from arch/mips/gt64120/wrppmc/irq.c)0
-rw-r--r--arch/mips/wrppmc/pci.c (renamed from arch/mips/gt64120/wrppmc/pci.c)0
-rw-r--r--arch/mips/wrppmc/reset.c (renamed from arch/mips/gt64120/wrppmc/reset.c)0
-rw-r--r--arch/mips/wrppmc/serial.c (renamed from arch/mips/gt64120/wrppmc/serial.c)0
-rw-r--r--arch/mips/wrppmc/setup.c (renamed from arch/mips/gt64120/wrppmc/setup.c)0
-rw-r--r--arch/mips/wrppmc/time.c (renamed from arch/mips/gt64120/wrppmc/time.c)0
-rw-r--r--arch/powerpc/Kconfig3
-rw-r--r--arch/powerpc/include/asm/abs_addr.h2
-rw-r--r--arch/powerpc/include/asm/asm-compat.h2
-rw-r--r--arch/powerpc/include/asm/cpm.h24
-rw-r--r--arch/powerpc/include/asm/cpm1.h3
-rw-r--r--arch/powerpc/include/asm/cputable.h4
-rw-r--r--arch/powerpc/include/asm/hvcall.h1
-rw-r--r--arch/powerpc/include/asm/hw_breakpoint.h74
-rw-r--r--arch/powerpc/include/asm/machdep.h4
-rw-r--r--arch/powerpc/include/asm/percpu.h3
-rw-r--r--arch/powerpc/include/asm/ppc-opcode.h7
-rw-r--r--arch/powerpc/include/asm/processor.h8
-rw-r--r--arch/powerpc/include/asm/rtas.h13
-rw-r--r--arch/powerpc/include/asm/time.h7
-rw-r--r--arch/powerpc/include/asm/topology.h3
-rw-r--r--arch/powerpc/include/asm/vdso_datapage.h2
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S1
-rw-r--r--arch/powerpc/kernel/fsl_booke_entry_mapping.S4
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c364
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c3
-rw-r--r--arch/powerpc/kernel/process.c14
-rw-r--r--arch/powerpc/kernel/ptrace.c64
-rw-r--r--arch/powerpc/kernel/rtas.c105
-rw-r--r--arch/powerpc/kernel/setup-common.c13
-rw-r--r--arch/powerpc/kernel/setup_64.c9
-rw-r--r--arch/powerpc/kernel/signal.c3
-rw-r--r--arch/powerpc/kernel/smp.c2
-rw-r--r--arch/powerpc/kernel/time.c197
-rw-r--r--arch/powerpc/kernel/traps.c8
-rw-r--r--arch/powerpc/kernel/vdso32/gettimeofday.S184
-rw-r--r--arch/powerpc/kernel/vdso64/gettimeofday.S88
-rw-r--r--arch/powerpc/lib/Makefile5
-rw-r--r--arch/powerpc/lib/ldstfp.S375
-rw-r--r--arch/powerpc/lib/sstep.c1514
-rw-r--r--arch/powerpc/mm/fsl_booke_mmu.c7
-rw-r--r--arch/powerpc/mm/numa.c122
-rw-r--r--arch/powerpc/mm/pgtable.c1
-rw-r--r--arch/powerpc/mm/tlb_hash32.c15
-rw-r--r--arch/powerpc/platforms/512x/Kconfig13
-rw-r--r--arch/powerpc/platforms/52xx/lite5200_pm.c3
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pm.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c12
-rw-r--r--arch/powerpc/platforms/iseries/vio.c3
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_32.c8
-rw-r--r--arch/powerpc/platforms/pseries/Makefile4
-rw-r--r--arch/powerpc/platforms/pseries/eeh_cache.c3
-rw-r--r--arch/powerpc/platforms/pseries/event_sources.c23
-rw-r--r--arch/powerpc/platforms/pseries/hotplug-cpu.c3
-rw-r--r--arch/powerpc/platforms/pseries/ras.c5
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c4
-rw-r--r--arch/powerpc/platforms/pseries/suspend.c214
-rw-r--r--arch/powerpc/sysdev/micropatch.c30
-rw-r--r--arch/powerpc/sysdev/mpic.c18
-rw-r--r--arch/powerpc/sysdev/mpic.h1
-rw-r--r--arch/s390/hypfs/inode.c6
-rw-r--r--arch/s390/include/asm/ccwdev.h2
-rw-r--r--arch/s390/mm/cmm.c11
-rw-r--r--arch/sh/Kconfig3
-rw-r--r--arch/sh/boards/Kconfig16
-rw-r--r--arch/sh/boards/Makefile2
-rw-r--r--arch/sh/boards/board-sh2007.c133
-rw-r--r--arch/sh/boards/board-sh7757lcr.c374
-rw-r--r--arch/sh/configs/sh2007_defconfig1357
-rw-r--r--arch/sh/configs/sh7757lcr_defconfig1126
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c2
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c2
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c2
-rw-r--r--arch/sh/include/asm/Kbuild2
-rw-r--r--arch/sh/include/asm/elf.h27
-rw-r--r--arch/sh/include/asm/fixmap.h4
-rw-r--r--arch/sh/include/asm/irq.h2
-rw-r--r--arch/sh/include/asm/kprobes.h1
-rw-r--r--arch/sh/include/asm/processor_32.h3
-rw-r--r--arch/sh/include/asm/processor_64.h3
-rw-r--r--arch/sh/include/asm/ptrace.h169
-rw-r--r--arch/sh/include/asm/ptrace_32.h83
-rw-r--r--arch/sh/include/asm/ptrace_64.h20
-rw-r--r--arch/sh/include/asm/system_32.h13
-rw-r--r--arch/sh/include/asm/tlbflush.h2
-rw-r--r--arch/sh/include/cpu-sh4/cpu/sh7757.h301
-rw-r--r--arch/sh/include/mach-common/mach/sh2007.h117
-rw-r--r--arch/sh/kernel/Makefile2
-rw-r--r--arch/sh/kernel/cpu/sh4/probe.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7757.c199
-rw-r--r--arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c1582
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c222
-rw-r--r--arch/sh/kernel/kprobes.c100
-rw-r--r--arch/sh/kernel/ptrace.c33
-rw-r--r--arch/sh/kernel/ptrace_32.c27
-rw-r--r--arch/sh/kernel/ptrace_64.c79
-rw-r--r--arch/sh/kernel/reboot.c4
-rw-r--r--arch/sh/mm/init.c52
-rw-r--r--arch/sh/mm/tlbflush_32.c16
-rw-r--r--arch/sh/mm/tlbflush_64.c5
-rw-r--r--arch/sh/tools/mach-types2
-rw-r--r--arch/sparc/configs/sparc64_defconfig49
-rw-r--r--arch/sparc/include/asm/pgtable_32.h5
-rw-r--r--arch/sparc/kernel/perf_event.c1
-rw-r--r--arch/sparc/kernel/sun4d_irq.c2
-rw-r--r--arch/sparc/mm/srmmu.c2
-rw-r--r--arch/sparc/mm/sun4c.c3
-rw-r--r--arch/tile/Kbuild3
-rw-r--r--arch/tile/Kconfig356
-rw-r--r--arch/tile/Kconfig.debug43
-rw-r--r--arch/tile/Makefile52
-rw-r--r--arch/tile/configs/tile_defconfig1290
-rw-r--r--arch/tile/include/arch/abi.h98
-rw-r--r--arch/tile/include/arch/chip.h23
-rw-r--r--arch/tile/include/arch/chip_tile64.h255
-rw-r--r--arch/tile/include/arch/chip_tilepro.h255
-rw-r--r--arch/tile/include/arch/icache.h94
-rw-r--r--arch/tile/include/arch/interrupts.h19
-rw-r--r--arch/tile/include/arch/interrupts_32.h304
-rw-r--r--arch/tile/include/arch/sim_def.h512
-rw-r--r--arch/tile/include/arch/spr_def.h19
-rw-r--r--arch/tile/include/arch/spr_def_32.h162
-rw-r--r--arch/tile/include/asm/Kbuild3
-rw-r--r--arch/tile/include/asm/asm-offsets.h1
-rw-r--r--arch/tile/include/asm/atomic.h159
-rw-r--r--arch/tile/include/asm/atomic_32.h370
-rw-r--r--arch/tile/include/asm/auxvec.h20
-rw-r--r--arch/tile/include/asm/backtrace.h193
-rw-r--r--arch/tile/include/asm/bitops.h126
-rw-r--r--arch/tile/include/asm/bitops_32.h132
-rw-r--r--arch/tile/include/asm/bitsperlong.h26
-rw-r--r--arch/tile/include/asm/bug.h1
-rw-r--r--arch/tile/include/asm/bugs.h1
-rw-r--r--arch/tile/include/asm/byteorder.h1
-rw-r--r--arch/tile/include/asm/cache.h52
-rw-r--r--arch/tile/include/asm/cacheflush.h140
-rw-r--r--arch/tile/include/asm/checksum.h24
-rw-r--r--arch/tile/include/asm/compat.h257
-rw-r--r--arch/tile/include/asm/cputime.h1
-rw-r--r--arch/tile/include/asm/current.h31
-rw-r--r--arch/tile/include/asm/delay.h34
-rw-r--r--arch/tile/include/asm/device.h1
-rw-r--r--arch/tile/include/asm/div64.h1
-rw-r--r--arch/tile/include/asm/dma-mapping.h102
-rw-r--r--arch/tile/include/asm/dma.h25
-rw-r--r--arch/tile/include/asm/elf.h167
-rw-r--r--arch/tile/include/asm/emergency-restart.h1
-rw-r--r--arch/tile/include/asm/errno.h1
-rw-r--r--arch/tile/include/asm/fcntl.h1
-rw-r--r--arch/tile/include/asm/fixmap.h124
-rw-r--r--arch/tile/include/asm/ftrace.h20
-rw-r--r--arch/tile/include/asm/futex.h141
-rw-r--r--arch/tile/include/asm/hardirq.h47
-rw-r--r--arch/tile/include/asm/hardwall.h56
-rw-r--r--arch/tile/include/asm/highmem.h73
-rw-r--r--arch/tile/include/asm/homecache.h125
-rw-r--r--arch/tile/include/asm/hugetlb.h109
-rw-r--r--arch/tile/include/asm/hv_driver.h60
-rw-r--r--arch/tile/include/asm/hw_irq.h18
-rw-r--r--arch/tile/include/asm/ide.h25
-rw-r--r--arch/tile/include/asm/io.h279
-rw-r--r--arch/tile/include/asm/ioctl.h1
-rw-r--r--arch/tile/include/asm/ioctls.h1
-rw-r--r--arch/tile/include/asm/ipc.h1
-rw-r--r--arch/tile/include/asm/ipcbuf.h1
-rw-r--r--arch/tile/include/asm/irq.h87
-rw-r--r--arch/tile/include/asm/irq_regs.h1
-rw-r--r--arch/tile/include/asm/irqflags.h266
-rw-r--r--arch/tile/include/asm/kdebug.h1
-rw-r--r--arch/tile/include/asm/kexec.h53
-rw-r--r--arch/tile/include/asm/kmap_types.h43
-rw-r--r--arch/tile/include/asm/linkage.h51
-rw-r--r--arch/tile/include/asm/local.h1
-rw-r--r--arch/tile/include/asm/memprof.h33
-rw-r--r--arch/tile/include/asm/mman.h40
-rw-r--r--arch/tile/include/asm/mmu.h31
-rw-r--r--arch/tile/include/asm/mmu_context.h131
-rw-r--r--arch/tile/include/asm/mmzone.h81
-rw-r--r--arch/tile/include/asm/module.h1
-rw-r--r--arch/tile/include/asm/msgbuf.h1
-rw-r--r--arch/tile/include/asm/mutex.h1
-rw-r--r--arch/tile/include/asm/opcode-tile.h30
-rw-r--r--arch/tile/include/asm/opcode-tile_32.h1506
-rw-r--r--arch/tile/include/asm/opcode-tile_64.h1506
-rw-r--r--arch/tile/include/asm/opcode_constants.h26
-rw-r--r--arch/tile/include/asm/opcode_constants_32.h480
-rw-r--r--arch/tile/include/asm/opcode_constants_64.h480
-rw-r--r--arch/tile/include/asm/page.h339
-rw-r--r--arch/tile/include/asm/param.h1
-rw-r--r--arch/tile/include/asm/pci-bridge.h117
-rw-r--r--arch/tile/include/asm/pci.h128
-rw-r--r--arch/tile/include/asm/percpu.h24
-rw-r--r--arch/tile/include/asm/pgalloc.h119
-rw-r--r--arch/tile/include/asm/pgtable.h480
-rw-r--r--arch/tile/include/asm/pgtable_32.h129
-rw-r--r--arch/tile/include/asm/poll.h1
-rw-r--r--arch/tile/include/asm/posix_types.h1
-rw-r--r--arch/tile/include/asm/processor.h338
-rw-r--r--arch/tile/include/asm/ptrace.h166
-rw-r--r--arch/tile/include/asm/resource.h1
-rw-r--r--arch/tile/include/asm/scatterlist.h22
-rw-r--r--arch/tile/include/asm/sections.h44
-rw-r--r--arch/tile/include/asm/sembuf.h1
-rw-r--r--arch/tile/include/asm/setup.h32
-rw-r--r--arch/tile/include/asm/shmbuf.h1
-rw-r--r--arch/tile/include/asm/shmparam.h1
-rw-r--r--arch/tile/include/asm/sigcontext.h27
-rw-r--r--arch/tile/include/asm/sigframe.h33
-rw-r--r--arch/tile/include/asm/siginfo.h30
-rw-r--r--arch/tile/include/asm/signal.h32
-rw-r--r--arch/tile/include/asm/smp.h147
-rw-r--r--arch/tile/include/asm/socket.h1
-rw-r--r--arch/tile/include/asm/sockios.h1
-rw-r--r--arch/tile/include/asm/spinlock.h24
-rw-r--r--arch/tile/include/asm/spinlock_32.h199
-rw-r--r--arch/tile/include/asm/spinlock_types.h60
-rw-r--r--arch/tile/include/asm/stack.h74
-rw-r--r--arch/tile/include/asm/stat.h1
-rw-r--r--arch/tile/include/asm/statfs.h1
-rw-r--r--arch/tile/include/asm/string.h32
-rw-r--r--arch/tile/include/asm/swab.h29
-rw-r--r--arch/tile/include/asm/syscall.h79
-rw-r--r--arch/tile/include/asm/syscalls.h108
-rw-r--r--arch/tile/include/asm/system.h248
-rw-r--r--arch/tile/include/asm/termbits.h1
-rw-r--r--arch/tile/include/asm/termios.h1
-rw-r--r--arch/tile/include/asm/thread_info.h166
-rw-r--r--arch/tile/include/asm/timex.h47
-rw-r--r--arch/tile/include/asm/tlb.h25
-rw-r--r--arch/tile/include/asm/tlbflush.h128
-rw-r--r--arch/tile/include/asm/topology.h85
-rw-r--r--arch/tile/include/asm/traps.h62
-rw-r--r--arch/tile/include/asm/types.h1
-rw-r--r--arch/tile/include/asm/uaccess.h580
-rw-r--r--arch/tile/include/asm/ucontext.h1
-rw-r--r--arch/tile/include/asm/unaligned.h24
-rw-r--r--arch/tile/include/asm/unistd.h46
-rw-r--r--arch/tile/include/asm/user.h21
-rw-r--r--arch/tile/include/asm/xor.h1
-rw-r--r--arch/tile/include/hv/drv_pcie_rc_intf.h38
-rw-r--r--arch/tile/include/hv/hypervisor.h2375
-rw-r--r--arch/tile/include/hv/pagesize.h32
-rw-r--r--arch/tile/include/hv/syscall_public.h42
-rw-r--r--arch/tile/kernel/Makefile17
-rw-r--r--arch/tile/kernel/asm-offsets.c76
-rw-r--r--arch/tile/kernel/backtrace.c621
-rw-r--r--arch/tile/kernel/compat.c167
-rw-r--r--arch/tile/kernel/compat_signal.c435
-rw-r--r--arch/tile/kernel/early_printk.c109
-rw-r--r--arch/tile/kernel/entry.S141
-rw-r--r--arch/tile/kernel/hardwall.c794
-rw-r--r--arch/tile/kernel/head_32.S180
-rw-r--r--arch/tile/kernel/hvglue.lds58
-rw-r--r--arch/tile/kernel/init_task.c59
-rw-r--r--arch/tile/kernel/intvec_32.S2008
-rw-r--r--arch/tile/kernel/irq.c334
-rw-r--r--arch/tile/kernel/machine_kexec.c279
-rw-r--r--arch/tile/kernel/messaging.c116
-rw-r--r--arch/tile/kernel/module.c257
-rw-r--r--arch/tile/kernel/pci-dma.c251
-rw-r--r--arch/tile/kernel/proc.c91
-rw-r--r--arch/tile/kernel/process.c671
-rw-r--r--arch/tile/kernel/ptrace.c205
-rw-r--r--arch/tile/kernel/reboot.c51
-rw-r--r--arch/tile/kernel/regs_32.S145
-rw-r--r--arch/tile/kernel/relocate_kernel.S280
-rw-r--r--arch/tile/kernel/setup.c1511
-rw-r--r--arch/tile/kernel/signal.c358
-rw-r--r--arch/tile/kernel/single_step.c663
-rw-r--r--arch/tile/kernel/smp.c256
-rw-r--r--arch/tile/kernel/smpboot.c278
-rw-r--r--arch/tile/kernel/stack.c486
-rw-r--r--arch/tile/kernel/sys.c120
-rw-r--r--arch/tile/kernel/tile-desc_32.c2498
-rw-r--r--arch/tile/kernel/time.c221
-rw-r--r--arch/tile/kernel/tlb.c97
-rw-r--r--arch/tile/kernel/traps.c317
-rw-r--r--arch/tile/kernel/vmlinux.lds.S98
-rw-r--r--arch/tile/lib/Makefile16
-rw-r--r--arch/tile/lib/atomic_32.c330
-rw-r--r--arch/tile/lib/atomic_asm_32.S196
-rw-r--r--arch/tile/lib/cacheflush.c23
-rw-r--r--arch/tile/lib/checksum.c102
-rw-r--r--arch/tile/lib/cpumask.c52
-rw-r--r--arch/tile/lib/delay.c34
-rw-r--r--arch/tile/lib/exports.c79
-rw-r--r--arch/tile/lib/mb_incoherent.S34
-rw-r--r--arch/tile/lib/memchr_32.c68
-rw-r--r--arch/tile/lib/memcpy_32.S628
-rw-r--r--arch/tile/lib/memcpy_tile64.c271
-rw-r--r--arch/tile/lib/memmove_32.c63
-rw-r--r--arch/tile/lib/memset_32.c275
-rw-r--r--arch/tile/lib/spinlock_32.c221
-rw-r--r--arch/tile/lib/spinlock_common.h64
-rw-r--r--arch/tile/lib/strchr_32.c66
-rw-r--r--arch/tile/lib/strlen_32.c36
-rw-r--r--arch/tile/lib/uaccess.c32
-rw-r--r--arch/tile/lib/usercopy_32.S223
-rw-r--r--arch/tile/mm/Makefile9
-rw-r--r--arch/tile/mm/elf.c164
-rw-r--r--arch/tile/mm/extable.c30
-rw-r--r--arch/tile/mm/fault.c867
-rw-r--r--arch/tile/mm/highmem.c328
-rw-r--r--arch/tile/mm/homecache.c433
-rw-r--r--arch/tile/mm/hugetlbpage.c343
-rw-r--r--arch/tile/mm/init.c1085
-rw-r--r--arch/tile/mm/migrate.h50
-rw-r--r--arch/tile/mm/migrate_32.S211
-rw-r--r--arch/tile/mm/mmap.c75
-rw-r--r--arch/tile/mm/pgtable.c530
-rw-r--r--arch/um/include/shared/os.h3
-rw-r--r--arch/um/kernel/ksyms.c3
-rw-r--r--arch/um/os-Linux/file.c15
-rw-r--r--arch/um/os-Linux/user_syms.c4
-rw-r--r--arch/x86/include/asm/pci_x86.h1
-rw-r--r--arch/x86/pci/common.c20
-rw-r--r--arch/x86/pci/legacy.c2
-rw-r--r--arch/xtensa/Kconfig17
-rw-r--r--arch/xtensa/Makefile7
-rw-r--r--arch/xtensa/boot/Makefile1
-rw-r--r--arch/xtensa/configs/iss_defconfig1
-rw-r--r--arch/xtensa/include/asm/cacheflush.h1
-rw-r--r--arch/xtensa/include/asm/coprocessor.h9
-rw-r--r--arch/xtensa/include/asm/elf.h1
-rw-r--r--arch/xtensa/include/asm/io.h40
-rw-r--r--arch/xtensa/include/asm/irq.h7
-rw-r--r--arch/xtensa/include/asm/pgalloc.h1
-rw-r--r--arch/xtensa/include/asm/processor.h1
-rw-r--r--arch/xtensa/include/asm/ptrace.h2
-rw-r--r--arch/xtensa/include/asm/serial.h12
-rw-r--r--arch/xtensa/kernel/Makefile8
-rw-r--r--arch/xtensa/kernel/asm-offsets.c1
-rw-r--r--arch/xtensa/kernel/entry.S1
-rw-r--r--arch/xtensa/kernel/head.S4
-rw-r--r--arch/xtensa/kernel/time.c2
-rw-r--r--arch/xtensa/platforms/iss/network.c22
-rw-r--r--arch/xtensa/platforms/xtavnet/Makefile10
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/hardware.h85
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/lcd.h22
-rw-r--r--arch/xtensa/platforms/xtavnet/include/platform/serial.h1
-rw-r--r--arch/xtensa/platforms/xtavnet/lcd.c79
-rw-r--r--arch/xtensa/platforms/xtavnet/setup.c269
-rw-r--r--crypto/ablkcipher.c2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/acpi/pci_root.c9
-rw-r--r--drivers/char/Makefile1
-rw-r--r--drivers/char/hvc_console.c12
-rw-r--r--drivers/char/hvc_tile.c67
-rw-r--r--drivers/char/hvsi.c4
-rw-r--r--drivers/dma/Kconfig2
-rw-r--r--drivers/dma/shdma.c8
-rw-r--r--drivers/hid/Kconfig11
-rw-r--r--drivers/hid/Makefile1
-rw-r--r--drivers/hid/hid-core.c2
-rw-r--r--drivers/hid/hid-elecom.c57
-rw-r--r--drivers/hid/hid-ids.h85
-rw-r--r--drivers/hid/hid-input.c3
-rw-r--r--drivers/hid/hid-magicmouse.c96
-rw-r--r--drivers/hid/hid-picolcd.c199
-rw-r--r--drivers/hid/hid-roccat-kone.c25
-rw-r--r--drivers/hid/hid-roccat-kone.h2
-rw-r--r--drivers/hid/hid-roccat.c9
-rw-r--r--drivers/hid/hid-roccat.h2
-rw-r--r--drivers/hid/hid-topseed.c5
-rw-r--r--drivers/hid/hidraw.c107
-rw-r--r--drivers/hid/usbhid/hid-core.c30
-rw-r--r--drivers/hid/usbhid/hiddev.c54
-rw-r--r--drivers/hwmon/Kconfig10
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/asc7621.c9
-rw-r--r--drivers/hwmon/emc1403.c33
-rw-r--r--drivers/hwmon/emc2103.c740
-rw-r--r--drivers/hwmon/it87.c46
-rw-r--r--drivers/hwmon/lm75.c39
-rw-r--r--drivers/hwmon/lm75.h1
-rw-r--r--drivers/hwmon/ltc4245.c177
-rw-r--r--drivers/hwmon/pc87360.c30
-rw-r--r--drivers/hwmon/w83627ehf.c97
-rw-r--r--drivers/i2c/busses/Kconfig2
-rw-r--r--drivers/i2c/busses/i2c-sh_mobile.c121
-rw-r--r--drivers/i2c/i2c-core.c87
-rw-r--r--drivers/i2c/i2c-dev.c26
-rw-r--r--drivers/ide/ide-taskfile.c10
-rw-r--r--drivers/ide/tx4938ide.c2
-rw-r--r--drivers/ide/tx4939ide.c2
-rw-r--r--drivers/input/evdev.c39
-rw-r--r--drivers/input/input.c267
-rw-r--r--drivers/input/mouse/synaptics.c1
-rw-r--r--drivers/input/serio/i8042-io.h5
-rw-r--r--drivers/macintosh/therm_windtunnel.c4
-rw-r--r--drivers/media/IR/Kconfig34
-rw-r--r--drivers/media/IR/Makefile3
-rw-r--r--drivers/media/IR/imon.c5
-rw-r--r--drivers/media/IR/ir-core-priv.h54
-rw-r--r--drivers/media/IR/ir-jvc-decoder.c152
-rw-r--r--drivers/media/IR/ir-lirc-codec.c283
-rw-r--r--drivers/media/IR/ir-nec-decoder.c151
-rw-r--r--drivers/media/IR/ir-raw-event.c167
-rw-r--r--drivers/media/IR/ir-rc5-decoder.c167
-rw-r--r--drivers/media/IR/ir-rc6-decoder.c153
-rw-r--r--drivers/media/IR/ir-sony-decoder.c155
-rw-r--r--drivers/media/IR/ir-sysfs.c261
-rw-r--r--drivers/media/IR/keymaps/Makefile2
-rw-r--r--drivers/media/IR/keymaps/rc-lirc.c41
-rw-r--r--drivers/media/IR/keymaps/rc-rc6-mce.c105
-rw-r--r--drivers/media/IR/lirc_dev.c764
-rw-r--r--drivers/media/IR/lirc_dev.h225
-rw-r--r--drivers/media/IR/mceusb.c1143
-rw-r--r--drivers/media/common/saa7146_fops.c2
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c8
-rw-r--r--drivers/media/common/tuners/tuner-simple.c3
-rw-r--r--drivers/media/common/tuners/xc5000.c59
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c10
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c10
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c10
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c82
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-init.c60
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig1
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c9
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h4
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c267
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.h10
-rw-r--r--drivers/media/dvb/frontends/lgs8gxx.c50
-rw-r--r--drivers/media/dvb/frontends/mb86a16.c1
-rw-r--r--drivers/media/dvb/frontends/tda10048.c43
-rw-r--r--drivers/media/dvb/mantis/Kconfig14
-rw-r--r--drivers/media/dvb/mantis/mantis_input.c5
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c4
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c2
-rw-r--r--drivers/media/radio/si4713-i2c.c12
-rw-r--r--drivers/media/video/Kconfig177
-rw-r--r--drivers/media/video/Makefile8
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-vbi.c138
-rw-r--r--drivers/media/video/au0828/au0828-video.c441
-rw-r--r--drivers/media/video/au0828/au0828.h20
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c2
-rw-r--r--drivers/media/video/cpia_usb.c3
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c3
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c40
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c11
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c15
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c317
-rw-r--r--drivers/media/video/cx23885/cx23885-ir.c2
-rw-r--r--drivers/media/video/cx23885/cx23885.h12
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c35
-rw-r--r--drivers/media/video/cx88/cx88-cards.c9
-rw-r--r--drivers/media/video/cx88/cx88-core.c2
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c25
-rw-r--r--drivers/media/video/cx88/cx88-input.c46
-rw-r--r--drivers/media/video/cx88/cx88.h1
-rw-r--r--drivers/media/video/dabusb.c13
-rw-r--r--drivers/media/video/davinci/Kconfig93
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c80
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c4
-rw-r--r--drivers/media/video/em28xx/em28xx.h1
-rw-r--r--drivers/media/video/fsl-viu.c1632
-rw-r--r--drivers/media/video/gspca/Kconfig18
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/conex.c8
-rw-r--r--drivers/media/video/gspca/cpia1.c19
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c731
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c4
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c42
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h13
-rw-r--r--drivers/media/video/gspca/gspca.c284
-rw-r--r--drivers/media/video/gspca/gspca.h19
-rw-r--r--drivers/media/video/gspca/jeilinj.c6
-rw-r--r--drivers/media/video/gspca/m5602/m5602_bridge.h1
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c15
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.c1
-rw-r--r--drivers/media/video/gspca/mars.c13
-rw-r--r--drivers/media/video/gspca/ov519.c28
-rw-r--r--drivers/media/video/gspca/ov534.c7
-rw-r--r--drivers/media/video/gspca/pac7302.c31
-rw-r--r--drivers/media/video/gspca/pac7311.c29
-rw-r--r--drivers/media/video/gspca/sn9c20x.c18
-rw-r--r--drivers/media/video/gspca/sonixb.c8
-rw-r--r--drivers/media/video/gspca/sonixj.c1
-rw-r--r--drivers/media/video/gspca/spca1528.c605
-rw-r--r--drivers/media/video/gspca/spca500.c13
-rw-r--r--drivers/media/video/gspca/sq930x.c1402
-rw-r--r--drivers/media/video/gspca/stk014.c17
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.h1
-rw-r--r--drivers/media/video/gspca/sunplus.c13
-rw-r--r--drivers/media/video/gspca/t613.c408
-rw-r--r--drivers/media/video/gspca/tv8532.c227
-rw-r--r--drivers/media/video/gspca/vc032x.c213
-rw-r--r--drivers/media/video/gspca/w996Xcf.c16
-rw-r--r--drivers/media/video/gspca/zc3xx.c92
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c5
-rw-r--r--drivers/media/video/ir-kbd-i2c.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c30
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c122
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c9
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-mailbox.h1
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c11
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c41
-rw-r--r--drivers/media/video/omap24xxcam.c2
-rw-r--r--drivers/media/video/ov511.c5995
-rw-r--r--drivers/media/video/ov511.h573
-rw-r--r--drivers/media/video/ovcamchip/Makefile4
-rw-r--r--drivers/media/video/ovcamchip/ov6x20.c414
-rw-r--r--drivers/media/video/ovcamchip/ov6x30.c373
-rw-r--r--drivers/media/video/ovcamchip/ov76be.c302
-rw-r--r--drivers/media/video/ovcamchip/ov7x10.c334
-rw-r--r--drivers/media/video/ovcamchip/ov7x20.c454
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c395
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h101
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ioread.c5
-rw-r--r--drivers/media/video/pxa_camera.c2
-rw-r--r--drivers/media/video/s2255drv.c724
-rw-r--r--drivers/media/video/saa7134/saa7134-alsa.c12
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c31
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c2
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c23
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/stv680.c1565
-rw-r--r--drivers/media/video/stv680.h227
-rw-r--r--drivers/media/video/tlg2300/pd-main.c3
-rw-r--r--drivers/media/video/usbvideo/Kconfig14
-rw-r--r--drivers/media/video/usbvideo/Makefile1
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.c1126
-rw-r--r--drivers/media/video/usbvideo/quickcam_messenger.h112
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c105
-rw-r--r--drivers/media/video/uvc/uvc_driver.c15
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c95
-rw-r--r--drivers/media/video/uvc/uvcvideo.h26
-rw-r--r--drivers/media/video/v4l2-common.c3
-rw-r--r--drivers/media/video/v4l2-dev.c6
-rw-r--r--drivers/media/video/videobuf-core.c84
-rw-r--r--drivers/media/video/videobuf-dma-contig.c6
-rw-r--r--drivers/media/video/videobuf-dma-sg.c76
-rw-r--r--drivers/media/video/videobuf-vmalloc.c36
-rw-r--r--drivers/media/video/w9968cf.c3620
-rw-r--r--drivers/media/video/w9968cf.h333
-rw-r--r--drivers/media/video/w9968cf_decoder.h86
-rw-r--r--drivers/media/video/w9968cf_vpp.h40
-rw-r--r--drivers/media/video/zc0301/Kconfig15
-rw-r--r--drivers/media/video/zc0301/Makefile3
-rw-r--r--drivers/media/video/zc0301/zc0301.h196
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c2098
-rw-r--r--drivers/media/video/zc0301/zc0301_pas202bcb.c362
-rw-r--r--drivers/media/video/zc0301/zc0301_pb0330.c188
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h107
-rw-r--r--drivers/media/video/zoran/videocodec.c5
-rw-r--r--drivers/mmc/host/msm_sdcc.c38
-rw-r--r--drivers/mmc/host/mxcmmc.c16
-rw-r--r--drivers/mtd/nand/mxc_nand.c33
-rw-r--r--drivers/net/e1000e/netdev.c16
-rw-r--r--drivers/net/pcmcia/axnet_cs.c7
-rw-r--r--drivers/net/r8169.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_pci.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h11
-rw-r--r--drivers/pci/bus.c4
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c2
-rw-r--r--drivers/pci/hotplug/shpchp_hpc.c2
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c19
-rw-r--r--drivers/pci/msi.c36
-rw-r--r--drivers/pci/pci-driver.c32
-rw-r--r--drivers/pci/pci-sysfs.c2
-rw-r--r--drivers/pci/pcie/Kconfig20
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c17
-rw-r--r--drivers/pci/pcie/aspm.c16
-rw-r--r--drivers/pci/proc.c2
-rw-r--r--drivers/pci/quirks.c24
-rw-r--r--drivers/pci/setup-bus.c12
-rw-r--r--drivers/s390/block/dasd_devmap.c4
-rw-r--r--drivers/s390/cio/ccwreq.c2
-rw-r--r--drivers/s390/cio/chsc.c51
-rw-r--r--drivers/s390/cio/chsc.h2
-rw-r--r--drivers/s390/cio/device.c47
-rw-r--r--drivers/s390/net/smsgiucv_app.c7
-rw-r--r--drivers/scsi/ipr.c37
-rw-r--r--drivers/scsi/ipr.h4
-rw-r--r--drivers/serial/68328serial.c8
-rw-r--r--drivers/serial/atmel_serial.c1
-rw-r--r--drivers/serial/mpc52xx_uart.c145
-rw-r--r--drivers/serial/sh-sci.c42
-rw-r--r--drivers/serial/sh-sci.h46
-rw-r--r--drivers/serial/suncore.c4
-rw-r--r--drivers/serial/sunsu.c13
-rw-r--r--drivers/sh/Makefile5
-rw-r--r--drivers/sh/clk.c17
-rw-r--r--drivers/spi/coldfire_qspi.c1
-rw-r--r--drivers/spi/spi_mpc8xxx.c22
-rw-r--r--drivers/staging/cx25821/Makefile11
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c35
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c38
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h13
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c420
-rw-r--r--drivers/staging/cx25821/cx25821-core.c86
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c3
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-defines.h15
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-reg.h32
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c18
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.h4
-rw-r--r--drivers/staging/cx25821/cx25821-reg.h1826
-rw-r--r--drivers/staging/cx25821/cx25821-sram.h50
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c91
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.h2
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c72
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.h2
-rw-r--r--drivers/staging/cx25821/cx25821-video.c905
-rw-r--r--drivers/staging/cx25821/cx25821-video.h20
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c434
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c434
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c436
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c435
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c434
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c434
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c434
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c433
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c480
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c418
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c416
-rw-r--r--drivers/staging/cx25821/cx25821.h49
-rw-r--r--drivers/staging/pohmelfs/inode.c14
-rw-r--r--drivers/staging/tm6000/Kconfig4
-rw-r--r--drivers/staging/tm6000/Makefile8
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c263
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c58
-rw-r--r--drivers/staging/tm6000/tm6000-core.c188
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c173
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c25
-rw-r--r--drivers/staging/tm6000/tm6000-input.c364
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c36
-rw-r--r--drivers/staging/tm6000/tm6000-usb-isoc.h5
-rw-r--r--drivers/staging/tm6000/tm6000-video.c335
-rw-r--r--drivers/staging/tm6000/tm6000.h88
-rw-r--r--drivers/usb/class/cdc-acm.c1
-rw-r--r--drivers/usb/core/hub.c2
-rw-r--r--drivers/usb/core/quirks.c4
-rw-r--r--drivers/usb/gadget/at91_udc.c139
-rw-r--r--drivers/usb/gadget/at91_udc.h1
-rw-r--r--drivers/usb/gadget/fsl_mxc_udc.c2
-rw-r--r--drivers/usb/gadget/s3c2410_udc.c4
-rw-r--r--drivers/usb/host/ehci-mxc.c2
-rw-r--r--drivers/usb/host/ohci-pnx4008.c2
-rw-r--r--drivers/usb/host/xhci-mem.c21
-rw-r--r--drivers/usb/host/xhci-ring.c11
-rw-r--r--drivers/usb/host/xhci.c2
-rw-r--r--drivers/usb/host/xhci.h2
-rw-r--r--drivers/usb/serial/ftdi_sio.c8
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h9
-rw-r--r--drivers/usb/serial/option.c4
-rw-r--r--drivers/usb/serial/qcserial.c2
-rw-r--r--drivers/usb/serial/sierra.c1
-rw-r--r--drivers/video/Kconfig8
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/console/Kconfig2
-rw-r--r--drivers/video/matrox/i2c-matroxfb.c2
-rw-r--r--drivers/video/msm/mddi.c2
-rw-r--r--drivers/video/msm/mdp.c1
-rw-r--r--drivers/video/omap/lcd_apollon.c3
-rw-r--r--drivers/video/omap2/vram.c33
-rw-r--r--drivers/video/sh_mipi_dsi.c505
-rw-r--r--drivers/video/tdfxfb.c4
-rw-r--r--drivers/zorro/proc.c17
-rw-r--r--fs/9p/fid.c3
-rw-r--r--fs/9p/v9fs.c2
-rw-r--r--fs/9p/v9fs_vfs.h3
-rw-r--r--fs/9p/vfs_dir.c134
-rw-r--r--fs/9p/vfs_file.c13
-rw-r--r--fs/9p/vfs_inode.c243
-rw-r--r--fs/9p/vfs_super.c47
-rw-r--r--fs/adfs/inode.c16
-rw-r--r--fs/affs/affs.h3
-rw-r--r--fs/affs/file.c11
-rw-r--r--fs/affs/inode.c38
-rw-r--r--fs/affs/super.c3
-rw-r--r--fs/afs/inode.c5
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/aio.c21
-rw-r--r--fs/attr.c88
-rw-r--r--fs/bfs/file.c14
-rw-r--r--fs/bfs/inode.c70
-rw-r--r--fs/binfmt_misc.c5
-rw-r--r--fs/block_dev.c17
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/inode.c22
-rw-r--r--fs/btrfs/super.c2
-rw-r--r--fs/buffer.c180
-rw-r--r--fs/ceph/addr.c2
-rw-r--r--fs/ceph/caps.c40
-rw-r--r--fs/ceph/ceph_fs.c50
-rw-r--r--fs/ceph/ceph_fs.h3
-rw-r--r--fs/ceph/file.c24
-rw-r--r--fs/ceph/inode.c5
-rw-r--r--fs/ceph/ioctl.c24
-rw-r--r--fs/ceph/ioctl.h2
-rw-r--r--fs/cifs/Kconfig9
-rw-r--r--fs/cifs/cifsglob.h6
-rw-r--r--fs/cifs/dir.c6
-rw-r--r--fs/cifs/inode.c74
-rw-r--r--fs/coda/inode.c8
-rw-r--r--fs/cramfs/inode.c88
-rw-r--r--fs/dcache.c27
-rw-r--r--fs/direct-io.c74
-rw-r--r--fs/drop_caches.c2
-rw-r--r--fs/ecryptfs/file.c56
-rw-r--r--fs/ecryptfs/inode.c18
-rw-r--r--fs/ecryptfs/messaging.c2
-rw-r--r--fs/ecryptfs/super.c8
-rw-r--r--fs/exofs/exofs.h3
-rw-r--r--fs/exofs/file.c1
-rw-r--r--fs/exofs/inode.c127
-rw-r--r--fs/exofs/super.c2
-rw-r--r--fs/ext2/dir.c23
-rw-r--r--fs/ext2/ext2.h5
-rw-r--r--fs/ext2/ialloc.c13
-rw-r--r--fs/ext2/inode.c81
-rw-r--r--fs/ext2/super.c14
-rw-r--r--fs/ext3/ialloc.c12
-rw-r--r--fs/ext3/inode.c78
-rw-r--r--fs/ext3/namei.c3
-rw-r--r--fs/ext3/resize.c2
-rw-r--r--fs/ext3/super.c31
-rw-r--r--fs/ext4/ext4.h3
-rw-r--r--fs/ext4/ialloc.c2
-rw-r--r--fs/ext4/inode.c53
-rw-r--r--fs/ext4/super.c10
-rw-r--r--fs/fat/fat.h1
-rw-r--r--fs/fat/file.c49
-rw-r--r--fs/fat/inode.c26
-rw-r--r--fs/freevxfs/vxfs_extern.h2
-rw-r--r--fs/freevxfs/vxfs_inode.c8
-rw-r--r--fs/freevxfs/vxfs_super.c2
-rw-r--r--fs/fs-writeback.c8
-rw-r--r--fs/fuse/dev.c229
-rw-r--r--fs/fuse/dir.c17
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/fuse/fuse_i.h3
-rw-r--r--fs/fuse/inode.c6
-rw-r--r--fs/gfs2/aops.c19
-rw-r--r--fs/gfs2/bmap.c16
-rw-r--r--fs/gfs2/bmap.h2
-rw-r--r--fs/gfs2/file.c4
-rw-r--r--fs/gfs2/glock.c10
-rw-r--r--fs/gfs2/incore.h1
-rw-r--r--fs/gfs2/inode.c39
-rw-r--r--fs/gfs2/ops_fstype.c27
-rw-r--r--fs/gfs2/ops_inode.c18
-rw-r--r--fs/gfs2/quota.c33
-rw-r--r--fs/gfs2/super.c48
-rw-r--r--fs/gfs2/sys.c57
-rw-r--r--fs/gfs2/xattr.c24
-rw-r--r--fs/hfs/hfs_fs.h2
-rw-r--r--fs/hfs/inode.c70
-rw-r--r--fs/hfs/super.c2
-rw-r--r--fs/hfsplus/hfsplus_fs.h1
-rw-r--r--fs/hfsplus/inode.c77
-rw-r--r--fs/hfsplus/super.c10
-rw-r--r--fs/hostfs/hostfs.h22
-rw-r--r--fs/hostfs/hostfs_kern.c517
-rw-r--r--fs/hostfs/hostfs_user.c112
-rw-r--r--fs/hpfs/file.c11
-rw-r--r--fs/hpfs/hpfs_fn.h2
-rw-r--r--fs/hpfs/inode.c24
-rw-r--r--fs/hpfs/super.c2
-rw-r--r--fs/hppfs/hppfs.c8
-rw-r--r--fs/hugetlbfs/inode.c41
-rw-r--r--fs/inode.c72
-rw-r--r--fs/jbd/journal.c7
-rw-r--r--fs/jbd/recovery.c11
-rw-r--r--fs/jffs2/dir.c16
-rw-r--r--fs/jffs2/fs.c10
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/super.c2
-rw-r--r--fs/jffs2/xattr.c2
-rw-r--r--fs/jfs/file.c14
-rw-r--r--fs/jfs/inode.c63
-rw-r--r--fs/jfs/jfs_inode.h2
-rw-r--r--fs/jfs/super.c8
-rw-r--r--fs/libfs.c70
-rw-r--r--fs/logfs/dir.c7
-rw-r--r--fs/logfs/file.c24
-rw-r--r--fs/logfs/inode.c47
-rw-r--r--fs/logfs/journal.c2
-rw-r--r--fs/logfs/logfs.h8
-rw-r--r--fs/logfs/readwrite.c62
-rw-r--r--fs/logfs/segment.c1
-rw-r--r--fs/logfs/super.c23
-rw-r--r--fs/minix/bitmap.c6
-rw-r--r--fs/minix/dir.c21
-rw-r--r--fs/minix/file.c22
-rw-r--r--fs/minix/inode.c35
-rw-r--r--fs/minix/minix.h4
-rw-r--r--fs/ncpfs/inode.c36
-rw-r--r--fs/nfs/callback_proc.c13
-rw-r--r--fs/nfs/client.c21
-rw-r--r--fs/nfs/delegation.c6
-rw-r--r--fs/nfs/delegation.h4
-rw-r--r--fs/nfs/inode.c83
-rw-r--r--fs/nfs/internal.h4
-rw-r--r--fs/nfs/nfs4_fs.h57
-rw-r--r--fs/nfs/nfs4proc.c381
-rw-r--r--fs/nfs/nfs4renewd.c4
-rw-r--r--fs/nfs/nfs4state.c82
-rw-r--r--fs/nfs/nfs4xdr.c105
-rw-r--r--fs/nfs/pagelist.c8
-rw-r--r--fs/nfs/read.c3
-rw-r--r--fs/nfs/super.c4
-rw-r--r--fs/nfs/unlink.c2
-rw-r--r--fs/nfs/write.c9
-rw-r--r--fs/nfsd/nfs3proc.c6
-rw-r--r--fs/nfsd/nfs4callback.c55
-rw-r--r--fs/nfsd/nfs4state.c25
-rw-r--r--fs/nfsd/nfs4xdr.c1
-rw-r--r--fs/nfsd/vfs.c2
-rw-r--r--fs/nilfs2/bmap.c6
-rw-r--r--fs/nilfs2/bmap.h16
-rw-r--r--fs/nilfs2/bmap_union.h42
-rw-r--r--fs/nilfs2/btree.c792
-rw-r--r--fs/nilfs2/btree.h12
-rw-r--r--fs/nilfs2/dir.c25
-rw-r--r--fs/nilfs2/direct.c96
-rw-r--r--fs/nilfs2/direct.h11
-rw-r--r--fs/nilfs2/gcdat.c2
-rw-r--r--fs/nilfs2/gcinode.c11
-rw-r--r--fs/nilfs2/inode.c78
-rw-r--r--fs/nilfs2/mdt.c1
-rw-r--r--fs/nilfs2/nilfs.h22
-rw-r--r--fs/nilfs2/recovery.c359
-rw-r--r--fs/nilfs2/segbuf.h24
-rw-r--r--fs/nilfs2/segment.c19
-rw-r--r--fs/nilfs2/segment.h10
-rw-r--r--fs/nilfs2/super.c314
-rw-r--r--fs/nilfs2/the_nilfs.c132
-rw-r--r--fs/nilfs2/the_nilfs.h23
-rw-r--r--fs/notify/inode_mark.c6
-rw-r--r--fs/notify/inotify/inotify.c7
-rw-r--r--fs/ntfs/inode.c10
-rw-r--r--fs/ntfs/inode.h2
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--fs/ocfs2/aops.c103
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c3
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c2
-rw-r--r--fs/ocfs2/dlmfs/dlmfs.c15
-rw-r--r--fs/ocfs2/file.c329
-rw-r--r--fs/ocfs2/file.h6
-rw-r--r--fs/ocfs2/inode.c21
-rw-r--r--fs/ocfs2/inode.h3
-rw-r--r--fs/ocfs2/journal.c6
-rw-r--r--fs/ocfs2/localalloc.c7
-rw-r--r--fs/ocfs2/quota_global.c2
-rw-r--r--fs/ocfs2/quota_local.c4
-rw-r--r--fs/ocfs2/refcounttree.c6
-rw-r--r--fs/ocfs2/suballoc.c2
-rw-r--r--fs/ocfs2/super.c3
-rw-r--r--fs/ocfs2/xattr.c200
-rw-r--r--fs/omfs/dir.c22
-rw-r--r--fs/omfs/file.c44
-rw-r--r--fs/omfs/inode.c53
-rw-r--r--fs/omfs/omfs.h1
-rw-r--r--fs/omfs/omfs_fs.h1
-rw-r--r--fs/partitions/ibm.c14
-rw-r--r--fs/proc/base.c16
-rw-r--r--fs/proc/generic.c18
-rw-r--r--fs/proc/inode.c6
-rw-r--r--fs/proc/proc_sysctl.c15
-rw-r--r--fs/qnx4/inode.c11
-rw-r--r--fs/quota/dquot.c40
-rw-r--r--fs/ramfs/file-nommu.c7
-rw-r--r--fs/reiserfs/file.c50
-rw-r--r--fs/reiserfs/inode.c134
-rw-r--r--fs/reiserfs/super.c10
-rw-r--r--fs/smbfs/inode.c12
-rw-r--r--fs/sync.c25
-rw-r--r--fs/sysfs/inode.c8
-rw-r--r--fs/sysfs/mount.c2
-rw-r--r--fs/sysfs/symlink.c23
-rw-r--r--fs/sysfs/sysfs.h2
-rw-r--r--fs/sysv/dir.c21
-rw-r--r--fs/sysv/file.c22
-rw-r--r--fs/sysv/ialloc.c1
-rw-r--r--fs/sysv/inode.c15
-rw-r--r--fs/sysv/itree.c19
-rw-r--r--fs/sysv/sysv.h4
-rw-r--r--fs/ubifs/file.c23
-rw-r--r--fs/ubifs/lpt.c14
-rw-r--r--fs/ubifs/lpt_commit.c2
-rw-r--r--fs/ubifs/recovery.c23
-rw-r--r--fs/ubifs/super.c14
-rw-r--r--fs/ubifs/ubifs.h2
-rw-r--r--fs/udf/file.c23
-rw-r--r--fs/udf/ialloc.c2
-rw-r--r--fs/udf/inode.c61
-rw-r--r--fs/udf/super.c5
-rw-r--r--fs/udf/udfdecl.h3
-rw-r--r--fs/ufs/dir.c13
-rw-r--r--fs/ufs/ialloc.c2
-rw-r--r--fs/ufs/inode.c63
-rw-r--r--fs/ufs/super.c2
-rw-r--r--fs/ufs/truncate.c16
-rw-r--r--fs/ufs/ufs.h2
-rw-r--r--fs/ufs/util.h4
-rw-r--r--fs/xfs/Makefile4
-rw-r--r--fs/xfs/linux-2.6/xfs_acl.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c502
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c33
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h111
-rw-r--r--fs/xfs/linux-2.6/xfs_dmapi_priv.h28
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c104
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_fs_subr.h25
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c27
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c6
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c30
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_quotaops.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c167
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h7
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c18
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_trace.h126
-rw-r--r--fs/xfs/quota/xfs_dquot.c114
-rw-r--r--fs/xfs/quota/xfs_dquot_item.c301
-rw-r--r--fs/xfs/quota/xfs_qm.c15
-rw-r--r--fs/xfs/quota/xfs_qm_bhv.c10
-rw-r--r--fs/xfs/quota/xfs_qm_stats.c10
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c51
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c35
-rw-r--r--fs/xfs/support/debug.c1
-rw-r--r--fs/xfs/xfs_alloc.c5
-rw-r--r--fs/xfs/xfs_alloc.h20
-rw-r--r--fs/xfs/xfs_alloc_btree.c5
-rw-r--r--fs/xfs/xfs_attr.c91
-rw-r--r--fs/xfs/xfs_attr_leaf.c5
-rw-r--r--fs/xfs/xfs_bmap.c300
-rw-r--r--fs/xfs/xfs_bmap.h37
-rw-r--r--fs/xfs/xfs_bmap_btree.c5
-rw-r--r--fs/xfs/xfs_btree.c5
-rw-r--r--fs/xfs/xfs_buf_item.c227
-rw-r--r--fs/xfs/xfs_buf_item.h2
-rw-r--r--fs/xfs/xfs_da_btree.c14
-rw-r--r--fs/xfs/xfs_dfrag.c16
-rw-r--r--fs/xfs/xfs_dir2.c11
-rw-r--r--fs/xfs/xfs_dir2_block.c2
-rw-r--r--fs/xfs/xfs_dir2_data.c2
-rw-r--r--fs/xfs/xfs_dir2_leaf.c4
-rw-r--r--fs/xfs/xfs_dir2_node.c2
-rw-r--r--fs/xfs/xfs_dir2_sf.c2
-rw-r--r--fs/xfs/xfs_dmapi.h170
-rw-r--r--fs/xfs/xfs_dmops.c55
-rw-r--r--fs/xfs/xfs_error.c4
-rw-r--r--fs/xfs/xfs_extfree_item.c278
-rw-r--r--fs/xfs/xfs_filestream.c4
-rw-r--r--fs/xfs/xfs_fsops.c7
-rw-r--r--fs/xfs/xfs_ialloc.c4
-rw-r--r--fs/xfs/xfs_ialloc_btree.c4
-rw-r--r--fs/xfs/xfs_iget.c52
-rw-r--r--fs/xfs/xfs_inode.c35
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_inode_item.c252
-rw-r--r--fs/xfs/xfs_inode_item.h12
-rw-r--r--fs/xfs/xfs_iomap.c76
-rw-r--r--fs/xfs/xfs_iomap.h22
-rw-r--r--fs/xfs/xfs_itable.c8
-rw-r--r--fs/xfs/xfs_log.c14
-rw-r--r--fs/xfs/xfs_log.h11
-rw-r--r--fs/xfs/xfs_log_cil.c4
-rw-r--r--fs/xfs/xfs_log_recover.c42
-rw-r--r--fs/xfs/xfs_mount.c3
-rw-r--r--fs/xfs/xfs_mount.h67
-rw-r--r--fs/xfs/xfs_rename.c63
-rw-r--r--fs/xfs/xfs_rtalloc.c9
-rw-r--r--fs/xfs/xfs_rw.c15
-rw-r--r--fs/xfs/xfs_trans.c211
-rw-r--r--fs/xfs/xfs_trans.h117
-rw-r--r--fs/xfs/xfs_trans_ail.c1
-rw-r--r--fs/xfs/xfs_trans_buf.c75
-rw-r--r--fs/xfs/xfs_trans_extfree.c23
-rw-r--r--fs/xfs/xfs_trans_inode.c74
-rw-r--r--fs/xfs/xfs_trans_item.c441
-rw-r--r--fs/xfs/xfs_trans_priv.h18
-rw-r--r--fs/xfs/xfs_utils.c8
-rw-r--r--fs/xfs/xfs_vnodeops.c327
-rw-r--r--include/asm-generic/atomic.h12
-rw-r--r--include/asm-generic/unistd.h33
-rw-r--r--include/linux/buffer_head.h20
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/dqblk_xfs.h24
-rw-r--r--include/linux/dvb/frontend.h1
-rw-r--r--include/linux/dvb/version.h2
-rw-r--r--include/linux/ext3_fs.h3
-rw-r--r--include/linux/fs.h56
-rw-r--r--include/linux/fuse.h34
-rw-r--r--include/linux/hid.h3
-rw-r--r--include/linux/hidraw.h3
-rw-r--r--include/linux/i2c.h30
-rw-r--r--include/linux/i2c/ltc4245.h21
-rw-r--r--include/linux/i8042.h12
-rw-r--r--include/linux/input.h39
-rw-r--r--include/linux/list.h13
-rw-r--r--include/linux/mm.h1
-rw-r--r--include/linux/nfs4.h1
-rw-r--r--include/linux/nfs_fs.h13
-rw-r--r--include/linux/nfs_fs_sb.h7
-rw-r--r--include/linux/nfs_page.h1
-rw-r--r--include/linux/nfs_xdr.h12
-rw-r--r--include/linux/omapfb.h2
-rw-r--r--include/linux/quotaops.h10
-rw-r--r--include/linux/reiserfs_fs.h2
-rw-r--r--include/linux/reiserfs_fs_i.h4
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/sunrpc/cache.h1
-rw-r--r--include/linux/types.h12
-rw-r--r--include/linux/usb/video.h7
-rw-r--r--include/linux/virtio_9p.h1
-rw-r--r--include/media/ir-core.h8
-rw-r--r--include/media/ir-kbd-i2c.h2
-rw-r--r--include/media/lirc.h163
-rw-r--r--include/media/rc-map.h7
-rw-r--r--include/media/videobuf-core.h6
-rw-r--r--include/media/videobuf-dma-sg.h39
-rw-r--r--include/media/videobuf-vmalloc.h2
-rw-r--r--include/net/9p/9p.h65
-rw-r--r--include/net/9p/client.h21
-rw-r--r--include/video/mipi_display.h130
-rw-r--r--include/video/sh_mipi_dsi.h35
-rw-r--r--include/video/sh_mobile_lcdc.h39
-rw-r--r--ipc/mqueue.c16
-rw-r--r--kernel/hw_breakpoint.c12
-rw-r--r--kernel/printk.c30
-rw-r--r--lib/Kconfig.debug19
-rw-r--r--mm/shmem.c23
-rw-r--r--mm/truncate.c38
-rw-r--r--net/9p/client.c131
-rw-r--r--net/9p/protocol.c66
-rw-r--r--net/9p/trans_fd.c2
-rw-r--r--net/bluetooth/hci_conn.c5
-rw-r--r--net/bluetooth/hci_event.c2
-rw-r--r--net/bluetooth/l2cap.c14
-rw-r--r--net/dsa/Kconfig2
-rw-r--r--net/ipv4/tcp.c1
-rw-r--r--net/phonet/pep.c1
-rw-r--r--net/sched/act_nat.c5
-rw-r--r--net/sunrpc/cache.c7
-rw-r--r--net/sunrpc/sunrpc_syms.c1
-rw-r--r--net/xfrm/xfrm_policy.c15
-rw-r--r--scripts/Makefile.build26
-rw-r--r--scripts/Makefile.help3
-rwxr-xr-xscripts/checkkconfigsymbols.sh2
-rwxr-xr-xscripts/checksyscalls.sh1
-rwxr-xr-xscripts/coccicheck80
-rw-r--r--scripts/coccinelle/alloc/drop_kmalloc_cast.cocci67
-rw-r--r--scripts/coccinelle/alloc/kzalloc-simple.cocci82
-rw-r--r--scripts/coccinelle/deref_null.cocci293
-rw-r--r--scripts/coccinelle/err_cast.cocci56
-rw-r--r--scripts/coccinelle/resource_size.cocci93
-rwxr-xr-xscripts/decodecode10
-rw-r--r--scripts/dtc/fstree.c1
-rw-r--r--scripts/kconfig/.gitignore1
-rw-r--r--scripts/kconfig/Makefile10
-rw-r--r--scripts/kconfig/conf.c57
-rw-r--r--scripts/kconfig/expr.c2
-rw-r--r--scripts/kconfig/expr.h2
-rw-r--r--scripts/kconfig/gconf.c7
-rw-r--r--scripts/kconfig/lxdialog/checklist.c10
-rw-r--r--scripts/kconfig/mconf.c2
-rw-r--r--scripts/kconfig/menu.c25
-rw-r--r--scripts/kconfig/qconf.cc106
-rw-r--r--scripts/kconfig/qconf.h17
-rw-r--r--scripts/kconfig/symbol.c42
-rw-r--r--scripts/package/builddeb5
-rw-r--r--tools/perf/arch/arm/Makefile4
-rw-r--r--tools/perf/arch/arm/util/dwarf-regs.c64
1845 files changed, 108095 insertions, 59011 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
index 88340a23ce91..063bda7fe707 100644
--- a/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
+++ b/Documentation/ABI/testing/sysfs-driver-hid-roccat-kone
@@ -33,19 +33,6 @@ Description: When read, this file returns the raw integer version number of the
left. E.g. a returned value of 138 means 1.38
This file is readonly.
-What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/kone_driver_version
-Date: March 2010
-Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
-Description: When read, this file returns the driver version.
- The format of the string is "v<major>.<minor>.<patchlevel>".
- This attribute is used by the userland tools to find the sysfs-
- paths of installed kone-mice and determine the capabilites of
- the driver. Versions of this driver for old kernels replace
- usbhid instead of generic-usb. The way to scan for this file
- has been chosen to provide a consistent way for all supported
- kernel versions.
- This file is readonly.
-
What: /sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/profile[1-5]
Date: March 2010
Contact: Stefan Achatz <erazor_de@users.sourceforge.net>
diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml
index 63c528fee624..e3a97fdd62a6 100644
--- a/Documentation/DocBook/dvb/dvbapi.xml
+++ b/Documentation/DocBook/dvb/dvbapi.xml
@@ -12,10 +12,12 @@
<othername role="mi">O. C.</othername>
<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
</author>
+</authorgroup>
+<authorgroup>
<author>
<firstname>Mauro</firstname>
-<surname>Chehab</surname>
<othername role="mi">Carvalho</othername>
+<surname>Chehab</surname>
<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
<contrib>Ported document to Docbook XML.</contrib>
</author>
@@ -23,13 +25,24 @@
<copyright>
<year>2002</year>
<year>2003</year>
- <year>2009</year>
<holder>Convergence GmbH</holder>
</copyright>
+<copyright>
+ <year>2009-2010</year>
+ <holder>Mauro Carvalho Chehab</holder>
+</copyright>
<revhistory>
<!-- Put document revisions here, newest first. -->
<revision>
+ <revnumber>2.0.3</revnumber>
+ <date>2010-07-03</date>
+ <authorinitials>mcc</authorinitials>
+ <revremark>
+ Add some frontend capabilities flags, present on kernel, but missing at the specs.
+ </revremark>
+</revision>
+<revision>
<revnumber>2.0.2</revnumber>
<date>2009-10-25</date>
<authorinitials>mcc</authorinitials>
@@ -63,7 +76,7 @@ Added ISDB-T test originally written by Patrick Boettcher
<title>LINUX DVB API</title>
-<subtitle>Version 3</subtitle>
+<subtitle>Version 5.2</subtitle>
<!-- ADD THE CHAPTERS HERE -->
<chapter id="dvb_introdution">
&sub-intro;
diff --git a/Documentation/DocBook/dvb/frontend.h.xml b/Documentation/DocBook/dvb/frontend.h.xml
index b99644f5340a..d08e0d401418 100644
--- a/Documentation/DocBook/dvb/frontend.h.xml
+++ b/Documentation/DocBook/dvb/frontend.h.xml
@@ -63,6 +63,7 @@ typedef enum fe_caps {
FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000,
FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
+ FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */
FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */
diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml
index 300ba1f04177..78d756de5906 100644
--- a/Documentation/DocBook/dvb/frontend.xml
+++ b/Documentation/DocBook/dvb/frontend.xml
@@ -64,8 +64,14 @@ a specific frontend type.</para>
FE_CAN_BANDWIDTH_AUTO = 0x40000,
FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
FE_CAN_HIERARCHY_AUTO = 0x100000,
- FE_CAN_MUTE_TS = 0x80000000,
- FE_CAN_CLEAN_SETUP = 0x40000000
+ FE_CAN_8VSB = 0x200000,
+ FE_CAN_16VSB = 0x400000,
+ FE_HAS_EXTENDED_CAPS = 0x800000,
+ FE_CAN_TURBO_FEC = 0x8000000,
+ FE_CAN_2G_MODULATION = 0x10000000,
+ FE_NEEDS_BENDING = 0x20000000,
+ FE_CAN_RECOVER = 0x40000000,
+ FE_CAN_MUTE_TS = 0x80000000
} fe_caps_t;
</programlisting>
</section>
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index 5d4d40f429a5..6ae97157b1c7 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -218,6 +218,7 @@
<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
+<!ENTITY sub-lirc_device_interface SYSTEM "v4l/lirc_device_interface.xml">
<!ENTITY sub-remote_controllers SYSTEM "v4l/remote_controllers.xml">
<!ENTITY sub-fdl-appendix SYSTEM "v4l/fdl-appendix.xml">
<!ENTITY sub-close SYSTEM "v4l/func-close.xml">
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
index eea564bb12cb..f11048d4053f 100644
--- a/Documentation/DocBook/media.tmpl
+++ b/Documentation/DocBook/media.tmpl
@@ -28,7 +28,7 @@
<title>LINUX MEDIA INFRASTRUCTURE API</title>
<copyright>
- <year>2009</year>
+ <year>2009-2010</year>
<holder>LinuxTV Developers</holder>
</copyright>
@@ -61,7 +61,7 @@ Foundation. A copy of the license is included in the chapter entitled
in fact it covers several different video standards including
DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
- <para>The third part covers other API's used by all media infrastructure devices</para>
+ <para>The third part covers Remote Controller API</para>
<para>For additional information and for the latest development code,
see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
<para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
@@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled
</author>
</authorgroup>
<copyright>
- <year>2009</year>
+ <year>2009-2010</year>
<holder>Mauro Carvalho Chehab</holder>
</copyright>
@@ -101,7 +101,7 @@ Foundation. A copy of the license is included in the chapter entitled
</revhistory>
</partinfo>
-<title>Other API's used by media infrastructure drivers</title>
+<title>Remote Controller API</title>
<chapter id="remote_controllers">
&sub-remote_controllers;
</chapter>
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
index 254c1d5d2e50..85b25275196f 100644
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -6,4 +6,5 @@
<param name="callout.graphics">0</param>
<!-- <param name="paper.type">A4</param> -->
<param name="generate.section.toc.level">2</param>
+<param name="use.id.as.filename">1</param>
</stylesheet>
diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
new file mode 100644
index 000000000000..0413234023d4
--- /dev/null
+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
@@ -0,0 +1,235 @@
+<section id="lirc_dev">
+<title>LIRC Device Interface</title>
+
+
+<section id="lirc_dev_intro">
+<title>Introduction</title>
+
+<para>The LIRC device interface is a bi-directional interface for
+transporting raw IR data between userspace and kernelspace. Fundamentally,
+it is just a chardev (/dev/lircX, for X = 0, 1, 2, ...), with a number
+of standard struct file_operations defined on it. With respect to
+transporting raw IR data to and fro, the essential fops are read, write
+and ioctl.</para>
+
+<para>Example dmesg output upon a driver registering w/LIRC:</para>
+ <blockquote>
+ <para>$ dmesg |grep lirc_dev</para>
+ <para>lirc_dev: IR Remote Control driver registered, major 248</para>
+ <para>rc rc0: lirc_dev: driver ir-lirc-codec (mceusb) registered at minor = 0</para>
+ </blockquote>
+
+<para>What you should see for a chardev:</para>
+ <blockquote>
+ <para>$ ls -l /dev/lirc*</para>
+ <para>crw-rw---- 1 root root 248, 0 Jul 2 22:20 /dev/lirc0</para>
+ </blockquote>
+</section>
+
+<section id="lirc_read">
+<title>LIRC read fop</title>
+
+<para>The lircd userspace daemon reads raw IR data from the LIRC chardev. The
+exact format of the data depends on what modes a driver supports, and what
+mode has been selected. lircd obtains supported modes and sets the active mode
+via the ioctl interface, detailed at <xref linkend="lirc_ioctl"/>. The generally
+preferred mode is LIRC_MODE_MODE2, in which packets containing an int value
+describing an IR signal are read from the chardev.</para>
+
+<para>See also <ulink url="http://www.lirc.org/html/technical.html">http://www.lirc.org/html/technical.html</ulink> for more info.</para>
+</section>
+
+<section id="lirc_write">
+<title>LIRC write fop</title>
+
+<para>The data written to the chardev is a pulse/space sequence of integer
+values. Pulses and spaces are only marked implicitly by their position. The
+data must start and end with a pulse, therefore, the data must always include
+an unevent number of samples. The write function must block until the data has
+been transmitted by the hardware.</para>
+</section>
+
+<section id="lirc_ioctl">
+<title>LIRC ioctl fop</title>
+
+<para>The LIRC device's ioctl definition is bound by the ioctl function
+definition of struct file_operations, leaving us with an unsigned int
+for the ioctl command and an unsigned long for the arg. For the purposes
+of ioctl portability across 32-bit and 64-bit, these values are capped
+to their 32-bit sizes.</para>
+
+<para>The following ioctls can be used to change specific hardware settings.
+In general each driver should have a default set of settings. The driver
+implementation is expected to re-apply the default settings when the device
+is closed by user-space, so that every application opening the device can rely
+on working with the default settings initially.</para>
+
+<variablelist>
+ <varlistentry>
+ <term>LIRC_GET_FEATURES</term>
+ <listitem>
+ <para>Obviously, get the underlying hardware device's features. If a driver
+ does not announce support of certain features, calling of the corresponding
+ ioctls is undefined.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_SEND_MODE</term>
+ <listitem>
+ <para>Get supported transmit mode. Only LIRC_MODE_PULSE is supported by lircd.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_REC_MODE</term>
+ <listitem>
+ <para>Get supported receive modes. Only LIRC_MODE_MODE2 and LIRC_MODE_LIRCCODE
+ are supported by lircd.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_SEND_CARRIER</term>
+ <listitem>
+ <para>Get carrier frequency (in Hz) currently used for transmit.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_REC_CARRIER</term>
+ <listitem>
+ <para>Get carrier frequency (in Hz) currently used for IR reception.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_{G,S}ET_{SEND,REC}_DUTY_CYCLE</term>
+ <listitem>
+ <para>Get/set the duty cycle (from 0 to 100) of the carrier signal. Currently,
+ no special meaning is defined for 0 or 100, but this could be used to switch
+ off carrier generation in the future, so these values should be reserved.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_REC_RESOLUTION</term>
+ <listitem>
+ <para>Some receiver have maximum resolution which is defined by internal
+ sample rate or data format limitations. E.g. it's common that signals can
+ only be reported in 50 microsecond steps. This integer value is used by
+ lircd to automatically adjust the aeps tolerance value in the lircd
+ config file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_M{IN,AX}_TIMEOUT</term>
+ <listitem>
+ <para>Some devices have internal timers that can be used to detect when
+ there's no IR activity for a long time. This can help lircd in detecting
+ that a IR signal is finished and can speed up the decoding process.
+ Returns an integer value with the minimum/maximum timeout that can be
+ set. Some devices have a fixed timeout, in that case both ioctls will
+ return the same value even though the timeout cannot be changed.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_M{IN,AX}_FILTER_{PULSE,SPACE}</term>
+ <listitem>
+ <para>Some devices are able to filter out spikes in the incoming signal
+ using given filter rules. These ioctls return the hardware capabilities
+ that describe the bounds of the possible filters. Filter settings depend
+ on the IR protocols that are expected. lircd derives the settings from
+ all protocols definitions found in its config file.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_GET_LENGTH</term>
+ <listitem>
+ <para>Retrieves the code length in bits (only for LIRC_MODE_LIRCCODE).
+ Reads on the device must be done in blocks matching the bit count.
+ The bit could should be rounded up so that it matches full bytes.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_{SEND,REC}_MODE</term>
+ <listitem>
+ <para>Set send/receive mode. Largely obsolete for send, as only
+ LIRC_MODE_PULSE is supported.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_{SEND,REC}_CARRIER</term>
+ <listitem>
+ <para>Set send/receive carrier (in Hz).</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_TRANSMITTER_MASK</term>
+ <listitem>
+ <para>This enables the given set of transmitters. The first transmitter
+ is encoded by the least significant bit, etc. When an invalid bit mask
+ is given, i.e. a bit is set, even though the device does not have so many
+ transitters, then this ioctl returns the number of available transitters
+ and does nothing otherwise.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_REC_TIMEOUT</term>
+ <listitem>
+ <para>Sets the integer value for IR inactivity timeout (cf.
+ LIRC_GET_MIN_TIMEOUT and LIRC_GET_MAX_TIMEOUT). A value of 0 (if
+ supported by the hardware) disables all hardware timeouts and data should
+ be reported as soon as possible. If the exact value cannot be set, then
+ the next possible value _greater_ than the given value should be set.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_REC_TIMEOUT_REPORTS</term>
+ <listitem>
+ <para>Enable (1) or disable (0) timeout reports in LIRC_MODE_MODE2. By
+ default, timeout reports should be turned off.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_REC_FILTER_{,PULSE,SPACE}</term>
+ <listitem>
+ <para>Pulses/spaces shorter than this are filtered out by hardware. If
+ filters cannot be set independently for pulse/space, the corresponding
+ ioctls must return an error and LIRC_SET_REC_FILTER shall be used instead.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_MEASURE_CARRIER_MODE</term>
+ <listitem>
+ <para>Enable (1)/disable (0) measure mode. If enabled, from the next key
+ press on, the driver will send LIRC_MODE2_FREQUENCY packets. By default
+ this should be turned off.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SET_REC_{DUTY_CYCLE,CARRIER}_RANGE</term>
+ <listitem>
+ <para>To set a range use LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE
+ with the lower bound first and later LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER
+ with the upper bound.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_NOTIFY_DECODE</term>
+ <listitem>
+ <para>This ioctl is called by lircd whenever a successful decoding of an
+ incoming IR signal could be done. This can be used by supporting hardware
+ to give visual feedback to the user e.g. by flashing a LED.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>LIRC_SETUP_{START,END}</term>
+ <listitem>
+ <para>Setting of several driver parameters can be optimized by encapsulating
+ the according ioctl calls with LIRC_SETUP_START/LIRC_SETUP_END. When a
+ driver receives a LIRC_SETUP_START ioctl it can choose to not commit
+ further setting changes to the hardware until a LIRC_SETUP_END is received.
+ But this is open to the driver implementation and every driver must also
+ handle parameter changes which are not encapsulated by LIRC_SETUP_START
+ and LIRC_SETUP_END. Drivers can also choose to ignore these ioctls.</para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+</section>
+</section>
diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml
index 73f5eab091f4..3c3b667b28e7 100644
--- a/Documentation/DocBook/v4l/remote_controllers.xml
+++ b/Documentation/DocBook/v4l/remote_controllers.xml
@@ -173,3 +173,5 @@ keymapping.</para>
<para>This program demonstrates how to replace the keymap tables.</para>
&sub-keytable-c;
</section>
+
+&sub-lirc_device_interface;
diff --git a/Documentation/coccinelle.txt b/Documentation/coccinelle.txt
new file mode 100644
index 000000000000..cd2b02837066
--- /dev/null
+++ b/Documentation/coccinelle.txt
@@ -0,0 +1,258 @@
+Copyright 2010 Nicolas Palix <npalix@diku.dk>
+Copyright 2010 Julia Lawall <julia@diku.dk>
+Copyright 2010 Gilles Muller <Gilles.Muller@lip6.fr>
+
+
+ Getting Coccinelle
+~~~~~~~~~~~~~~~~~~~~
+
+The semantic patches included in the kernel use the 'virtual rule'
+feature which was introduced in Coccinelle version 0.1.11.
+
+Coccinelle (>=0.2.0) is available through the package manager
+of many distributions, e.g. :
+
+ - Debian (>=squeeze)
+ - Fedora (>=13)
+ - Ubuntu (>=10.04 Lucid Lynx)
+ - OpenSUSE
+ - Arch Linux
+ - NetBSD
+ - FreeBSD
+
+
+You can get the latest version released from the Coccinelle homepage at
+http://coccinelle.lip6.fr/
+
+Once you have it, run the following command:
+
+ ./configure
+ make
+
+as a regular user, and install it with
+
+ sudo make install
+
+
+ Using Coccinelle on the Linux kernel
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A Coccinelle-specific target is defined in the top level
+Makefile. This target is named 'coccicheck' and calls the 'coccicheck'
+front-end in the 'scripts' directory.
+
+Four modes are defined: report, patch, context, and org. The mode to
+use is specified by setting the MODE variable with 'MODE=<mode>'.
+
+'report' generates a list in the following format:
+ file:line:column-column: message
+
+'patch' proposes a fix, when possible.
+
+'context' highlights lines of interest and their context in a
+diff-like style.Lines of interest are indicated with '-'.
+
+'org' generates a report in the Org mode format of Emacs.
+
+Note that not all semantic patches implement all modes.
+
+To make a report for every semantic patch, run the following command:
+
+ make coccicheck MODE=report
+
+NB: The 'report' mode is the default one.
+
+To produce patches, run:
+
+ make coccicheck MODE=patch
+
+
+The coccicheck target applies every semantic patch available in the
+subdirectories of 'scripts/coccinelle' to the entire Linux kernel.
+
+For each semantic patch, a changelog message is proposed. It gives a
+description of the problem being checked by the semantic patch, and
+includes a reference to Coccinelle.
+
+As any static code analyzer, Coccinelle produces false
+positives. Thus, reports must be carefully checked, and patches
+reviewed.
+
+
+ Using Coccinelle with a single semantic patch
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The optional make variable COCCI can be used to check a single
+semantic patch. In that case, the variable must be initialized with
+the name of the semantic patch to apply.
+
+For instance:
+
+ make coccicheck COCCI=<my_SP.cocci> MODE=patch
+or
+ make coccicheck COCCI=<my_SP.cocci> MODE=report
+
+
+ Proposing new semantic patches
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+New semantic patches can be proposed and submitted by kernel
+developers. For sake of clarity, they should be organized in the
+subdirectories of 'scripts/coccinelle/'.
+
+
+ Detailed description of the 'report' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'report' generates a list in the following format:
+ file:line:column-column: message
+
+Example:
+
+Running
+
+ make coccicheck MODE=report COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="ERR_CAST can be used with %s" % (x)
+coccilib.report.print_report(p[0], msg)
+</smpl>
+
+This SmPL excerpt generates entries on the standard output, as
+illustrated below:
+
+/home/user/linux/crypto/ctr.c:188:9-16: ERR_CAST can be used with alg
+/home/user/linux/crypto/authenc.c:619:9-16: ERR_CAST can be used with auth
+/home/user/linux/crypto/xts.c:227:9-16: ERR_CAST can be used with alg
+
+
+ Detailed description of the 'patch' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When the 'patch' mode is available, it proposes a fix for each problem
+identified.
+
+Example:
+
+Running
+ make coccicheck MODE=patch COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@ depends on !context && patch && !org && !report @
+expression x;
+@@
+
+- ERR_PTR(PTR_ERR(x))
++ ERR_CAST(x)
+</smpl>
+
+This SmPL excerpt generates patch hunks on the standard output, as
+illustrated below:
+
+diff -u -p a/crypto/ctr.c b/crypto/ctr.c
+--- a/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
++++ b/crypto/ctr.c 2010-06-03 23:44:49.000000000 +0200
+@@ -185,7 +185,7 @@ static struct crypto_instance *crypto_ct
+ alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ if (IS_ERR(alg))
+- return ERR_PTR(PTR_ERR(alg));
++ return ERR_CAST(alg);
+
+ /* Block size must be >= 4 bytes. */
+ err = -EINVAL;
+
+ Detailed description of the 'context' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'context' highlights lines of interest and their context
+in a diff-like style.
+
+NOTE: The diff-like output generated is NOT an applicable patch. The
+ intent of the 'context' mode is to highlight the important lines
+ (annotated with minus, '-') and gives some surrounding context
+ lines around. This output can be used with the diff mode of
+ Emacs to review the code.
+
+Example:
+
+Running
+ make coccicheck MODE=context COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@ depends on context && !patch && !org && !report@
+expression x;
+@@
+
+* ERR_PTR(PTR_ERR(x))
+</smpl>
+
+This SmPL excerpt generates diff hunks on the standard output, as
+illustrated below:
+
+diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing
+--- /home/user/linux/crypto/ctr.c 2010-05-26 10:49:38.000000000 +0200
++++ /tmp/nothing
+@@ -185,7 +185,6 @@ static struct crypto_instance *crypto_ct
+ alg = crypto_attr_alg(tb[1], CRYPTO_ALG_TYPE_CIPHER,
+ CRYPTO_ALG_TYPE_MASK);
+ if (IS_ERR(alg))
+- return ERR_PTR(PTR_ERR(alg));
+
+ /* Block size must be >= 4 bytes. */
+ err = -EINVAL;
+
+ Detailed description of the 'org' mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+'org' generates a report in the Org mode format of Emacs.
+
+Example:
+
+Running
+ make coccicheck MODE=org COCCI=scripts/coccinelle/err_cast.cocci
+
+will execute the following part of the SmPL script.
+
+<smpl>
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="ERR_CAST can be used with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+</smpl>
+
+This SmPL excerpt generates Org entries on the standard output, as
+illustrated below:
+
+* TODO [[view:/home/user/linux/crypto/ctr.c::face=ovl-face1::linb=188::colb=9::cole=16][ERR_CAST can be used with alg]]
+* TODO [[view:/home/user/linux/crypto/authenc.c::face=ovl-face1::linb=619::colb=9::cole=16][ERR_CAST can be used with auth]]
+* TODO [[view:/home/user/linux/crypto/xts.c::face=ovl-face1::linb=227::colb=9::cole=16][ERR_CAST can be used with alg]]
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 239cbdbf4d12..9ea94dc3556e 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -26,7 +26,7 @@ use IO::Handle;
"dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
"or51211", "or51132_qam", "or51132_vsb", "bluebird",
"opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
- "af9015", "ngene");
+ "af9015", "ngene", "az6027");
# Check args
syntax() if (scalar(@ARGV) != 1);
@@ -567,6 +567,23 @@ sub ngene {
"$file1, $file2";
}
+sub az6027{
+ my $file = "AZ6027_Linux_Driver.tar.gz";
+ my $url = "http://linux.terratec.de/files/$file";
+ my $firmware = "dvb-usb-az6027-03.fw";
+
+ wgetfile($file, $url);
+
+ #untar
+ if( system("tar xzvf $file $firmware")){
+ die "failed to untar firmware";
+ }
+ if( system("rm $file")){
+ die ("unable to remove unnecessary files");
+ }
+
+ $firmware;
+}
# ---------------------------------------------------------------
# Utilities
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c268783bc4e7..ca527fcdd527 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -459,57 +459,6 @@ Who: Corentin Chary <corentin.chary@gmail.com>
----------------------------
-What: usbvideo quickcam_messenger driver
-When: 2.6.35
-Files: drivers/media/video/usbvideo/quickcam_messenger.[ch]
-Why: obsolete v4l1 driver replaced by gspca_stv06xx
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
-What: ov511 v4l1 driver
-When: 2.6.35
-Files: drivers/media/video/ov511.[ch]
-Why: obsolete v4l1 driver replaced by gspca_ov519
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
-What: w9968cf v4l1 driver
-When: 2.6.35
-Files: drivers/media/video/w9968cf*.[ch]
-Why: obsolete v4l1 driver replaced by gspca_ov519
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
-What: ovcamchip sensor framework
-When: 2.6.35
-Files: drivers/media/video/ovcamchip/*
-Why: Only used by obsoleted v4l1 drivers
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
-What: stv680 v4l1 driver
-When: 2.6.35
-Files: drivers/media/video/stv680.[ch]
-Why: obsolete v4l1 driver replaced by gspca_stv0680
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
-What: zc0301 v4l driver
-When: 2.6.35
-Files: drivers/media/video/zc0301/*
-Why: Duplicate functionality with the gspca_zc3xx driver, zc0301 only
- supports 2 USB-ID's (because it only supports a limited set of
- sensors) wich are also supported by the gspca_zc3xx driver
- (which supports 53 USB-ID's in total)
-Who: Hans de Goede <hdegoede@redhat.com>
-
-----------------------------
-
What: sysfs-class-rfkill state file
When: Feb 2014
Files: net/rfkill/core.c
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 96d4293607ec..bbcc15651a21 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -92,8 +92,8 @@ prototypes:
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, int);
- void (*drop_inode) (struct inode *);
- void (*delete_inode) (struct inode *);
+ int (*drop_inode) (struct inode *);
+ void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
@@ -101,14 +101,13 @@ prototypes:
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
- void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct vfsmount *);
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
locking rules:
- All may block.
+ All may block [not true, see below]
None have BKL
s_umount
alloc_inode:
@@ -116,22 +115,25 @@ destroy_inode:
dirty_inode: (must not sleep)
write_inode:
drop_inode: !!!inode_lock!!!
-delete_inode:
+evict_inode:
put_super: write
write_super: read
sync_fs: read
freeze_fs: read
unfreeze_fs: read
-statfs: no
-remount_fs: maybe (see below)
-clear_inode:
+statfs: maybe(read) (see below)
+remount_fs: write
umount_begin: no
show_options: no (namespace_sem)
quota_read: no (see below)
quota_write: no (see below)
-->remount_fs() will have the s_umount exclusive lock if it's already mounted.
-When called from get_sb_single, it does NOT have the s_umount lock.
+->statfs() has s_umount (shared) when called by ustat(2) (native or
+compat), but that's an accident of bad API; s_umount is used to pin
+the superblock down when we only have dev_t given us by userland to
+identify the superblock. Everything else (statfs(), fstatfs(), etc.)
+doesn't hold it when calling ->statfs() - superblock is pinned down
+by resolving the pathname passed to syscall.
->quota_read() and ->quota_write() functions are both guaranteed to
be the only ones operating on the quota file by the quota code (via
dqio_sem) (unless an admin really wants to screw up something and
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt
index d3e7673995eb..d5c0cef38a71 100644
--- a/Documentation/filesystems/nilfs2.txt
+++ b/Documentation/filesystems/nilfs2.txt
@@ -49,7 +49,10 @@ Mount options
NILFS2 supports the following mount options:
(*) == default
-nobarrier Disables barriers.
+barrier(*) This enables/disables the use of write barriers. This
+nobarrier requires an IO stack which can support barriers, and
+ if nilfs gets an error on a barrier write, it will
+ disable again with a warning.
errors=continue Keep going on a filesystem error.
errors=remount-ro(*) Remount the filesystem read-only on an error.
errors=panic Panic and halt the machine if an error occurs.
@@ -74,9 +77,10 @@ norecovery Disable recovery of the filesystem on mount.
This disables every write access on the device for
read-only mounts or snapshots. This option will fail
for r/w mounts on an unclean volume.
-discard Issue discard/TRIM commands to the underlying block
- device when blocks are freed. This is useful for SSD
- devices and sparse/thinly-provisioned LUNs.
+discard This enables/disables the use of discard/TRIM commands.
+nodiscard(*) The discard/TRIM commands are sent to the underlying
+ block device when blocks are freed. This is useful
+ for SSD devices and sparse/thinly-provisioned LUNs.
NILFS2 usage
============
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index a7e9746ee7ea..b12c89538680 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -273,3 +273,48 @@ it's safe to remove it. If you don't need it, remove it.
deliberate; as soon as struct block_device * is propagated in a reasonable
way by that code fixing will become trivial; until then nothing can be
done.
+
+[mandatory]
+
+ block truncatation on error exit from ->write_begin, and ->direct_IO
+moved from generic methods (block_write_begin, cont_write_begin,
+nobh_write_begin, blockdev_direct_IO*) to callers. Take a look at
+ext2_write_failed and callers for an example.
+
+[mandatory]
+
+ ->truncate is going away. The whole truncate sequence needs to be
+implemented in ->setattr, which is now mandatory for filesystems
+implementing on-disk size changes. Start with a copy of the old inode_setattr
+and vmtruncate, and the reorder the vmtruncate + foofs_vmtruncate sequence to
+be in order of zeroing blocks using block_truncate_page or similar helpers,
+size update and on finally on-disk truncation which should not fail.
+inode_change_ok now includes the size checks for ATTR_SIZE and must be called
+in the beginning of ->setattr unconditionally.
+
+[mandatory]
+
+ ->clear_inode() and ->delete_inode() are gone; ->evict_inode() should
+be used instead. It gets called whenever the inode is evicted, whether it has
+remaining links or not. Caller does *not* evict the pagecache or inode-associated
+metadata buffers; getting rid of those is responsibility of method, as it had
+been for ->delete_inode().
+ ->drop_inode() returns int now; it's called on final iput() with inode_lock
+held and it returns true if filesystems wants the inode to be dropped. As before,
+generic_drop_inode() is still the default and it's been updated appropriately.
+generic_delete_inode() is also alive and it consists simply of return 1. Note that
+all actual eviction work is done by caller after ->drop_inode() returns.
+ clear_inode() is gone; use end_writeback() instead. As before, it must
+be called exactly once on each call of ->evict_inode() (as it used to be for
+each call of ->delete_inode()). Unlike before, if you are using inode-associated
+metadata buffers (i.e. mark_buffer_dirty_inode()), it's your responsibility to
+call invalidate_inode_buffers() before end_writeback().
+ No async writeback (and thus no calls of ->write_inode()) will happen
+after end_writeback() returns, so actions that should not overlap with ->write_inode()
+(e.g. freeing on-disk inode if i_nlink is 0) ought to be done after that call.
+
+ NOTE: checking i_nlink in the beginning of ->write_inode() and bailing out
+if it's zero is not *and* *never* *had* *been* enough. Final unlink() and iput()
+may happen while the inode is in the middle of ->write_inode(); e.g. if you blindly
+free the on-disk inode, you may end up doing that while ->write_inode() is writing
+to it.
diff --git a/Documentation/hwmon/emc2103 b/Documentation/hwmon/emc2103
new file mode 100644
index 000000000000..a12b2c127140
--- /dev/null
+++ b/Documentation/hwmon/emc2103
@@ -0,0 +1,33 @@
+Kernel driver emc2103
+======================
+
+Supported chips:
+ * SMSC EMC2103
+ Addresses scanned: I2C 0x2e
+ Prefix: 'emc2103'
+ Datasheet: Not public
+
+Authors:
+ Steve Glendinning <steve.glendinning@smsc.com>
+
+Description
+-----------
+
+The Standard Microsystems Corporation (SMSC) EMC2103 chips
+contain up to 4 temperature sensors and a single fan controller.
+
+Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
+triggered if the rotation speed has dropped below a programmable limit. Fan
+readings can be divided by a programmable divider (1, 2, 4 or 8) to give
+the readings more range or accuracy. Not all RPM values can accurately be
+represented, so some rounding is done. With a divider of 1, the lowest
+representable value is 480 RPM.
+
+This driver supports RPM based control, to use this a fan target
+should be written to fan1_target and pwm1_enable should be set to 3.
+
+The 2103-2 and 2103-4 variants have a third temperature sensor, which can
+be connected to two anti-parallel diodes. These values can be read
+as temp3 and temp4. If only one diode is attached to this channel, temp4
+will show as "fault". The module parameter "apd=0" can be used to suppress
+this 4th channel when anti-parallel diodes are not fitted.
diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245
index 86b5880d8502..b478b0864965 100644
--- a/Documentation/hwmon/ltc4245
+++ b/Documentation/hwmon/ltc4245
@@ -72,9 +72,31 @@ in6_min_alarm 5v output undervoltage alarm
in7_min_alarm 3v output undervoltage alarm
in8_min_alarm Vee (-12v) output undervoltage alarm
-in9_input GPIO voltage data
+in9_input GPIO voltage data (see note 1)
+in10_input GPIO voltage data (see note 1)
+in11_input GPIO voltage data (see note 1)
power1_input 12v power usage (mW)
power2_input 5v power usage (mW)
power3_input 3v power usage (mW)
power4_input Vee (-12v) power usage (mW)
+
+
+Note 1
+------
+
+If you have NOT configured the driver to sample all GPIO pins as analog
+voltages, then the in10_input and in11_input sysfs attributes will not be
+created. The driver will sample the GPIO pin that is currently connected to the
+ADC as an analog voltage, and report the value in in9_input.
+
+If you have configured the driver to sample all GPIO pins as analog voltages,
+then they will be sampled in round-robin fashion. If userspace reads too
+slowly, -EAGAIN will be returned when you read the sysfs attribute containing
+the sensor reading.
+
+The LTC4245 chip can be configured to sample all GPIO pins with two methods:
+1) platform data -- see include/linux/i2c/ltc4245.h
+2) OF device tree -- add the "ltc4245,use-extra-gpios" property to each chip
+
+The default mode of operation is to sample a single GPIO pin.
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index d4e2917c6f18..ff45d1f837c8 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -107,10 +107,24 @@ in[0-*]_min Voltage min value.
Unit: millivolt
RW
+in[0-*]_lcrit Voltage critical min value.
+ Unit: millivolt
+ RW
+ If voltage drops to or below this limit, the system may
+ take drastic action such as power down or reset. At the very
+ least, it should report a fault.
+
in[0-*]_max Voltage max value.
Unit: millivolt
RW
+in[0-*]_crit Voltage critical max value.
+ Unit: millivolt
+ RW
+ If voltage reaches or exceeds this limit, the system may
+ take drastic action such as power down or reset. At the very
+ least, it should report a fault.
+
in[0-*]_input Voltage input value.
Unit: millivolt
RO
@@ -284,7 +298,7 @@ temp[1-*]_input Temperature input value.
Unit: millidegree Celsius
RO
-temp[1-*]_crit Temperature critical value, typically greater than
+temp[1-*]_crit Temperature critical max value, typically greater than
corresponding temp_max values.
Unit: millidegree Celsius
RW
@@ -296,6 +310,11 @@ temp[1-*]_crit_hyst
from the critical value.
RW
+temp[1-*]_lcrit Temperature critical min value, typically lower than
+ corresponding temp_min values.
+ Unit: millidegree Celsius
+ RW
+
temp[1-*]_offset
Temperature offset which is added to the temperature reading
by the chip.
@@ -344,9 +363,6 @@ Also see the Alarms section for status flags associated with temperatures.
* Currents *
************
-Note that no known chip provides current measurements as of writing,
-so this part is theoretical, so to say.
-
curr[1-*]_max Current max value
Unit: milliampere
RW
@@ -471,6 +487,7 @@ limit-related alarms, not both. The driver should just reflect the hardware
implementation.
in[0-*]_alarm
+curr[1-*]_alarm
fan[1-*]_alarm
temp[1-*]_alarm
Channel alarm
@@ -482,6 +499,8 @@ OR
in[0-*]_min_alarm
in[0-*]_max_alarm
+curr[1-*]_min_alarm
+curr[1-*]_max_alarm
fan[1-*]_min_alarm
fan[1-*]_max_alarm
temp[1-*]_min_alarm
@@ -497,7 +516,6 @@ to notify open diodes, unconnected fans etc. where the hardware
supports it. When this boolean has value 1, the measurement for that
channel should not be trusted.
-in[0-*]_fault
fan[1-*]_fault
temp[1-*]_fault
Input fault condition
@@ -513,6 +531,7 @@ beep_enable Master beep enable
RW
in[0-*]_beep
+curr[1-*]_beep
fan[1-*]_beep
temp[1-*]_beep
Channel beep
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index b7e42ec4b26b..13d556112fc0 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -20,6 +20,10 @@ Supported chips:
Prefix: 'w83667hg'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet: not available
+ * Winbond W83667HG-B
+ Prefix: 'w83667hg'
+ Addresses scanned: ISA address retrieved from Super I/O registers
+ Datasheet: Available from Nuvoton upon request
Authors:
Jean Delvare <khali@linux-fr.org>
@@ -32,8 +36,8 @@ Description
-----------
This driver implements support for the Winbond W83627EHF, W83627EHG,
-W83627DHG, W83627DHG-P and W83667HG super I/O chips. We will refer to them
-collectively as Winbond chips.
+W83627DHG, W83627DHG-P, W83667HG and W83667HG-B super I/O chips.
+We will refer to them collectively as Winbond chips.
The chips implement three temperature sensors, five fan rotation
speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
@@ -68,14 +72,15 @@ follows:
temp1 -> pwm1
temp2 -> pwm2
temp3 -> pwm3
-prog -> pwm4 (not on 667HG; the programmable setting is not supported by
- the driver)
+prog -> pwm4 (not on 667HG and 667HG-B; the programmable setting is not
+ supported by the driver)
/sys files
----------
name - this is a standard hwmon device entry. For the W83627EHF and W83627EHG,
- it is set to "w83627ehf" and for the W83627DHG it is set to "w83627dhg"
+ it is set to "w83627ehf", for the W83627DHG it is set to "w83627dhg",
+ and for the W83667HG it is set to "w83667hg".
pwm[1-4] - this file stores PWM duty cycle or DC value (fan speed) in range:
0 (stop) to 255 (full)
diff --git a/Documentation/i2c/instantiating-devices b/Documentation/i2c/instantiating-devices
index e89490270aba..87da405a8597 100644
--- a/Documentation/i2c/instantiating-devices
+++ b/Documentation/i2c/instantiating-devices
@@ -102,7 +102,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
memset(&i2c_info, 0, sizeof(struct i2c_board_info));
strlcpy(i2c_info.name, "isp1301_pnx", I2C_NAME_SIZE);
isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
- normal_i2c);
+ normal_i2c, NULL);
i2c_put_adapter(i2c_adap);
(...)
}
diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt
index 634c625da8ce..0d8addbb0fae 100644
--- a/Documentation/kbuild/kbuild.txt
+++ b/Documentation/kbuild/kbuild.txt
@@ -40,15 +40,15 @@ Set the directory to look for the kernel source when building external
modules.
The directory can be specified in several ways:
1) Use "M=..." on the command line
-2) Environmnet variable KBUILD_EXTMOD
-3) Environmnet variable SUBDIRS
+2) Environment variable KBUILD_EXTMOD
+3) Environment variable SUBDIRS
The possibilities are listed in the order they take precedence.
Using "M=..." will always override the others.
KBUILD_OUTPUT
--------------------------------------------------
Specify the output directory when building the kernel.
-The output directory can also be specificed using "O=...".
+The output directory can also be specified using "O=...".
Setting "O=..." takes precedence over KBUILD_OUTPUT.
ARCH
@@ -90,7 +90,7 @@ The script will be called with the following arguments:
$3 - kernel map file
$4 - default install path (use root directory if blank)
-The implmentation of "make install" is architecture specific
+The implementation of "make install" is architecture specific
and it may differ from the above.
INSTALLKERNEL is provided to enable the possibility to
diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt
index 71c602d61680..8abd041b605d 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -168,7 +168,7 @@ more details, with real examples.
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
- obj-$(CONFIG_ISDN) += isdn.o
+ obj-$(CONFIG_ISDN_I4L) += isdn.o
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
--- 3.3 Loadable module goals - obj-m
@@ -187,34 +187,35 @@ more details, with real examples.
Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'
If a kernel module is built from several source files, you specify
- that you want to build a module in the same way as above.
-
- Kbuild needs to know which the parts that you want to build your
- module from, so you have to tell it by setting an
- $(<module_name>-objs) variable.
+ that you want to build a module in the same way as above; however,
+ kbuild needs to know which object files you want to build your
+ module from, so you have to tell it by setting a $(<module_name>-y)
+ variable.
Example:
#drivers/isdn/i4l/Makefile
- obj-$(CONFIG_ISDN) += isdn.o
- isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
+ obj-$(CONFIG_ISDN_I4L) += isdn.o
+ isdn-y := isdn_net_lib.o isdn_v110.o isdn_common.o
In this example, the module name will be isdn.o. Kbuild will
- compile the objects listed in $(isdn-objs) and then run
+ compile the objects listed in $(isdn-y) and then run
"$(LD) -r" on the list of these files to generate isdn.o.
- Kbuild recognises objects used for composite objects by the suffix
- -objs, and the suffix -y. This allows the Makefiles to use
- the value of a CONFIG_ symbol to determine if an object is part
- of a composite object.
+ Due to kbuild recognizing $(<module_name>-y) for composite objects,
+ you can use the value of a CONFIG_ symbol to optionally include an
+ object file as part of a composite object.
Example:
#fs/ext2/Makefile
- obj-$(CONFIG_EXT2_FS) += ext2.o
- ext2-y := balloc.o bitmap.o
- ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
+ obj-$(CONFIG_EXT2_FS) += ext2.o
+ ext2-y := balloc.o dir.o file.o ialloc.o inode.o ioctl.o \
+ namei.o super.o symlink.o
+ ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o xattr_user.o \
+ xattr_trusted.o
- In this example, xattr.o is only part of the composite object
- ext2.o if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
+ In this example, xattr.o, xattr_user.o and xattr_trusted.o are only
+ part of the composite object ext2.o if $(CONFIG_EXT2_FS_XATTR)
+ evaluates to 'y'.
Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
@@ -244,12 +245,12 @@ more details, with real examples.
may contain both a built-in.o and a lib.a file.
Example:
- #arch/i386/lib/Makefile
- lib-y := checksum.o delay.o
+ #arch/x86/lib/Makefile
+ lib-y := delay.o
- This will create a library lib.a based on checksum.o and delay.o.
- For kbuild to actually recognize that there is a lib.a being built,
- the directory shall be listed in libs-y.
+ This will create a library lib.a based on delay.o. For kbuild to
+ actually recognize that there is a lib.a being built, the directory
+ shall be listed in libs-y.
See also "6.3 List directories to visit when descending".
Use of lib-y is normally restricted to lib/ and arch/*/lib.
@@ -284,43 +285,40 @@ more details, with real examples.
--- 3.7 Compilation flags
ccflags-y, asflags-y and ldflags-y
- The three flags listed above applies only to the kbuild makefile
- where they are assigned. They are used for all the normal
- cc, as and ld invocation happenign during a recursive build.
+ These three flags apply only to the kbuild makefile in which they
+ are assigned. They are used for all the normal cc, as and ld
+ invocations happening during a recursive build.
Note: Flags with the same behaviour were previously named:
EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
- They are yet supported but their use are deprecated.
+ They are still supported but their usage is deprecated.
- ccflags-y specifies options for compiling C files with $(CC).
+ ccflags-y specifies options for compiling with $(CC).
Example:
- # drivers/sound/emu10k1/Makefile
- ccflags-y += -I$(obj)
- ccflags-$(DEBUG) += -DEMU10K1_DEBUG
-
+ # drivers/acpi/Makefile
+ ccflags-y := -Os
+ ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
This variable is necessary because the top Makefile owns the
variable $(KBUILD_CFLAGS) and uses it for compilation flags for the
entire tree.
- asflags-y is a similar string for per-directory options
- when compiling assembly language source.
+ asflags-y specifies options for assembling with $(AS).
Example:
- #arch/x86_64/kernel/Makefile
- asflags-y := -traditional
+ #arch/sparc/kernel/Makefile
+ asflags-y := -ansi
-
- ldflags-y is a string for per-directory options to $(LD).
+ ldflags-y specifies options for linking with $(LD).
Example:
- #arch/m68k/fpsp040/Makefile
- ldflags-y := -x
+ #arch/cris/boot/compressed/Makefile
+ ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
subdir-ccflags-y, subdir-asflags-y
- The two flags listed above are similar to ccflags-y and as-falgs-y.
- The difference is that the subdir- variants has effect for the kbuild
- file where tey are present and all subdirectories.
+ The two flags listed above are similar to ccflags-y and asflags-y.
+ The difference is that the subdir- variants have effect for the kbuild
+ file where they are present and all subdirectories.
Options specified using subdir-* are added to the commandline before
the options specified using the non-subdir variants.
@@ -340,18 +338,18 @@ more details, with real examples.
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
-DGDTH_STATISTICS
- CFLAGS_seagate.o = -DARBITRATE -DPARITY -DSEAGATE_USE_ASM
- These three lines specify compilation flags for aha152x.o,
- gdth.o, and seagate.o
+ These two lines specify compilation flags for aha152x.o and gdth.o.
$(AFLAGS_$@) is a similar feature for source files in assembly
languages.
Example:
# arch/arm/kernel/Makefile
- AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -traditional
- AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
+ AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
+ AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
+ AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
+
--- 3.9 Dependency tracking
@@ -1176,14 +1174,14 @@ When kbuild executes, the following steps are followed (roughly):
=== 7 Kbuild syntax for exported headers
The kernel include a set of headers that is exported to userspace.
-Many headers can be exported as-is but other headers requires a
+Many headers can be exported as-is but other headers require a
minimal pre-processing before they are ready for user-space.
The pre-processing does:
- drop kernel specific annotations
- drop include of compiler.h
-- drop all sections that is kernel internat (guarded by ifdef __KERNEL__)
+- drop all sections that are kernel internal (guarded by ifdef __KERNEL__)
-Each relevant directory contain a file name "Kbuild" which specify the
+Each relevant directory contains a file name "Kbuild" which specifies the
headers to be exported.
See subsequent chapter for the syntax of the Kbuild file.
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 82d6aeb5228f..3cf6b496f0f8 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -89,8 +89,8 @@ parameter is applicable:
RAM RAM disk support is enabled.
S390 S390 architecture is enabled.
SCSI Appropriate SCSI support is enabled.
- A lot of drivers has their options described inside of
- Documentation/scsi/.
+ A lot of drivers have their options described inside
+ the Documentation/scsi/ sub-directory.
SECURITY Different security models are enabled.
SELINUX SELinux support is enabled.
SERIAL Serial support is enabled.
@@ -286,9 +286,6 @@ and is between 256 and 4096 characters. It is defined in the file
add_efi_memmap [EFI; X86] Include EFI memory map in
kernel's map of available physical RAM.
- advansys= [HW,SCSI]
- See header of drivers/scsi/advansys.c.
-
aedsp16= [HW,OSS] Audio Excel DSP 16
Format: <io>,<irq>,<dma>,<mss_io>,<mpu_io>,<mpu_irq>
See also header of sound/oss/aedsp16.c.
@@ -299,18 +296,6 @@ and is between 256 and 4096 characters. It is defined in the file
try_unsupported: try to drive unsupported chipsets
(may crash computer or cause data corruption)
- aha152x= [HW,SCSI]
- See Documentation/scsi/aha152x.txt.
-
- aha1542= [HW,SCSI]
- Format: <portbase>[,<buson>,<busoff>[,<dmaspeed>]]
-
- aic7xxx= [HW,SCSI]
- See Documentation/scsi/aic7xxx.txt.
-
- aic79xx= [HW,SCSI]
- See Documentation/scsi/aic79xx.txt.
-
alignment= [KNL,ARM]
Allow the default userspace alignment fault handler
behaviour to be specified. Bit 0 enables warnings,
@@ -371,8 +356,6 @@ and is between 256 and 4096 characters. It is defined in the file
atarimouse= [HW,MOUSE] Atari Mouse
- atascsi= [HW,SCSI] Atari SCSI
-
atkbd.extra= [HW] Enable extra LEDs and keys on IBM RapidAccess,
EzKey and similar keyboards
@@ -422,10 +405,6 @@ and is between 256 and 4096 characters. It is defined in the file
bttv.pll= See Documentation/video4linux/bttv/Insmod-options
bttv.tuner= and Documentation/video4linux/bttv/CARDLIST
- BusLogic= [HW,SCSI]
- See drivers/scsi/BusLogic.c, comment before function
- BusLogic_ParseDriverOptions().
-
c101= [NET] Moxa C101 synchronous serial card
cachesize= [BUGS=X86-32] Override level 2 CPU cache size detection.
@@ -676,8 +655,6 @@ and is between 256 and 4096 characters. It is defined in the file
dscc4.setup= [NET]
- dtc3181e= [HW,SCSI]
-
dynamic_printk Enables pr_debug()/dev_dbg() calls if
CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
These can also be switched on/off via
@@ -715,8 +692,6 @@ and is between 256 and 4096 characters. It is defined in the file
This is desgined to be used in conjunction with
the boot argument: earlyprintk=vga
- eata= [HW,SCSI]
-
edd= [EDD]
Format: {"off" | "on" | "skip[mbr]"}
@@ -772,12 +747,6 @@ and is between 256 and 4096 characters. It is defined in the file
Format: <interval>,<probability>,<space>,<times>
See also /Documentation/fault-injection/.
- fd_mcs= [HW,SCSI]
- See header of drivers/scsi/fd_mcs.c.
-
- fdomain= [HW,SCSI]
- See header of drivers/scsi/fdomain.c.
-
floppy= [HW]
See Documentation/blockdev/floppy.txt.
@@ -837,14 +806,9 @@ and is between 256 and 4096 characters. It is defined in the file
When zero, profiling data is discarded and associated
debugfs files are removed at module unload time.
- gdth= [HW,SCSI]
- See header of drivers/scsi/gdth.c.
-
gpt [EFI] Forces disk with valid GPT signature but
invalid Protective MBR to be treated as GPT.
- gvp11= [HW,SCSI]
-
hashdist= [KNL,NUMA] Large hashes allocated during boot
are distributed across NUMA nodes. Defaults on
for 64bit NUMA, off otherwise.
@@ -936,9 +900,6 @@ and is between 256 and 4096 characters. It is defined in the file
i8k.restricted [HW] Allow controlling fans only if SYS_ADMIN
capability is set.
- ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter
- See Documentation/mca.txt.
-
icn= [HW,ISDN]
Format: <io>[,<membase>[,<icn_id>[,<icn_id2>]]]
@@ -988,9 +949,6 @@ and is between 256 and 4096 characters. It is defined in the file
programs exec'd, files mmap'd for exec, and all files
opened for read by uid=0.
- in2000= [HW,SCSI]
- See header of drivers/scsi/in2000.c.
-
init= [KNL]
Format: <full_path>
Run specified binary instead of /sbin/init as init
@@ -1068,9 +1026,6 @@ and is between 256 and 4096 characters. It is defined in the file
See comment before ip2_setup() in
drivers/char/ip2/ip2base.c.
- ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
- See header of drivers/scsi/ips.c.
-
irqfixup [HW]
When an interrupt is not handled search all handlers
for it. Intended to get systems with badly broken
@@ -1343,9 +1298,6 @@ and is between 256 and 4096 characters. It is defined in the file
ltpc= [NET]
Format: <io>,<irq>,<dma>
- mac5380= [HW,SCSI] Format:
- <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
-
machvec= [IA64] Force the use of a particular machine-vector
(machvec) in a generic kernel.
Example: machvec=hpzx1_swiotlb
@@ -1367,13 +1319,6 @@ and is between 256 and 4096 characters. It is defined in the file
be mounted
Format: <1-256>
- max_luns= [SCSI] Maximum number of LUNs to probe.
- Should be between 1 and 2^32-1.
-
- max_report_luns=
- [SCSI] Maximum number of LUNs received.
- Should be between 1 and 16384.
-
mcatest= [IA-64]
mce [X86-32] Machine Check Exception
@@ -1573,19 +1518,6 @@ and is between 256 and 4096 characters. It is defined in the file
n2= [NET] SDL Inc. RISCom/N2 synchronous serial card
- NCR_D700= [HW,SCSI]
- See header of drivers/scsi/NCR_D700.c.
-
- ncr5380= [HW,SCSI]
-
- ncr53c400= [HW,SCSI]
-
- ncr53c400a= [HW,SCSI]
-
- ncr53c406a= [HW,SCSI]
-
- ncr53c8xx= [HW,SCSI]
-
netdev= [NET] Network devices parameters
Format: <irq>,<io>,<mem_start>,<mem_end>,<name>
Note that mem_start is often overloaded to mean
@@ -1687,8 +1619,6 @@ and is between 256 and 4096 characters. It is defined in the file
nodelayacct [KNL] Disable per-task delay accounting
- nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
-
nodsp [SH] Disable hardware DSP at boot time.
noefi [X86] Disable EFI runtime services support.
@@ -1863,10 +1793,6 @@ and is between 256 and 4096 characters. It is defined in the file
perfmon on Intel CPUs instead of the
CPU specific event set.
- osst= [HW,SCSI] SCSI Tape Driver
- Format: <buffer_size>,<write_threshold>
- See also Documentation/scsi/st.txt.
-
panic= [KNL] Kernel behaviour on panic
Format: <timeout>
@@ -1902,9 +1828,6 @@ and is between 256 and 4096 characters. It is defined in the file
pas2= [HW,OSS] Format:
<io>,<irq>,<dma>,<dma16>,<sb_io>,<sb_irq>,<sb_dma>,<sb_dma16>
- pas16= [HW,SCSI]
- See header of drivers/scsi/pas16.c.
-
pause_on_oops=
Halt all CPUs after the first oops has been printed for
the specified number of seconds. This is to be used if
@@ -1970,6 +1893,8 @@ and is between 256 and 4096 characters. It is defined in the file
norom [X86] Do not assign address space to
expansion ROMs that do not already have
BIOS assigned address ranges.
+ nobar [X86] Do not assign address space to the
+ BARs that weren't assigned by the BIOS.
irqmask=0xMMMM [X86] Set a bit mask of IRQs allowed to be
assigned automatically to PCI devices. You can
make the kernel exclude IRQs of your ISA cards
@@ -2273,30 +2198,6 @@ and is between 256 and 4096 characters. It is defined in the file
sched_debug [KNL] Enables verbose scheduler debug messages.
- scsi_debug_*= [SCSI]
- See drivers/scsi/scsi_debug.c.
-
- scsi_default_dev_flags=
- [SCSI] SCSI default device flags
- Format: <integer>
-
- scsi_dev_flags= [SCSI] Black/white list entry for vendor and model
- Format: <vendor>:<model>:<flags>
- (flags are integer value)
-
- scsi_logging_level= [SCSI] a bit mask of logging levels
- See drivers/scsi/scsi_logging.h for bits. Also
- settable via sysctl at dev.scsi.logging_level
- (/proc/sys/dev/scsi/logging_level).
- There is also a nice 'scsi_logging_level' script in the
- S390-tools package, available for download at
- http://www-128.ibm.com/developerworks/linux/linux390/s390-tools-1.5.4.html
-
- scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
- discovered. async scans them in kernel threads,
- allowing boot to proceed. none ignores them, expecting
- user space to do the scan.
-
security= [SECURITY] Choose a security module to enable at boot.
If this boot parameter is not specified, only the first
security module asking for security registration will be
@@ -2323,9 +2224,6 @@ and is between 256 and 4096 characters. It is defined in the file
The parameter means the number of CPUs to show,
for example 1 means boot CPU only.
- sim710= [SCSI,HW]
- See header of drivers/scsi/sim710.c.
-
simeth= [IA-64]
simscsi=
@@ -2522,9 +2420,6 @@ and is between 256 and 4096 characters. It is defined in the file
sscape= [HW,OSS]
Format: <io>,<irq>,<dma>,<mpu_io>,<mpu_irq>
- st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
- See Documentation/scsi/st.txt.
-
stacktrace [FTRACE]
Enabled the stack tracer on boot up.
@@ -2582,18 +2477,12 @@ and is between 256 and 4096 characters. It is defined in the file
switches= [HW,M68k]
- sym53c416= [HW,SCSI]
- See header of drivers/scsi/sym53c416.c.
-
sysrq_always_enabled
[KNL]
Ignore sysrq setting - this boot parameter will
neutralize any effect of /proc/sys/kernel/sysrq.
Useful for debugging.
- t128= [HW,SCSI]
- See header of drivers/scsi/t128.c.
-
tdfx= [HW,DRM]
test_suspend= [SUSPEND]
@@ -2630,10 +2519,6 @@ and is between 256 and 4096 characters. It is defined in the file
<deci-seconds>: poll all this frequency
0: no polling (default)
- tmscsim= [HW,SCSI]
- See comment before function dc390_setup() in
- drivers/scsi/tmscsim.c.
-
topology= [S390]
Format: {off | on}
Specify if the kernel should make use of the cpu
@@ -2678,9 +2563,6 @@ and is between 256 and 4096 characters. It is defined in the file
<port#>,<js1>,<js2>,<js3>,<js4>,<js5>,<js6>,<js7>
See also Documentation/input/joystick-parport.txt
- u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
- See header of drivers/scsi/u14-34f.c.
-
uart401= [HW,OSS]
Format: <io>,<irq>
@@ -2855,12 +2737,6 @@ and is between 256 and 4096 characters. It is defined in the file
waveartist= [HW,OSS]
Format: <io>,<irq>,<dma>,<dma2>
- wd33c93= [HW,SCSI]
- See header of drivers/scsi/wd33c93.c.
-
- wd7000= [HW,SCSI]
- See header of drivers/scsi/wd7000.c.
-
watchdog timers [HW,WDT] For information on watchdog timers,
see Documentation/watchdog/watchdog-parameters.txt
or other driver-specific files in the
diff --git a/Documentation/scsi/scsi-parameters.txt b/Documentation/scsi/scsi-parameters.txt
new file mode 100644
index 000000000000..21e5798526ee
--- /dev/null
+++ b/Documentation/scsi/scsi-parameters.txt
@@ -0,0 +1,139 @@
+ SCSI Kernel Parameters
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+See Documentation/kernel-parameters.txt for general information on
+specifying module parameters.
+
+This document may not be entirely up to date and comprehensive. The command
+"modinfo -p ${modulename}" shows a current list of all parameters of a loadable
+module. Loadable modules, after being loaded into the running kernel, also
+reveal their parameters in /sys/module/${modulename}/parameters/. Some of these
+parameters may be changed at runtime by the command
+"echo -n ${value} > /sys/module/${modulename}/parameters/${parm}".
+
+
+ advansys= [HW,SCSI]
+ See header of drivers/scsi/advansys.c.
+
+ aha152x= [HW,SCSI]
+ See Documentation/scsi/aha152x.txt.
+
+ aha1542= [HW,SCSI]
+ Format: <portbase>[,<buson>,<busoff>[,<dmaspeed>]]
+
+ aic7xxx= [HW,SCSI]
+ See Documentation/scsi/aic7xxx.txt.
+
+ aic79xx= [HW,SCSI]
+ See Documentation/scsi/aic79xx.txt.
+
+ atascsi= [HW,SCSI] Atari SCSI
+
+ BusLogic= [HW,SCSI]
+ See drivers/scsi/BusLogic.c, comment before function
+ BusLogic_ParseDriverOptions().
+
+ dtc3181e= [HW,SCSI]
+
+ eata= [HW,SCSI]
+
+ fd_mcs= [HW,SCSI]
+ See header of drivers/scsi/fd_mcs.c.
+
+ fdomain= [HW,SCSI]
+ See header of drivers/scsi/fdomain.c.
+
+ gdth= [HW,SCSI]
+ See header of drivers/scsi/gdth.c.
+
+ gvp11= [HW,SCSI]
+
+ ibmmcascsi= [HW,MCA,SCSI] IBM MicroChannel SCSI adapter
+ See Documentation/mca.txt.
+
+ in2000= [HW,SCSI]
+ See header of drivers/scsi/in2000.c.
+
+ ips= [HW,SCSI] Adaptec / IBM ServeRAID controller
+ See header of drivers/scsi/ips.c.
+
+ mac5380= [HW,SCSI] Format:
+ <can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags>
+
+ max_luns= [SCSI] Maximum number of LUNs to probe.
+ Should be between 1 and 2^32-1.
+
+ max_report_luns=
+ [SCSI] Maximum number of LUNs received.
+ Should be between 1 and 16384.
+
+ NCR_D700= [HW,SCSI]
+ See header of drivers/scsi/NCR_D700.c.
+
+ ncr5380= [HW,SCSI]
+
+ ncr53c400= [HW,SCSI]
+
+ ncr53c400a= [HW,SCSI]
+
+ ncr53c406a= [HW,SCSI]
+
+ ncr53c8xx= [HW,SCSI]
+
+ nodisconnect [HW,SCSI,M68K] Disables SCSI disconnects.
+
+ osst= [HW,SCSI] SCSI Tape Driver
+ Format: <buffer_size>,<write_threshold>
+ See also Documentation/scsi/st.txt.
+
+ pas16= [HW,SCSI]
+ See header of drivers/scsi/pas16.c.
+
+ scsi_debug_*= [SCSI]
+ See drivers/scsi/scsi_debug.c.
+
+ scsi_default_dev_flags=
+ [SCSI] SCSI default device flags
+ Format: <integer>
+
+ scsi_dev_flags= [SCSI] Black/white list entry for vendor and model
+ Format: <vendor>:<model>:<flags>
+ (flags are integer value)
+
+ scsi_logging_level= [SCSI] a bit mask of logging levels
+ See drivers/scsi/scsi_logging.h for bits. Also
+ settable via sysctl at dev.scsi.logging_level
+ (/proc/sys/dev/scsi/logging_level).
+ There is also a nice 'scsi_logging_level' script in the
+ S390-tools package, available for download at
+ http://www-128.ibm.com/developerworks/linux/linux390/s390-tools-1.5.4.html
+
+ scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
+ discovered. async scans them in kernel threads,
+ allowing boot to proceed. none ignores them, expecting
+ user space to do the scan.
+
+ sim710= [SCSI,HW]
+ See header of drivers/scsi/sim710.c.
+
+ st= [HW,SCSI] SCSI tape parameters (buffers, etc.)
+ See Documentation/scsi/st.txt.
+
+ sym53c416= [HW,SCSI]
+ See header of drivers/scsi/sym53c416.c.
+
+ t128= [HW,SCSI]
+ See header of drivers/scsi/t128.c.
+
+ tmscsim= [HW,SCSI]
+ See comment before function dc390_setup() in
+ drivers/scsi/tmscsim.c.
+
+ u14-34f= [HW,SCSI] UltraStor 14F/34F SCSI host adapter
+ See header of drivers/scsi/u14-34f.c.
+
+ wd33c93= [HW,SCSI]
+ See header of drivers/scsi/wd33c93.c.
+
+ wd7000= [HW,SCSI]
+ See header of drivers/scsi/wd7000.c.
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 16ca030e1185..87c46347bd63 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -17,9 +17,9 @@
16 -> DVBWorld DVB-S2 2005 [0001:2005]
17 -> NetUP Dual DVB-S2 CI [1b55:2a2c]
18 -> Hauppauge WinTV-HVR1270 [0070:2211]
- 19 -> Hauppauge WinTV-HVR1275 [0070:2215]
- 20 -> Hauppauge WinTV-HVR1255 [0070:2251]
- 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295]
+ 19 -> Hauppauge WinTV-HVR1275 [0070:2215,0070:221d,0070:22f2]
+ 20 -> Hauppauge WinTV-HVR1255 [0070:2251,0070:2259,0070:22f1]
+ 21 -> Hauppauge WinTV-HVR1210 [0070:2291,0070:2295,0070:2299,0070:229d,0070:22f0,0070:22f3,0070:22f4,0070:22f5]
22 -> Mygica X8506 DMB-TH [14f1:8651]
23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657]
24 -> Hauppauge WinTV-HVR1850 [0070:8541]
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 1387a69ae3aa..4000c29fcfb6 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -178,4 +178,5 @@
177 -> Hawell HW-404M7
178 -> Beholder BeholdTV H7 [5ace:7190]
179 -> Beholder BeholdTV A7 [5ace:7090]
-180 -> Avermedia M733A [1461:4155,1461:4255]
+180 -> Avermedia PCI M733A [1461:4155,1461:4255]
+181 -> TechoTrend TT-budget T-3000 [13c2:2804]
diff --git a/Documentation/video4linux/extract_xc3028.pl b/Documentation/video4linux/extract_xc3028.pl
index 47877deae6d7..47877deae6d7 100644..100755
--- a/Documentation/video4linux/extract_xc3028.pl
+++ b/Documentation/video4linux/extract_xc3028.pl
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index f13eb036c439..56ba7bba7168 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -29,8 +29,12 @@ zc3xx 041e:4029 Creative WebCam Vista Pro
zc3xx 041e:4034 Creative Instant P0620
zc3xx 041e:4035 Creative Instant P0620D
zc3xx 041e:4036 Creative Live !
+sq930x 041e:4038 Creative Joy-IT
zc3xx 041e:403a Creative Nx Pro 2
spca561 041e:403b Creative Webcam Vista (VF0010)
+sq930x 041e:403c Creative Live! Ultra
+sq930x 041e:403d Creative Live! Ultra for Notebooks
+sq930x 041e:4041 Creative Live! Motion
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
ov519 041e:4052 Creative Live! VISTA IM
zc3xx 041e:4053 Creative Live!Cam Video IM
@@ -138,6 +142,7 @@ finepix 04cb:013d Fujifilm FinePix unknown model
finepix 04cb:013f Fujifilm FinePix F420
sunplus 04f1:1001 JVC GC A50
spca561 04fc:0561 Flexcam 100
+spca1528 04fc:1528 Sunplus MD80 clone
sunplus 04fc:500c Sunplus CA500C
sunplus 04fc:504a Aiptek Mini PenCam 1.3
sunplus 04fc:504b Maxell MaxPocket LE 1.3
@@ -253,6 +258,7 @@ pac7302 093a:2620 Apollo AC-905
pac7302 093a:2621 PAC731x
pac7302 093a:2622 Genius Eye 312
pac7302 093a:2624 PAC7302
+pac7302 093a:2625 Genius iSlim 310
pac7302 093a:2626 Labtec 2200
pac7302 093a:2628 Genius iLook 300
pac7302 093a:2629 Genious iSlim 300
@@ -362,6 +368,8 @@ sq905c 2770:9052 Disney pix micro 2 (VGA)
sq905c 2770:905c All 11 known cameras with this ID
sq905 2770:9120 All 24 known cameras with this ID
sq905c 2770:913d All 4 known cameras with this ID
+sq930x 2770:930b Sweex Motion Tracking / I-Tec iCam Tracer
+sq930x 2770:930c Trust WB-3500T / NSG Robbie 2.0
spca500 2899:012c Toptro Industrial
ov519 8020:ef04 ov519
spca508 8086:0110 Intel Easy PC Camera
diff --git a/Documentation/vm/page-types.c b/Documentation/vm/page-types.c
index 66e9358e2144..ccd951fa94ee 100644
--- a/Documentation/vm/page-types.c
+++ b/Documentation/vm/page-types.c
@@ -694,7 +694,7 @@ static void usage(void)
#endif
" -l|--list Show page details in ranges\n"
" -L|--list-each Show page details one by one\n"
-" -N|--no-summary Don't show summay info\n"
+" -N|--no-summary Don't show summary info\n"
" -X|--hwpoison hwpoison pages\n"
" -x|--unpoison unpoison pages\n"
" -h|--help Show this usage message\n"
diff --git a/MAINTAINERS b/MAINTAINERS
index 58848125b8bf..550f969f6125 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -950,8 +950,9 @@ ARM/SHMOBILE ARM ARCHITECTURE
M: Paul Mundt <lethal@linux-sh.org>
M: Magnus Damm <magnus.damm@gmail.com>
L: linux-sh@vger.kernel.org
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git
W: http://oss.renesas.com
+Q: http://patchwork.kernel.org/project/linux-sh/list/
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/lethal/genesis-2.6.git
S: Supported
F: arch/arm/mach-shmobile/
F: drivers/sh/
@@ -1571,6 +1572,16 @@ L: platform-driver-x86@vger.kernel.org
S: Supported
F: drivers/platform/x86/classmate-laptop.c
+COCCINELLE/Semantic Patches (SmPL)
+M: Julia Lawall <julia@diku.dk>
+M: Gilles Muller <Gilles.Muller@lip6.fr>
+M: Nicolas Palix <npalix@diku.dk>
+L: cocci@diku.dk (moderated for non-subscribers)
+W: http://coccinelle.lip6.fr/
+S: Supported
+F: scripts/coccinelle/
+F: scripts/coccicheck
+
CODA FILE SYSTEM
M: Jan Harkes <jaharkes@cs.cmu.edu>
M: coda@cs.cmu.edu
@@ -3253,8 +3264,8 @@ F: fs/autofs4/
KERNEL BUILD + files below scripts/ (unless maintained elsewhere)
M: Michal Marek <mmarek@suse.cz>
-T: git git://repo.or.cz/linux-kbuild.git for-next
-T: git git://repo.or.cz/linux-kbuild.git for-linus
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git for-next
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6.git rc-fixes
L: linux-kbuild@vger.kernel.org
S: Maintained
F: Documentation/kbuild/
@@ -5224,6 +5235,13 @@ M: Nicolas Pitre <nico@fluxnic.net>
S: Odd Fixes
F: drivers/net/smc91x.*
+SMSC EMC2103 HARDWARE MONITOR DRIVER
+M: Steve Glendinning <steve.glendinning@smsc.com>
+L: lm-sensors@lm-sensors.org
+S: Supported
+F: Documentation/hwmon/emc2103
+F: drivers/hwmon/emc2103.c
+
SMSC47B397 HARDWARE MONITOR DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
L: lm-sensors@lm-sensors.org
@@ -5537,6 +5555,15 @@ W: http://tcp-lp-mod.sourceforge.net/
S: Maintained
F: net/ipv4/tcp_lp.c
+TEGRA SUPPORT
+M: Colin Cross <ccross@android.com>
+M: Erik Gilling <konkers@android.com>
+M: Olof Johansson <olof@lixom.net>
+L: linux-tegra@vger.kernel.org
+T: git git://android.git.kernel.org/kernel/tegra.git
+S: Supported
+F: arch/arm/mach-tegra
+
TEHUTI ETHERNET DRIVER
M: Alexander Indenbaum <baum@tehutinetworks.net>
M: Andy Gospodarek <andy@greyhouse.net>
@@ -5589,6 +5616,12 @@ F: include/linux/tipc*.h
F: include/net/tipc/
F: net/tipc/
+TILE ARCHITECTURE
+M: Chris Metcalf <cmetcalf@tilera.com>
+W: http://www.tilera.com/scm/
+S: Supported
+F: arch/tile/
+
TLAN NETWORK DRIVER
M: Samuel Chessman <chessman@tux.org>
L: tlan-devel@lists.sourceforge.net (subscribers-only)
diff --git a/Makefile b/Makefile
index 037ff4e62ca0..a14c207db8ac 100644
--- a/Makefile
+++ b/Makefile
@@ -412,9 +412,9 @@ endif
# of make so .config is not included in this case either (for *config).
no-dot-config-targets := clean mrproper distclean \
- cscope TAGS tags help %docs check% \
+ cscope TAGS tags help %docs check% coccicheck \
include/linux/version.h headers_% \
- kernelrelease kernelversion
+ kernelversion
config-targets := 0
mixed-targets := 0
@@ -526,7 +526,7 @@ endif # $(dot-config)
# The all: target is the default when no target is given on the
# command line.
# This allow a user to issue only 'make' to build a kernel including modules
-# Defaults vmlinux but it is usually overridden in the arch makefile
+# Defaults to vmlinux, but the arch makefile usually adds further targets
all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
@@ -557,6 +557,10 @@ KBUILD_CFLAGS += -g
KBUILD_AFLAGS += -gdwarf-2
endif
+ifdef CONFIG_DEBUG_INFO_REDUCED
+KBUILD_CFLAGS += $(call cc-option, -femit-struct-debug-baseonly)
+endif
+
ifdef CONFIG_FUNCTION_TRACER
KBUILD_CFLAGS += -pg
endif
@@ -1209,8 +1213,9 @@ help:
@echo ' includecheck - Check for duplicate included header files'
@echo ' export_report - List the usages of all exported symbols'
@echo ' headers_check - Sanity check on exported headers'
- @echo ' headerdep - Detect inclusion cycles in headers'; \
- echo ''
+ @echo ' headerdep - Detect inclusion cycles in headers'
+ @$(MAKE) -f $(srctree)/scripts/Makefile.help checker-help
+ @echo ''
@echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help
@echo ''
@@ -1369,6 +1374,9 @@ versioncheck:
-name '*.[hcS]' -type f -print | sort \
| xargs $(PERL) -w $(srctree)/scripts/checkversion.pl
+coccicheck:
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@
+
namespacecheck:
$(PERL) $(srctree)/scripts/namespace.pl
@@ -1393,9 +1401,9 @@ checkstack:
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
$(PERL) $(src)/scripts/checkstack.pl $(CHECKSTACK_ARCH)
-kernelrelease:
- $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
- $(error kernelrelease not valid - run 'make prepare' to update it))
+kernelrelease: include/config/kernel.release
+ @echo $(KERNELRELEASE)
+
kernelversion:
@echo $(KERNELVERSION)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 98922f7d2d12..3bcf9bd02e7c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -10,6 +10,7 @@ config ARM
default y
select HAVE_AOUT
select HAVE_IDE
+ select HAVE_LMB
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select GENERIC_ATOMIC64 if (!CPU_32v6K)
@@ -24,6 +25,7 @@ config ARM
select HAVE_KERNEL_LZMA
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
+ select HAVE_REGS_AND_STACK_ACCESS_API
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -439,21 +441,6 @@ config ARCH_IXP4XX
help
Support for Intel's IXP4XX (XScale) family of processors.
-config ARCH_L7200
- bool "LinkUp-L7200"
- select CPU_ARM720T
- select FIQ
- select ARCH_USES_GETTIMEOFFSET
- help
- Say Y here if you intend to run this kernel on a LinkUp Systems
- L7200 Software Development Board which uses an ARM720T processor.
- Information on this board can be obtained at:
-
- <http://www.linkupsys.com/>
-
- If you have any questions or comments about the Linux kernel port
- to this board, send e-mail to <sjhill@cotw.com>.
-
config ARCH_DOVE
bool "Marvell Dove"
select PCI
@@ -561,6 +548,18 @@ config ARCH_NUC93X
Support for Nuvoton (Winbond logic dept.) NUC93X MCU,The NUC93X is a
low-power and high performance MPEG-4/JPEG multimedia controller chip.
+config ARCH_TEGRA
+ bool "NVIDIA Tegra"
+ select GENERIC_TIME
+ select GENERIC_CLOCKEVENTS
+ select GENERIC_GPIO
+ select HAVE_CLK
+ select COMMON_CLKDEV
+ select ARCH_HAS_BARRIERS if CACHE_L2X0
+ help
+ This enables support for NVIDIA Tegra based systems (Tegra APX,
+ Tegra 6xx and Tegra 2 series).
+
config ARCH_PNX4008
bool "Philips Nexperia PNX4008 Mobile"
select CPU_ARM926T
@@ -586,6 +585,7 @@ config ARCH_MSM
bool "Qualcomm MSM"
select HAVE_CLK
select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
help
Support for Qualcomm MSM/QSD based systems. This runs on the
apps processor of the MSM/QSD and depends on a shared memory
@@ -719,7 +719,6 @@ config ARCH_SHARK
config ARCH_LH7A40X
bool "Sharp LH7A40X"
select CPU_ARM922T
- select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
select ARCH_USES_GETTIMEOFFSET
help
@@ -908,6 +907,8 @@ source "arch/arm/mach-shmobile/Kconfig"
source "arch/arm/plat-stmp3xxx/Kconfig"
+source "arch/arm/mach-tegra/Kconfig"
+
source "arch/arm/mach-u300/Kconfig"
source "arch/arm/mach-ux500/Kconfig"
@@ -1031,11 +1032,6 @@ endmenu
source "arch/arm/common/Kconfig"
-config FORCE_MAX_ZONEORDER
- int
- depends on SA1111
- default "9"
-
menu "Bus support"
config ARM_AMBA
@@ -1100,10 +1096,11 @@ config SMP
bool "Symmetric Multi-Processing (EXPERIMENTAL)"
depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\
MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 ||\
- ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
depends on GENERIC_CLOCKEVENTS
select USE_GENERIC_SMP_HELPERS
- select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4)
+ select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500 || \
+ ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
help
This enables support for systems with more than one CPU. If you have
a system with only one CPU, like most personal computers, say N. If
@@ -1172,9 +1169,11 @@ config HOTPLUG_CPU
config LOCAL_TIMERS
bool "Use local timer interrupts"
depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \
- REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500)
+ REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || \
+ ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || ARCH_TEGRA)
default y
- select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500)
+ select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_VEXPRESS || ARCH_OMAP4 || ARCH_U8500 || \
+ ARCH_TEGRA)
help
Enable support for local timers on SMP platforms, rather then the
legacy IPI broadcast method. Local timers allows the system
@@ -1185,7 +1184,6 @@ source kernel/Kconfig.preempt
config HZ
int
- default 128 if ARCH_L7200
default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P6440 || ARCH_S5P6442 || ARCH_S5PV210
default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
default AT91_TIMER_HZ if ARCH_AT91
@@ -1241,10 +1239,6 @@ config OABI_COMPAT
config ARCH_HAS_HOLES_MEMORYMODEL
bool
-# Discontigmem is deprecated
-config ARCH_DISCONTIGMEM_ENABLE
- bool
-
config ARCH_SPARSEMEM_ENABLE
bool
@@ -1252,13 +1246,7 @@ config ARCH_SPARSEMEM_DEFAULT
def_bool ARCH_SPARSEMEM_ENABLE
config ARCH_SELECT_MEMORY_MODEL
- def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE
-
-config NODES_SHIFT
- int
- default "4" if ARCH_LH7A40X
- default "2"
- depends on NEED_MULTIPLE_NODES
+ def_bool ARCH_SPARSEMEM_ENABLE
config HIGHMEM
bool "High Memory Support (EXPERIMENTAL)"
@@ -1290,8 +1278,36 @@ config HW_PERF_EVENTS
Enable hardware performance counter support for perf events. If
disabled, perf events will use software events only.
+config SPARSE_IRQ
+ bool "Support sparse irq numbering"
+ depends on EXPERIMENTAL
+ help
+ This enables support for sparse irqs. This is useful in general
+ as most CPUs have a fairly sparse array of IRQ vectors, which
+ the irq_desc then maps directly on to. Systems with a high
+ number of off-chip IRQs will want to treat this as
+ experimental until they have been independently verified.
+
+ If you don't know what to do here, say N.
+
source "mm/Kconfig"
+config FORCE_MAX_ZONEORDER
+ int "Maximum zone order" if ARCH_SHMOBILE
+ range 11 64 if ARCH_SHMOBILE
+ default "9" if SA1111
+ default "11"
+ help
+ The kernel memory allocator divides physically contiguous memory
+ blocks into "zones", where each zone is a power of two number of
+ pages. This option selects the largest power of two that the kernel
+ keeps in the memory allocator. If you need to allocate very large
+ blocks of physically contiguous memory, then you may need to
+ increase this value.
+
+ This config option is actually maximum order plus one. For example,
+ a value of 11 means that the largest free memory block is 2^10 pages.
+
config LEDS
bool "Timer and CPU usage LEDs"
depends on ARCH_CDB89712 || ARCH_EBSA110 || \
@@ -1375,6 +1391,18 @@ config UACCESS_WITH_MEMCPY
However, if the CPU data cache is using a write-allocate mode,
this option is unlikely to provide any performance gain.
+config CC_STACKPROTECTOR
+ bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
+ help
+ This option turns on the -fstack-protector GCC feature. This
+ feature puts, at the beginning of functions, a canary value on
+ the stack just before the return address, and validates
+ the value just before actually returning. Stack based buffer
+ overflows (that need to overwrite this return address) now also
+ overwrite the canary, which gets detected and the attack is then
+ neutralized via a kernel panic.
+ This feature requires gcc version 4.2 or above.
+
endmenu
menu "Boot options"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 64ba313724d2..963066a0ef2f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -34,6 +34,10 @@ ifeq ($(CONFIG_FRAME_POINTER),y)
KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
endif
+ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
+KBUILD_CFLAGS +=-fstack-protector
+endif
+
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
@@ -139,14 +143,13 @@ machine-$(CONFIG_ARCH_IXP23XX) := ixp23xx
machine-$(CONFIG_ARCH_IXP4XX) := ixp4xx
machine-$(CONFIG_ARCH_KIRKWOOD) := kirkwood
machine-$(CONFIG_ARCH_KS8695) := ks8695
-machine-$(CONFIG_ARCH_L7200) := l7200
machine-$(CONFIG_ARCH_LH7A40X) := lh7a40x
machine-$(CONFIG_ARCH_LOKI) := loki
machine-$(CONFIG_ARCH_MMP) := mmp
machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0
-machine-$(CONFIG_ARCH_MX1) := mx1
-machine-$(CONFIG_ARCH_MX2) := mx2
+machine-$(CONFIG_ARCH_MX1) := imx
+machine-$(CONFIG_ARCH_MX2) := imx
machine-$(CONFIG_ARCH_MX25) := mx25
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
@@ -175,6 +178,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark
machine-$(CONFIG_ARCH_SHMOBILE) := shmobile
machine-$(CONFIG_ARCH_STMP378X) := stmp378x
machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx
+machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_U300) := u300
machine-$(CONFIG_ARCH_U8500) := ux500
machine-$(CONFIG_ARCH_VERSATILE) := versatile
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 53faa9063a03..7a29301d516b 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -19,10 +19,6 @@ ifeq ($(CONFIG_ARCH_SHARK),y)
OBJS += head-shark.o ofw-shark.o
endif
-ifeq ($(CONFIG_ARCH_L7200),y)
-OBJS += head-l7200.o
-endif
-
ifeq ($(CONFIG_ARCH_P720T),y)
# Borrow this code from SA1100
OBJS += head-sa1100.o
diff --git a/arch/arm/boot/compressed/head-l7200.S b/arch/arm/boot/compressed/head-l7200.S
deleted file mode 100644
index d0e3b20856cd..000000000000
--- a/arch/arm/boot/compressed/head-l7200.S
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/head-l7200.S
- *
- * Copyright (C) 2000 Steve Hill <sjhill@cotw.com>
- *
- * Some code borrowed from Nicolas Pitre's 'head-sa1100.S' file. This
- * is merged with head.S by the linker.
- */
-
-#include <asm/mach-types.h>
-
-#ifndef CONFIG_ARCH_L7200
-#error What am I doing here...
-#endif
-
- .section ".start", "ax"
-
-__L7200_start:
- mov r0, #0x00100000 @ FLASH address of initrd
- mov r2, #0xf1000000 @ RAM address of initrd
- add r3, r2, #0x00700000 @ Size of initrd
-1:
- ldmia r0!, {r4, r5, r6, r7}
- stmia r2!, {r4, r5, r6, r7}
- cmp r2, r3
- ble 1b
-
- mov r8, #0 @ Zero it out
- mov r7, #MACH_TYPE_L7200 @ Set architecture ID
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 337741f734ac..7dfa9a85bc0c 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -108,6 +108,51 @@ static void gic_unmask_irq(unsigned int irq)
spin_unlock(&irq_controller_lock);
}
+static int gic_set_type(unsigned int irq, unsigned int type)
+{
+ void __iomem *base = gic_dist_base(irq);
+ unsigned int gicirq = gic_irq(irq);
+ u32 enablemask = 1 << (gicirq % 32);
+ u32 enableoff = (gicirq / 32) * 4;
+ u32 confmask = 0x2 << ((gicirq % 16) * 2);
+ u32 confoff = (gicirq / 16) * 4;
+ bool enabled = false;
+ u32 val;
+
+ /* Interrupt configuration for SGIs can't be changed */
+ if (gicirq < 16)
+ return -EINVAL;
+
+ if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING)
+ return -EINVAL;
+
+ spin_lock(&irq_controller_lock);
+
+ val = readl(base + GIC_DIST_CONFIG + confoff);
+ if (type == IRQ_TYPE_LEVEL_HIGH)
+ val &= ~confmask;
+ else if (type == IRQ_TYPE_EDGE_RISING)
+ val |= confmask;
+
+ /*
+ * As recommended by the spec, disable the interrupt before changing
+ * the configuration
+ */
+ if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+ writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+ enabled = true;
+ }
+
+ writel(val, base + GIC_DIST_CONFIG + confoff);
+
+ if (enabled)
+ writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+
+ spin_unlock(&irq_controller_lock);
+
+ return 0;
+}
+
#ifdef CONFIG_SMP
static int gic_set_cpu(unsigned int irq, const struct cpumask *mask_val)
{
@@ -161,6 +206,7 @@ static struct irq_chip gic_chip = {
.ack = gic_ack_irq,
.mask = gic_mask_irq,
.unmask = gic_unmask_irq,
+ .set_type = gic_set_type,
#ifdef CONFIG_SMP
.set_affinity = gic_set_cpu,
#endif
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index 6f80665f477e..ac2fd440652e 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -185,13 +185,10 @@ static struct sa1111_dev_info sa1111_devices[] = {
},
};
-void __init sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes)
+void __init sa1111_adjust_zones(unsigned long *size, unsigned long *holes)
{
unsigned int sz = SZ_1M >> PAGE_SHIFT;
- if (node != 0)
- sz = 0;
-
size[1] = size[0] - sz;
size[0] = sz;
}
diff --git a/arch/arm/configs/ap4evb_defconfig b/arch/arm/configs/ap4evb_defconfig
index 2eef85e3c9b9..57cb4b0ea83e 100644
--- a/arch/arm/configs/ap4evb_defconfig
+++ b/arch/arm/configs/ap4evb_defconfig
@@ -1,57 +1,1315 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35-rc1
+# Mon May 31 14:29:17 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
CONFIG_ARCH_SHMOBILE=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# SH-Mobile System Type
+#
+# CONFIG_ARCH_SH7367 is not set
+# CONFIG_ARCH_SH7377 is not set
CONFIG_ARCH_SH7372=y
+
+#
+# SH-Mobile Board Type
+#
CONFIG_MACH_AP4EVB=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x10000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_TIMER_TMU=y
+CONFIG_SH_CLK_CPG=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC0,115200 earlyprintk=sh-sci.0,115200"
+CONFIG_CMDLINE="console=ttySC0,115200"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_SH_FLCTL is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_SH_KEYSC=y
+# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_SH_SCI_DMA=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+# CONFIG_I2C_CHARDEV is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_OCORES is not set
+CONFIG_I2C_SH_MOBILE=y
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX7300 is not set
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_HTC_I2CPLD is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TC35892 is not set
+# CONFIG_MFD_TMIO is not set
+CONFIG_TMIO_MMC_DMA=y
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+# CONFIG_VIDEO_ALLOW_V4L1 is not set
+# CONFIG_VIDEO_V4L1_COMPAT is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+CONFIG_IR_CORE=y
+CONFIG_VIDEO_IR=y
+CONFIG_RC_MAP=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+# CONFIG_IR_IMON is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_MEDIA_TUNER_MC44S803=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+CONFIG_VIDEO_IR_I2C=y
+# CONFIG_VIDEO_SH_VOU is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
+CONFIG_USB_GSPCA=y
+# CONFIG_USB_M5602 is not set
+# CONFIG_USB_STV06XX is not set
+# CONFIG_USB_GL860 is not set
+# CONFIG_USB_GSPCA_BENQ is not set
+# CONFIG_USB_GSPCA_CONEX is not set
+# CONFIG_USB_GSPCA_CPIA1 is not set
+# CONFIG_USB_GSPCA_ETOMS is not set
+# CONFIG_USB_GSPCA_FINEPIX is not set
+# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_MARS is not set
+# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_OV519 is not set
+# CONFIG_USB_GSPCA_OV534 is not set
+# CONFIG_USB_GSPCA_OV534_9 is not set
+# CONFIG_USB_GSPCA_PAC207 is not set
+# CONFIG_USB_GSPCA_PAC7302 is not set
+# CONFIG_USB_GSPCA_PAC7311 is not set
+# CONFIG_USB_GSPCA_SN9C2028 is not set
+# CONFIG_USB_GSPCA_SN9C20X is not set
+# CONFIG_USB_GSPCA_SONIXB is not set
+# CONFIG_USB_GSPCA_SONIXJ is not set
+# CONFIG_USB_GSPCA_SPCA500 is not set
+# CONFIG_USB_GSPCA_SPCA501 is not set
+# CONFIG_USB_GSPCA_SPCA505 is not set
+# CONFIG_USB_GSPCA_SPCA506 is not set
+# CONFIG_USB_GSPCA_SPCA508 is not set
+# CONFIG_USB_GSPCA_SPCA561 is not set
+# CONFIG_USB_GSPCA_SQ905 is not set
+# CONFIG_USB_GSPCA_SQ905C is not set
+# CONFIG_USB_GSPCA_STK014 is not set
+# CONFIG_USB_GSPCA_STV0680 is not set
+# CONFIG_USB_GSPCA_SUNPLUS is not set
+# CONFIG_USB_GSPCA_T613 is not set
+# CONFIG_USB_GSPCA_TV8532 is not set
+# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_ZC3XX is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_HDPVR is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_CX231XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_USB_S2255 is not set
+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+CONFIG_FB_SYS_FILLRECT=y
+CONFIG_FB_SYS_COPYAREA=y
+CONFIG_FB_SYS_IMAGEBLIT=y
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+CONFIG_FB_SYS_FOPS=y
+CONFIG_FB_DEFERRED_IO=y
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_SH_MIPI_DSI=y
+CONFIG_SH_LCD_MIPI_DSI=y
+CONFIG_FB_SH_MOBILE_LCDC=y
+# CONFIG_FB_TMIO is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=y
+
+#
+# SoC Audio support for SuperH
+#
+CONFIG_SND_SOC_SH4_FSI=y
+CONFIG_SND_FSI_AK4642=y
+CONFIG_SND_FSI_DA7210=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+CONFIG_SND_SOC_AK4642=y
+CONFIG_SND_SOC_DA7210=y
+# CONFIG_SOUND_PRIME is not set
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+CONFIG_USB_R8A66597_HCD=y
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_TMIO=y
+CONFIG_MMC_SH_MMCIF=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+CONFIG_RTC_DRV_RS5C372=y
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_SH_DMAE=y
+# CONFIG_TIMB_DMA is not set
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
-# CONFIG_CRC32 is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/g3evm_defconfig b/arch/arm/configs/g3evm_defconfig
index 4a336ab5a0c0..549e46064a29 100644
--- a/arch/arm/configs/g3evm_defconfig
+++ b/arch/arm/configs/g3evm_defconfig
@@ -1,57 +1,823 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Thu May 20 12:21:19 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
CONFIG_ARCH_SHMOBILE=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# SH-Mobile System Type
+#
CONFIG_ARCH_SH7367=y
+# CONFIG_ARCH_SH7377 is not set
+# CONFIG_ARCH_SH7372 is not set
+
+#
+# SH-Mobile Board Type
+#
CONFIG_MACH_G3EVM=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x50000000
+CONFIG_MEMORY_SIZE=0x08000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_TIMER_TMU=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC1,115200 earlyprintk=sh-sci.1,115200"
+CONFIG_CMDLINE="console=ttySC1,115200"
+# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_SH_FLCTL=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/arm/configs/g4evm_defconfig b/arch/arm/configs/g4evm_defconfig
index 21c6d0307bc3..3841bc609d41 100644
--- a/arch/arm/configs/g4evm_defconfig
+++ b/arch/arm/configs/g4evm_defconfig
@@ -1,57 +1,827 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Thu May 20 12:37:38 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_LZO=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+# CONFIG_EMBEDDED is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
CONFIG_ARCH_SHMOBILE=y
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# SH-Mobile System Type
+#
+# CONFIG_ARCH_SH7367 is not set
CONFIG_ARCH_SH7377=y
+# CONFIG_ARCH_SH7372 is not set
+
+#
+# SH-Mobile Board Type
+#
CONFIG_MACH_G4EVM=y
+
+#
+# SH-Mobile System Configuration
+#
+
+#
+# Memory configuration
+#
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x08000000
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_CMT=y
+CONFIG_SH_TIMER_TMU=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySC4,115200 earlyprintk=sh-sci.4,115200"
+CONFIG_CMDLINE="console=ttySC4,115200"
+# CONFIG_XIP_KERNEL is not set
CONFIG_KEXEC=y
+CONFIG_ATAGS_PROC=y
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
# CONFIG_SUSPEND is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+# CONFIG_NET is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
CONFIG_MTD_CFI_INTELEXT=y
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+CONFIG_MTD_NAND_SH_FLCTL=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
# CONFIG_BLK_DEV is not set
# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
CONFIG_SERIAL_SH_SCI=y
CONFIG_SERIAL_SH_SCI_NR_UARTS=8
CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+CONFIG_MFD_CORE=y
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+CONFIG_MFD_SH_MOBILE_SDHI=y
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_FSNOTIFY is not set
# CONFIG_DNOTIFY is not set
+# CONFIG_INOTIFY is not set
# CONFIG_INOTIFY_USER is not set
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
# CONFIG_MISC_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
# CONFIG_FTRACE is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+# CONFIG_CRYPTO is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
# CONFIG_CRC32 is not set
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/lusl7200_defconfig b/arch/arm/configs/lusl7200_defconfig
deleted file mode 100644
index 816fc42884c9..000000000000
--- a/arch/arm/configs/lusl7200_defconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EMBEDDED=y
-# CONFIG_HOTPLUG is not set
-CONFIG_MODULES=y
-CONFIG_ARCH_L7200=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x00010000
-CONFIG_ZBOOT_ROM_BSS=0xf03e0000
-CONFIG_ZBOOT_ROM=y
-CONFIG_CMDLINE="console=tty0 console=ttyLU1,115200 root=/dev/ram initrd=0xf1000000,0x005dac7b mem=32M"
-CONFIG_BINFMT_AOUT=y
-CONFIG_BLK_DEV_RAM=y
-# CONFIG_INPUT is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_EXT2_FS=y
-CONFIG_DEBUG_USER=y
-# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/s5pc110_defconfig b/arch/arm/configs/s5pc110_defconfig
deleted file mode 100644
index 22c2d147f793..000000000000
--- a/arch/arm/configs/s5pc110_defconfig
+++ /dev/null
@@ -1,66 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S5PV210=y
-CONFIG_S3C_LOWLEVEL_UART_PORT=1
-CONFIG_MACH_SMDKC110=y
-CONFIG_VMSPLIT_2G=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
-CONFIG_VFP=y
-CONFIG_NEON=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_SAMSUNG=y
-CONFIG_SERIAL_SAMSUNG_CONSOLE=y
-CONFIG_HW_RANDOM=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_PREEMPT is not set
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_S3C_UART=1
-CONFIG_CRC_CCITT=y
diff --git a/arch/arm/configs/s5pv210_defconfig b/arch/arm/configs/s5pv210_defconfig
index 1753836d0055..b2fbbff002dd 100644
--- a/arch/arm/configs/s5pv210_defconfig
+++ b/arch/arm/configs/s5pv210_defconfig
@@ -7,6 +7,10 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_ARCH_S5PV210=y
CONFIG_S3C_LOWLEVEL_UART_PORT=1
+CONFIG_S3C_DEV_FB=y
+CONFIG_S5PV210_SETUP_FB_24BPP=y
+CONFIG_MACH_AQUILA=y
+CONFIG_MACH_SMDKC110=y
CONFIG_MACH_SMDKV210=y
CONFIG_VMSPLIT_2G=y
CONFIG_PREEMPT=y
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
new file mode 100644
index 000000000000..c81b6d9c9fa2
--- /dev/null
+++ b/arch/arm/configs/tegra_defconfig
@@ -0,0 +1,1095 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35-rc2
+# Tue Jun 8 17:11:49 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_LOCKBREAK=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+# CONFIG_SYSVIPC is not set
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=17
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+# CONFIG_CGROUP_NS is not set
+CONFIG_CGROUP_FREEZER=y
+# CONFIG_CGROUP_DEVICE is not set
+# CONFIG_CPUSETS is not set
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+# CONFIG_CGROUP_MEM_RES_CTLR is not set
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+# CONFIG_BLK_CGROUP is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+# CONFIG_ELF_CORE is not set
+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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+CONFIG_ARCH_TEGRA=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+
+#
+# NVIDIA Tegra options
+#
+CONFIG_ARCH_TEGRA_2x_SOC=y
+
+#
+# Tegra board type
+#
+CONFIG_MACH_HARMONY=y
+# CONFIG_TEGRA_DEBUG_UART_NONE is not set
+# CONFIG_TEGRA_DEBUG_UARTA is not set
+# CONFIG_TEGRA_DEBUG_UARTB is not set
+# CONFIG_TEGRA_DEBUG_UARTC is not set
+CONFIG_TEGRA_DEBUG_UARTD=y
+# CONFIG_TEGRA_DEBUG_UARTE is not set
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_OUTER_CACHE=y
+CONFIG_OUTER_CACHE_SYNC=y
+CONFIG_CACHE_L2X0=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_ARCH_HAS_BARRIERS=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_ARM_GIC=y
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_SMP=y
+CONFIG_HAVE_ARM_SCU=y
+CONFIG_HAVE_ARM_TWD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+CONFIG_LOCAL_TIMERS=y
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HIGHMEM=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=448M@0M console=ttyS0,115200n8 earlyprintk init=/bin/ash"
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+# CONFIG_NEON is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP_SMP=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM_OPS=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+# CONFIG_NET_KEY_MIGRATE is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+CONFIG_INET_ESP=y
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+# CONFIG_IPV6_ROUTE_INFO is not set
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_INET6_XFRM_TUNNEL=y
+CONFIG_INET6_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_SUBTREES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+CONFIG_RPS=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_NET_ETHERNET is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+# CONFIG_MFD_SUPPORT is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+CONFIG_FB_TEGRA=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+# CONFIG_NFS_FS is not set
+# CONFIG_NFSD is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB_LEAK is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+CONFIG_DEBUG_SG=y
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_CPU_NOTIFIER_ERROR_INJECT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_ARM_UNWIND=y
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/arm/configs/tnetv107x_defconfig b/arch/arm/configs/tnetv107x_defconfig
new file mode 100644
index 000000000000..efc101f0f8b5
--- /dev/null
+++ b/arch/arm/configs/tnetv107x_defconfig
@@ -0,0 +1,1741 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34-rc5
+# Sun May 2 15:05:52 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_PERF_COUNTERS is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P6440 is not set
+# CONFIG_ARCH_S5P6442 is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+CONFIG_ARCH_DAVINCI=y
+# CONFIG_ARCH_OMAP is not set
+CONFIG_CP_INTC=y
+
+#
+# TI DaVinci Implementations
+#
+
+#
+# DaVinci Core Type
+#
+# CONFIG_ARCH_DAVINCI_DM644x is not set
+# CONFIG_ARCH_DAVINCI_DM355 is not set
+# CONFIG_ARCH_DAVINCI_DM646x is not set
+# CONFIG_ARCH_DAVINCI_DA830 is not set
+# CONFIG_ARCH_DAVINCI_DA850 is not set
+# CONFIG_ARCH_DAVINCI_DM365 is not set
+CONFIG_ARCH_DAVINCI_TNETV107X=y
+
+#
+# DaVinci Board Type
+#
+CONFIG_MACH_TNETV107X=y
+CONFIG_DAVINCI_MUX=y
+CONFIG_DAVINCI_MUX_DEBUG=y
+CONFIG_DAVINCI_MUX_WARNINGS=y
+CONFIG_DAVINCI_RESET_CLOCKS=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_V6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT=5
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_411920 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ARCH_HAS_HOLES_MEMORYMODEL=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_LEDS=y
+# CONFIG_LEDS_CPU is not set
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE=""
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+# CONFIG_VFP is not set
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+# CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+# CONFIG_IP_NF_IPTABLES is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=m
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+CONFIG_MTD_CFI_INTELEXT=m
+CONFIG_MTD_CFI_AMDSTD=m
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=m
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_GPIO is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+CONFIG_MTD_NAND_DAVINCI=y
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=m
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=1
+CONFIG_BLK_DEV_RAM_SIZE=32768
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IWMC3200TOP is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=m
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=m
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_TI_DAVINCI_EMAC is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+CONFIG_NETCONSOLE=y
+# CONFIG_NETCONSOLE_DYNAMIC is not set
+CONFIG_NETPOLL=y
+CONFIG_NETPOLL_TRAP=y
+CONFIG_NET_POLL_CONTROLLER=y
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+CONFIG_INPUT_SPARSEKMAP=m
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=m
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=m
+# CONFIG_KEYBOARD_LKKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+CONFIG_KEYBOARD_XTKBD=m
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_ATI_REMOTE is not set
+# CONFIG_INPUT_ATI_REMOTE2 is not set
+# CONFIG_INPUT_KEYSPAN_REMOTE is not set
+# CONFIG_INPUT_POWERMATE is not set
+# CONFIG_INPUT_YEALINK is not set
+# CONFIG_INPUT_CM109 is not set
+# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=3
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SHT15 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_DAVINCI_WATCHDOG=m
+# CONFIG_MAX63XX_WATCHDOG is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=m
+CONFIG_FB=y
+CONFIG_FIRMWARE_EDID=y
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=m
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=m
+CONFIG_SND_TIMER=m
+CONFIG_SND_PCM=m
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_HRTIMER is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+CONFIG_SND_SOC=m
+CONFIG_SND_DAVINCI_SOC=m
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=m
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_HID_3M_PCT is not set
+CONFIG_HID_A4TECH=m
+CONFIG_HID_APPLE=m
+CONFIG_HID_BELKIN=m
+CONFIG_HID_CHERRY=m
+CONFIG_HID_CHICONY=m
+CONFIG_HID_CYPRESS=m
+# CONFIG_HID_DRAGONRISE is not set
+CONFIG_HID_EZKEY=m
+# CONFIG_HID_KYE is not set
+CONFIG_HID_GYRATION=m
+# CONFIG_HID_TWINHAN is not set
+# CONFIG_HID_KENSINGTON is not set
+CONFIG_HID_LOGITECH=m
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+CONFIG_HID_MICROSOFT=m
+# CONFIG_HID_MOSART is not set
+CONFIG_HID_MONTEREY=m
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+CONFIG_HID_PANTHERLORD=m
+# CONFIG_PANTHERLORD_FF is not set
+CONFIG_HID_PETALYNX=m
+# CONFIG_HID_QUANTA is not set
+CONFIG_HID_SAMSUNG=m
+CONFIG_HID_SONY=m
+# CONFIG_HID_STANTUM is not set
+CONFIG_HID_SUNPLUS=m
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=m
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=m
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+CONFIG_USB_MUSB_HDRC=m
+CONFIG_USB_MUSB_SOC=y
+
+#
+# DaVinci 35x and 644x USB support
+#
+# CONFIG_USB_MUSB_HOST is not set
+CONFIG_USB_MUSB_PERIPHERAL=y
+# CONFIG_USB_MUSB_OTG is not set
+CONFIG_USB_GADGET_MUSB_HDRC=y
+CONFIG_MUSB_PIO_ONLY=y
+# CONFIG_USB_MUSB_DEBUG is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=m
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+CONFIG_USB_TEST=m
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG is not set
+CONFIG_USB_GADGET_DEBUG_FILES=y
+CONFIG_USB_GADGET_DEBUG_FS=y
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+# CONFIG_USB_GADGET_PXA25X is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_S3C_HSOTG is not set
+# CONFIG_USB_GADGET_IMX is not set
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_FSL_QE is not set
+# CONFIG_USB_GADGET_CI13XXX is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LANGWELL is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_ZERO=m
+# CONFIG_USB_AUDIO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+# CONFIG_USB_ETH_EEM is not set
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_MASS_STORAGE is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+CONFIG_USB_G_PRINTER=m
+CONFIG_USB_CDC_COMPOSITE=m
+# CONFIG_USB_G_NOKIA is not set
+# CONFIG_USB_G_MULTI is not set
+
+#
+# OTG and related infrastructure
+#
+CONFIG_USB_OTG_UTILS=y
+# CONFIG_USB_GPIO_VBUS is not set
+# CONFIG_USB_ULPI is not set
+CONFIG_NOP_USB_XCEIV=m
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+# CONFIG_MMC_SDHCI is not set
+CONFIG_MMC_DAVINCI=y
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+CONFIG_LEDS_GPIO=m
+CONFIG_LEDS_GPIO_PLATFORM=y
+# CONFIG_LEDS_LT3593 is not set
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+CONFIG_LEDS_TRIGGER_TIMER=m
+CONFIG_LEDS_TRIGGER_HEARTBEAT=m
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_GPIO is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=m
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_XFS_FS=m
+# CONFIG_XFS_QUOTA is not set
+# CONFIG_XFS_POSIX_ACL is not set
+# CONFIG_XFS_RT is not set
+# CONFIG_XFS_DEBUG is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=m
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3=y
+# CONFIG_NFSD_V3_ACL is not set
+# CONFIG_NFSD_V4 is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_EXPORTFS=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+CONFIG_SMB_FS=m
+# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_MINIX_SUBPARTITION is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_LDM_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_KARMA_PARTITION is not set
+# CONFIG_EFI_PARTITION is not set
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+CONFIG_DEBUG_PREEMPT=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_PI_LIST=y
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+CONFIG_DEBUG_MUTEXES=y
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+CONFIG_DEBUG_USER=y
+CONFIG_DEBUG_ERRORS=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_LL is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+CONFIG_CRC_T10DIF=m
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_GENERIC_ALLOCATOR=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index a0162fa94564..7e79503ab89b 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -40,12 +40,12 @@ static inline void atomic_add(int i, atomic_t *v)
int result;
__asm__ __volatile__("@ atomic_add\n"
-"1: ldrex %0, [%2]\n"
-" add %0, %0, %3\n"
-" strex %1, %0, [%2]\n"
+"1: ldrex %0, [%3]\n"
+" add %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
}
@@ -58,12 +58,12 @@ static inline int atomic_add_return(int i, atomic_t *v)
smp_mb();
__asm__ __volatile__("@ atomic_add_return\n"
-"1: ldrex %0, [%2]\n"
-" add %0, %0, %3\n"
-" strex %1, %0, [%2]\n"
+"1: ldrex %0, [%3]\n"
+" add %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
@@ -78,12 +78,12 @@ static inline void atomic_sub(int i, atomic_t *v)
int result;
__asm__ __volatile__("@ atomic_sub\n"
-"1: ldrex %0, [%2]\n"
-" sub %0, %0, %3\n"
-" strex %1, %0, [%2]\n"
+"1: ldrex %0, [%3]\n"
+" sub %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
}
@@ -96,12 +96,12 @@ static inline int atomic_sub_return(int i, atomic_t *v)
smp_mb();
__asm__ __volatile__("@ atomic_sub_return\n"
-"1: ldrex %0, [%2]\n"
-" sub %0, %0, %3\n"
-" strex %1, %0, [%2]\n"
+"1: ldrex %0, [%3]\n"
+" sub %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "Ir" (i)
: "cc");
@@ -118,11 +118,11 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new)
do {
__asm__ __volatile__("@ atomic_cmpxchg\n"
- "ldrex %1, [%2]\n"
+ "ldrex %1, [%3]\n"
"mov %0, #0\n"
- "teq %1, %3\n"
- "strexeq %0, %4, [%2]\n"
- : "=&r" (res), "=&r" (oldval)
+ "teq %1, %4\n"
+ "strexeq %0, %5, [%3]\n"
+ : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "Ir" (old), "r" (new)
: "cc");
} while (res);
@@ -137,12 +137,12 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
unsigned long tmp, tmp2;
__asm__ __volatile__("@ atomic_clear_mask\n"
-"1: ldrex %0, [%2]\n"
-" bic %0, %0, %3\n"
-" strex %1, %0, [%2]\n"
+"1: ldrex %0, [%3]\n"
+" bic %0, %0, %4\n"
+" strex %1, %0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (tmp), "=&r" (tmp2)
+ : "=&r" (tmp), "=&r" (tmp2), "+Qo" (*addr)
: "r" (addr), "Ir" (mask)
: "cc");
}
@@ -249,7 +249,7 @@ static inline u64 atomic64_read(atomic64_t *v)
__asm__ __volatile__("@ atomic64_read\n"
" ldrexd %0, %H0, [%1]"
: "=&r" (result)
- : "r" (&v->counter)
+ : "r" (&v->counter), "Qo" (v->counter)
);
return result;
@@ -260,11 +260,11 @@ static inline void atomic64_set(atomic64_t *v, u64 i)
u64 tmp;
__asm__ __volatile__("@ atomic64_set\n"
-"1: ldrexd %0, %H0, [%1]\n"
-" strexd %0, %2, %H2, [%1]\n"
+"1: ldrexd %0, %H0, [%2]\n"
+" strexd %0, %3, %H3, [%2]\n"
" teq %0, #0\n"
" bne 1b"
- : "=&r" (tmp)
+ : "=&r" (tmp), "=Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
}
@@ -275,13 +275,13 @@ static inline void atomic64_add(u64 i, atomic64_t *v)
unsigned long tmp;
__asm__ __volatile__("@ atomic64_add\n"
-"1: ldrexd %0, %H0, [%2]\n"
-" adds %0, %0, %3\n"
-" adc %H0, %H0, %H3\n"
-" strexd %1, %0, %H0, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" adds %0, %0, %4\n"
+" adc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
}
@@ -294,13 +294,13 @@ static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
smp_mb();
__asm__ __volatile__("@ atomic64_add_return\n"
-"1: ldrexd %0, %H0, [%2]\n"
-" adds %0, %0, %3\n"
-" adc %H0, %H0, %H3\n"
-" strexd %1, %0, %H0, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" adds %0, %0, %4\n"
+" adc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
@@ -315,13 +315,13 @@ static inline void atomic64_sub(u64 i, atomic64_t *v)
unsigned long tmp;
__asm__ __volatile__("@ atomic64_sub\n"
-"1: ldrexd %0, %H0, [%2]\n"
-" subs %0, %0, %3\n"
-" sbc %H0, %H0, %H3\n"
-" strexd %1, %0, %H0, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %0, %0, %4\n"
+" sbc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
}
@@ -334,13 +334,13 @@ static inline u64 atomic64_sub_return(u64 i, atomic64_t *v)
smp_mb();
__asm__ __volatile__("@ atomic64_sub_return\n"
-"1: ldrexd %0, %H0, [%2]\n"
-" subs %0, %0, %3\n"
-" sbc %H0, %H0, %H3\n"
-" strexd %1, %0, %H0, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" subs %0, %0, %4\n"
+" sbc %H0, %H0, %H4\n"
+" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (i)
: "cc");
@@ -358,12 +358,12 @@ static inline u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old, u64 new)
do {
__asm__ __volatile__("@ atomic64_cmpxchg\n"
- "ldrexd %1, %H1, [%2]\n"
+ "ldrexd %1, %H1, [%3]\n"
"mov %0, #0\n"
- "teq %1, %3\n"
- "teqeq %H1, %H3\n"
- "strexdeq %0, %4, %H4, [%2]"
- : "=&r" (res), "=&r" (oldval)
+ "teq %1, %4\n"
+ "teqeq %H1, %H4\n"
+ "strexdeq %0, %5, %H5, [%3]"
+ : "=&r" (res), "=&r" (oldval), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "r" (old), "r" (new)
: "cc");
} while (res);
@@ -381,11 +381,11 @@ static inline u64 atomic64_xchg(atomic64_t *ptr, u64 new)
smp_mb();
__asm__ __volatile__("@ atomic64_xchg\n"
-"1: ldrexd %0, %H0, [%2]\n"
-" strexd %1, %3, %H3, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
+" strexd %1, %4, %H4, [%3]\n"
" teq %1, #0\n"
" bne 1b"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (ptr->counter)
: "r" (&ptr->counter), "r" (new)
: "cc");
@@ -402,16 +402,16 @@ static inline u64 atomic64_dec_if_positive(atomic64_t *v)
smp_mb();
__asm__ __volatile__("@ atomic64_dec_if_positive\n"
-"1: ldrexd %0, %H0, [%2]\n"
+"1: ldrexd %0, %H0, [%3]\n"
" subs %0, %0, #1\n"
" sbc %H0, %H0, #0\n"
" teq %H0, #0\n"
" bmi 2f\n"
-" strexd %1, %0, %H0, [%2]\n"
+" strexd %1, %0, %H0, [%3]\n"
" teq %1, #0\n"
" bne 1b\n"
"2:"
- : "=&r" (result), "=&r" (tmp)
+ : "=&r" (result), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter)
: "cc");
@@ -429,18 +429,18 @@ static inline int atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
smp_mb();
__asm__ __volatile__("@ atomic64_add_unless\n"
-"1: ldrexd %0, %H0, [%3]\n"
-" teq %0, %4\n"
-" teqeq %H0, %H4\n"
+"1: ldrexd %0, %H0, [%4]\n"
+" teq %0, %5\n"
+" teqeq %H0, %H5\n"
" moveq %1, #0\n"
" beq 2f\n"
-" adds %0, %0, %5\n"
-" adc %H0, %H0, %H5\n"
-" strexd %2, %0, %H0, [%3]\n"
+" adds %0, %0, %6\n"
+" adc %H0, %H0, %H6\n"
+" strexd %2, %0, %H0, [%4]\n"
" teq %2, #0\n"
" bne 1b\n"
"2:"
- : "=&r" (val), "=&r" (ret), "=&r" (tmp)
+ : "=&r" (val), "+r" (ret), "=&r" (tmp), "+Qo" (v->counter)
: "r" (&v->counter), "r" (u), "r" (a)
: "cc");
diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index 51662feb9f1d..0a96e8c1b82a 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -121,4 +121,7 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
extern void elf_set_personality(const struct elf32_hdr *);
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))
+extern unsigned long arch_randomize_brk(struct mm_struct *mm);
+#define arch_randomize_brk arch_randomize_brk
+
#endif
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index f7bd52b1c365..c1062c317103 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -19,6 +19,7 @@
#define HWCAP_NEON 4096
#define HWCAP_VFPv3 8192
#define HWCAP_VFPv3D16 16384
+#define HWCAP_TLS 32768
#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
/*
diff --git a/arch/arm/include/asm/irq.h b/arch/arm/include/asm/irq.h
index 237282f7c762..2721a5814cb9 100644
--- a/arch/arm/include/asm/irq.h
+++ b/arch/arm/include/asm/irq.h
@@ -7,6 +7,8 @@
#define irq_canonicalize(i) (i)
#endif
+#define NR_IRQS_LEGACY 16
+
/*
* Use this value to indicate lack of interrupt
* capability
diff --git a/arch/arm/include/asm/kexec.h b/arch/arm/include/asm/kexec.h
index df15a0dc228e..8ec9ef5c3c7b 100644
--- a/arch/arm/include/asm/kexec.h
+++ b/arch/arm/include/asm/kexec.h
@@ -19,10 +19,26 @@
#ifndef __ASSEMBLY__
-struct kimage;
-/* Provide a dummy definition to avoid build failures. */
+/**
+ * crash_setup_regs() - save registers for the panic kernel
+ * @newregs: registers are saved here
+ * @oldregs: registers to be saved (may be %NULL)
+ *
+ * Function copies machine registers from @oldregs to @newregs. If @oldregs is
+ * %NULL then current registers are stored there.
+ */
static inline void crash_setup_regs(struct pt_regs *newregs,
- struct pt_regs *oldregs) { }
+ struct pt_regs *oldregs)
+{
+ if (oldregs) {
+ memcpy(newregs, oldregs, sizeof(*newregs));
+ } else {
+ __asm__ __volatile__ ("stmia %0, {r0 - r15}"
+ : : "r" (&newregs->ARM_r0));
+ __asm__ __volatile__ ("mrs %0, cpsr"
+ : "=r" (newregs->ARM_cpsr));
+ }
+}
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/lmb.h b/arch/arm/include/asm/lmb.h
new file mode 100644
index 000000000000..1f4965701e62
--- /dev/null
+++ b/arch/arm/include/asm/lmb.h
@@ -0,0 +1,16 @@
+#ifndef _ASM_ARM_LMB_H
+#define _ASM_ARM_LMB_H
+
+#ifdef CONFIG_MMU
+extern phys_addr_t lowmem_end_addr;
+#define LMB_REAL_LIMIT lowmem_end_addr
+#else
+#define LMB_REAL_LIMIT 0
+#endif
+
+struct meminfo;
+struct machine_desc;
+
+extern void arm_lmb_init(struct meminfo *, struct machine_desc *);
+
+#endif
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index c59842dc7cb8..dd15c0fc1e4b 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -20,6 +20,7 @@ struct machine_desc {
* by assembler code in head.S, head-common.S
*/
unsigned int nr; /* architecture number */
+ unsigned int nr_irqs; /* number of IRQs */
unsigned int phys_io; /* start of physical io */
unsigned int io_pg_offst; /* byte offset for io
* page tabe entry */
@@ -37,6 +38,7 @@ struct machine_desc {
void (*fixup)(struct machine_desc *,
struct tag *, char **,
struct meminfo *);
+ void (*reserve)(void);/* reserve lmb blocks */
void (*map_io)(void);/* IO mapping function */
void (*init_irq)(void);
struct sys_timer *timer; /* system tick timer */
diff --git a/arch/arm/include/asm/mach/irq.h b/arch/arm/include/asm/mach/irq.h
index 8920b2d6e3b8..ce3eee9fe26c 100644
--- a/arch/arm/include/asm/mach/irq.h
+++ b/arch/arm/include/asm/mach/irq.h
@@ -17,6 +17,7 @@ struct seq_file;
/*
* This is internal. Do not use it.
*/
+extern unsigned int arch_nr_irqs;
extern void (*init_arch_irq)(void);
extern void init_FIQ(void);
extern int show_fiq_list(struct seq_file *, void *);
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index 4312ee5e3d0b..82df0ae71bb4 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -158,7 +158,7 @@
#endif
#ifndef arch_adjust_zones
-#define arch_adjust_zones(node,size,holes) do { } while (0)
+#define arch_adjust_zones(size,holes) do { } while (0)
#elif !defined(CONFIG_ZONE_DMA)
#error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA"
#endif
@@ -234,76 +234,11 @@ static inline __deprecated void *bus_to_virt(unsigned long x)
* virt_to_page(k) convert a _valid_ virtual address to struct page *
* virt_addr_valid(k) indicates whether a virtual address is valid
*/
-#ifndef CONFIG_DISCONTIGMEM
-
#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
-#define PHYS_TO_NID(addr) (0)
-
-#else /* CONFIG_DISCONTIGMEM */
-
-/*
- * This is more complex. We have a set of mem_map arrays spread
- * around in memory.
- */
-#include <linux/numa.h>
-
-#define arch_pfn_to_nid(pfn) PFN_TO_NID(pfn)
-#define arch_local_page_offset(pfn, nid) LOCAL_MAP_NR((pfn) << PAGE_SHIFT)
-
-#define virt_to_page(kaddr) \
- (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
-
-#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES)
-
-/*
- * Common discontigmem stuff.
- * PHYS_TO_NID is used by the ARM kernel/setup.c
- */
-#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT)
-
-/*
- * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
-
-/*
- * Given a page frame number, find the owning node of the memory
- * and returns the mem_map of that node.
- */
-#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
-
-#ifdef NODE_MEM_SIZE_BITS
-#define NODE_MEM_SIZE_MASK ((1 << NODE_MEM_SIZE_BITS) - 1)
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-#define KVADDR_TO_NID(addr) \
- (((unsigned long)(addr) - PAGE_OFFSET) >> NODE_MEM_SIZE_BITS)
-
-/*
- * Given a page frame number, convert it to a node id.
- */
-#define PFN_TO_NID(pfn) \
- (((pfn) - PHYS_PFN_OFFSET) >> (NODE_MEM_SIZE_BITS - PAGE_SHIFT))
-
-/*
- * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
- * and returns the index corresponding to the appropriate page in the
- * node's mem_map.
- */
-#define LOCAL_MAP_NR(addr) \
- (((unsigned long)(addr) & NODE_MEM_SIZE_MASK) >> PAGE_SHIFT)
-
-#endif /* NODE_MEM_SIZE_BITS */
-
-#endif /* !CONFIG_DISCONTIGMEM */
-
/*
* Optional coherency support. Currently used only by selected
* Intel XSC3-based systems.
diff --git a/arch/arm/include/asm/mmzone.h b/arch/arm/include/asm/mmzone.h
deleted file mode 100644
index ae63a4fd28c8..000000000000
--- a/arch/arm/include/asm/mmzone.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * arch/arm/include/asm/mmzone.h
- *
- * 1999-12-29 Nicolas Pitre Created
- *
- * This program is free software; you can 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_MMZONE_H
-#define __ASM_MMZONE_H
-
-/*
- * Currently defined in arch/arm/mm/discontig.c
- */
-extern pg_data_t discontig_node_data[];
-
-/*
- * Return a pointer to the node data for node n.
- */
-#define NODE_DATA(nid) (&discontig_node_data[nid])
-
-/*
- * NODE_MEM_MAP gives the kaddr for the mem_map of the node.
- */
-#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
-
-#include <mach/memory.h>
-
-#endif
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index 9dcb11e59026..c974be8913a7 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -184,6 +184,42 @@ extern unsigned long profile_pc(struct pt_regs *regs);
#define predicate(x) ((x) & 0xf0000000)
#define PREDICATE_ALWAYS 0xe0000000
+/*
+ * kprobe-based event tracer support
+ */
+#include <linux/stddef.h>
+#include <linux/types.h>
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, ARM_ORIG_r0))
+
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+extern bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr);
+extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n);
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/* Valid only for Kernel mode traps. */
+static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+{
+ return regs->ARM_sp;
+}
+
#endif /* __KERNEL__ */
#endif /* __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index f392fb4437af..f1e5a9bca249 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -201,8 +201,7 @@ static struct tagtable __tagtable_##fn __tag = { tag, fn }
struct membank {
unsigned long start;
unsigned long size;
- unsigned short node;
- unsigned short highmem;
+ unsigned int highmem;
};
struct meminfo {
@@ -212,9 +211,8 @@ struct meminfo {
extern struct meminfo meminfo;
-#define for_each_nodebank(iter,mi,no) \
- for (iter = 0; iter < (mi)->nr_banks; iter++) \
- if ((mi)->bank[iter].node == no)
+#define for_each_bank(iter,mi) \
+ for (iter = 0; iter < (mi)->nr_banks; iter++)
#define bank_pfn_start(bank) __phys_to_pfn((bank)->start)
#define bank_pfn_end(bank) __phys_to_pfn((bank)->start + (bank)->size)
diff --git a/arch/arm/include/asm/stackprotector.h b/arch/arm/include/asm/stackprotector.h
new file mode 100644
index 000000000000..de003327be97
--- /dev/null
+++ b/arch/arm/include/asm/stackprotector.h
@@ -0,0 +1,38 @@
+/*
+ * GCC stack protector support.
+ *
+ * Stack protector works by putting predefined pattern at the start of
+ * the stack frame and verifying that it hasn't been overwritten when
+ * returning from the function. The pattern is called stack canary
+ * and gcc expects it to be defined by a global variable called
+ * "__stack_chk_guard" on ARM. This unfortunately means that on SMP
+ * we cannot have a different canary value per task.
+ */
+
+#ifndef _ASM_STACKPROTECTOR_H
+#define _ASM_STACKPROTECTOR_H 1
+
+#include <linux/random.h>
+#include <linux/version.h>
+
+extern unsigned long __stack_chk_guard;
+
+/*
+ * Initialize the stackprotector canary value.
+ *
+ * NOTE: this must only be called from functions that never return,
+ * and it must always be inlined.
+ */
+static __always_inline void boot_init_stack_canary(void)
+{
+ unsigned long canary;
+
+ /* Try to get a semi random initial value. */
+ get_random_bytes(&canary, sizeof(canary));
+ canary ^= LINUX_VERSION_CODE;
+
+ current->stack_canary = canary;
+ __stack_chk_guard = current->stack_canary;
+}
+
+#endif /* _ASM_STACKPROTECTOR_H */
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
new file mode 100644
index 000000000000..e71d6ff8d104
--- /dev/null
+++ b/arch/arm/include/asm/tls.h
@@ -0,0 +1,46 @@
+#ifndef __ASMARM_TLS_H
+#define __ASMARM_TLS_H
+
+#ifdef __ASSEMBLY__
+ .macro set_tls_none, tp, tmp1, tmp2
+ .endm
+
+ .macro set_tls_v6k, tp, tmp1, tmp2
+ mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
+ .endm
+
+ .macro set_tls_v6, tp, tmp1, tmp2
+ ldr \tmp1, =elf_hwcap
+ ldr \tmp1, [\tmp1, #0]
+ mov \tmp2, #0xffff0fff
+ tst \tmp1, #HWCAP_TLS @ hardware TLS available?
+ mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
+ streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
+ .endm
+
+ .macro set_tls_software, tp, tmp1, tmp2
+ mov \tmp1, #0xffff0fff
+ str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
+ .endm
+#endif
+
+#ifdef CONFIG_TLS_REG_EMUL
+#define tls_emu 1
+#define has_tls_reg 1
+#define set_tls set_tls_none
+#elif __LINUX_ARM_ARCH__ >= 7 || \
+ (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
+#define tls_emu 0
+#define has_tls_reg 1
+#define set_tls set_tls_v6k
+#elif __LINUX_ARM_ARCH__ == 6
+#define tls_emu 0
+#define has_tls_reg (elf_hwcap & HWCAP_TLS)
+#define set_tls set_tls_v6
+#else
+#define tls_emu 0
+#define has_tls_reg 0
+#define set_tls set_tls_software
+#endif
+
+#endif /* __ASMARM_TLS_H */
diff --git a/arch/arm/include/asm/vfpmacros.h b/arch/arm/include/asm/vfpmacros.h
index 422f3cc204a2..3d5fc41ae8d3 100644
--- a/arch/arm/include/asm/vfpmacros.h
+++ b/arch/arm/include/asm/vfpmacros.h
@@ -3,6 +3,8 @@
*
* Assembler-only file containing VFP macros and register definitions.
*/
+#include <asm/hwcap.h>
+
#include "vfp.h"
@ Macros to allow building with old toolkits (with no VFP support)
@@ -22,12 +24,20 @@
LDC p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d0-d15}
#endif
#ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+ ldr \tmp, =elf_hwcap @ may not have MVFR regs
+ ldr \tmp, [\tmp, #0]
+ tst \tmp, #HWCAP_VFPv3D16
+ ldceq p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
cmp \tmp, #2 @ 32 x 64bit registers?
ldceql p11, cr0, [\base],#32*4 @ FLDMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
#endif
+#endif
.endm
@ write all the working registers out of the VFP
@@ -38,10 +48,18 @@
STC p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d0-d15}
#endif
#ifdef CONFIG_VFPv3
+#if __LINUX_ARM_ARCH__ <= 6
+ ldr \tmp, =elf_hwcap @ may not have MVFR regs
+ ldr \tmp, [\tmp, #0]
+ tst \tmp, #HWCAP_VFPv3D16
+ stceq p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
+ addne \base, \base, #32*4 @ step over unused register space
+#else
VFPFMRX \tmp, MVFR0 @ Media and VFP Feature Register 0
and \tmp, \tmp, #MVFR0_A_SIMD_MASK @ A_SIMD field
cmp \tmp, #2 @ 32 x 64bit registers?
stceql p11, cr0, [\base],#32*4 @ FSTMIAD \base!, {d16-d31}
addne \base, \base, #32*4 @ step over unused register space
#endif
+#endif
.endm
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 26d302c28e13..ea023c6aa31e 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_ARM_UNWIND) += unwind.o
obj-$(CONFIG_HAVE_TCM) += tcm.o
+obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index 883511522fca..85f2a019f77b 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -40,6 +40,9 @@
int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
+#ifdef CONFIG_CC_STACKPROTECTOR
+ DEFINE(TSK_STACK_CANARY, offsetof(struct task_struct, stack_canary));
+#endif
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
diff --git a/arch/arm/kernel/crash_dump.c b/arch/arm/kernel/crash_dump.c
new file mode 100644
index 000000000000..cd3b853a8a6d
--- /dev/null
+++ b/arch/arm/kernel/crash_dump.c
@@ -0,0 +1,60 @@
+/*
+ * arch/arm/kernel/crash_dump.c
+ *
+ * Copyright (C) 2010 Nokia Corporation.
+ * Author: Mika Westerberg
+ *
+ * This code is taken from arch/x86/kernel/crash_dump_64.c
+ * Created by: Hariprasad Nellitheertha (hari@in.ibm.com)
+ * Copyright (C) IBM Corporation, 2004. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/crash_dump.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+/* stores the physical address of elf header of crash image */
+unsigned long long elfcorehdr_addr = ELFCORE_ADDR_MAX;
+
+/**
+ * copy_oldmem_page() - copy one page from old kernel memory
+ * @pfn: page frame number to be copied
+ * @buf: buffer where the copied page is placed
+ * @csize: number of bytes to copy
+ * @offset: offset in bytes into the page
+ * @userbuf: if set, @buf is int he user address space
+ *
+ * This function copies one page from old kernel memory into buffer pointed by
+ * @buf. If @buf is in userspace, set @userbuf to %1. Returns number of bytes
+ * copied or negative error in case of failure.
+ */
+ssize_t copy_oldmem_page(unsigned long pfn, char *buf,
+ size_t csize, unsigned long offset,
+ int userbuf)
+{
+ void *vaddr;
+
+ if (!csize)
+ return 0;
+
+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
+ if (!vaddr)
+ return -ENOMEM;
+
+ if (userbuf) {
+ if (copy_to_user(buf, vaddr + offset, csize)) {
+ iounmap(vaddr);
+ return -EFAULT;
+ }
+ } else {
+ memcpy(buf, vaddr + offset, csize);
+ }
+
+ iounmap(vaddr);
+ return csize;
+}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7ee48e7f8f31..bb8e93a76407 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -22,6 +22,7 @@
#include <asm/thread_notify.h>
#include <asm/unwind.h>
#include <asm/unistd.h>
+#include <asm/tls.h>
#include "entry-header.S"
@@ -162,8 +163,6 @@ ENDPROC(__und_invalid)
@ r4 - orig_r0 (see pt_regs definition in ptrace.h)
@
stmia r5, {r0 - r4}
-
- asm_trace_hardirqs_off
.endm
.align 5
@@ -204,7 +203,7 @@ __dabt_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
- disable_irq
+ disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -218,6 +217,9 @@ ENDPROC(__dabt_svc)
__irq_svc:
svc_entry
+#ifdef CONFIG_TRACE_IRQFLAGS
+ bl trace_hardirqs_off
+#endif
#ifdef CONFIG_PREEMPT
get_thread_info tsk
ldr r8, [tsk, #TI_PREEMPT] @ get preempt count
@@ -291,7 +293,7 @@ __und_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
-1: disable_irq
+1: disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -327,7 +329,7 @@ __pabt_svc:
@
@ IRQs off again before pulling preserved data off the stack
@
- disable_irq
+ disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -393,8 +395,6 @@ ENDPROC(__pabt_svc)
@ Clear FP to mark the first stack frame
@
zero_fp
-
- asm_trace_hardirqs_off
.endm
.macro kuser_cmpxchg_check
@@ -465,9 +465,6 @@ __irq_usr:
THUMB( movne r0, #0 )
THUMB( strne r0, [r0] )
#endif
-#ifdef CONFIG_TRACE_IRQFLAGS
- bl trace_hardirqs_on
-#endif
mov why, #0
b ret_to_user
@@ -739,11 +736,11 @@ ENTRY(__switch_to)
#ifdef CONFIG_MMU
ldr r6, [r2, #TI_CPU_DOMAIN]
#endif
-#if defined(CONFIG_HAS_TLS_REG)
- mcr p15, 0, r3, c13, c0, 3 @ set TLS register
-#elif !defined(CONFIG_TLS_REG_EMUL)
- mov r4, #0xffff0fff
- str r3, [r4, #-15] @ TLS val at 0xffff0ff0
+ set_tls r3, r4, r5
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+ ldr r7, [r2, #TI_TASK]
+ ldr r8, =__stack_chk_guard
+ ldr r7, [r7, #TSK_STACK_CANARY]
#endif
#ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
@@ -753,6 +750,9 @@ ENTRY(__switch_to)
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
+#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
+ str r7, [r8]
+#endif
THUMB( mov ip, r4 )
mov r0, r5
ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
@@ -1009,17 +1009,12 @@ kuser_cmpxchg_fixup:
*/
__kuser_get_tls: @ 0xffff0fe0
-
-#if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL)
- ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0
-#else
- mrc p15, 0, r0, c13, c0, 3 @ read TLS register
-#endif
+ ldr r0, [pc, #(16 - 8)] @ read TLS, set in kuser_get_tls_init
usr_ret lr
-
- .rep 5
- .word 0 @ pad up to __kuser_helper_version
- .endr
+ mrc p15, 0, r0, c13, c0, 3 @ 0xffff0fe8 hardware TLS code
+ .rep 4
+ .word 0 @ 0xffff0ff0 software TLS value, then
+ .endr @ pad up to __kuser_helper_version
/*
* Reference declaration:
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3b3d2c80509c..c0d5c3b3a760 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -47,12 +47,14 @@
#define irq_finish(irq) do { } while (0)
#endif
+unsigned int arch_nr_irqs;
void (*init_arch_irq)(void) __initdata = NULL;
unsigned long irq_err_count;
int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *) v, cpu;
+ struct irq_desc *desc;
struct irqaction * action;
unsigned long flags;
@@ -67,24 +69,25 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
}
- if (i < NR_IRQS) {
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
+ if (i < nr_irqs) {
+ desc = irq_to_desc(i);
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ action = desc->action;
if (!action)
goto unlock;
seq_printf(p, "%3d: ", i);
for_each_present_cpu(cpu)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
+ seq_printf(p, " %10s", desc->chip->name ? : "-");
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
seq_printf(p, ", %s", action->name);
seq_putc(p, '\n');
unlock:
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ } else if (i == nr_irqs) {
#ifdef CONFIG_FIQ
show_fiq_list(p, v);
#endif
@@ -112,7 +115,7 @@ asmlinkage void __exception asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
*/
- if (unlikely(irq >= NR_IRQS)) {
+ if (unlikely(irq >= nr_irqs)) {
if (printk_ratelimit())
printk(KERN_WARNING "Bad IRQ%u\n", irq);
ack_bad_irq(irq);
@@ -132,12 +135,12 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
struct irq_desc *desc;
unsigned long flags;
- if (irq >= NR_IRQS) {
+ if (irq >= nr_irqs) {
printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
return;
}
- desc = irq_desc + irq;
+ desc = irq_to_desc(irq);
raw_spin_lock_irqsave(&desc->lock, flags);
desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
if (iflags & IRQF_VALID)
@@ -151,14 +154,25 @@ void set_irq_flags(unsigned int irq, unsigned int iflags)
void __init init_IRQ(void)
{
+ struct irq_desc *desc;
int irq;
- for (irq = 0; irq < NR_IRQS; irq++)
- irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ for (irq = 0; irq < nr_irqs; irq++) {
+ desc = irq_to_desc_alloc_node(irq, 0);
+ desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE;
+ }
init_arch_irq();
}
+#ifdef CONFIG_SPARSE_IRQ
+int __init arch_probe_nr_irqs(void)
+{
+ nr_irqs = arch_nr_irqs ? arch_nr_irqs : NR_IRQS;
+ return 0;
+}
+#endif
+
#ifdef CONFIG_HOTPLUG_CPU
static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
@@ -178,10 +192,9 @@ static void route_irq(struct irq_desc *desc, unsigned int irq, unsigned int cpu)
void migrate_irqs(void)
{
unsigned int i, cpu = smp_processor_id();
+ struct irq_desc *desc;
- for (i = 0; i < NR_IRQS; i++) {
- struct irq_desc *desc = irq_desc + i;
-
+ for_each_irq_desc(i, desc) {
if (desc->node == cpu) {
unsigned int newcpu = cpumask_any_and(desc->affinity,
cpu_online_mask);
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index da1f94906a4e..8bccbfa693ff 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -583,13 +583,14 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
{
insn_llret_3arg_fn_t *i_fn = (insn_llret_3arg_fn_t *)&p->ainsn.insn[0];
kprobe_opcode_t insn = p->opcode;
+ long ppc = (long)p->addr + 8;
union reg_pair fnr;
int rd = (insn >> 12) & 0xf;
int rn = (insn >> 16) & 0xf;
int rm = insn & 0xf;
long rdv;
- long rnv = regs->uregs[rn];
- long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+ long rnv = (rn == 15) ? ppc : regs->uregs[rn];
+ long rmv = (rm == 15) ? ppc : regs->uregs[rm];
long cpsr = regs->ARM_cpsr;
fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 598ca61e7bca..81e989858d42 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -43,6 +43,10 @@ void machine_shutdown(void)
void machine_crash_shutdown(struct pt_regs *regs)
{
+ local_irq_disable();
+ crash_save_cpu(regs, smp_processor_id());
+
+ printk(KERN_INFO "Loading crashdump kernel...\n");
}
void machine_kexec(struct kimage *image)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index acf5e6fdb6dc..43557a1eb610 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -28,6 +28,7 @@
#include <linux/tick.h>
#include <linux/utsname.h>
#include <linux/uaccess.h>
+#include <linux/random.h>
#include <asm/leds.h>
#include <asm/processor.h>
@@ -36,6 +37,12 @@
#include <asm/stacktrace.h>
#include <asm/mach/time.h>
+#ifdef CONFIG_CC_STACKPROTECTOR
+#include <linux/stackprotector.h>
+unsigned long __stack_chk_guard __read_mostly;
+EXPORT_SYMBOL(__stack_chk_guard);
+#endif
+
static const char *processor_modes[] = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
@@ -351,17 +358,21 @@ EXPORT_SYMBOL(dump_fpu);
/*
* Shuffle the argument into the correct register before calling the
- * thread function. r1 is the thread argument, r2 is the pointer to
- * the thread function, and r3 points to the exit function.
+ * thread function. r4 is the thread argument, r5 is the pointer to
+ * the thread function, and r6 points to the exit function.
*/
extern void kernel_thread_helper(void);
asm( ".pushsection .text\n"
" .align\n"
" .type kernel_thread_helper, #function\n"
"kernel_thread_helper:\n"
-" mov r0, r1\n"
-" mov lr, r3\n"
-" mov pc, r2\n"
+#ifdef CONFIG_TRACE_IRQFLAGS
+" bl trace_hardirqs_on\n"
+#endif
+" msr cpsr_c, r7\n"
+" mov r0, r4\n"
+" mov lr, r6\n"
+" mov pc, r5\n"
" .size kernel_thread_helper, . - kernel_thread_helper\n"
" .popsection");
@@ -391,11 +402,12 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
memset(&regs, 0, sizeof(regs));
- regs.ARM_r1 = (unsigned long)arg;
- regs.ARM_r2 = (unsigned long)fn;
- regs.ARM_r3 = (unsigned long)kernel_thread_exit;
+ regs.ARM_r4 = (unsigned long)arg;
+ regs.ARM_r5 = (unsigned long)fn;
+ regs.ARM_r6 = (unsigned long)kernel_thread_exit;
+ regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
regs.ARM_pc = (unsigned long)kernel_thread_helper;
- regs.ARM_cpsr = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
+ regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
@@ -421,3 +433,9 @@ unsigned long get_wchan(struct task_struct *p)
} while (count ++ < 16);
return 0;
}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+ unsigned long range_end = mm->brk + 0x02000000;
+ return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
+}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 3f562a7c0a99..f99d489822d5 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -52,6 +52,102 @@
#define BREAKINST_THUMB 0xde01
#endif
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
+
+#define REG_OFFSET_NAME(r) \
+ {.name = #r, .offset = offsetof(struct pt_regs, ARM_##r)}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(r0),
+ REG_OFFSET_NAME(r1),
+ REG_OFFSET_NAME(r2),
+ REG_OFFSET_NAME(r3),
+ REG_OFFSET_NAME(r4),
+ REG_OFFSET_NAME(r5),
+ REG_OFFSET_NAME(r6),
+ REG_OFFSET_NAME(r7),
+ REG_OFFSET_NAME(r8),
+ REG_OFFSET_NAME(r9),
+ REG_OFFSET_NAME(r10),
+ REG_OFFSET_NAME(fp),
+ REG_OFFSET_NAME(ip),
+ REG_OFFSET_NAME(sp),
+ REG_OFFSET_NAME(lr),
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(cpsr),
+ REG_OFFSET_NAME(ORIG_r0),
+ REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+bool regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
+
/*
* this routine will get a word off of the processes privileged stack.
* the offset is how far from the base addr as stored in the THREAD.
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index 61930eb09029..fd26f8d65151 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -10,6 +10,12 @@ relocate_new_kernel:
ldr r0,kexec_indirection_page
ldr r1,kexec_start_address
+ /*
+ * If there is no indirection page (we are doing crashdumps)
+ * skip any relocation.
+ */
+ cmp r0, #0
+ beq 2f
0: /* top, read another word for the indirection page */
ldr r3, [r0],#4
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 122d999bdc7c..31517a01b7dd 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -19,12 +19,15 @@
#include <linux/seq_file.h>
#include <linux/screen_info.h>
#include <linux/init.h>
+#include <linux/kexec.h>
+#include <linux/crash_dump.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
+#include <linux/lmb.h>
#include <asm/unified.h>
#include <asm/cpu.h>
@@ -269,6 +272,21 @@ static void __init cacheid_init(void)
extern struct proc_info_list *lookup_processor_type(unsigned int);
extern struct machine_desc *lookup_machine_type(unsigned int);
+static void __init feat_v6_fixup(void)
+{
+ int id = read_cpuid_id();
+
+ if ((id & 0xff0f0000) != 0x41070000)
+ return;
+
+ /*
+ * HWCAP_TLS is available only on 1136 r1p0 and later,
+ * see also kuser_get_tls_init.
+ */
+ if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0))
+ elf_hwcap &= ~HWCAP_TLS;
+}
+
static void __init setup_processor(void)
{
struct proc_info_list *list;
@@ -311,6 +329,8 @@ static void __init setup_processor(void)
elf_hwcap &= ~HWCAP_THUMB;
#endif
+ feat_v6_fixup();
+
cacheid_init();
cpu_proc_init();
}
@@ -402,13 +422,12 @@ static int __init arm_add_memory(unsigned long start, unsigned long size)
size -= start & ~PAGE_MASK;
bank->start = PAGE_ALIGN(start);
bank->size = size & PAGE_MASK;
- bank->node = PHYS_TO_NID(start);
/*
* Check whether this memory region has non-zero size or
* invalid node number.
*/
- if (bank->size == 0 || bank->node >= MAX_NUMNODES)
+ if (bank->size == 0)
return -EINVAL;
meminfo.nr_banks++;
@@ -663,6 +682,79 @@ static int __init customize_machine(void)
}
arch_initcall(customize_machine);
+#ifdef CONFIG_KEXEC
+static inline unsigned long long get_total_mem(void)
+{
+ unsigned long total;
+
+ total = max_low_pfn - min_low_pfn;
+ return total << PAGE_SHIFT;
+}
+
+/**
+ * reserve_crashkernel() - reserves memory are for crash kernel
+ *
+ * This function reserves memory area given in "crashkernel=" kernel command
+ * line parameter. The memory reserved is used by a dump capture kernel when
+ * primary kernel is crashing.
+ */
+static void __init reserve_crashkernel(void)
+{
+ unsigned long long crash_size, crash_base;
+ unsigned long long total_mem;
+ int ret;
+
+ total_mem = get_total_mem();
+ ret = parse_crashkernel(boot_command_line, total_mem,
+ &crash_size, &crash_base);
+ if (ret)
+ return;
+
+ ret = reserve_bootmem(crash_base, crash_size, BOOTMEM_EXCLUSIVE);
+ if (ret < 0) {
+ printk(KERN_WARNING "crashkernel reservation failed - "
+ "memory is in use (0x%lx)\n", (unsigned long)crash_base);
+ return;
+ }
+
+ printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
+ "for crashkernel (System RAM: %ldMB)\n",
+ (unsigned long)(crash_size >> 20),
+ (unsigned long)(crash_base >> 20),
+ (unsigned long)(total_mem >> 20));
+
+ crashk_res.start = crash_base;
+ crashk_res.end = crash_base + crash_size - 1;
+ insert_resource(&iomem_resource, &crashk_res);
+}
+#else
+static inline void reserve_crashkernel(void) {}
+#endif /* CONFIG_KEXEC */
+
+/*
+ * Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
+ * is_kdump_kernel() to determine if we are booting after a panic. Hence
+ * ifdef it under CONFIG_CRASH_DUMP and not CONFIG_PROC_VMCORE.
+ */
+
+#ifdef CONFIG_CRASH_DUMP
+/*
+ * elfcorehdr= specifies the location of elf core header stored by the crashed
+ * kernel. This option will be passed by kexec loader to the capture kernel.
+ */
+static int __init setup_elfcorehdr(char *arg)
+{
+ char *end;
+
+ if (!arg)
+ return -EINVAL;
+
+ elfcorehdr_addr = memparse(arg, &end);
+ return end > arg ? 0 : -EINVAL;
+}
+early_param("elfcorehdr", setup_elfcorehdr);
+#endif /* CONFIG_CRASH_DUMP */
+
void __init setup_arch(char **cmdline_p)
{
struct tag *tags = (struct tag *)&init_tags;
@@ -716,12 +808,15 @@ void __init setup_arch(char **cmdline_p)
parse_early_param();
+ arm_lmb_init(&meminfo, mdesc);
+
paging_init(mdesc);
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_SMP
smp_init_cpus();
#endif
+ reserve_crashkernel();
cpu_init();
tcm_init();
@@ -729,6 +824,7 @@ void __init setup_arch(char **cmdline_p)
/*
* Set up various architecture-specific pointers
*/
+ arch_nr_irqs = mdesc->nr_irqs;
init_arch_irq = mdesc->init_irq;
system_timer = mdesc->timer;
init_machine = mdesc->init_machine;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 1621e5327b2a..cda78d59aa31 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -30,6 +30,7 @@
#include <asm/unistd.h>
#include <asm/traps.h>
#include <asm/unwind.h>
+#include <asm/tls.h>
#include "ptrace.h"
#include "signal.h"
@@ -518,17 +519,20 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
case NR(set_tls):
thread->tp_value = regs->ARM_r0;
-#if defined(CONFIG_HAS_TLS_REG)
- asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) );
-#elif !defined(CONFIG_TLS_REG_EMUL)
- /*
- * User space must never try to access this directly.
- * Expect your app to break eventually if you do so.
- * The user helper at 0xffff0fe0 must be used instead.
- * (see entry-armv.S for details)
- */
- *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
-#endif
+ if (tls_emu)
+ return 0;
+ if (has_tls_reg) {
+ asm ("mcr p15, 0, %0, c13, c0, 3"
+ : : "r" (regs->ARM_r0));
+ } else {
+ /*
+ * User space must never try to access this directly.
+ * Expect your app to break eventually if you do so.
+ * The user helper at 0xffff0fe0 must be used instead.
+ * (see entry-armv.S for details)
+ */
+ *((unsigned int *)0xffff0ff0) = regs->ARM_r0;
+ }
return 0;
#ifdef CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG
@@ -743,6 +747,16 @@ void __init trap_init(void)
return;
}
+static void __init kuser_get_tls_init(unsigned long vectors)
+{
+ /*
+ * vectors + 0xfe0 = __kuser_get_tls
+ * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
+ */
+ if (tls_emu || has_tls_reg)
+ memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4);
+}
+
void __init early_trap_init(void)
{
unsigned long vectors = CONFIG_VECTORS_BASE;
@@ -761,6 +775,11 @@ void __init early_trap_init(void)
memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
/*
+ * Do processor specific fixups for the kuser helpers
+ */
+ kuser_get_tls_init(vectors);
+
+ /*
* Copy signal return handlers into the vector page, and
* set sigreturn to be a pointer to these.
*/
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 030ba7219f48..59ff42ddf0ae 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -41,7 +41,6 @@ else
endif
lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o
-lib-$(CONFIG_ARCH_L7200) += io-acorn.o
lib-$(CONFIG_ARCH_SHARK) += io-shark.o
$(obj)/csumpartialcopy.o: $(obj)/csumpartialcopygeneric.S
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 841eaf8f27e2..939bccd70569 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -366,6 +366,17 @@ config MACH_STAMP9G20
endif
+if (ARCH_AT91SAM9260 || ARCH_AT91SAM9G20)
+comment "AT91SAM9260/AT91SAM9G20 boards"
+
+config MACH_SNAPPER_9260
+ bool "Bluewater Systems Snapper 9260/9G20 module"
+ help
+ Select this if you are using the Bluewater Systems Snapper 9260 or
+ Snapper 9G20 modules.
+ <http://www.bluewatersys.com/>
+endif
+
# ----------------------------------------------------------
if ARCH_AT91SAM9G45
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index c1f821e58222..ca2ac003f41f 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -66,6 +66,9 @@ obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o
obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o
obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o
+# AT91SAM9260/AT91SAM9G20 board-specific support
+obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o
+
# AT91SAM9G45 board-specific support
obj-$(CONFIG_MACH_AT91SAM9G45EKES) += board-sam9m10g45ek.o
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 85166b7e69a1..753c0d31a3d3 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -20,6 +20,7 @@
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
#include <mach/at91_shdwc.h>
+#include <mach/cpu.h>
#include "generic.h"
#include "clock.h"
@@ -176,6 +177,13 @@ static struct clk mmc1_clk = {
.type = CLK_TYPE_PERIPHERAL,
};
+/* Video decoder clock - Only for sam9m10/sam9m11 */
+static struct clk vdec_clk = {
+ .name = "vdec_clk",
+ .pmc_mask = 1 << AT91SAM9G45_ID_VDEC,
+ .type = CLK_TYPE_PERIPHERAL,
+};
+
/* One additional fake clock for ohci */
static struct clk ohci_clk = {
.name = "ohci_clk",
@@ -239,6 +247,9 @@ static void __init at91sam9g45_register_clocks(void)
for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
clk_register(periph_clocks[i]);
+ if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11())
+ clk_register(&vdec_clk);
+
clk_register(&pck0);
clk_register(&pck1);
}
diff --git a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
index a4102d72cc9b..c49f5c003ee1 100644
--- a/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
+++ b/arch/arm/mach-at91/board-sam9g20ek-2slot-mmc.c
@@ -26,6 +26,9 @@
#include <linux/spi/spi.h>
#include <linux/spi/at73c213.h>
#include <linux/clk.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
#include <mach/hardware.h>
#include <asm/setup.h>
@@ -235,6 +238,46 @@ static struct gpio_led ek_leds[] = {
}
};
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("HPVDD", "0-001b"),
+ REGULATOR_SUPPLY("DBVDD", "0-001b"),
+ REGULATOR_SUPPLY("DCVDD", "0-001b"),
+};
+
+static struct regulator_init_data ek_avdd_reg_init_data = {
+ .constraints = {
+ .name = "3V3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .consumer_supplies = ek_audio_consumer_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config ek_vdd_pdata = {
+ .supply_name = "board-3V3",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 0,
+ .init_data = &ek_avdd_reg_init_data,
+};
+static struct platform_device ek_voltage_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_vdd_pdata,
+ },
+};
+static void __init ek_add_regulators(void)
+{
+ platform_device_register(&ek_voltage_regulator);
+}
+#else
+static void __init ek_add_regulators(void) {}
+#endif
+
static struct i2c_board_info __initdata ek_i2c_devices[] = {
{
I2C_BOARD_INFO("24c512", 0x50),
@@ -256,6 +299,8 @@ static void __init ek_board_init(void)
ek_add_device_nand();
/* Ethernet */
at91_add_device_eth(&ek_macb_data);
+ /* Regulators */
+ ek_add_regulators();
/* MMC */
#if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE)
at91_add_device_mci(0, &ek_mmc_data);
diff --git a/arch/arm/mach-at91/board-sam9g20ek.c b/arch/arm/mach-at91/board-sam9g20ek.c
index c11fd47aec5d..6ea9808b8868 100644
--- a/arch/arm/mach-at91/board-sam9g20ek.c
+++ b/arch/arm/mach-at91/board-sam9g20ek.c
@@ -27,6 +27,9 @@
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/clk.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/consumer.h>
#include <mach/hardware.h>
#include <asm/setup.h>
@@ -269,6 +272,46 @@ static void __init ek_add_device_buttons(void)
static void __init ek_add_device_buttons(void) {}
#endif
+#if defined(CONFIG_REGULATOR_FIXED_VOLTAGE) || defined(CONFIG_REGULATOR_FIXED_VOLTAGE_MODULE)
+static struct regulator_consumer_supply ek_audio_consumer_supplies[] = {
+ REGULATOR_SUPPLY("AVDD", "0-001b"),
+ REGULATOR_SUPPLY("HPVDD", "0-001b"),
+ REGULATOR_SUPPLY("DBVDD", "0-001b"),
+ REGULATOR_SUPPLY("DCVDD", "0-001b"),
+};
+
+static struct regulator_init_data ek_avdd_reg_init_data = {
+ .constraints = {
+ .name = "3V3",
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .consumer_supplies = ek_audio_consumer_supplies,
+ .num_consumer_supplies = ARRAY_SIZE(ek_audio_consumer_supplies),
+};
+
+static struct fixed_voltage_config ek_vdd_pdata = {
+ .supply_name = "board-3V3",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .enabled_at_boot = 0,
+ .init_data = &ek_avdd_reg_init_data,
+};
+static struct platform_device ek_voltage_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &ek_vdd_pdata,
+ },
+};
+static void __init ek_add_regulators(void)
+{
+ platform_device_register(&ek_voltage_regulator);
+}
+#else
+static void __init ek_add_regulators(void) {}
+#endif
+
static struct i2c_board_info __initdata ek_i2c_devices[] = {
{
@@ -294,6 +337,8 @@ static void __init ek_board_init(void)
ek_add_device_nand();
/* Ethernet */
at91_add_device_eth(&ek_macb_data);
+ /* Regulators */
+ ek_add_regulators();
/* MMC */
at91_add_device_mmc(0, &ek_mmc_data);
/* I2C */
diff --git a/arch/arm/mach-at91/board-snapper9260.c b/arch/arm/mach-at91/board-snapper9260.c
new file mode 100644
index 000000000000..2c08ae4ad3a1
--- /dev/null
+++ b/arch/arm/mach-at91/board-snapper9260.c
@@ -0,0 +1,189 @@
+/*
+ * linux/arch/arm/mach-at91/board-snapper9260.c
+ *
+ * Copyright (C) 2010 Bluewater System Ltd
+ *
+ * Author: Andre Renaud <andre@bluewatersys.com>
+ * Author: Ryan Mallon <ryan@bluewatersys.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/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c/pca953x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/hardware.h>
+#include <mach/board.h>
+#include <mach/at91sam9_smc.h>
+
+#include "sam9_smc.h"
+#include "generic.h"
+
+#define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x))
+
+static void __init snapper9260_map_io(void)
+{
+ at91sam9260_initialize(18432000);
+
+ /* Debug on ttyS0 */
+ at91_register_uart(0, 0, 0);
+ at91_set_serial_console(0);
+
+ at91_register_uart(AT91SAM9260_ID_US0, 1,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ at91_register_uart(AT91SAM9260_ID_US1, 2,
+ ATMEL_UART_CTS | ATMEL_UART_RTS);
+ at91_register_uart(AT91SAM9260_ID_US2, 3, 0);
+}
+
+static void __init snapper9260_init_irq(void)
+{
+ at91sam9260_init_interrupts(NULL);
+}
+
+static struct at91_usbh_data __initdata snapper9260_usbh_data = {
+ .ports = 2,
+};
+
+static struct at91_udc_data __initdata snapper9260_udc_data = {
+ .vbus_pin = SNAPPER9260_IO_EXP_GPIO(5),
+ .vbus_active_low = 1,
+ .vbus_polled = 1,
+};
+
+static struct at91_eth_data snapper9260_macb_data = {
+ .is_rmii = 1,
+};
+
+static struct mtd_partition __initdata snapper9260_nand_partitions[] = {
+ {
+ .name = "Preboot",
+ .offset = 0,
+ .size = SZ_128K,
+ },
+ {
+ .name = "Bootloader",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_256K,
+ },
+ {
+ .name = "Environment",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_128K,
+ },
+ {
+ .name = "Kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = SZ_4M,
+ },
+ {
+ .name = "Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct mtd_partition * __init
+snapper9260_nand_partition_info(int size, int *num_partitions)
+{
+ *num_partitions = ARRAY_SIZE(snapper9260_nand_partitions);
+ return snapper9260_nand_partitions;
+}
+
+static struct atmel_nand_data __initdata snapper9260_nand_data = {
+ .ale = 21,
+ .cle = 22,
+ .rdy_pin = AT91_PIN_PC13,
+ .partition_info = snapper9260_nand_partition_info,
+ .bus_width_16 = 0,
+};
+
+static struct sam9_smc_config __initdata snapper9260_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 0,
+ .ncs_write_setup = 0,
+ .nwe_setup = 0,
+
+ .ncs_read_pulse = 5,
+ .nrd_pulse = 2,
+ .ncs_write_pulse = 5,
+ .nwe_pulse = 2,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = (AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
+ AT91_SMC_EXNWMODE_DISABLE),
+ .tdf_cycles = 1,
+};
+
+static struct pca953x_platform_data snapper9260_io_expander_data = {
+ .gpio_base = SNAPPER9260_IO_EXP_GPIO(0),
+};
+
+static struct i2c_board_info __initdata snapper9260_i2c_devices[] = {
+ {
+ /* IO expander */
+ I2C_BOARD_INFO("max7312", 0x28),
+ .platform_data = &snapper9260_io_expander_data,
+ },
+ {
+ /* Audio codec */
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+ {
+ /* RTC */
+ I2C_BOARD_INFO("isl1208", 0x6f),
+ },
+};
+
+static void __init snapper9260_add_device_nand(void)
+{
+ at91_set_A_periph(AT91_PIN_PC14, 0);
+ sam9_smc_configure(3, &snapper9260_nand_smc_config);
+ at91_add_device_nand(&snapper9260_nand_data);
+}
+
+static void __init snapper9260_board_init(void)
+{
+ at91_add_device_i2c(snapper9260_i2c_devices,
+ ARRAY_SIZE(snapper9260_i2c_devices));
+ at91_add_device_serial();
+ at91_add_device_usbh(&snapper9260_usbh_data);
+ at91_add_device_udc(&snapper9260_udc_data);
+ at91_add_device_eth(&snapper9260_macb_data);
+ at91_add_device_ssc(AT91SAM9260_ID_SSC, (ATMEL_SSC_TF | ATMEL_SSC_TK |
+ ATMEL_SSC_TD | ATMEL_SSC_RD));
+ snapper9260_add_device_nand();
+}
+
+MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
+ .phys_io = AT91_BASE_SYS,
+ .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
+ .boot_params = AT91_SDRAM_BASE + 0x100,
+ .timer = &at91sam926x_timer,
+ .map_io = snapper9260_map_io,
+ .init_irq = snapper9260_init_irq,
+ .init_machine = snapper9260_board_init,
+MACHINE_END
+
+
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
index d8c1ededaa75..9c6af9737485 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9.h
@@ -84,7 +84,7 @@
*/
#define AT91_ECC (0xffffe200 - AT91_BASE_SYS)
#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC (0xffffe600 - AT91_BASE_SYS)
+#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
#define AT91_SMC (0xffffe800 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
#define AT91_CCFG (0xffffeb10 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
index 1499b1cbffdd..976f4a6c3353 100644
--- a/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
@@ -15,7 +15,7 @@
#ifndef AT91CAP9_DDRSDR_H
#define AT91CAP9_DDRSDR_H
-#define AT91_DDRSDRC_MR (AT91_DDRSDRC + 0x00) /* Mode Register */
+#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
#define AT91_DDRSDRC_MODE (0xf << 0) /* Command Mode */
#define AT91_DDRSDRC_MODE_NORMAL 0
#define AT91_DDRSDRC_MODE_NOP 1
@@ -25,10 +25,10 @@
#define AT91_DDRSDRC_MODE_EXT_LMR 5
#define AT91_DDRSDRC_MODE_DEEP 6
-#define AT91_DDRSDRC_RTR (AT91_DDRSDRC + 0x04) /* Refresh Timer Register */
+#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
-#define AT91_DDRSDRC_CR (AT91_DDRSDRC + 0x08) /* Configuration Register */
+#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
@@ -49,7 +49,7 @@
#define AT91_DDRSDRC_DLL (1 << 7) /* Reset DLL */
#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
-#define AT91_DDRSDRC_T0PR (AT91_DDRSDRC + 0x0C) /* Timing 0 Register */
+#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
@@ -59,13 +59,13 @@
#define AT91_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
-#define AT91_DDRSDRC_T1PR (AT91_DDRSDRC + 0x10) /* Timing 1 Register */
+#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
-#define AT91_DDRSDRC_LPR (AT91_DDRSDRC + 0x18) /* Low Power Register */
+#define AT91_DDRSDRC_LPR 0x18 /* Low Power Register */
#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
#define AT91_DDRSDRC_LPCB_DISABLE 0
#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
@@ -80,14 +80,14 @@
#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
-#define AT91_DDRSDRC_MDR (AT91_DDRSDRC + 0x1C) /* Memory Device Register */
+#define AT91_DDRSDRC_MDR 0x1C /* Memory Device Register */
#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
#define AT91_DDRSDRC_MD_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
#define AT91_DDRSDRC_MD_DDR 2
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
-#define AT91_DDRSDRC_DLLR (AT91_DDRSDRC + 0x20) /* DLL Information Register */
+#define AT91_DDRSDRC_DLLR 0x20 /* DLL Information Register */
#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
@@ -98,5 +98,11 @@
#define AT91_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
#define AT91_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h
index 43c396b9b4cb..4e79036d3b80 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9260.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9260.h
@@ -84,7 +84,7 @@
* System Peripherals (offset from AT91_BASE_SYS)
*/
#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
-#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/at91sam9261.h b/arch/arm/mach-at91/include/mach/at91sam9261.h
index 87de8be17484..2b5618518129 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9261.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9261.h
@@ -68,7 +68,7 @@
/*
* System Peripherals (offset from AT91_BASE_SYS)
*/
-#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
new file mode 100644
index 000000000000..d27b15ba8ebf
--- /dev/null
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -0,0 +1,130 @@
+/*
+ * Header file for the Atmel DDR/SDR SDRAM Controller
+ *
+ * Copyright (C) 2010 Atmel Corporation
+ * Nicolas Ferre <nicolas.ferre@atmel.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 AT91SAM9_DDRSDR_H
+#define AT91SAM9_DDRSDR_H
+
+#define AT91_DDRSDRC_MR 0x00 /* Mode Register */
+#define AT91_DDRSDRC_MODE (0x7 << 0) /* Command Mode */
+#define AT91_DDRSDRC_MODE_NORMAL 0
+#define AT91_DDRSDRC_MODE_NOP 1
+#define AT91_DDRSDRC_MODE_PRECHARGE 2
+#define AT91_DDRSDRC_MODE_LMR 3
+#define AT91_DDRSDRC_MODE_REFRESH 4
+#define AT91_DDRSDRC_MODE_EXT_LMR 5
+#define AT91_DDRSDRC_MODE_DEEP 6
+
+#define AT91_DDRSDRC_RTR 0x04 /* Refresh Timer Register */
+#define AT91_DDRSDRC_COUNT (0xfff << 0) /* Refresh Timer Counter */
+
+#define AT91_DDRSDRC_CR 0x08 /* Configuration Register */
+#define AT91_DDRSDRC_NC (3 << 0) /* Number of Column Bits */
+#define AT91_DDRSDRC_NC_SDR8 (0 << 0)
+#define AT91_DDRSDRC_NC_SDR9 (1 << 0)
+#define AT91_DDRSDRC_NC_SDR10 (2 << 0)
+#define AT91_DDRSDRC_NC_SDR11 (3 << 0)
+#define AT91_DDRSDRC_NC_DDR9 (0 << 0)
+#define AT91_DDRSDRC_NC_DDR10 (1 << 0)
+#define AT91_DDRSDRC_NC_DDR11 (2 << 0)
+#define AT91_DDRSDRC_NC_DDR12 (3 << 0)
+#define AT91_DDRSDRC_NR (3 << 2) /* Number of Row Bits */
+#define AT91_DDRSDRC_NR_11 (0 << 2)
+#define AT91_DDRSDRC_NR_12 (1 << 2)
+#define AT91_DDRSDRC_NR_13 (2 << 2)
+#define AT91_DDRSDRC_NR_14 (3 << 2)
+#define AT91_DDRSDRC_CAS (7 << 4) /* CAS Latency */
+#define AT91_DDRSDRC_CAS_2 (2 << 4)
+#define AT91_DDRSDRC_CAS_3 (3 << 4)
+#define AT91_DDRSDRC_CAS_25 (6 << 4)
+#define AT91_DDRSDRC_RST_DLL (1 << 7) /* Reset DLL */
+#define AT91_DDRSDRC_DICDS (1 << 8) /* Output impedance control */
+#define AT91_DDRSDRC_DIS_DLL (1 << 9) /* Disable DLL */
+#define AT91_DDRSDRC_OCD (1 << 12) /* Off-Chip Driver */
+#define AT91_DDRSDRC_DQMS (1 << 16) /* Mask Data is Shared */
+#define AT91_DDRSDRC_ACTBST (1 << 18) /* Active Bank X to Burst Stop Read Access Bank Y */
+
+#define AT91_DDRSDRC_T0PR 0x0C /* Timing 0 Register */
+#define AT91_DDRSDRC_TRAS (0xf << 0) /* Active to Precharge delay */
+#define AT91_DDRSDRC_TRCD (0xf << 4) /* Row to Column delay */
+#define AT91_DDRSDRC_TWR (0xf << 8) /* Write recovery delay */
+#define AT91_DDRSDRC_TRC (0xf << 12) /* Row cycle delay */
+#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
+#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
+#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */
+#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay */
+#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
+
+#define AT91_DDRSDRC_T1PR 0x10 /* Timing 1 Register */
+#define AT91_DDRSDRC_TRFC (0x1f << 0) /* Row Cycle Delay */
+#define AT91_DDRSDRC_TXSNR (0xff << 8) /* Exit self-refresh to non-read */
+#define AT91_DDRSDRC_TXSRD (0xff << 16) /* Exit self-refresh to read */
+#define AT91_DDRSDRC_TXP (0xf << 24) /* Exit power-down delay */
+
+#define AT91_DDRSDRC_T2PR 0x14 /* Timing 2 Register */
+#define AT91_DDRSDRC_TXARD (0xf << 0) /* Exit active power down delay to read command in mode "Fast Exit" */
+#define AT91_DDRSDRC_TXARDS (0xf << 4) /* Exit active power down delay to read command in mode "Slow Exit" */
+#define AT91_DDRSDRC_TRPA (0xf << 8) /* Row Precharge All delay */
+#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */
+
+#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */
+#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
+#define AT91_DDRSDRC_LPCB_DISABLE 0
+#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
+#define AT91_DDRSDRC_LPCB_POWER_DOWN 2
+#define AT91_DDRSDRC_LPCB_DEEP_POWER_DOWN 3
+#define AT91_DDRSDRC_CLKFR (1 << 2) /* Clock Frozen */
+#define AT91_DDRSDRC_PASR (7 << 4) /* Partial Array Self Refresh */
+#define AT91_DDRSDRC_TCSR (3 << 8) /* Temperature Compensated Self Refresh */
+#define AT91_DDRSDRC_DS (3 << 10) /* Drive Strength */
+#define AT91_DDRSDRC_TIMEOUT (3 << 12) /* Time to define when Low Power Mode is enabled */
+#define AT91_DDRSDRC_TIMEOUT_0_CLK_CYCLES (0 << 12)
+#define AT91_DDRSDRC_TIMEOUT_64_CLK_CYCLES (1 << 12)
+#define AT91_DDRSDRC_TIMEOUT_128_CLK_CYCLES (2 << 12)
+#define AT91_DDRSDRC_APDE (1 << 16) /* Active power down exit time */
+#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
+
+#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
+#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
+#define AT91_DDRSDRC_MD_SDR 0
+#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
+#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
+#define AT91_DDRSDRC_MD_DDR2 6
+#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
+#define AT91_DDRSDRC_DBW_32BITS (0 << 4)
+#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
+
+#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */
+#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
+#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
+#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
+#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
+
+#define AT91_DDRSDRC_HS 0x2C /* High Speed Register */
+#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */
+
+#define AT91_DDRSDRC_DELAY(n) (0x30 + (0x4 * (n))) /* Delay I/O Register n */
+
+#define AT91_DDRSDRC_WPMR 0xE4 /* Write Protect Mode Register */
+#define AT91_DDRSDRC_WP (1 << 0) /* Write protect enable */
+#define AT91_DDRSDRC_WPKEY (0xffffff << 8) /* Write protect key */
+#define AT91_DDRSDRC_KEY (0x444452 << 8) /* Write protect key = "DDR" */
+
+#define AT91_DDRSDRC_WPSR 0xE8 /* Write Protect Status Register */
+#define AT91_DDRSDRC_WPVS (1 << 0) /* Write protect violation status */
+#define AT91_DDRSDRC_WPVSRC (0xffff << 8) /* Write protect violation source */
+
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_DDRSDRC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_DDRSDRC##num + reg, value)
+
+#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
index b7260389f7ca..100f5a592926 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_sdramc.h
@@ -17,7 +17,7 @@
#define AT91SAM9_SDRAMC_H
/* SDRAM Controller (SDRAMC) registers */
-#define AT91_SDRAMC_MR (AT91_SDRAMC + 0x00) /* SDRAM Controller Mode Register */
+#define AT91_SDRAMC_MR 0x00 /* SDRAM Controller Mode Register */
#define AT91_SDRAMC_MODE (0xf << 0) /* Command Mode */
#define AT91_SDRAMC_MODE_NORMAL 0
#define AT91_SDRAMC_MODE_NOP 1
@@ -27,10 +27,10 @@
#define AT91_SDRAMC_MODE_EXT_LMR 5
#define AT91_SDRAMC_MODE_DEEP 6
-#define AT91_SDRAMC_TR (AT91_SDRAMC + 0x04) /* SDRAM Controller Refresh Timer Register */
+#define AT91_SDRAMC_TR 0x04 /* SDRAM Controller Refresh Timer Register */
#define AT91_SDRAMC_COUNT (0xfff << 0) /* Refresh Timer Counter */
-#define AT91_SDRAMC_CR (AT91_SDRAMC + 0x08) /* SDRAM Controller Configuration Register */
+#define AT91_SDRAMC_CR 0x08 /* SDRAM Controller Configuration Register */
#define AT91_SDRAMC_NC (3 << 0) /* Number of Column Bits */
#define AT91_SDRAMC_NC_8 (0 << 0)
#define AT91_SDRAMC_NC_9 (1 << 0)
@@ -57,7 +57,7 @@
#define AT91_SDRAMC_TRAS (0xf << 24) /* Active to Precharge Delay */
#define AT91_SDRAMC_TXSR (0xf << 28) /* Exit Self Refresh to Active Delay */
-#define AT91_SDRAMC_LPR (AT91_SDRAMC + 0x10) /* SDRAM Controller Low Power Register */
+#define AT91_SDRAMC_LPR 0x10 /* SDRAM Controller Low Power Register */
#define AT91_SDRAMC_LPCB (3 << 0) /* Low-power Configurations */
#define AT91_SDRAMC_LPCB_DISABLE 0
#define AT91_SDRAMC_LPCB_SELF_REFRESH 1
@@ -71,16 +71,21 @@
#define AT91_SDRAMC_TIMEOUT_64_CLK_CYCLES (1 << 12)
#define AT91_SDRAMC_TIMEOUT_128_CLK_CYCLES (2 << 12)
-#define AT91_SDRAMC_IER (AT91_SDRAMC + 0x14) /* SDRAM Controller Interrupt Enable Register */
-#define AT91_SDRAMC_IDR (AT91_SDRAMC + 0x18) /* SDRAM Controller Interrupt Disable Register */
-#define AT91_SDRAMC_IMR (AT91_SDRAMC + 0x1C) /* SDRAM Controller Interrupt Mask Register */
-#define AT91_SDRAMC_ISR (AT91_SDRAMC + 0x20) /* SDRAM Controller Interrupt Status Register */
+#define AT91_SDRAMC_IER 0x14 /* SDRAM Controller Interrupt Enable Register */
+#define AT91_SDRAMC_IDR 0x18 /* SDRAM Controller Interrupt Disable Register */
+#define AT91_SDRAMC_IMR 0x1C /* SDRAM Controller Interrupt Mask Register */
+#define AT91_SDRAMC_ISR 0x20 /* SDRAM Controller Interrupt Status Register */
#define AT91_SDRAMC_RES (1 << 0) /* Refresh Error Status */
-#define AT91_SDRAMC_MDR (AT91_SDRAMC + 0x24) /* SDRAM Memory Device Register */
+#define AT91_SDRAMC_MDR 0x24 /* SDRAM Memory Device Register */
#define AT91_SDRAMC_MD (3 << 0) /* Memory Device Type */
#define AT91_SDRAMC_MD_SDRAM 0
#define AT91_SDRAMC_MD_LOW_POWER_SDRAM 1
+/* Register access macros */
+#define at91_ramc_read(num, reg) \
+ at91_sys_read(AT91_SDRAMC##num + reg)
+#define at91_ramc_write(num, reg, value) \
+ at91_sys_write(AT91_SDRAMC##num + reg, value)
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9rl.h b/arch/arm/mach-at91/include/mach/at91sam9rl.h
index fc2de6c09c86..87ba8517ad98 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9rl.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9rl.h
@@ -74,7 +74,7 @@
*/
#define AT91_DMA (0xffffe600 - AT91_BASE_SYS)
#define AT91_ECC (0xffffe800 - AT91_BASE_SYS)
-#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_CCFG (0xffffef10 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 833659d1200a..3bef931d0b1c 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -52,6 +52,7 @@ static inline unsigned long at91_cpu_fully_identify(void)
#define ARCH_EXID_AT91SAM9M11 0x00000001
#define ARCH_EXID_AT91SAM9M10 0x00000002
+#define ARCH_EXID_AT91SAM9G46 0x00000003
#define ARCH_EXID_AT91SAM9G45 0x00000004
static inline unsigned long at91_exid_identify(void)
@@ -128,9 +129,18 @@ static inline unsigned long at91cap9_rev_identify(void)
#ifdef CONFIG_ARCH_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_cpu_identify() == ARCH_ID_AT91SAM9G45)
#define cpu_is_at91sam9g45es() (at91_cpu_fully_identify() == ARCH_ID_AT91SAM9G45ES)
+#define cpu_is_at91sam9m10() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9M10))
+#define cpu_is_at91sam9m46() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9G46))
+#define cpu_is_at91sam9m11() (cpu_is_at91sam9g45() && \
+ (at91_exid_identify() == ARCH_EXID_AT91SAM9M11))
#else
#define cpu_is_at91sam9g45() (0)
#define cpu_is_at91sam9g45es() (0)
+#define cpu_is_at91sam9m10() (0)
+#define cpu_is_at91sam9g46() (0)
+#define cpu_is_at91sam9m11() (0)
#endif
#ifdef CONFIG_ARCH_AT91CAP9
diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h
index 04c91e31c9c5..bfdd8ab26dc8 100644
--- a/arch/arm/mach-at91/include/mach/gpio.h
+++ b/arch/arm/mach-at91/include/mach/gpio.h
@@ -19,6 +19,7 @@
#define PIN_BASE NR_AIC_IRQS
#define MAX_GPIO_BANKS 5
+#define NR_BUILTIN_GPIO (PIN_BASE + (MAX_GPIO_BANKS * 32))
/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 08322c44df1a..8c87d0c1b8f8 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -30,14 +30,50 @@ static inline u32 sdram_selfrefresh_enable(void)
{
u32 saved_lpr, lpr;
- saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR);
+ saved_lpr = at91_ramc_read(0, AT91_DDRSDRC_LPR);
lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
- at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
return saved_lpr;
}
-#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr)
+
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
+
+/* We manage both DDRAM/SDRAM controllers, we need more than one value to
+ * remember.
+ */
+static u32 saved_lpr1;
+
+static inline u32 sdram_selfrefresh_enable(void)
+{
+ /* Those tow values allow us to delay self-refresh activation
+ * to the maximum. */
+ u32 lpr0, lpr1;
+ u32 saved_lpr0;
+
+ saved_lpr1 = at91_ramc_read(1, AT91_DDRSDRC_LPR);
+ lpr1 = saved_lpr1 & ~AT91_DDRSDRC_LPCB;
+ lpr1 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+ saved_lpr0 = at91_ramc_read(0, AT91_DDRSDRC_LPR);
+ lpr0 = saved_lpr0 & ~AT91_DDRSDRC_LPCB;
+ lpr0 |= AT91_DDRSDRC_LPCB_SELF_REFRESH;
+
+ /* self-refresh mode now */
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, lpr0);
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, lpr1);
+
+ return saved_lpr0;
+}
+
+#define sdram_selfrefresh_disable(saved_lpr0) \
+ do { \
+ at91_ramc_write(0, AT91_DDRSDRC_LPR, saved_lpr0); \
+ at91_ramc_write(1, AT91_DDRSDRC_LPR, saved_lpr1); \
+ } while (0)
#else
#include <mach/at91sam9_sdramc.h>
@@ -47,7 +83,6 @@ static inline u32 sdram_selfrefresh_enable(void)
* FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
* handle those cases both here and in the Suspend-To-RAM support.
*/
-#define AT91_SDRAMC AT91_SDRAMC0
#warning Assuming EB1 SDRAM controller is *NOT* used
#endif
@@ -55,13 +90,13 @@ static inline u32 sdram_selfrefresh_enable(void)
{
u32 saved_lpr, lpr;
- saved_lpr = at91_sys_read(AT91_SDRAMC_LPR);
+ saved_lpr = at91_ramc_read(0, AT91_SDRAMC_LPR);
lpr = saved_lpr & ~AT91_SDRAMC_LPCB;
- at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
+ at91_ramc_write(0, AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH);
return saved_lpr;
}
-#define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr)
+#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91_SDRAMC_LPR, saved_lpr)
#endif
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 9c5b48e68a71..b6b00a1f6125 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -16,10 +16,12 @@
#include <mach/hardware.h>
#include <mach/at91_pmc.h>
-#ifdef CONFIG_ARCH_AT91RM9200
+#if defined(CONFIG_ARCH_AT91RM9200)
#include <mach/at91rm9200_mc.h>
#elif defined(CONFIG_ARCH_AT91CAP9)
#include <mach/at91cap9_ddrsdr.h>
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
+#include <mach/at91sam9_ddrsdr.h>
#else
#include <mach/at91sam9_sdramc.h>
#endif
@@ -30,7 +32,6 @@
* FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
* handle those cases both here and in the Suspend-To-RAM support.
*/
-#define AT91_SDRAMC AT91_SDRAMC0
#warning Assuming EB1 SDRAM controller is *NOT* used
#endif
@@ -113,12 +114,14 @@ ENTRY(at91_slow_clock)
/*
* Register usage:
* R1 = Base address of AT91_PMC
- * R2 = Base address of AT91_SDRAMC (or AT91_SYS on AT91RM9200)
+ * R2 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
* R3 = temporary register
* R4 = temporary register
+ * R5 = Base address of second RAM Controller or 0 if not present
*/
ldr r1, .at91_va_base_pmc
ldr r2, .at91_va_base_sdramc
+ ldr r5, .at91_va_base_ramc1
/* Drain write buffer */
mcr p15, 0, r0, c7, c10, 4
@@ -127,20 +130,33 @@ ENTRY(at91_slow_clock)
/* Put SDRAM in self-refresh mode */
mov r3, #1
str r3, [r2, #AT91_SDRAMC_SRR]
-#elif defined(CONFIG_ARCH_AT91CAP9)
- /* Enable SDRAM self-refresh mode */
- ldr r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
- str r3, .saved_sam9_lpr
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
- mov r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
- str r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+ /* prepare for DDRAM self-refresh mode */
+ ldr r3, [r2, #AT91_DDRSDRC_LPR]
+ str r3, .saved_sam9_lpr
+ bic r3, #AT91_DDRSDRC_LPCB
+ orr r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* figure out if we use the second ram controller */
+ cmp r5, #0
+ ldrne r4, [r5, #AT91_DDRSDRC_LPR]
+ strne r4, .saved_sam9_lpr1
+ bicne r4, #AT91_DDRSDRC_LPCB
+ orrne r4, #AT91_DDRSDRC_LPCB_SELF_REFRESH
+
+ /* Enable DDRAM self-refresh mode */
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+ strne r4, [r5, #AT91_DDRSDRC_LPR]
#else
/* Enable SDRAM self-refresh mode */
- ldr r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+ ldr r3, [r2, #AT91_SDRAMC_LPR]
str r3, .saved_sam9_lpr
- mov r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
- str r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+ bic r3, #AT91_SDRAMC_LPCB
+ orr r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
+ str r3, [r2, #AT91_SDRAMC_LPR]
#endif
/* Save Master clock setting */
@@ -247,14 +263,21 @@ ENTRY(at91_slow_clock)
#ifdef CONFIG_ARCH_AT91RM9200
/* Do nothing - self-refresh is automatically disabled. */
-#elif defined(CONFIG_ARCH_AT91CAP9)
- /* Restore LPR on AT91CAP9 */
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
+ /* Restore LPR on AT91 with DDRAM */
ldr r3, .saved_sam9_lpr
- str r3, [r2, #AT91_DDRSDRC_LPR - AT91_DDRSDRC]
+ str r3, [r2, #AT91_DDRSDRC_LPR]
+
+ /* if we use the second ram controller */
+ cmp r5, #0
+ ldrne r4, .saved_sam9_lpr1
+ strne r4, [r5, #AT91_DDRSDRC_LPR]
+
#else
- /* Restore LPR on AT91SAM9 */
+ /* Restore LPR on AT91 with SDRAM */
ldr r3, .saved_sam9_lpr
- str r3, [r2, #AT91_SDRAMC_LPR - AT91_SDRAMC]
+ str r3, [r2, #AT91_SDRAMC_LPR]
#endif
/* Restore registers, and return */
@@ -273,18 +296,29 @@ ENTRY(at91_slow_clock)
.saved_sam9_lpr:
.word 0
+.saved_sam9_lpr1:
+ .word 0
+
.at91_va_base_pmc:
.word AT91_VA_BASE_SYS + AT91_PMC
#ifdef CONFIG_ARCH_AT91RM9200
.at91_va_base_sdramc:
.word AT91_VA_BASE_SYS
-#elif defined(CONFIG_ARCH_AT91CAP9)
+#elif defined(CONFIG_ARCH_AT91CAP9) \
+ || defined(CONFIG_ARCH_AT91SAM9G45)
.at91_va_base_sdramc:
- .word AT91_VA_BASE_SYS + AT91_DDRSDRC
+ .word AT91_VA_BASE_SYS + AT91_DDRSDRC0
#else
.at91_va_base_sdramc:
- .word AT91_VA_BASE_SYS + AT91_SDRAMC
+ .word AT91_VA_BASE_SYS + AT91_SDRAMC0
+#endif
+
+.at91_va_base_ramc1:
+#if defined(CONFIG_ARCH_AT91SAM9G45)
+ .word AT91_VA_BASE_SYS + AT91_DDRSDRC1
+#else
+ .word 0
#endif
ENTRY(at91_slow_clock_sz)
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig
index dbaae5f746a1..eb34bd1251d4 100644
--- a/arch/arm/mach-clps711x/Kconfig
+++ b/arch/arm/mach-clps711x/Kconfig
@@ -30,7 +30,6 @@ config ARCH_CLEP7312
config ARCH_EDB7211
bool "EDB7211"
select ISA
- select ARCH_DISCONTIGMEM_ENABLE
select ARCH_SPARSEMEM_ENABLE
select ARCH_SELECT_MEMORY_MODEL
help
diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c
index 09fb57e45213..3c3bf45039ff 100644
--- a/arch/arm/mach-clps711x/clep7312.c
+++ b/arch/arm/mach-clps711x/clep7312.c
@@ -32,7 +32,6 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags,
mi->nr_banks=1;
mi->bank[0].start = 0xc0000000;
mi->bank[0].size = 0x01000000;
- mi->bank[0].node = 0;
}
diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c
index dc81cc68595d..3c13111eb0a9 100644
--- a/arch/arm/mach-clps711x/edb7211-arch.c
+++ b/arch/arm/mach-clps711x/edb7211-arch.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
+#include <linux/lmb.h>
#include <linux/types.h>
#include <linux/string.h>
@@ -29,6 +30,12 @@
extern void edb7211_map_io(void);
+/* Reserve screen memory region at the start of main system memory. */
+static void __init edb7211_reserve(void)
+{
+ lmb_reserve(PHYS_OFFSET, 0x00020000);
+}
+
static void __init
fixup_edb7211(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
@@ -43,10 +50,8 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags,
*/
mi->bank[0].start = 0xc0000000;
mi->bank[0].size = 8*1024*1024;
- mi->bank[0].node = 0;
mi->bank[1].start = 0xc1000000;
mi->bank[1].size = 8*1024*1024;
- mi->bank[1].node = 1;
mi->nr_banks = 2;
}
@@ -57,6 +62,7 @@ MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)")
.boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */
.fixup = fixup_edb7211,
.map_io = edb7211_map_io,
+ .reserve = edb7211_reserve,
.init_irq = clps711x_init_irq,
.timer = &clps711x_timer,
MACHINE_END
diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c
index 7430e4049d87..a696099aa4f8 100644
--- a/arch/arm/mach-clps711x/fortunet.c
+++ b/arch/arm/mach-clps711x/fortunet.c
@@ -39,7 +39,6 @@ struct meminfo memmap = {
{
.start = 0xC0000000,
.size = 0x01000000,
- .node = 0
},
},
};
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 0316e201ada0..71f90f864748 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -50,6 +50,11 @@ config ARCH_DAVINCI_DM365
select AINTC
select ARCH_DAVINCI_DMx
+config ARCH_DAVINCI_TNETV107X
+ select CPU_V6
+ select CP_INTC
+ bool "TNETV107X based system"
+
comment "DaVinci Board Type"
config MACH_DAVINCI_EVM
@@ -173,6 +178,13 @@ config DA850_UI_RMII
endchoice
+config MACH_TNETV107X
+ bool "TI TNETV107X Reference Platform"
+ default ARCH_DAVINCI_TNETV107X
+ depends on ARCH_DAVINCI_TNETV107X
+ help
+ Say Y here to select the TI TNETV107X Evaluation Module.
+
config DAVINCI_MUX
bool "DAVINCI multiplexing support"
depends on ARCH_DAVINCI
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 6aac880eb794..eab4c0fd667a 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o
obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o
obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o
obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += tnetv107x.o devices-tnetv107x.o
+obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o
obj-$(CONFIG_AINTC) += irq.o
obj-$(CONFIG_CP_INTC) += cp_intc.o
@@ -30,6 +32,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
+obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o
# Power Management
obj-$(CONFIG_CPU_FREQ) += cpufreq.o
diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c
new file mode 100644
index 000000000000..fe2a9d9c8bb7
--- /dev/null
+++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c
@@ -0,0 +1,174 @@
+/*
+ * Texas Instruments TNETV107X EVM Board Support
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/dma-mapping.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/ratelimit.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/mux.h>
+#include <mach/cp_intc.h>
+#include <mach/tnetv107x.h>
+
+#define EVM_MMC_WP_GPIO 21
+#define EVM_MMC_CD_GPIO 24
+
+static int initialize_gpio(int gpio, char *desc)
+{
+ int ret;
+
+ ret = gpio_request(gpio, desc);
+ if (ret < 0) {
+ pr_err_ratelimited("cannot open %s gpio\n", desc);
+ return -ENOSYS;
+ }
+ gpio_direction_input(gpio);
+ return gpio;
+}
+
+static int mmc_get_cd(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_CD_GPIO, "mmc card detect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 0 : 1;
+}
+
+static int mmc_get_ro(int index)
+{
+ static int gpio;
+
+ if (!gpio)
+ gpio = initialize_gpio(EVM_MMC_WP_GPIO, "mmc write protect");
+
+ if (gpio < 0)
+ return gpio;
+
+ return gpio_get_value(gpio) ? 1 : 0;
+}
+
+static struct davinci_mmc_config mmc_config = {
+ .get_cd = mmc_get_cd,
+ .get_ro = mmc_get_ro,
+ .wires = 4,
+ .max_freq = 50000000,
+ .caps = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED,
+ .version = MMC_CTLR_VERSION_1,
+};
+
+static const short sdio1_pins[] __initdata = {
+ TNETV107X_SDIO1_CLK_1, TNETV107X_SDIO1_CMD_1,
+ TNETV107X_SDIO1_DATA0_1, TNETV107X_SDIO1_DATA1_1,
+ TNETV107X_SDIO1_DATA2_1, TNETV107X_SDIO1_DATA3_1,
+ TNETV107X_GPIO21, TNETV107X_GPIO24,
+ -1
+};
+
+static const short uart1_pins[] __initdata = {
+ TNETV107X_UART1_RD, TNETV107X_UART1_TD,
+ -1
+};
+
+static struct mtd_partition nand_partitions[] = {
+ /* bootloader (U-Boot, etc) in first 12 sectors */
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = (12*SZ_128K),
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* bootloader params in the next sector */
+ {
+ .name = "params",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_128K,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ },
+ /* kernel */
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = SZ_4M,
+ .mask_flags = 0,
+ },
+ /* file system */
+ {
+ .name = "filesystem",
+ .offset = MTDPART_OFS_NXTBLK,
+ .size = MTDPART_SIZ_FULL,
+ .mask_flags = 0,
+ }
+};
+
+static struct davinci_nand_pdata nand_config = {
+ .mask_cle = 0x4000,
+ .mask_ale = 0x2000,
+ .parts = nand_partitions,
+ .nr_parts = ARRAY_SIZE(nand_partitions),
+ .ecc_mode = NAND_ECC_HW,
+ .options = NAND_USE_FLASH_BBT,
+ .ecc_bits = 1,
+};
+
+static struct davinci_uart_config serial_config __initconst = {
+ .enabled_uarts = BIT(1),
+};
+
+static struct tnetv107x_device_info evm_device_info __initconst = {
+ .serial_config = &serial_config,
+ .mmc_config[1] = &mmc_config, /* controller 1 */
+ .nand_config[0] = &nand_config, /* chip select 0 */
+};
+
+static __init void tnetv107x_evm_board_init(void)
+{
+ davinci_cfg_reg_list(sdio1_pins);
+ davinci_cfg_reg_list(uart1_pins);
+
+ tnetv107x_devices_init(&evm_device_info);
+}
+
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+static int __init tnetv107x_evm_console_init(void)
+{
+ return add_preferred_console("ttyS", 0, "115200");
+}
+console_initcall(tnetv107x_evm_console_init);
+#endif
+
+MACHINE_START(TNETV107X, "TNETV107X EVM")
+ .phys_io = TNETV107X_IO_BASE,
+ .io_pg_offst = (TNETV107X_IO_VIRT >> 18) & 0xfffc,
+ .boot_params = (TNETV107X_DDR_BASE + 0x100),
+ .map_io = tnetv107x_init,
+ .init_irq = cp_intc_init,
+ .timer = &davinci_timer,
+ .init_machine = tnetv107x_evm_board_init,
+MACHINE_END
diff --git a/arch/arm/mach-davinci/devices-tnetv107x.c b/arch/arm/mach-davinci/devices-tnetv107x.c
new file mode 100644
index 000000000000..4eef6ccdc73e
--- /dev/null
+++ b/arch/arm/mach-davinci/devices-tnetv107x.c
@@ -0,0 +1,318 @@
+/*
+ * Texas Instruments TNETV107X SoC devices
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+
+#include <mach/common.h>
+#include <mach/irqs.h>
+#include <mach/edma.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_TPCC_BASE 0x01c00000
+#define TNETV107X_TPTC0_BASE 0x01c10000
+#define TNETV107X_TPTC1_BASE 0x01c10400
+#define TNETV107X_WDOG_BASE 0x08086700
+#define TNETV107X_SDIO0_BASE 0x08088700
+#define TNETV107X_SDIO1_BASE 0x08088800
+#define TNETV107X_ASYNC_EMIF_CNTRL_BASE 0x08200000
+#define TNETV107X_ASYNC_EMIF_DATA_CE0_BASE 0x30000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE1_BASE 0x40000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE2_BASE 0x44000000
+#define TNETV107X_ASYNC_EMIF_DATA_CE3_BASE 0x48000000
+
+/* TNETV107X specific EDMA3 information */
+#define EDMA_TNETV107X_NUM_DMACH 64
+#define EDMA_TNETV107X_NUM_TCC 64
+#define EDMA_TNETV107X_NUM_PARAMENTRY 128
+#define EDMA_TNETV107X_NUM_EVQUE 2
+#define EDMA_TNETV107X_NUM_TC 2
+#define EDMA_TNETV107X_CHMAP_EXIST 0
+#define EDMA_TNETV107X_NUM_REGIONS 4
+#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u
+#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu
+
+#define TNETV107X_DMACH_SDIO0_RX 26
+#define TNETV107X_DMACH_SDIO0_TX 27
+#define TNETV107X_DMACH_SDIO1_RX 28
+#define TNETV107X_DMACH_SDIO1_TX 29
+
+static const s8 edma_tc_mapping[][2] = {
+ /* event queue no TC no */
+ { 0, 0 },
+ { 1, 1 },
+ { -1, -1 }
+};
+
+static const s8 edma_priority_mapping[][2] = {
+ /* event queue no Prio */
+ { 0, 3 },
+ { 1, 7 },
+ { -1, -1 }
+};
+
+static struct edma_soc_info edma_info[] = {
+ {
+ .n_channel = EDMA_TNETV107X_NUM_DMACH,
+ .n_region = EDMA_TNETV107X_NUM_REGIONS,
+ .n_slot = EDMA_TNETV107X_NUM_PARAMENTRY,
+ .n_tc = EDMA_TNETV107X_NUM_TC,
+ .n_cc = 1,
+ .queue_tc_mapping = edma_tc_mapping,
+ .queue_priority_mapping = edma_priority_mapping,
+ },
+};
+
+static struct resource edma_resources[] = {
+ {
+ .name = "edma_cc0",
+ .start = TNETV107X_TPCC_BASE,
+ .end = TNETV107X_TPCC_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc0",
+ .start = TNETV107X_TPTC0_BASE,
+ .end = TNETV107X_TPTC0_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma_tc1",
+ .start = TNETV107X_TPTC1_BASE,
+ .end = TNETV107X_TPTC1_BASE + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "edma0",
+ .start = IRQ_TNETV107X_TPCC,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "edma0_err",
+ .start = IRQ_TNETV107X_TPCC_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device edma_device = {
+ .name = "edma",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(edma_resources),
+ .resource = edma_resources,
+ .dev.platform_data = edma_info,
+};
+
+static struct plat_serial8250_port serial_data[] = {
+ {
+ .mapbase = TNETV107X_UART0_BASE,
+ .irq = IRQ_TNETV107X_UART0,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART1_BASE,
+ .irq = IRQ_TNETV107X_UART1,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .mapbase = TNETV107X_UART2_BASE,
+ .irq = IRQ_TNETV107X_UART2,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
+ UPF_FIXED_TYPE | UPF_IOREMAP,
+ .type = PORT_AR7,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ },
+ {
+ .flags = 0,
+ },
+};
+
+struct platform_device tnetv107x_serial_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev.platform_data = serial_data,
+};
+
+static struct resource mmc0_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO0_BASE,
+ .end = TNETV107X_SDIO0_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO0,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO0_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static struct resource mmc1_resources[] = {
+ { /* Memory mapped registers */
+ .start = TNETV107X_SDIO1_BASE,
+ .end = TNETV107X_SDIO1_BASE + 0x0ff,
+ .flags = IORESOURCE_MEM
+ },
+ { /* MMC interrupt */
+ .start = IRQ_TNETV107X_MMC1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* SDIO interrupt */
+ .start = IRQ_TNETV107X_SDIO1,
+ .flags = IORESOURCE_IRQ
+ },
+ { /* DMA RX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_RX),
+ .flags = IORESOURCE_DMA
+ },
+ { /* DMA TX */
+ .start = EDMA_CTLR_CHAN(0, TNETV107X_DMACH_SDIO1_TX),
+ .flags = IORESOURCE_DMA
+ },
+};
+
+static u64 mmc0_dma_mask = DMA_BIT_MASK(32);
+static u64 mmc1_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device mmc_devices[2] = {
+ {
+ .name = "davinci_mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &mmc0_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc0_resources),
+ .resource = mmc0_resources
+ },
+ {
+ .name = "davinci_mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &mmc1_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(mmc1_resources),
+ .resource = mmc1_resources
+ },
+};
+
+static const u32 emif_windows[] = {
+ TNETV107X_ASYNC_EMIF_DATA_CE0_BASE, TNETV107X_ASYNC_EMIF_DATA_CE1_BASE,
+ TNETV107X_ASYNC_EMIF_DATA_CE2_BASE, TNETV107X_ASYNC_EMIF_DATA_CE3_BASE,
+};
+
+static const u32 emif_window_sizes[] = { SZ_256M, SZ_64M, SZ_64M, SZ_64M };
+
+static struct resource wdt_resources[] = {
+ {
+ .start = TNETV107X_WDOG_BASE,
+ .end = TNETV107X_WDOG_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+struct platform_device tnetv107x_wdt_device = {
+ .name = "tnetv107x_wdt",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static int __init nand_init(int chipsel, struct davinci_nand_pdata *data)
+{
+ struct resource res[2];
+ struct platform_device *pdev;
+ u32 range;
+ int ret;
+
+ /* Figure out the resource range from the ale/cle masks */
+ range = max(data->mask_cle, data->mask_ale);
+ range = PAGE_ALIGN(range + 4) - 1;
+
+ if (range >= emif_window_sizes[chipsel])
+ return -EINVAL;
+
+ pdev = kzalloc(sizeof(*pdev), GFP_KERNEL);
+ if (!pdev)
+ return -ENOMEM;
+
+ pdev->name = "davinci_nand";
+ pdev->id = chipsel;
+ pdev->dev.platform_data = data;
+
+ memset(res, 0, sizeof(res));
+
+ res[0].start = emif_windows[chipsel];
+ res[0].end = res[0].start + range;
+ res[0].flags = IORESOURCE_MEM;
+
+ res[1].start = TNETV107X_ASYNC_EMIF_CNTRL_BASE;
+ res[1].end = res[1].start + SZ_4K - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+ if (ret < 0) {
+ kfree(pdev);
+ return ret;
+ }
+
+ return platform_device_register(pdev);
+}
+
+void __init tnetv107x_devices_init(struct tnetv107x_device_info *info)
+{
+ int i;
+
+ platform_device_register(&edma_device);
+ platform_device_register(&tnetv107x_wdt_device);
+
+ if (info->serial_config)
+ davinci_serial_init(info->serial_config);
+
+ for (i = 0; i < 2; i++)
+ if (info->mmc_config[i]) {
+ mmc_devices[i].dev.platform_data = info->mmc_config[i];
+ platform_device_register(&mmc_devices[i]);
+ }
+
+ for (i = 0; i < 4; i++)
+ if (info->nand_config[i])
+ nand_init(i, info->nand_config[i]);
+}
diff --git a/arch/arm/mach-davinci/dm365.c b/arch/arm/mach-davinci/dm365.c
index a146849d78f0..652f4b6ee1cd 100644
--- a/arch/arm/mach-davinci/dm365.c
+++ b/arch/arm/mach-davinci/dm365.c
@@ -1020,6 +1020,8 @@ static struct davinci_timer_info dm365_timer_info = {
.clocksource_id = T0_TOP,
};
+#define DM365_UART1_BASE (IO_PHYS + 0x106000)
+
static struct plat_serial8250_port dm365_serial_platform_data[] = {
{
.mapbase = DAVINCI_UART0_BASE,
@@ -1030,7 +1032,7 @@ static struct plat_serial8250_port dm365_serial_platform_data[] = {
.regshift = 2,
},
{
- .mapbase = DAVINCI_UART1_BASE,
+ .mapbase = DM365_UART1_BASE,
.irq = IRQ_UARTINT1,
.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
UPF_IOREMAP,
diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c b/arch/arm/mach-davinci/gpio-tnetv107x.c
new file mode 100644
index 000000000000..d10298620e2c
--- /dev/null
+++ b/arch/arm/mach-davinci/gpio-tnetv107x.c
@@ -0,0 +1,205 @@
+/*
+ * Texas Instruments TNETV107X GPIO Controller
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+
+#include <mach/common.h>
+#include <mach/tnetv107x.h>
+
+struct tnetv107x_gpio_regs {
+ u32 idver;
+ u32 data_in[3];
+ u32 data_out[3];
+ u32 direction[3];
+ u32 enable[3];
+};
+
+#define gpio_reg_index(gpio) ((gpio) >> 5)
+#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f)
+
+#define gpio_reg_rmw(reg, mask, val) \
+ __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg))
+
+#define gpio_reg_set_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio))
+
+#define gpio_reg_clear_bit(reg, gpio) \
+ gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0)
+
+#define gpio_reg_get_bit(reg, gpio) \
+ (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio))
+
+#define chip2controller(chip) \
+ container_of(chip, struct davinci_gpio_controller, chip)
+
+#define TNETV107X_GPIO_CTLRS DIV_ROUND_UP(TNETV107X_N_GPIO, 32)
+
+static struct davinci_gpio_controller chips[TNETV107X_GPIO_CTLRS];
+
+static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(&regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static void tnetv107x_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_clear_bit(&regs->enable, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int tnetv107x_gpio_dir_in(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ gpio_reg_set_bit(&regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_dir_out(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(&regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(&regs->data_out, gpio);
+
+ gpio_reg_clear_bit(&regs->direction, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+
+ return 0;
+}
+
+static int tnetv107x_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ int ret;
+
+ ret = gpio_reg_get_bit(&regs->data_in, gpio);
+
+ return ret ? 1 : 0;
+}
+
+static void tnetv107x_gpio_set(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ struct davinci_gpio_controller *ctlr = chip2controller(chip);
+ struct tnetv107x_gpio_regs __iomem *regs = ctlr->regs;
+ unsigned gpio = chip->base + offset;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctlr->lock, flags);
+
+ if (value)
+ gpio_reg_set_bit(&regs->data_out, gpio);
+ else
+ gpio_reg_clear_bit(&regs->data_out, gpio);
+
+ spin_unlock_irqrestore(&ctlr->lock, flags);
+}
+
+static int __init tnetv107x_gpio_setup(void)
+{
+ int i, base;
+ unsigned ngpio;
+ struct davinci_soc_info *soc_info = &davinci_soc_info;
+ struct tnetv107x_gpio_regs *regs;
+ struct davinci_gpio_controller *ctlr;
+
+ if (soc_info->gpio_type != GPIO_TYPE_TNETV107X)
+ return 0;
+
+ ngpio = soc_info->gpio_num;
+ if (ngpio == 0) {
+ pr_err("GPIO setup: how many GPIOs?\n");
+ return -EINVAL;
+ }
+
+ if (WARN_ON(TNETV107X_N_GPIO < ngpio))
+ ngpio = TNETV107X_N_GPIO;
+
+ regs = ioremap(soc_info->gpio_base, SZ_4K);
+ if (WARN_ON(!regs))
+ return -EINVAL;
+
+ for (i = 0, base = 0; base < ngpio; i++, base += 32) {
+ ctlr = &chips[i];
+
+ ctlr->chip.label = "tnetv107x";
+ ctlr->chip.can_sleep = 0;
+ ctlr->chip.base = base;
+ ctlr->chip.ngpio = ngpio - base;
+ if (ctlr->chip.ngpio > 32)
+ ctlr->chip.ngpio = 32;
+
+ ctlr->chip.request = tnetv107x_gpio_request;
+ ctlr->chip.free = tnetv107x_gpio_free;
+ ctlr->chip.direction_input = tnetv107x_gpio_dir_in;
+ ctlr->chip.get = tnetv107x_gpio_get;
+ ctlr->chip.direction_output = tnetv107x_gpio_dir_out;
+ ctlr->chip.set = tnetv107x_gpio_set;
+
+ spin_lock_init(&ctlr->lock);
+
+ ctlr->regs = regs;
+ ctlr->set_data = &regs->data_out[i];
+ ctlr->clr_data = &regs->data_out[i];
+ ctlr->in_data = &regs->data_in[i];
+
+ gpiochip_add(&ctlr->chip);
+ }
+
+ soc_info->gpio_ctlrs = chips;
+ soc_info->gpio_ctlrs_num = DIV_ROUND_UP(ngpio, 32);
+ return 0;
+}
+pure_initcall(tnetv107x_gpio_setup);
diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S
index 3cd93a801d9b..f761dfdb8689 100644
--- a/arch/arm/mach-davinci/include/mach/debug-macro.S
+++ b/arch/arm/mach-davinci/include/mach/debug-macro.S
@@ -17,22 +17,50 @@
*/
#include <linux/serial_reg.h>
+
+#include <asm/memory.h>
+
+#include <mach/serial.h>
+
#define UART_SHIFT 2
+ .pushsection .data
+davinci_uart_phys: .word 0
+davinci_uart_virt: .word 0
+ .popsection
+
.macro addruart, rx, tmp
+
+ /* Use davinci_uart_phys/virt if already configured */
+10: mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =__virt_to_phys(davinci_uart_phys)
+ ldrne \rx, =davinci_uart_virt
+ ldr \rx, [\rx]
+ cmp \rx, #0 @ is port configured?
+ bne 99f @ already configured
+
mrc p15, 0, \rx, c1, c0
tst \rx, #1 @ MMU enabled?
- moveq \rx, #0x01000000 @ physical base address
- movne \rx, #0xfe000000 @ virtual base
-#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx)
-#error Cannot enable DaVinci and DA8XX platforms concurrently
-#elif defined(CONFIG_MACH_DAVINCI_DA830_EVM) || \
- defined(CONFIG_MACH_DAVINCI_DA850_EVM)
- orr \rx, \rx, #0x00d00000 @ physical base address
- orr \rx, \rx, #0x0000d000 @ of UART 2
-#else
- orr \rx, \rx, #0x00c20000 @ UART 0
-#endif
+
+ /* Copy uart phys address from decompressor uart info */
+ ldreq \tmp, =__virt_to_phys(davinci_uart_phys)
+ ldrne \tmp, =davinci_uart_phys
+ ldreq \rx, =DAVINCI_UART_INFO
+ ldrne \rx, =__phys_to_virt(DAVINCI_UART_INFO)
+ ldr \rx, [\rx, #0]
+ str \rx, [\tmp]
+
+ /* Copy uart virt address from decompressor uart info */
+ ldreq \tmp, =__virt_to_phys(davinci_uart_virt)
+ ldrne \tmp, =davinci_uart_virt
+ ldreq \rx, =DAVINCI_UART_INFO
+ ldrne \rx, =__phys_to_virt(DAVINCI_UART_INFO)
+ ldr \rx, [\rx, #4]
+ str \rx, [\tmp]
+
+ b 10b
+99:
.endm
.macro senduart,rd,rx
diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h
index 504cc180a60b..fbece126c2bf 100644
--- a/arch/arm/mach-davinci/include/mach/gpio.h
+++ b/arch/arm/mach-davinci/include/mach/gpio.h
@@ -25,6 +25,7 @@
enum davinci_gpio_type {
GPIO_TYPE_DAVINCI = 0,
+ GPIO_TYPE_TNETV107X,
};
/*
@@ -87,9 +88,13 @@ static inline u32 __gpio_mask(unsigned gpio)
return 1 << (gpio % 32);
}
-/* The get/set/clear functions will inline when called with constant
+/*
+ * The get/set/clear functions will inline when called with constant
* parameters referencing built-in GPIOs, for low-overhead bitbanging.
*
+ * gpio_set_value() will inline only on traditional Davinci style controllers
+ * with distinct set/clear registers.
+ *
* Otherwise, calls with variable parameters or referencing external
* GPIOs (e.g. on GPIO expander chips) use outlined functions.
*/
@@ -100,12 +105,15 @@ static inline void gpio_set_value(unsigned gpio, int value)
u32 mask;
ctlr = __gpio_to_controller(gpio);
- mask = __gpio_mask(gpio);
- if (value)
- __raw_writel(mask, ctlr->set_data);
- else
- __raw_writel(mask, ctlr->clr_data);
- return;
+
+ if (ctlr->set_data != ctlr->clr_data) {
+ mask = __gpio_mask(gpio);
+ if (value)
+ __raw_writel(mask, ctlr->set_data);
+ else
+ __raw_writel(mask, ctlr->clr_data);
+ return;
+ }
}
__gpio_set_value(gpio, value);
diff --git a/arch/arm/mach-davinci/include/mach/memory.h b/arch/arm/mach-davinci/include/mach/memory.h
index a91edfb8beea..22eb97c1c30b 100644
--- a/arch/arm/mach-davinci/include/mach/memory.h
+++ b/arch/arm/mach-davinci/include/mach/memory.h
@@ -48,19 +48,16 @@
* below 128M
*/
static inline void
-__arch_adjust_zones(int node, unsigned long *size, unsigned long *holes)
+__arch_adjust_zones(unsigned long *size, unsigned long *holes)
{
unsigned int sz = (128<<20) >> PAGE_SHIFT;
- if (node != 0)
- sz = 0;
-
size[1] = size[0] - sz;
size[0] = sz;
}
-#define arch_adjust_zones(node, zone_size, holes) \
- if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(node, zone_size, holes)
+#define arch_adjust_zones(zone_size, holes) \
+ if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(zone_size, holes)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + (128<<20) - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + (128<<20))
diff --git a/arch/arm/mach-davinci/include/mach/serial.h b/arch/arm/mach-davinci/include/mach/serial.h
index f6c4f34909a2..8051110b8ac3 100644
--- a/arch/arm/mach-davinci/include/mach/serial.h
+++ b/arch/arm/mach-davinci/include/mach/serial.h
@@ -11,8 +11,19 @@
#ifndef __ASM_ARCH_SERIAL_H
#define __ASM_ARCH_SERIAL_H
+#include <asm/memory.h>
+
#include <mach/hardware.h>
+/*
+ * Stolen area that contains debug uart physical and virtual addresses. These
+ * addresses are filled in by the uncompress.h code, and are used by the debug
+ * macros in debug-macro.S.
+ *
+ * This area sits just below the page tables (see arch/arm/kernel/head.S).
+ */
+#define DAVINCI_UART_INFO (PHYS_OFFSET + 0x3ff8)
+
#define DAVINCI_UART0_BASE (IO_PHYS + 0x20000)
#define DAVINCI_UART1_BASE (IO_PHYS + 0x20400)
#define DAVINCI_UART2_BASE (IO_PHYS + 0x20800)
@@ -21,16 +32,26 @@
#define DA8XX_UART1_BASE (IO_PHYS + 0x10c000)
#define DA8XX_UART2_BASE (IO_PHYS + 0x10d000)
+#define TNETV107X_UART0_BASE 0x08108100
+#define TNETV107X_UART1_BASE 0x08088400
+#define TNETV107X_UART2_BASE 0x08108300
+
+#define TNETV107X_UART0_VIRT IOMEM(0xfee08100)
+#define TNETV107X_UART1_VIRT IOMEM(0xfed88400)
+#define TNETV107X_UART2_VIRT IOMEM(0xfee08300)
+
/* DaVinci UART register offsets */
#define UART_DAVINCI_PWREMU 0x0c
#define UART_DM646X_SCR 0x10
#define UART_DM646X_SCR_TX_WATERMARK 0x08
+#ifndef __ASSEMBLY__
struct davinci_uart_config {
/* Bit field of UARTs present; bit 0 --> UART1 */
unsigned int enabled_uarts;
};
extern int davinci_serial_init(struct davinci_uart_config *);
+#endif
#endif /* __ASM_ARCH_SERIAL_H */
diff --git a/arch/arm/mach-davinci/include/mach/tnetv107x.h b/arch/arm/mach-davinci/include/mach/tnetv107x.h
new file mode 100644
index 000000000000..c72064733123
--- /dev/null
+++ b/arch/arm/mach-davinci/include/mach/tnetv107x.h
@@ -0,0 +1,55 @@
+/*
+ * Texas Instruments TNETV107X SoC Specific Defines
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ASM_ARCH_DAVINCI_TNETV107X_H
+#define __ASM_ARCH_DAVINCI_TNETV107X_H
+
+#include <asm/sizes.h>
+
+#define TNETV107X_DDR_BASE 0x80000000
+
+/*
+ * Fixed mapping for early init starts here. If low-level debug is enabled,
+ * this area also gets mapped via io_pg_offset and io_phys by the boot code.
+ * To fit in with the io_pg_offset calculation, the io base address selected
+ * here _must_ be a multiple of 2^20.
+ */
+#define TNETV107X_IO_BASE 0x08000000
+#define TNETV107X_IO_VIRT (IO_VIRT + SZ_1M)
+
+#define TNETV107X_N_GPIO 65
+
+#ifndef __ASSEMBLY__
+
+#include <linux/serial_8250.h>
+#include <mach/mmc.h>
+#include <mach/nand.h>
+#include <mach/serial.h>
+
+struct tnetv107x_device_info {
+ struct davinci_uart_config *serial_config;
+ struct davinci_mmc_config *mmc_config[2]; /* 2 controllers */
+ struct davinci_nand_pdata *nand_config[4]; /* 4 chipsels */
+};
+
+extern struct platform_device tnetv107x_wdt_device;
+extern struct platform_device tnetv107x_serial_device;
+
+extern void __init tnetv107x_init(void);
+extern void __init tnetv107x_devices_init(struct tnetv107x_device_info *);
+extern void __init tnetv107x_irq_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_DAVINCI_TNETV107X_H */
diff --git a/arch/arm/mach-davinci/include/mach/uncompress.h b/arch/arm/mach-davinci/include/mach/uncompress.h
index 33796b4db17f..15a6192ad6eb 100644
--- a/arch/arm/mach-davinci/include/mach/uncompress.h
+++ b/arch/arm/mach-davinci/include/mach/uncompress.h
@@ -1,8 +1,17 @@
/*
* Serial port stubs for kernel decompress status messages
*
- * Author: Anant Gole
- * (C) Copyright (C) 2006, Texas Instruments, Inc
+ * Initially based on:
+ * arch/arm/plat-omap/include/mach/uncompress.h
+ *
+ * Original copyrights follow.
+ *
+ * Copyright (C) 2000 RidgeRun, Inc.
+ * Author: Greg Lonnon <glonnon@ridgerun.com>
+ *
+ * Rewritten by:
+ * Author: <source@mvista.com>
+ * 2004 (c) MontaVista Software, Inc.
*
* This file is licensed under the terms of the GNU General Public License
* version 2. This program is licensed "as is" without any warranty of any
@@ -11,30 +20,17 @@
#include <linux/types.h>
#include <linux/serial_reg.h>
-#include <mach/serial.h>
#include <asm/mach-types.h>
-extern unsigned int __machine_arch_type;
+#include <mach/serial.h>
static u32 *uart;
-
-static u32 *get_uart_base(void)
-{
- if (__machine_arch_type == MACH_TYPE_DAVINCI_DA830_EVM ||
- __machine_arch_type == MACH_TYPE_DAVINCI_DA850_EVM)
- return (u32 *)DA8XX_UART2_BASE;
- else
- return (u32 *)DAVINCI_UART0_BASE;
-}
+static u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
/* PORT_16C550A, in polled non-fifo mode */
-
static void putc(char c)
{
- if (!uart)
- uart = get_uart_base();
-
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
uart[UART_TX] = c;
@@ -42,12 +38,61 @@ static void putc(char c)
static inline void flush(void)
{
- if (!uart)
- uart = get_uart_base();
-
while (!(uart[UART_LSR] & UART_LSR_THRE))
barrier();
}
-#define arch_decomp_setup()
+static inline void set_uart_info(u32 phys, void * __iomem virt)
+{
+ uart = (u32 *)phys;
+ uart_info[0] = phys;
+ uart_info[1] = (u32)virt;
+}
+
+#define _DEBUG_LL_ENTRY(machine, phys, virt) \
+ if (machine_is_##machine()) { \
+ set_uart_info(phys, virt); \
+ break; \
+ }
+
+#define DEBUG_LL_DAVINCI(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DAVINCI_UART##port##_BASE, \
+ IO_ADDRESS(DAVINCI_UART##port##_BASE))
+
+#define DEBUG_LL_DA8XX(machine, port) \
+ _DEBUG_LL_ENTRY(machine, DA8XX_UART##port##_BASE, \
+ IO_ADDRESS(DA8XX_UART##port##_BASE))
+
+#define DEBUG_LL_TNETV107X(machine, port) \
+ _DEBUG_LL_ENTRY(machine, TNETV107X_UART##port##_BASE, \
+ TNETV107X_UART##port##_VIRT)
+
+static inline void __arch_decomp_setup(unsigned long arch_id)
+{
+ /*
+ * Initialize the port based on the machine ID from the bootloader.
+ * Note that we're using macros here instead of switch statement
+ * as machine_is functions are optimized out for the boards that
+ * are not selected.
+ */
+ do {
+ /* Davinci boards */
+ DEBUG_LL_DAVINCI(davinci_evm, 0);
+ DEBUG_LL_DAVINCI(sffsdr, 0);
+ DEBUG_LL_DAVINCI(neuros_osd2, 0);
+ DEBUG_LL_DAVINCI(davinci_dm355_evm, 0);
+ DEBUG_LL_DAVINCI(dm355_leopard, 0);
+ DEBUG_LL_DAVINCI(davinci_dm6467_evm, 0);
+ DEBUG_LL_DAVINCI(davinci_dm365_evm, 0);
+
+ /* DA8xx boards */
+ DEBUG_LL_DA8XX(davinci_da830_evm, 2);
+ DEBUG_LL_DA8XX(davinci_da850_evm, 2);
+
+ /* TNETV107x boards */
+ DEBUG_LL_TNETV107X(tnetv107x, 1);
+ } while (0);
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
#define arch_decomp_wdog()
diff --git a/arch/arm/mach-davinci/tnetv107x.c b/arch/arm/mach-davinci/tnetv107x.c
new file mode 100644
index 000000000000..864e60482c53
--- /dev/null
+++ b/arch/arm/mach-davinci/tnetv107x.c
@@ -0,0 +1,753 @@
+/*
+ * Texas Instruments TNETV107X SoC Support
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/time.h>
+#include <mach/cputype.h>
+#include <mach/psc.h>
+#include <mach/cp_intc.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/tnetv107x.h>
+
+#include "clock.h"
+#include "mux.h"
+
+/* Base addresses for on-chip devices */
+#define TNETV107X_INTC_BASE 0x03000000
+#define TNETV107X_TIMER0_BASE 0x08086500
+#define TNETV107X_TIMER1_BASE 0x08086600
+#define TNETV107X_CHIP_CFG_BASE 0x08087000
+#define TNETV107X_GPIO_BASE 0x08088000
+#define TNETV107X_CLOCK_CONTROL_BASE 0x0808a000
+#define TNETV107X_PSC_BASE 0x0808b000
+
+/* Reference clock frequencies */
+#define OSC_FREQ_ONCHIP (24000 * 1000)
+#define OSC_FREQ_OFFCHIP_SYS (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_ETH (25000 * 1000)
+#define OSC_FREQ_OFFCHIP_TDM (19200 * 1000)
+
+#define N_PLLS 3
+
+/* Clock Control Registers */
+struct clk_ctrl_regs {
+ u32 pll_bypass;
+ u32 _reserved0;
+ u32 gem_lrst;
+ u32 _reserved1;
+ u32 pll_unlock_stat;
+ u32 sys_unlock;
+ u32 eth_unlock;
+ u32 tdm_unlock;
+};
+
+/* SSPLL Registers */
+struct sspll_regs {
+ u32 modes;
+ u32 post_div;
+ u32 pre_div;
+ u32 mult_factor;
+ u32 divider_range;
+ u32 bw_divider;
+ u32 spr_amount;
+ u32 spr_rate_div;
+ u32 diag;
+};
+
+/* Watchdog Timer Registers */
+struct wdt_regs {
+ u32 kick_lock;
+ u32 kick;
+ u32 change_lock;
+ u32 change ;
+ u32 disable_lock;
+ u32 disable;
+ u32 prescale_lock;
+ u32 prescale;
+};
+
+static struct clk_ctrl_regs __iomem *clk_ctrl_regs;
+
+static struct sspll_regs __iomem *sspll_regs[N_PLLS];
+static int sspll_regs_base[N_PLLS] = { 0x40, 0x80, 0xc0 };
+
+/* PLL bypass bit shifts in clk_ctrl_regs->pll_bypass register */
+static u32 bypass_mask[N_PLLS] = { BIT(0), BIT(2), BIT(1) };
+
+/* offchip (external) reference clock frequencies */
+static u32 pll_ext_freq[] = {
+ OSC_FREQ_OFFCHIP_SYS,
+ OSC_FREQ_OFFCHIP_TDM,
+ OSC_FREQ_OFFCHIP_ETH
+};
+
+/* PSC control registers */
+static u32 psc_regs[] __initconst = { TNETV107X_PSC_BASE };
+
+/* Host map for interrupt controller */
+static u32 intc_host_map[] = { 0x01010000, 0x01010101, -1 };
+
+static unsigned long clk_sspll_recalc(struct clk *clk);
+
+/* Level 1 - the PLLs */
+#define define_pll_clk(cname, pll, divmask, base) \
+ static struct pll_data pll_##cname##_data = { \
+ .num = pll, \
+ .div_ratio_mask = divmask, \
+ .phys_base = base + \
+ TNETV107X_CLOCK_CONTROL_BASE, \
+ }; \
+ static struct clk pll_##cname##_clk = { \
+ .name = "pll_" #cname "_clk", \
+ .pll_data = &pll_##cname##_data, \
+ .flags = CLK_PLL, \
+ .recalc = clk_sspll_recalc, \
+ }
+
+define_pll_clk(sys, 0, 0x1ff, 0x600);
+define_pll_clk(tdm, 1, 0x0ff, 0x200);
+define_pll_clk(eth, 2, 0x0ff, 0x400);
+
+/* Level 2 - divided outputs from the PLLs */
+#define define_pll_div_clk(pll, cname, div) \
+ static struct clk pll##_##cname##_clk = { \
+ .name = #pll "_" #cname "_clk",\
+ .parent = &pll_##pll##_clk, \
+ .flags = CLK_PLL, \
+ .div_reg = PLLDIV##div, \
+ }
+
+define_pll_div_clk(sys, arm1176, 1);
+define_pll_div_clk(sys, dsp, 2);
+define_pll_div_clk(sys, ddr, 3);
+define_pll_div_clk(sys, full, 4);
+define_pll_div_clk(sys, lcd, 5);
+define_pll_div_clk(sys, vlynq_ref, 6);
+define_pll_div_clk(sys, tsc, 7);
+define_pll_div_clk(sys, half, 8);
+
+define_pll_div_clk(eth, 5mhz, 1);
+define_pll_div_clk(eth, 50mhz, 2);
+define_pll_div_clk(eth, 125mhz, 3);
+define_pll_div_clk(eth, 250mhz, 4);
+define_pll_div_clk(eth, 25mhz, 5);
+
+define_pll_div_clk(tdm, 0, 1);
+define_pll_div_clk(tdm, extra, 2);
+define_pll_div_clk(tdm, 1, 3);
+
+
+/* Level 3 - LPSC gated clocks */
+#define __lpsc_clk(cname, _parent, mod, flg) \
+ static struct clk clk_##cname = { \
+ .name = #cname, \
+ .parent = &_parent, \
+ .lpsc = TNETV107X_LPSC_##mod,\
+ .flags = flg, \
+ }
+
+#define lpsc_clk_enabled(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, ALWAYS_ENABLED)
+
+#define lpsc_clk(cname, parent, mod) \
+ __lpsc_clk(cname, parent, mod, 0)
+
+lpsc_clk_enabled(arm, sys_arm1176_clk, ARM);
+lpsc_clk_enabled(gem, sys_dsp_clk, GEM);
+lpsc_clk_enabled(ddr2_phy, sys_ddr_clk, DDR2_PHY);
+lpsc_clk_enabled(tpcc, sys_full_clk, TPCC);
+lpsc_clk_enabled(tptc0, sys_full_clk, TPTC0);
+lpsc_clk_enabled(tptc1, sys_full_clk, TPTC1);
+lpsc_clk_enabled(ram, sys_full_clk, RAM);
+lpsc_clk_enabled(aemif, sys_full_clk, AEMIF);
+lpsc_clk_enabled(chipcfg, sys_half_clk, CHIP_CFG);
+lpsc_clk_enabled(rom, sys_half_clk, ROM);
+lpsc_clk_enabled(secctl, sys_half_clk, SECCTL);
+lpsc_clk_enabled(keymgr, sys_half_clk, KEYMGR);
+lpsc_clk_enabled(gpio, sys_half_clk, GPIO);
+lpsc_clk_enabled(debugss, sys_half_clk, DEBUGSS);
+lpsc_clk_enabled(system, sys_half_clk, SYSTEM);
+lpsc_clk_enabled(ddr2_vrst, sys_ddr_clk, DDR2_EMIF1_VRST);
+lpsc_clk_enabled(ddr2_vctl_rst, sys_ddr_clk, DDR2_EMIF2_VCTL_RST);
+lpsc_clk_enabled(wdt_arm, sys_half_clk, WDT_ARM);
+
+lpsc_clk(mbx_lite, sys_arm1176_clk, MBX_LITE);
+lpsc_clk(ethss, eth_125mhz_clk, ETHSS);
+lpsc_clk(tsc, sys_tsc_clk, TSC);
+lpsc_clk(uart0, sys_half_clk, UART0);
+lpsc_clk(uart1, sys_half_clk, UART1);
+lpsc_clk(uart2, sys_half_clk, UART2);
+lpsc_clk(pktsec, sys_half_clk, PKTSEC);
+lpsc_clk(keypad, sys_half_clk, KEYPAD);
+lpsc_clk(mdio, sys_half_clk, MDIO);
+lpsc_clk(sdio0, sys_half_clk, SDIO0);
+lpsc_clk(sdio1, sys_half_clk, SDIO1);
+lpsc_clk(timer0, sys_half_clk, TIMER0);
+lpsc_clk(timer1, sys_half_clk, TIMER1);
+lpsc_clk(wdt_dsp, sys_half_clk, WDT_DSP);
+lpsc_clk(ssp, sys_half_clk, SSP);
+lpsc_clk(tdm0, tdm_0_clk, TDM0);
+lpsc_clk(tdm1, tdm_1_clk, TDM1);
+lpsc_clk(vlynq, sys_vlynq_ref_clk, VLYNQ);
+lpsc_clk(mcdma, sys_half_clk, MCDMA);
+lpsc_clk(usb0, sys_half_clk, USB0);
+lpsc_clk(usb1, sys_half_clk, USB1);
+lpsc_clk(usbss, sys_half_clk, USBSS);
+lpsc_clk(ethss_rgmii, eth_250mhz_clk, ETHSS_RGMII);
+lpsc_clk(imcop, sys_dsp_clk, IMCOP);
+lpsc_clk(spare, sys_half_clk, SPARE);
+
+/* LCD needs a full power down to clear controller state */
+__lpsc_clk(lcd, sys_lcd_clk, LCD, PSC_SWRSTDISABLE);
+
+
+/* Level 4 - leaf clocks for LPSC modules shared across drivers */
+static struct clk clk_rng = { .name = "rng", .parent = &clk_pktsec };
+static struct clk clk_pka = { .name = "pka", .parent = &clk_pktsec };
+
+static struct clk_lookup clks[] = {
+ CLK(NULL, "pll_sys_clk", &pll_sys_clk),
+ CLK(NULL, "pll_eth_clk", &pll_eth_clk),
+ CLK(NULL, "pll_tdm_clk", &pll_tdm_clk),
+ CLK(NULL, "sys_arm1176_clk", &sys_arm1176_clk),
+ CLK(NULL, "sys_dsp_clk", &sys_dsp_clk),
+ CLK(NULL, "sys_ddr_clk", &sys_ddr_clk),
+ CLK(NULL, "sys_full_clk", &sys_full_clk),
+ CLK(NULL, "sys_lcd_clk", &sys_lcd_clk),
+ CLK(NULL, "sys_vlynq_ref_clk", &sys_vlynq_ref_clk),
+ CLK(NULL, "sys_tsc_clk", &sys_tsc_clk),
+ CLK(NULL, "sys_half_clk", &sys_half_clk),
+ CLK(NULL, "eth_5mhz_clk", &eth_5mhz_clk),
+ CLK(NULL, "eth_50mhz_clk", &eth_50mhz_clk),
+ CLK(NULL, "eth_125mhz_clk", &eth_125mhz_clk),
+ CLK(NULL, "eth_250mhz_clk", &eth_250mhz_clk),
+ CLK(NULL, "eth_25mhz_clk", &eth_25mhz_clk),
+ CLK(NULL, "tdm_0_clk", &tdm_0_clk),
+ CLK(NULL, "tdm_extra_clk", &tdm_extra_clk),
+ CLK(NULL, "tdm_1_clk", &tdm_1_clk),
+ CLK(NULL, "clk_arm", &clk_arm),
+ CLK(NULL, "clk_gem", &clk_gem),
+ CLK(NULL, "clk_ddr2_phy", &clk_ddr2_phy),
+ CLK(NULL, "clk_tpcc", &clk_tpcc),
+ CLK(NULL, "clk_tptc0", &clk_tptc0),
+ CLK(NULL, "clk_tptc1", &clk_tptc1),
+ CLK(NULL, "clk_ram", &clk_ram),
+ CLK(NULL, "clk_mbx_lite", &clk_mbx_lite),
+ CLK("tnetv107x-fb.0", NULL, &clk_lcd),
+ CLK(NULL, "clk_ethss", &clk_ethss),
+ CLK(NULL, "aemif", &clk_aemif),
+ CLK(NULL, "clk_chipcfg", &clk_chipcfg),
+ CLK("tnetv107x-ts.0", NULL, &clk_tsc),
+ CLK(NULL, "clk_rom", &clk_rom),
+ CLK(NULL, "uart2", &clk_uart2),
+ CLK(NULL, "clk_pktsec", &clk_pktsec),
+ CLK("tnetv107x-rng.0", NULL, &clk_rng),
+ CLK("tnetv107x-pka.0", NULL, &clk_pka),
+ CLK(NULL, "clk_secctl", &clk_secctl),
+ CLK(NULL, "clk_keymgr", &clk_keymgr),
+ CLK("tnetv107x-keypad.0", NULL, &clk_keypad),
+ CLK(NULL, "clk_gpio", &clk_gpio),
+ CLK(NULL, "clk_mdio", &clk_mdio),
+ CLK("davinci_mmc.0", NULL, &clk_sdio0),
+ CLK(NULL, "uart0", &clk_uart0),
+ CLK(NULL, "uart1", &clk_uart1),
+ CLK(NULL, "timer0", &clk_timer0),
+ CLK(NULL, "timer1", &clk_timer1),
+ CLK("tnetv107x_wdt.0", NULL, &clk_wdt_arm),
+ CLK(NULL, "clk_wdt_dsp", &clk_wdt_dsp),
+ CLK("ti-ssp.0", NULL, &clk_ssp),
+ CLK(NULL, "clk_tdm0", &clk_tdm0),
+ CLK(NULL, "clk_vlynq", &clk_vlynq),
+ CLK(NULL, "clk_mcdma", &clk_mcdma),
+ CLK(NULL, "clk_usb0", &clk_usb0),
+ CLK(NULL, "clk_tdm1", &clk_tdm1),
+ CLK(NULL, "clk_debugss", &clk_debugss),
+ CLK(NULL, "clk_ethss_rgmii", &clk_ethss_rgmii),
+ CLK(NULL, "clk_system", &clk_system),
+ CLK(NULL, "clk_imcop", &clk_imcop),
+ CLK(NULL, "clk_spare", &clk_spare),
+ CLK("davinci_mmc.1", NULL, &clk_sdio1),
+ CLK(NULL, "clk_usb1", &clk_usb1),
+ CLK(NULL, "clk_usbss", &clk_usbss),
+ CLK(NULL, "clk_ddr2_vrst", &clk_ddr2_vrst),
+ CLK(NULL, "clk_ddr2_vctl_rst", &clk_ddr2_vctl_rst),
+ CLK(NULL, NULL, NULL),
+};
+
+static const struct mux_config pins[] = {
+#ifdef CONFIG_DAVINCI_MUX
+ MUX_CFG(TNETV107X, ASR_A00, 0, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO32, 0, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A01, 0, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO33, 0, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A02, 0, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO34, 0, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A03, 0, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO35, 0, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A04, 0, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO36, 0, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A05, 0, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO37, 0, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A06, 1, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO38, 1, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A07, 1, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO39, 1, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A08, 1, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO40, 1, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A09, 1, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO41, 1, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A10, 1, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO42, 1, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A11, 1, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_0, 1, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A12, 2, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_1, 2, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A13, 2, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO43, 2, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A14, 2, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO44, 2, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A15, 2, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO45, 2, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A16, 2, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO46, 2, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A17, 2, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO47, 2, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_A18, 3, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO48, 3, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_0, 3, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A19, 3, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO49, 3, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_0, 3, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A20, 3, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO50, 3, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_0, 3, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A21, 3, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO51, 3, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_0, 3, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A22, 3, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO52, 3, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_0, 3, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_A23, 3, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO53, 3, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_0, 3, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_BA_1, 4, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO54, 4, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SYS_PLL_CLK, 4, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS0, 4, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS1, 4, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_CS2, 4, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM_PLL_CLK, 4, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_CS3, 4, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ETH_PHY_CLK, 4, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ASR_D00, 4, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO55, 4, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D01, 5, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO56, 5, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D02, 5, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO57, 5, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D03, 5, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO58, 5, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D04, 5, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_0, 5, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D05, 5, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_0, 5, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D06, 5, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO61_0, 5, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D07, 6, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_0, 6, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D08, 6, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_0, 6, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D09, 6, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_0, 6, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D10, 6, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA3_1, 6, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D11, 6, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA2_1, 6, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D12, 6, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA1_1, 6, 25, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D13, 7, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_DATA0_1, 7, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D14, 7, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CMD_1, 7, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_D15, 7, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SDIO1_CLK_1, 7, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_OE, 7, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_2, 7, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_RNW, 7, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_0, 7, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WAIT, 7, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_0, 7, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE, 8, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, BOOT_STRP_3, 8, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM0, 8, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO31, 8, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD17_0, 8, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, ASR_WE_DQM1, 8, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_0, 8, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, VLYNQ_CLK, 9, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO14, 9, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD19_0, 9, 0, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD0, 9, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO15, 9, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_0, 9, 5, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_RXD1, 9, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO16, 9, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_0, 9, 10, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD0, 9, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO17, 9, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_0, 9, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, VLYNQ_TXD1, 9, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO18, 9, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_0, 9, 20, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, SDIO0_CLK, 10, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO19, 10, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_CMD, 10, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO20, 10, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA0, 10, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO21, 10, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA1, 10, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO22, 10, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA2, 10, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO23, 10, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SDIO0_DATA3, 10, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO24, 10, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EMU0, 11, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, EMU1, 11, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, RTCK, 12, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TRST_N, 12, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TCK, 12, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDI, 12, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDO, 12, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TMS, 12, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_CLK, 13, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_RX, 13, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_TX, 13, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM1_FS, 13, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R0, 14, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R1, 14, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R2, 14, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R3, 14, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R4, 14, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R5, 14, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_R6, 15, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO12, 15, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_R7, 15, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO10, 15, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, KEYPAD_C0, 15, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C1, 15, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C2, 15, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C3, 15, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C4, 16, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C5, 16, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, KEYPAD_C6, 16, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO13, 16, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TEST_CLK_IN, 16, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, KEYPAD_C7, 16, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO11, 16, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, SSP0_0, 17, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_DCLK, 17, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD20_1, 17, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_1, 17, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_CS_N, 17, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD21_1, 17, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_2, 17, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_D, 17, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD22_1, 17, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP0_3, 17, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, SCC_RESETN, 17, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, LCD_PD23_1, 17, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_0, 18, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO25, 18, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_CTS, 18, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_1, 18, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO26, 18, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RD, 18, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_2, 18, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO27, 18, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_RTS, 18, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, SSP1_3, 18, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO28, 18, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, UART2_TD, 18, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, UART0_CTS, 19, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RD, 19, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_RTS, 19, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART0_TD, 19, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_RD, 19, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, UART1_TD, 19, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_AC_NCS, 20, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_HSYNC_RNW, 20, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_VSYNC_A0, 20, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_MCLK, 20, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_0, 20, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PCLK_E, 20, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD00, 20, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD01, 21, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD02, 21, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD03, 21, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD04, 21, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD05, 21, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD06, 21, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD07, 22, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD08, 22, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO59_1, 22, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD09, 22, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO60_1, 22, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD10, 22, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, ASR_BA0_1, 22, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO61_1, 22, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD11, 22, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO62_1, 22, 20, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD12, 22, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO63_1, 22, 25, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD13, 23, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO64_1, 23, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD14, 23, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO29_1, 23, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, LCD_PD15, 23, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO30_1, 23, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, EINT0, 24, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO08, 24, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, EINT1, 24, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, GPIO09, 24, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO00, 24, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD20_2, 24, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_2, 24, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO01, 24, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD21_2, 24, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_1, 24, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO02, 24, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD22_2, 24, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO03, 24, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD23_2, 24, 25, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, GPIO04, 25, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD16_1, 25, 0, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB0_RXERR, 25, 0, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO05, 25, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD17_1, 25, 5, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, TDM_CLK_IN_1, 25, 5, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO06, 25, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD18, 25, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, 24M_CLK_OUT_2, 25, 10, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, GPIO07, 25, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, LCD_PD19_1, 25, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, USB1_RXERR, 25, 15, 0x1f, 0x0c, false)
+ MUX_CFG(TNETV107X, ETH_PLL_CLK, 25, 15, 0x1f, 0x1c, false)
+ MUX_CFG(TNETV107X, MDIO, 26, 0, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, MDC, 26, 5, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, AIC_MUTE_STAT_N, 26, 10, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_CLK, 26, 10, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNS_EN_N, 26, 15, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_FS, 26, 15, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HDS_EN_STAT_N, 26, 20, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_TX, 26, 20, 0x1f, 0x04, false)
+ MUX_CFG(TNETV107X, AIC_HNF_EN_STAT_N, 26, 25, 0x1f, 0x00, false)
+ MUX_CFG(TNETV107X, TDM0_RX, 26, 25, 0x1f, 0x04, false)
+#endif
+};
+
+/* FIQ are pri 0-1; otherwise 2-7, with 7 lowest priority */
+static u8 irq_prios[TNETV107X_N_CP_INTC_IRQ] = {
+ /* fill in default priority 7 */
+ [0 ... (TNETV107X_N_CP_INTC_IRQ - 1)] = 7,
+ /* now override as needed, e.g. [xxx] = 5 */
+};
+
+/* Contents of JTAG ID register used to identify exact cpu type */
+static struct davinci_id ids[] = {
+ {
+ .variant = 0x0,
+ .part_no = 0xb8a1,
+ .manufacturer = 0x017,
+ .cpu_id = DAVINCI_CPU_ID_TNETV107X,
+ .name = "tnetv107x rev1.0",
+ },
+};
+
+static struct davinci_timer_instance timer_instance[2] = {
+ {
+ .base = TNETV107X_TIMER0_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_0_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_0_TINT34,
+ },
+ {
+ .base = TNETV107X_TIMER1_BASE,
+ .bottom_irq = IRQ_TNETV107X_TIMER_1_TINT12,
+ .top_irq = IRQ_TNETV107X_TIMER_1_TINT34,
+ },
+};
+
+static struct davinci_timer_info timer_info = {
+ .timers = timer_instance,
+ .clockevent_id = T0_BOT,
+ .clocksource_id = T0_TOP,
+};
+
+/*
+ * TNETV107X platforms do not use the static mappings from Davinci
+ * IO_PHYS/IO_VIRT. This SOC's interesting MMRs are at different addresses,
+ * and changing IO_PHYS would break away from existing Davinci SOCs.
+ *
+ * The primary impact of the current model is that IO_ADDRESS() is not to be
+ * used to map registers on TNETV107X.
+ *
+ * 1. The first chunk is for INTC: This needs to be mapped in via iotable
+ * because ioremap() does not seem to be operational at the time when
+ * irqs are initialized. Without this, consistent dma init bombs.
+ *
+ * 2. The second chunk maps in register areas that need to be populated into
+ * davinci_soc_info. Note that alignment restrictions come into play if
+ * low-level debug is enabled (see note in <mach/tnetv107x.h>).
+ */
+static struct map_desc io_desc[] = {
+ { /* INTC */
+ .virtual = IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_INTC_BASE),
+ .length = SZ_16K,
+ .type = MT_DEVICE
+ },
+ { /* Most of the rest */
+ .virtual = TNETV107X_IO_VIRT,
+ .pfn = __phys_to_pfn(TNETV107X_IO_BASE),
+ .length = IO_SIZE - SZ_1M,
+ .type = MT_DEVICE
+ },
+};
+
+static unsigned long clk_sspll_recalc(struct clk *clk)
+{
+ int pll;
+ unsigned long mult = 0, prediv = 1, postdiv = 1;
+ unsigned long ref = OSC_FREQ_ONCHIP, ret;
+ u32 tmp;
+
+ if (WARN_ON(!clk->pll_data))
+ return clk->rate;
+
+ if (!clk_ctrl_regs) {
+ void __iomem *tmp;
+
+ tmp = ioremap(TNETV107X_CLOCK_CONTROL_BASE, SZ_4K);
+
+ if (WARN(!tmp, "failed ioremap for clock control regs\n"))
+ return clk->parent ? clk->parent->rate : 0;
+
+ for (pll = 0; pll < N_PLLS; pll++)
+ sspll_regs[pll] = tmp + sspll_regs_base[pll];
+
+ clk_ctrl_regs = tmp;
+ }
+
+ pll = clk->pll_data->num;
+
+ tmp = __raw_readl(&clk_ctrl_regs->pll_bypass);
+ if (!(tmp & bypass_mask[pll])) {
+ mult = __raw_readl(&sspll_regs[pll]->mult_factor);
+ prediv = __raw_readl(&sspll_regs[pll]->pre_div) + 1;
+ postdiv = __raw_readl(&sspll_regs[pll]->post_div) + 1;
+ }
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (tmp & PLLCTL_CLKMODE)
+ ref = pll_ext_freq[pll];
+
+ clk->pll_data->input_rate = ref;
+
+ tmp = __raw_readl(clk->pll_data->base + PLLCTL);
+ if (!(tmp & PLLCTL_PLLEN))
+ return ref;
+
+ ret = ref;
+ if (mult)
+ ret += ((unsigned long long)ref * mult) / 256;
+
+ ret /= (prediv * postdiv);
+
+ return ret;
+}
+
+static void tnetv107x_watchdog_reset(struct platform_device *pdev)
+{
+ struct wdt_regs __iomem *regs;
+
+ regs = ioremap(pdev->resource[0].start, SZ_4K);
+
+ /* disable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(0, &regs->disable);
+
+ /* program prescale */
+ __raw_writel(0x5a5a, &regs->prescale_lock);
+ __raw_writel(0xa5a5, &regs->prescale_lock);
+ __raw_writel(0, &regs->prescale);
+
+ /* program countdown */
+ __raw_writel(0x6666, &regs->change_lock);
+ __raw_writel(0xbbbb, &regs->change_lock);
+ __raw_writel(1, &regs->change);
+
+ /* enable watchdog */
+ __raw_writel(0x7777, &regs->disable_lock);
+ __raw_writel(0xcccc, &regs->disable_lock);
+ __raw_writel(0xdddd, &regs->disable_lock);
+ __raw_writel(1, &regs->disable);
+
+ /* kick */
+ __raw_writel(0x5555, &regs->kick_lock);
+ __raw_writel(0xaaaa, &regs->kick_lock);
+ __raw_writel(1, &regs->kick);
+}
+
+static struct davinci_soc_info tnetv107x_soc_info = {
+ .io_desc = io_desc,
+ .io_desc_num = ARRAY_SIZE(io_desc),
+ .ids = ids,
+ .ids_num = ARRAY_SIZE(ids),
+ .jtag_id_reg = TNETV107X_CHIP_CFG_BASE + 0x018,
+ .cpu_clks = clks,
+ .psc_bases = psc_regs,
+ .psc_bases_num = ARRAY_SIZE(psc_regs),
+ .pinmux_base = TNETV107X_CHIP_CFG_BASE + 0x150,
+ .pinmux_pins = pins,
+ .pinmux_pins_num = ARRAY_SIZE(pins),
+ .intc_type = DAVINCI_INTC_TYPE_CP_INTC,
+ .intc_base = TNETV107X_INTC_BASE,
+ .intc_irq_prios = irq_prios,
+ .intc_irq_num = TNETV107X_N_CP_INTC_IRQ,
+ .intc_host_map = intc_host_map,
+ .gpio_base = TNETV107X_GPIO_BASE,
+ .gpio_type = GPIO_TYPE_TNETV107X,
+ .gpio_num = TNETV107X_N_GPIO,
+ .timer_info = &timer_info,
+ .serial_dev = &tnetv107x_serial_device,
+ .reset = tnetv107x_watchdog_reset,
+ .reset_device = &tnetv107x_wdt_device,
+};
+
+void __init tnetv107x_init(void)
+{
+ davinci_common_init(&tnetv107x_soc_info);
+}
diff --git a/arch/arm/mach-ep93xx/adssphere.c b/arch/arm/mach-ep93xx/adssphere.c
index 3a1a855bfdca..f744f676783f 100644
--- a/arch/arm/mach-ep93xx/adssphere.c
+++ b/arch/arm/mach-ep93xx/adssphere.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <mach/hardware.h>
@@ -21,26 +20,6 @@
#include <asm/mach/arch.h>
-static struct physmap_flash_data adssphere_flash_data = {
- .width = 4,
-};
-
-static struct resource adssphere_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_32M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device adssphere_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &adssphere_flash_data,
- },
- .num_resources = 1,
- .resource = &adssphere_flash_resource,
-};
-
static struct ep93xx_eth_data __initdata adssphere_eth_data = {
.phy_id = 1,
};
@@ -48,8 +27,7 @@ static struct ep93xx_eth_data __initdata adssphere_eth_data = {
static void __init adssphere_init_machine(void)
{
ep93xx_init_devices();
- platform_device_register(&adssphere_flash);
-
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
ep93xx_register_eth(&adssphere_eth_data, 1);
}
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 9092677f63eb..8e37a045188c 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -29,6 +29,7 @@
#include <linux/termios.h>
#include <linux/amba/bus.h>
#include <linux/amba/serial.h>
+#include <linux/mtd/physmap.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/spi/spi.h>
@@ -215,8 +216,8 @@ void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
spin_lock_irqsave(&syscon_swlock, flags);
val = __raw_readl(EP93XX_SYSCON_DEVCFG);
- val |= set_bits;
val &= ~clear_bits;
+ val |= set_bits;
__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
__raw_writel(val, EP93XX_SYSCON_DEVCFG);
@@ -348,6 +349,43 @@ static struct platform_device ep93xx_ohci_device = {
/*************************************************************************
+ * EP93xx physmap'ed flash
+ *************************************************************************/
+static struct physmap_flash_data ep93xx_flash_data;
+
+static struct resource ep93xx_flash_resource = {
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device ep93xx_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &ep93xx_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ep93xx_flash_resource,
+};
+
+/**
+ * ep93xx_register_flash() - Register the external flash device.
+ * @width: bank width in octets
+ * @start: resource start address
+ * @size: resource size
+ */
+void __init ep93xx_register_flash(unsigned int width,
+ resource_size_t start, resource_size_t size)
+{
+ ep93xx_flash_data.width = width;
+
+ ep93xx_flash_resource.start = start;
+ ep93xx_flash_resource.end = start + size - 1;
+
+ platform_device_register(&ep93xx_flash);
+}
+
+
+/*************************************************************************
* EP93xx ethernet peripheral handling
*************************************************************************/
static struct ep93xx_eth_data ep93xx_eth_data;
@@ -620,6 +658,11 @@ static struct platform_device ep93xx_fb_device = {
.resource = ep93xx_fb_resource,
};
+static struct platform_device ep93xx_bl_device = {
+ .name = "ep93xx-bl",
+ .id = -1,
+};
+
/**
* ep93xx_register_fb - Register the framebuffer platform device.
* @data: platform specific framebuffer configuration (__initdata)
@@ -628,6 +671,7 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data)
{
ep93xxfb_data = *data;
platform_device_register(&ep93xx_fb_device);
+ platform_device_register(&ep93xx_bl_device);
}
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 3884182cd362..c2ce9034ba87 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -27,7 +27,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
@@ -38,39 +37,13 @@
#include <asm/mach/arch.h>
-static struct physmap_flash_data edb93xx_flash_data;
-
-static struct resource edb93xx_flash_resource = {
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device edb93xx_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &edb93xx_flash_data,
- },
- .num_resources = 1,
- .resource = &edb93xx_flash_resource,
-};
-
-static void __init __edb93xx_register_flash(unsigned int width,
- resource_size_t start, resource_size_t size)
-{
- edb93xx_flash_data.width = width;
- edb93xx_flash_resource.start = start;
- edb93xx_flash_resource.end = start + size - 1;
-
- platform_device_register(&edb93xx_flash);
-}
-
static void __init edb93xx_register_flash(void)
{
if (machine_is_edb9307() || machine_is_edb9312() ||
machine_is_edb9315()) {
- __edb93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_32M);
} else {
- __edb93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
}
}
diff --git a/arch/arm/mach-ep93xx/gesbc9312.c b/arch/arm/mach-ep93xx/gesbc9312.c
index a809618e9f05..d97168c0ba33 100644
--- a/arch/arm/mach-ep93xx/gesbc9312.c
+++ b/arch/arm/mach-ep93xx/gesbc9312.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <mach/hardware.h>
@@ -21,26 +20,6 @@
#include <asm/mach/arch.h>
-static struct physmap_flash_data gesbc9312_flash_data = {
- .width = 4,
-};
-
-static struct resource gesbc9312_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device gesbc9312_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &gesbc9312_flash_data,
- },
- .num_resources = 1,
- .resource = &gesbc9312_flash_resource,
-};
-
static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
.phy_id = 1,
};
@@ -48,8 +27,7 @@ static struct ep93xx_eth_data __initdata gesbc9312_eth_data = {
static void __init gesbc9312_init_machine(void)
{
ep93xx_init_devices();
- platform_device_register(&gesbc9312_flash);
-
+ ep93xx_register_flash(4, EP93XX_CS6_PHYS_BASE, SZ_8M);
ep93xx_register_eth(&gesbc9312_eth_data, 0);
}
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 9a4413dd44bb..a6c09176334c 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -43,6 +43,9 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
unsigned int ep93xx_chip_revision(void);
+void ep93xx_register_flash(unsigned int width,
+ resource_size_t start, resource_size_t size);
+
void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
void ep93xx_register_i2c(struct i2c_gpio_platform_data *data,
struct i2c_board_info *devices, int num);
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
index 1cc911b4efa6..2ba776320a82 100644
--- a/arch/arm/mach-ep93xx/micro9.c
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -14,7 +14,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -31,31 +30,6 @@
* Micro9-Lite uses a separate MTD map driver for flash support
* Micro9-Slim has up to 64MB of either 32-bit or 16-bit flash on CS1
*************************************************************************/
-static struct physmap_flash_data micro9_flash_data;
-
-static struct resource micro9_flash_resource = {
- .start = EP93XX_CS1_PHYS_BASE,
- .end = EP93XX_CS1_PHYS_BASE + SZ_64M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device micro9_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &micro9_flash_data,
- },
- .num_resources = 1,
- .resource = &micro9_flash_resource,
-};
-
-static void __init __micro9_register_flash(unsigned int width)
-{
- micro9_flash_data.width = width;
-
- platform_device_register(&micro9_flash);
-}
-
static unsigned int __init micro9_detect_bootwidth(void)
{
u32 v;
@@ -70,10 +44,17 @@ static unsigned int __init micro9_detect_bootwidth(void)
static void __init micro9_register_flash(void)
{
+ unsigned int width;
+
if (machine_is_micro9())
- __micro9_register_flash(4);
+ width = 4;
else if (machine_is_micro9m() || machine_is_micro9s())
- __micro9_register_flash(micro9_detect_bootwidth());
+ width = micro9_detect_bootwidth();
+ else
+ width = 0;
+
+ if (width)
+ ep93xx_register_flash(width, EP93XX_CS1_PHYS_BASE, SZ_64M);
}
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c
index 388aec95f60e..5dded5884133 100644
--- a/arch/arm/mach-ep93xx/simone.c
+++ b/arch/arm/mach-ep93xx/simone.c
@@ -18,7 +18,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
@@ -29,26 +28,6 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-static struct physmap_flash_data simone_flash_data = {
- .width = 2,
-};
-
-static struct resource simone_flash_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_8M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device simone_flash = {
- .name = "physmap-flash",
- .id = 0,
- .num_resources = 1,
- .resource = &simone_flash_resource,
- .dev = {
- .platform_data = &simone_flash_data,
- },
-};
-
static struct ep93xx_eth_data __initdata simone_eth_data = {
.phy_id = 1,
};
@@ -77,8 +56,7 @@ static struct i2c_board_info __initdata simone_i2c_board_info[] = {
static void __init simone_init_machine(void)
{
ep93xx_init_devices();
-
- platform_device_register(&simone_flash);
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_8M);
ep93xx_register_eth(&simone_eth_data, 1);
ep93xx_register_fb(&simone_fb_info);
ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info,
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c
index ae7319e588c7..93aeab8af705 100644
--- a/arch/arm/mach-ep93xx/ts72xx.c
+++ b/arch/arm/mach-ep93xx/ts72xx.c
@@ -17,7 +17,6 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/m48t86.h>
-#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
@@ -173,31 +172,13 @@ static struct platform_device ts72xx_nand_flash = {
};
-/*************************************************************************
- * NOR flash (TS-7200 only)
- *************************************************************************/
-static struct physmap_flash_data ts72xx_nor_data = {
- .width = 2,
-};
-
-static struct resource ts72xx_nor_resource = {
- .start = EP93XX_CS6_PHYS_BASE,
- .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device ts72xx_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev.platform_data = &ts72xx_nor_data,
- .resource = &ts72xx_nor_resource,
- .num_resources = 1,
-};
-
static void __init ts72xx_register_flash(void)
{
+ /*
+ * TS7200 has NOR flash all other TS72xx board have NAND flash.
+ */
if (board_is_ts7200()) {
- platform_device_register(&ts72xx_nor_flash);
+ ep93xx_register_flash(2, EP93XX_CS6_PHYS_BASE, SZ_16M);
} else {
resource_size_t start;
diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-imx/Kconfig
index 742fd4e6dcb9..c5c0369bb481 100644
--- a/arch/arm/mach-mx2/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -1,42 +1,103 @@
+config IMX_HAVE_DMA_V1
+ bool
+
+if ARCH_MX1
+
+config SOC_IMX1
+ select CPU_ARM920T
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ bool
+
+comment "MX1 platforms:"
+config MACH_MXLADS
+ bool
+
+config ARCH_MX1ADS
+ bool "MX1ADS platform"
+ select MACH_MXLADS
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Say Y here if you are using Motorola MX1ADS/MXLADS boards
+
+config MACH_SCB9328
+ bool "Synertronixx scb9328"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ help
+ Say Y here if you are using a Synertronixx scb9328 board
+
+endif
+
if ARCH_MX2
+config SOC_IMX21
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ bool
+
+config SOC_IMX27
+ select CPU_ARM926T
+ select ARCH_MXC_AUDMUX_V1
+ select IMX_HAVE_DMA_V1
+ select IMX_HAVE_IOMUX_V1
+ bool
+
choice
prompt "CPUs:"
default MACH_MX21
config MACH_MX21
bool "i.MX21 support"
- select ARCH_MXC_AUDMUX_V1
+ select SOC_IMX21
help
This enables support for Freescale's MX2 based i.MX21 processor.
config MACH_MX27
bool "i.MX27 support"
- select ARCH_MXC_AUDMUX_V1
+ select SOC_IMX27
help
This enables support for Freescale's MX2 based i.MX27 processor.
endchoice
-comment "MX2 platforms:"
+endif
+
+if MACH_MX21
+
+comment "MX21 platforms:"
config MACH_MX21ADS
bool "MX21ADS platform"
- depends on MACH_MX21
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for MX21ADS platform. This includes specific
configurations for the board and its peripherals.
+endif
+
+if MACH_MX27
+
+comment "MX27 platforms:"
+
config MACH_MX27ADS
bool "MX27ADS platform"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for MX27ADS platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCM038
bool "Phytec phyCORE-i.MX27 CPU module (pcm038)"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
Include support for phyCORE-i.MX27 (aka pcm038) platform. This
@@ -58,7 +119,9 @@ endchoice
config MACH_CPUIMX27
bool "Eukrea CPUIMX27 module"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for Eukrea CPUIMX27 platform. This includes
specific configurations for the module and its peripherals.
@@ -67,9 +130,16 @@ config MACH_EUKREA_CPUIMX27_USESDHC2
bool "CPUIMX27 integrates SDHC2 module"
depends on MACH_CPUIMX27
help
- This adds support for the internal SDHC2 used on CPUIMX27 used
+ This adds support for the internal SDHC2 used on CPUIMX27
for wifi or eMMC.
+config MACH_EUKREA_CPUIMX27_USEUART4
+ bool "CPUIMX27 integrates UART4 module"
+ depends on MACH_CPUIMX27
+ help
+ This adds support for the internal UART4 used on CPUIMX27
+ for bluetooth.
+
choice
prompt "Baseboard"
depends on MACH_CPUIMX27
@@ -78,6 +148,8 @@ choice
config MACH_EUKREA_MBIMX27_BASEBOARD
prompt "Eukrea MBIMX27 development board"
bool
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
This adds board specific devices that can be found on Eukrea's
MBIMX27 evaluation board.
@@ -86,21 +158,24 @@ endchoice
config MACH_MX27_3DS
bool "MX27PDK platform"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for MX27PDK platform. This includes specific
configurations for the board and its peripherals.
config MACH_IMX27LITE
bool "LogicPD MX27 LITEKIT platform"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for MX27 LITEKIT platform. This includes specific
configurations for the board and its peripherals.
config MACH_PCA100
bool "Phytec phyCARD-s (pca100)"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
Include support for phyCARD-s (aka pca100) platform. This
@@ -108,7 +183,9 @@ config MACH_PCA100
config MACH_MXT_TD60
bool "Maxtrack i-MXT TD60"
- depends on MACH_MX27
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
help
Include support for i-MXT (aka td60) platform. This
includes specific configurations for the module and its peripherals.
diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-imx/Makefile
index e3254faac828..46a9fdfbbd15 100644
--- a/arch/arm/mach-mx2/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -4,14 +4,24 @@
# Object file lists.
-obj-y := devices.o serial.o
+obj-y := devices.o
-obj-$(CONFIG_MACH_MX21) += clock_imx21.o mm-imx21.o
+obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
-obj-$(CONFIG_MACH_MX27) += cpu_imx27.o
-obj-$(CONFIG_MACH_MX27) += clock_imx27.o mm-imx27.o
+obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
+obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
+
+obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
+obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
+
+# Support for CMOS sensor interface
+obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
+
+obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
+obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
+
obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
diff --git a/arch/arm/mach-mx2/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index e867398a8fdb..7988a85cf07d 100644
--- a/arch/arm/mach-mx2/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -1,3 +1,7 @@
+zreladdr-$(CONFIG_ARCH_MX1) := 0x08008000
+params_phys-$(CONFIG_ARCH_MX1) := 0x08000100
+initrd_phys-$(CONFIG_ARCH_MX1) := 0x08800000
+
zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000
params_phys-$(CONFIG_MACH_MX21) := 0xC0000100
initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000
diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-imx/clock-imx1.c
index 6cf2d4a7511d..c05096c38301 100644
--- a/arch/arm/mach-mx1/clock.c
+++ b/arch/arm/mach-imx/clock-imx1.c
@@ -2,18 +2,17 @@
* Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 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>
@@ -29,7 +28,41 @@
#include <mach/clock.h>
#include <mach/hardware.h>
#include <mach/common.h>
-#include "crm_regs.h"
+
+#define IO_ADDR_CCM(off) (MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR + (off)))
+
+/* CCM register addresses */
+#define CCM_CSCR IO_ADDR_CCM(0x0)
+#define CCM_MPCTL0 IO_ADDR_CCM(0x4)
+#define CCM_SPCTL0 IO_ADDR_CCM(0xc)
+#define CCM_PCDR IO_ADDR_CCM(0x20)
+
+#define CCM_CSCR_CLKO_OFFSET 29
+#define CCM_CSCR_CLKO_MASK (0x7 << 29)
+#define CCM_CSCR_USB_OFFSET 26
+#define CCM_CSCR_USB_MASK (0x7 << 26)
+#define CCM_CSCR_OSC_EN_SHIFT 17
+#define CCM_CSCR_SYSTEM_SEL (1 << 16)
+#define CCM_CSCR_BCLK_OFFSET 10
+#define CCM_CSCR_BCLK_MASK (0xf << 10)
+#define CCM_CSCR_PRESC (1 << 15)
+
+#define CCM_PCDR_PCLK3_OFFSET 16
+#define CCM_PCDR_PCLK3_MASK (0x7f << 16)
+#define CCM_PCDR_PCLK2_OFFSET 4
+#define CCM_PCDR_PCLK2_MASK (0xf << 4)
+#define CCM_PCDR_PCLK1_OFFSET 0
+#define CCM_PCDR_PCLK1_MASK 0xf
+
+#define IO_ADDR_SCM(off) (MX1_IO_ADDRESS(MX1_SCM_BASE_ADDR + (off)))
+
+/* SCM register addresses */
+#define SCM_GCCR IO_ADDR_SCM(0xc)
+
+#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
+#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
+#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
+#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
static int _clk_enable(struct clk *clk)
{
@@ -596,7 +629,8 @@ int __init mx1_clocks_init(unsigned long fref)
clk_enable(&hclk);
clk_enable(&fclk);
- mxc_timer_init(&gpt_clk, IO_ADDRESS(TIM1_BASE_ADDR), TIM1_INT);
+ mxc_timer_init(&gpt_clk, MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR),
+ MX1_TIM1_INT);
return 0;
}
diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-imx/clock-imx21.c
index bb419ef4d133..bb419ef4d133 100644
--- a/arch/arm/mach-mx2/clock_imx21.c
+++ b/arch/arm/mach-imx/clock-imx21.c
diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 0f0823c8b170..5a1aa15c8a16 100644
--- a/arch/arm/mach-mx2/clock_imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -644,7 +644,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
_REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
- _REGISTER_CLOCK(NULL, "csi", csi_clk)
+ _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk)
_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk1)
_REGISTER_CLOCK("mxc-ehci.0", "usb", usb_clk)
diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-imx/cpu-imx27.c
index d8d3b2d84dc5..d8d3b2d84dc5 100644
--- a/arch/arm/mach-mx2/cpu_imx27.c
+++ b/arch/arm/mach-imx/cpu-imx27.c
diff --git a/arch/arm/mach-imx/devices-imx1.h b/arch/arm/mach-imx/devices-imx1.h
new file mode 100644
index 000000000000..a8d94f078196
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx1.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx1.h>
+#include <mach/devices-common.h>
+
+#define imx1_add_i2c_imx(pdata) \
+ imx_add_imx_i2c(0, MX1_I2C_BASE_ADDR, SZ_4K, MX1_INT_I2C, pdata)
+
+#define imx1_add_imx_uart0(pdata) \
+ imx_add_imx_uart_3irq(0, MX1_UART1_BASE_ADDR, 0xd0, MX1_INT_UART1RX, MX1_INT_UART1TX, MX1_INT_UART1RTS, pdata)
+#define imx1_add_imx_uart1(pdata) \
+ imx_add_imx_uart_3irq(0, MX1_UART2_BASE_ADDR, 0xd0, MX1_INT_UART2RX, MX1_INT_UART2TX, MX1_INT_UART2RTS, pdata)
diff --git a/arch/arm/mach-imx/devices-imx21.h b/arch/arm/mach-imx/devices-imx21.h
new file mode 100644
index 000000000000..42788e99d127
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx21.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx21.h>
+#include <mach/devices-common.h>
+
+#define imx21_add_i2c_imx(pdata) \
+ imx_add_imx_i2c(0, MX2x_I2C_BASE_ADDR, SZ_4K, MX2x_INT_I2C, pdata)
+
+#define imx21_add_imx_uart0(pdata) \
+ imx_add_imx_uart_1irq(0, MX21_UART1_BASE_ADDR, SZ_4K, MX21_INT_UART1, pdata)
+#define imx21_add_imx_uart1(pdata) \
+ imx_add_imx_uart_1irq(1, MX21_UART2_BASE_ADDR, SZ_4K, MX21_INT_UART2, pdata)
+#define imx21_add_imx_uart2(pdata) \
+ imx_add_imx_uart_1irq(2, MX21_UART3_BASE_ADDR, SZ_4K, MX21_INT_UART3, pdata)
+#define imx21_add_imx_uart3(pdata) \
+ imx_add_imx_uart_1irq(3, MX21_UART4_BASE_ADDR, SZ_4K, MX21_INT_UART4, pdata)
+
+#define imx21_add_mxc_nand(pdata) \
+ imx_add_mxc_nand_v1(MX21_NFC_BASE_ADDR, MX21_INT_NANDFC, pdata)
+
+#define imx21_add_spi_imx0(pdata) \
+ imx_add_spi_imx(0, MX21_CSPI1_BASE_ADDR, SZ_4K, MX21_INT_CSPI1, pdata)
+#define imx21_add_spi_imx1(pdata) \
+ imx_add_spi_imx(1, MX21_CSPI2_BASE_ADDR, SZ_4K, MX21_INT_CSPI2, pdata)
diff --git a/arch/arm/mach-imx/devices-imx27.h b/arch/arm/mach-imx/devices-imx27.h
new file mode 100644
index 000000000000..65e7bb7ec2e8
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx27.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx27.h>
+#include <mach/devices-common.h>
+
+#define imx27_add_i2c_imx0(pdata) \
+ imx_add_imx_i2c(0, MX27_I2C1_BASE_ADDR, SZ_4K, MX27_INT_I2C1, pdata)
+#define imx27_add_i2c_imx1(pdata) \
+ imx_add_imx_i2c(1, MX27_I2C2_BASE_ADDR, SZ_4K, MX27_INT_I2C2, pdata)
+
+#define imx27_add_imx_uart0(pdata) \
+ imx_add_imx_uart_1irq(0, MX27_UART1_BASE_ADDR, SZ_4K, MX27_INT_UART1, pdata)
+#define imx27_add_imx_uart1(pdata) \
+ imx_add_imx_uart_1irq(1, MX27_UART2_BASE_ADDR, SZ_4K, MX27_INT_UART2, pdata)
+#define imx27_add_imx_uart2(pdata) \
+ imx_add_imx_uart_1irq(2, MX27_UART3_BASE_ADDR, SZ_4K, MX27_INT_UART3, pdata)
+#define imx27_add_imx_uart3(pdata) \
+ imx_add_imx_uart_1irq(3, MX27_UART4_BASE_ADDR, SZ_4K, MX27_INT_UART4, pdata)
+#define imx27_add_imx_uart4(pdata) \
+ imx_add_imx_uart_1irq(4, MX27_UART5_BASE_ADDR, SZ_4K, MX27_INT_UART5, pdata)
+#define imx27_add_imx_uart5(pdata) \
+ imx_add_imx_uart_1irq(5, MX27_UART6_BASE_ADDR, SZ_4K, MX27_INT_UART6, pdata)
+
+#define imx27_add_mxc_nand(pdata) \
+ imx_add_mxc_nand_v1(MX27_NFC_BASE_ADDR, MX27_INT_NANDFC, pdata)
+
+#define imx27_add_spi_imx0(pdata) \
+ imx_add_spi_imx(0, MX27_CSPI1_BASE_ADDR, SZ_4K, MX27_INT_CSPI1, pdata)
+#define imx27_add_spi_imx1(pdata) \
+ imx_add_spi_imx(1, MX27_CSPI2_BASE_ADDR, SZ_4K, MX27_INT_CSPI2, pdata)
+#define imx27_add_spi_imx2(pdata) \
+ imx_add_spi_imx(2, MX27_CSPI3_BASE_ADDR, SZ_4K, MX27_INT_CSPI3, pdata)
diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-imx/devices.c
index a0aeb8a4adc1..9c271a752b84 100644
--- a/arch/arm/mach-mx2/devices.c
+++ b/arch/arm/mach-imx/devices.c
@@ -11,6 +11,9 @@
*
* Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
+ * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ * Copyright (c) 2008 Darius Augulis <darius.augulis@teltonika.lt>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -32,6 +35,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/dma-mapping.h>
+#include <linux/serial.h>
#include <mach/irqs.h>
#include <mach/hardware.h>
@@ -40,38 +44,179 @@
#include "devices.h"
-/*
- * SPI master controller
- *
- * - i.MX1: 2 channel (slighly different register setting)
- * - i.MX21: 2 channel
- * - i.MX27: 3 channel
- */
-#define DEFINE_IMX_SPI_DEVICE(n, baseaddr, irq) \
- static struct resource mxc_spi_resources ## n[] = { \
- { \
- .start = baseaddr, \
- .end = baseaddr + SZ_4K - 1, \
- .flags = IORESOURCE_MEM, \
- }, { \
- .start = irq, \
- .end = irq, \
- .flags = IORESOURCE_IRQ, \
- }, \
- }; \
- \
- struct platform_device mxc_spi_device ## n = { \
- .name = "spi_imx", \
- .id = n, \
- .num_resources = ARRAY_SIZE(mxc_spi_resources ## n), \
- .resource = mxc_spi_resources ## n, \
+#if defined(CONFIG_ARCH_MX1)
+static struct resource imx1_camera_resources[] = {
+ {
+ .start = 0x00224000,
+ .end = 0x00224010,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX1_CSI_INT,
+ .end = MX1_CSI_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 imx1_camera_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device imx1_camera_device = {
+ .name = "mx1-camera",
+ .id = 0, /* This is used to put cameras on this interface */
+ .dev = {
+ .dma_mask = &imx1_camera_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .resource = imx1_camera_resources,
+ .num_resources = ARRAY_SIZE(imx1_camera_resources),
+};
+
+static struct resource imx_rtc_resources[] = {
+ {
+ .start = 0x00204000,
+ .end = 0x00204024,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX1_RTC_INT,
+ .end = MX1_RTC_INT,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_RTC_SAMINT,
+ .end = MX1_RTC_SAMINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device imx_rtc_device = {
+ .name = "rtc-imx",
+ .id = 0,
+ .resource = imx_rtc_resources,
+ .num_resources = ARRAY_SIZE(imx_rtc_resources),
+};
+
+static struct resource imx_wdt_resources[] = {
+ {
+ .start = 0x00201000,
+ .end = 0x00201008,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX1_WDT_INT,
+ .end = MX1_WDT_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device imx_wdt_device = {
+ .name = "imx-wdt",
+ .id = 0,
+ .resource = imx_wdt_resources,
+ .num_resources = ARRAY_SIZE(imx_wdt_resources),
+};
+
+static struct resource imx_usb_resources[] = {
+ {
+ .start = 0x00212000,
+ .end = 0x00212148,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX1_USBD_INT0,
+ .end = MX1_USBD_INT0,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT1,
+ .end = MX1_USBD_INT1,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT2,
+ .end = MX1_USBD_INT2,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT3,
+ .end = MX1_USBD_INT3,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT4,
+ .end = MX1_USBD_INT4,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT5,
+ .end = MX1_USBD_INT5,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = MX1_USBD_INT6,
+ .end = MX1_USBD_INT6,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device imx_usb_device = {
+ .name = "imx_udc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_usb_resources),
+ .resource = imx_usb_resources,
+};
+
+/* GPIO port description */
+static struct mxc_gpio_port imx_gpio_ports[] = {
+ {
+ .chip.label = "gpio-0",
+ .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR),
+ .irq = MX1_GPIO_INT_PORTA,
+ .virtual_irq_start = MXC_GPIO_IRQ_START,
+ }, {
+ .chip.label = "gpio-1",
+ .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x100),
+ .irq = MX1_GPIO_INT_PORTB,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
+ }, {
+ .chip.label = "gpio-2",
+ .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x200),
+ .irq = MX1_GPIO_INT_PORTC,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
+ }, {
+ .chip.label = "gpio-3",
+ .base = (void __iomem *)MX1_IO_ADDRESS(MX1_GPIO_BASE_ADDR + 0x300),
+ .irq = MX1_GPIO_INT_PORTD,
+ .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
}
+};
+
+int __init imx1_register_gpios(void)
+{
+ return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+}
+#endif
-DEFINE_IMX_SPI_DEVICE(0, MX2x_CSPI1_BASE_ADDR, MX2x_INT_CSPI1);
-DEFINE_IMX_SPI_DEVICE(1, MX2x_CSPI2_BASE_ADDR, MX2x_INT_CSPI2);
+#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
#ifdef CONFIG_MACH_MX27
-DEFINE_IMX_SPI_DEVICE(2, MX27_CSPI3_BASE_ADDR, MX27_INT_CSPI3);
+static struct resource mx27_camera_resources[] = {
+ {
+ .start = MX27_CSI_BASE_ADDR,
+ .end = MX27_CSI_BASE_ADDR + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX27_EMMA_PRP_BASE_ADDR,
+ .end = MX27_EMMA_PRP_BASE_ADDR + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX27_INT_CSI,
+ .end = MX27_INT_CSI,
+ .flags = IORESOURCE_IRQ,
+ },{
+ .start = MX27_INT_EMMAPRP,
+ .end = MX27_INT_EMMAPRP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+struct platform_device mx27_camera_device = {
+ .name = "mx2-camera",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mx27_camera_resources),
+ .resource = mx27_camera_resources,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
#endif
/*
@@ -140,34 +285,6 @@ struct platform_device mxc_w1_master_device = {
.resource = mxc_w1_master_resources,
};
-#define DEFINE_MXC_NAND_DEVICE(pfx, baseaddr, irq) \
- static struct resource pfx ## _nand_resources[] = { \
- { \
- .start = baseaddr, \
- .end = baseaddr + SZ_4K - 1, \
- .flags = IORESOURCE_MEM, \
- }, { \
- .start = irq, \
- .end = irq, \
- .flags = IORESOURCE_IRQ, \
- }, \
- }; \
- \
- struct platform_device pfx ## _nand_device = { \
- .name = "mxc_nand", \
- .id = 0, \
- .num_resources = ARRAY_SIZE(pfx ## _nand_resources), \
- .resource = pfx ## _nand_resources, \
- }
-
-#ifdef CONFIG_MACH_MX21
-DEFINE_MXC_NAND_DEVICE(imx21, MX21_NFC_BASE_ADDR, MX21_INT_NANDFC);
-#endif
-
-#ifdef CONFIG_MACH_MX27
-DEFINE_MXC_NAND_DEVICE(imx27, MX27_NFC_BASE_ADDR, MX27_INT_NANDFC);
-#endif
-
/*
* lcdc:
* - i.MX1: the basic controller
@@ -218,32 +335,6 @@ struct platform_device mxc_fec_device = {
};
#endif
-#define DEFINE_IMX_I2C_DEVICE(n, baseaddr, irq) \
- static struct resource mxc_i2c_resources ## n[] = { \
- { \
- .start = baseaddr, \
- .end = baseaddr + SZ_4K - 1, \
- .flags = IORESOURCE_MEM, \
- }, { \
- .start = irq, \
- .end = irq, \
- .flags = IORESOURCE_IRQ, \
- } \
- }; \
- \
- struct platform_device mxc_i2c_device ## n = { \
- .name = "imx-i2c", \
- .id = n, \
- .num_resources = ARRAY_SIZE(mxc_i2c_resources ## n), \
- .resource = mxc_i2c_resources ## n, \
- }
-
-DEFINE_IMX_I2C_DEVICE(0, MX2x_I2C_BASE_ADDR, MX2x_INT_I2C);
-
-#ifdef CONFIG_MACH_MX27
-DEFINE_IMX_I2C_DEVICE(1, MX27_I2C2_BASE_ADDR, MX27_INT_I2C2);
-#endif
-
static struct resource mxc_pwm_resources[] = {
{
.start = MX2x_PWM_BASE_ADDR,
@@ -454,26 +545,21 @@ DEFINE_IMX_SSI_DEVICE(1, 2, MX2x_SSI1_BASE_ADDR, MX2x_INT_SSI1);
#ifdef CONFIG_MACH_MX21
DEFINE_MXC_GPIO_PORTS(MX21, imx21);
+
+int __init imx21_register_gpios(void)
+{
+ return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
+}
#endif
#ifdef CONFIG_MACH_MX27
DEFINE_MXC_GPIO_PORTS(MX27, imx27);
-#endif
-int __init mxc_register_gpios(void)
+int __init imx27_register_gpios(void)
{
-#ifdef CONFIG_MACH_MX21
- if (cpu_is_mx21())
- return mxc_gpio_init(imx21_gpio_ports, ARRAY_SIZE(imx21_gpio_ports));
- else
-#endif
-#ifdef CONFIG_MACH_MX27
- if (cpu_is_mx27())
- return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
- else
-#endif
- return 0;
+ return mxc_gpio_init(imx27_gpio_ports, ARRAY_SIZE(imx27_gpio_ports));
}
+#endif
#ifdef CONFIG_MACH_MX21
static struct resource mx21_usbhc_resources[] = {
@@ -501,3 +587,23 @@ struct platform_device mx21_usbhc_device = {
};
#endif
+static struct resource imx_kpp_resources[] = {
+ {
+ .start = MX2x_KPP_BASE_ADDR,
+ .end = MX2x_KPP_BASE_ADDR + 0xf,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = MX2x_INT_KPP,
+ .end = MX2x_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device imx_kpp_device = {
+ .name = "imx-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(imx_kpp_resources),
+ .resource = imx_kpp_resources,
+};
+
+#endif
diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-imx/devices.h
index 84ed51380174..efd4527506a5 100644
--- a/arch/arm/mach-mx2/devices.h
+++ b/arch/arm/mach-imx/devices.h
@@ -1,3 +1,11 @@
+#ifdef CONFIG_ARCH_MX1
+extern struct platform_device imx1_camera_device;
+extern struct platform_device imx_rtc_device;
+extern struct platform_device imx_wdt_device;
+extern struct platform_device imx_usb_device;
+#endif
+
+#if defined(CONFIG_MACH_MX21) || defined(CONFIG_MACH_MX27)
extern struct platform_device mxc_gpt1;
extern struct platform_device mxc_gpt2;
#ifdef CONFIG_MACH_MX27
@@ -6,37 +14,19 @@ extern struct platform_device mxc_gpt4;
extern struct platform_device mxc_gpt5;
#endif
extern struct platform_device mxc_wdt;
-extern struct platform_device mxc_uart_device0;
-extern struct platform_device mxc_uart_device1;
-extern struct platform_device mxc_uart_device2;
-extern struct platform_device mxc_uart_device3;
-extern struct platform_device mxc_uart_device4;
-extern struct platform_device mxc_uart_device5;
extern struct platform_device mxc_w1_master_device;
-#ifdef CONFIG_MACH_MX21
-extern struct platform_device imx21_nand_device;
-#endif
-#ifdef CONFIG_MACH_MX27
-extern struct platform_device imx27_nand_device;
-#endif
extern struct platform_device mxc_fb_device;
extern struct platform_device mxc_fec_device;
extern struct platform_device mxc_pwm_device;
-extern struct platform_device mxc_i2c_device0;
-#ifdef CONFIG_MACH_MX27
-extern struct platform_device mxc_i2c_device1;
-#endif
extern struct platform_device mxc_sdhc_device0;
extern struct platform_device mxc_sdhc_device1;
extern struct platform_device mxc_otg_udc_device;
+extern struct platform_device mx27_camera_device;
extern struct platform_device mxc_otg_host;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
-extern struct platform_device mxc_spi_device0;
-extern struct platform_device mxc_spi_device1;
-#ifdef CONFIG_MACH_MX27
-extern struct platform_device mxc_spi_device2;
-#endif
extern struct platform_device mx21_usbhc_device;
extern struct platform_device imx_ssi_device0;
extern struct platform_device imx_ssi_device1;
+extern struct platform_device imx_kpp_device;
+#endif
diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/mach-imx/dma-v1.c
index e16014b0d13c..fd1d9197d06e 100644
--- a/arch/arm/plat-mxc/dma-mx1-mx2.c
+++ b/arch/arm/mach-imx/dma-v1.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/plat-mxc/dma-mx1-mx2.c
+ * linux/arch/arm/plat-mxc/dma-v1.c
*
* i.MX DMA registration and IRQ dispatching
*
@@ -34,7 +34,7 @@
#include <asm/system.h>
#include <asm/irq.h>
#include <mach/hardware.h>
-#include <mach/dma-mx1-mx2.h>
+#include <mach/dma-v1.h>
#define DMA_DCR 0x00 /* Control Register */
#define DMA_DISR 0x04 /* Interrupt status Register */
diff --git a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
index f3b169d5245f..27e7226ec9d4 100644
--- a/arch/arm/mach-mx2/eukrea_mbimx27-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Eric Benard - eric@eukrea.com
+ * Copyright (C) 2009-2010 Eric Benard - eric@eukrea.com
*
* Based on pcm970-baseboard.c which is :
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
@@ -24,6 +24,9 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#include <linux/backlight.h>
+#include <video/platform_lcd.h>
+#include <linux/input/matrix_keypad.h>
#include <asm/mach/arch.h>
@@ -32,8 +35,11 @@
#include <mach/imxfb.h>
#include <mach/hardware.h>
#include <mach/mmc.h>
-#include <mach/imx-uart.h>
+#include <mach/spi.h>
+#include <mach/ssi.h>
+#include <mach/audmux.h>
+#include "devices-imx27.h"
#include "devices.h"
static int eukrea_mbimx27_pins[] = {
@@ -48,10 +54,12 @@ static int eukrea_mbimx27_pins[] = {
PE10_PF_UART3_CTS,
PE11_PF_UART3_RTS,
/* UART4 */
+#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
PB26_AF_UART4_RTS,
PB28_AF_UART4_TXD,
PB29_AF_UART4_CTS,
PB31_AF_UART4_RXD,
+#endif
/* SDHC1*/
PE18_PF_SD1_D0,
PE19_PF_SD1_D1,
@@ -84,10 +92,29 @@ static int eukrea_mbimx27_pins[] = {
PA30_PF_CONTRAST,
PA31_PF_OE_ACD,
/* SPI1 */
- PD28_PF_CSPI1_SS0,
PD29_PF_CSPI1_SCLK,
PD30_PF_CSPI1_MISO,
PD31_PF_CSPI1_MOSI,
+ /* SSI4 */
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
+ || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
+ PC16_PF_SSI4_FS,
+ PC17_PF_SSI4_RXD | GPIO_PUEN,
+ PC18_PF_SSI4_TXD | GPIO_PUEN,
+ PC19_PF_SSI4_CLK,
+#endif
+};
+
+static const uint32_t eukrea_mbimx27_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+};
+
+static struct matrix_keymap_data eukrea_mbimx27_keymap_data = {
+ .keymap = eukrea_mbimx27_keymap,
+ .keymap_size = ARRAY_SIZE(eukrea_mbimx27_keymap),
};
static struct gpio_led gpio_leds[] = {
@@ -103,12 +130,6 @@ static struct gpio_led gpio_leds[] = {
.active_low = 1,
.gpio = GPIO_PORTF | 19,
},
- {
- .name = "backlight",
- .default_trigger = "backlight",
- .active_low = 0,
- .gpio = GPIO_PORTE | 5,
- },
};
static struct gpio_led_platform_data gpio_led_info = {
@@ -127,7 +148,7 @@ static struct platform_device leds_gpio = {
static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
{
.mode = {
- .name = "CMO-QGVA",
+ .name = "CMO-QVGA",
.refresh = 60,
.xres = 320,
.yres = 240,
@@ -141,6 +162,38 @@ static struct imx_fb_videomode eukrea_mbimx27_modes[] = {
},
.pcr = 0xFAD08B80,
.bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 32000,
+ .hsync_len = 1,
+ .left_margin = 35,
+ .right_margin = 0,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 0,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
+ }, {
+ .mode = {
+ .name = "DVI-SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = 25000,
+ .hsync_len = 1,
+ .left_margin = 35,
+ .right_margin = 0,
+ .vsync_len = 1,
+ .upper_margin = 7,
+ .lower_margin = 0,
+ },
+ .pcr = 0xFA208B80,
+ .bpp = 16,
},
};
@@ -153,16 +206,52 @@ static struct imx_fb_platform_data eukrea_mbimx27_fb_data = {
.dmacr = 0x00040060,
};
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- },
- {
- .flags = IMXUART_HAVE_RTSCTS,
+static void eukrea_mbimx27_bl_set_intensity(int intensity)
+{
+ if (intensity)
+ gpio_direction_output(GPIO_PORTE | 5, 1);
+ else
+ gpio_direction_output(GPIO_PORTE | 5, 0);
+}
+
+static struct generic_bl_info eukrea_mbimx27_bl_info = {
+ .name = "eukrea_mbimx27-bl",
+ .max_intensity = 0xff,
+ .default_intensity = 0xff,
+ .set_bl_intensity = eukrea_mbimx27_bl_set_intensity,
+};
+
+static struct platform_device eukrea_mbimx27_bl_dev = {
+ .name = "generic-bl",
+ .id = 1,
+ .dev = {
+ .platform_data = &eukrea_mbimx27_bl_info,
},
};
-#if defined(CONFIG_TOUCHSCREEN_ADS7846)
+static void eukrea_mbimx27_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_PORTA | 25, 1);
+ else
+ gpio_direction_output(GPIO_PORTA | 25, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimx27_lcd_power_data = {
+ .set_power = eukrea_mbimx27_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimx27_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimx27_lcd_power_data,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
#define ADS7846_PENDOWN (GPIO_PORTD | 25)
@@ -173,7 +262,6 @@ static void ads7846_dev_init(void)
printk(KERN_ERR "can't get ads746 pen down GPIO\n");
return;
}
-
gpio_direction_input(ADS7846_PENDOWN);
}
@@ -186,7 +274,9 @@ static struct ads7846_platform_data ads7846_config __initdata = {
.get_pendown_state = ads7846_get_pendown_state,
.keep_vref_on = 1,
};
+#endif
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
[0] = {
.modalias = "ads7846",
@@ -199,9 +289,15 @@ static struct spi_board_info eukrea_mbimx27_spi_board_info[] __initdata = {
},
};
+static struct i2c_board_info eukrea_mbimx27_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
static int eukrea_mbimx27_spi_cs[] = {GPIO_PORTD | 28};
-static struct spi_imx_master eukrea_mbimx27_spi_0_data = {
+static const struct spi_imx_master eukrea_mbimx27_spi0_data __initconst = {
.chipselect = eukrea_mbimx27_spi_cs,
.num_chipselect = ARRAY_SIZE(eukrea_mbimx27_spi_cs),
};
@@ -211,6 +307,14 @@ static struct platform_device *platform_devices[] __initdata = {
&leds_gpio,
};
+static struct imxmmc_platform_data sdhc_pdata = {
+ .dat3_card_detect = 1,
+};
+
+struct imx_ssi_platform_data eukrea_mbimx27_ssi_pdata = {
+ .flags = IMX_SSI_DMA | IMX_SSI_USE_I2S_SLAVE,
+};
+
/*
* system init for baseboard usage. Will be called by cpuimx27 init.
*
@@ -222,21 +326,52 @@ void __init eukrea_mbimx27_baseboard_init(void)
mxc_gpio_setup_multiple_pins(eukrea_mbimx27_pins,
ARRAY_SIZE(eukrea_mbimx27_pins), "MBIMX27");
- mxc_register_device(&mxc_uart_device1, &uart_pdata[0]);
- mxc_register_device(&mxc_uart_device2, &uart_pdata[1]);
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320) \
+ || defined(CONFIG_SND_SOC_EUKREA_TLV320_MODULE)
+ /* SSI unit master I2S codec connected to SSI_PINS_4*/
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
+ MXC_AUDMUX_V1_PCR_SYN |
+ MXC_AUDMUX_V1_PCR_TFSDIR |
+ MXC_AUDMUX_V1_PCR_TCLKDIR |
+ MXC_AUDMUX_V1_PCR_RFSDIR |
+ MXC_AUDMUX_V1_PCR_RCLKDIR |
+ MXC_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+ MXC_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
+ MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
+ );
+ mxc_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
+ MXC_AUDMUX_V1_PCR_SYN |
+ MXC_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
+ );
+#endif
+
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+#if !defined(MACH_EUKREA_CPUIMX27_USEUART4)
+ imx27_add_imx_uart3(&uart_pdata);
+#endif
mxc_register_device(&mxc_fb_device, &eukrea_mbimx27_fb_data);
- mxc_register_device(&mxc_sdhc_device0, NULL);
+ mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
-#if defined(CONFIG_TOUCHSCREEN_ADS7846)
+ i2c_register_board_info(0, eukrea_mbimx27_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimx27_i2c_devices));
+
+ mxc_register_device(&imx_ssi_device0, &eukrea_mbimx27_ssi_pdata);
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) \
|| defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
- /* SPI and ADS7846 Touchscreen controler init */
- mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+ /* ADS7846 Touchscreen controller init */
mxc_gpio_mode(GPIO_PORTD | 25 | GPIO_GPIO | GPIO_IN);
- mxc_register_device(&mxc_spi_device0, &eukrea_mbimx27_spi_0_data);
+ ads7846_dev_init();
+#endif
+
+#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+ /* SPI_CS0 init */
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
+ imx27_add_spi_imx0(&eukrea_mbimx27_spi0_data);
spi_register_board_info(eukrea_mbimx27_spi_board_info,
ARRAY_SIZE(eukrea_mbimx27_spi_board_info));
- ads7846_dev_init();
#endif
/* Leds configuration */
@@ -244,6 +379,14 @@ void __init eukrea_mbimx27_baseboard_init(void)
mxc_gpio_mode(GPIO_PORTF | 19 | GPIO_GPIO | GPIO_OUT);
/* Backlight */
mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_OUT);
+ gpio_request(GPIO_PORTE | 5, "backlight");
+ platform_device_register(&eukrea_mbimx27_bl_dev);
+ /* LCD Reset */
+ mxc_gpio_mode(GPIO_PORTA | 25 | GPIO_GPIO | GPIO_OUT);
+ gpio_request(GPIO_PORTA | 25, "lcd_enable");
+ platform_device_register(&eukrea_mbimx27_lcd_powerdev);
+
+ mxc_register_device(&imx_kpp_device, &eukrea_mbimx27_keymap_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
new file mode 100644
index 000000000000..df5f522da6b3
--- /dev/null
+++ b/arch/arm/mach-imx/include/mach/dma-mx1-mx2.h
@@ -0,0 +1,10 @@
+#ifndef __MACH_DMA_MX1_MX2_H__
+#define __MACH_DMA_MX1_MX2_H__
+/*
+ * Don't use this header in new code, it will go away when all users are
+ * converted to mach/dma-v1.h
+ */
+
+#include <mach/dma-v1.h>
+
+#endif /* ifndef __MACH_DMA_MX1_MX2_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h b/arch/arm/mach-imx/include/mach/dma-v1.h
index 7c4870bd5a21..287431cc13e5 100644
--- a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
+++ b/arch/arm/mach-imx/include/mach/dma-v1.h
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h
+ * linux/arch/arm/mach-imx/include/mach/dma-v1.h
*
* i.MX DMA registration and IRQ dispatching
*
@@ -22,8 +22,10 @@
* MA 02110-1301, USA.
*/
-#ifndef __ASM_ARCH_MXC_DMA_H
-#define __ASM_ARCH_MXC_DMA_H
+#ifndef __MACH_DMA_V1_H__
+#define __MACH_DMA_V1_H__
+
+#define imx_has_dma_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
#define IMX_DMA_CHANNELS 16
@@ -102,4 +104,4 @@ enum imx_dma_prio {
int imx_dma_request_by_prio(const char *name, enum imx_dma_prio prio);
-#endif /* _ASM_ARCH_MXC_DMA_H */
+#endif /* __MACH_DMA_V1_H__ */
diff --git a/arch/arm/mach-mx2/mach-cpuimx27.c b/arch/arm/mach-imx/mach-cpuimx27.c
index 1f616dcaabc9..2a135449e52c 100644
--- a/arch/arm/mach-mx2/mach-cpuimx27.c
+++ b/arch/arm/mach-imx/mach-cpuimx27.c
@@ -26,6 +26,9 @@
#include <linux/mtd/physmap.h>
#include <linux/platform_device.h>
#include <linux/serial_8250.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -35,11 +38,12 @@
#include <mach/board-eukrea_cpuimx27.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/i2c.h>
#include <mach/iomux-mx27.h>
-#include <mach/imx-uart.h>
#include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+#include "devices-imx27.h"
#include "devices.h"
static int eukrea_cpuimx27_pins[] = {
@@ -49,10 +53,12 @@ static int eukrea_cpuimx27_pins[] = {
PE14_PF_UART1_CTS,
PE15_PF_UART1_RTS,
/* UART4 */
+#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
PB26_AF_UART4_RTS,
PB28_AF_UART4_TXD,
PB29_AF_UART4_CTS,
PB31_AF_UART4_RXD,
+#endif
/* FEC */
PD0_AIN_FEC_TXD0,
PD1_AIN_FEC_TXD1,
@@ -76,19 +82,47 @@ static int eukrea_cpuimx27_pins[] = {
PD17_PF_I2C_DATA,
PD18_PF_I2C_CLK,
/* SDHC2 */
+#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
PB4_PF_SD2_D0,
PB5_PF_SD2_D1,
PB6_PF_SD2_D2,
PB7_PF_SD2_D3,
PB8_PF_SD2_CMD,
PB9_PF_SD2_CLK,
+#endif
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
/* Quad UART's IRQ */
- GPIO_PORTD | 22 | GPIO_GPIO | GPIO_IN,
- GPIO_PORTD | 23 | GPIO_GPIO | GPIO_IN,
- GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN,
- GPIO_PORTD | 30 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 22 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 27 | GPIO_GPIO | GPIO_IN,
+ GPIO_PORTB | 30 | GPIO_GPIO | GPIO_IN,
#endif
+ /* OTG */
+ PC7_PF_USBOTG_DATA5,
+ PC8_PF_USBOTG_DATA6,
+ PC9_PF_USBOTG_DATA0,
+ PC10_PF_USBOTG_DATA2,
+ PC11_PF_USBOTG_DATA1,
+ PC12_PF_USBOTG_DATA4,
+ PC13_PF_USBOTG_DATA3,
+ PE0_PF_USBOTG_NXT,
+ PE1_PF_USBOTG_STP,
+ PE2_PF_USBOTG_DIR,
+ PE24_PF_USBOTG_CLK,
+ PE25_PF_USBOTG_DATA7,
+ /* USBH2 */
+ PA0_PF_USBH2_CLK,
+ PA1_PF_USBH2_DIR,
+ PA2_PF_USBH2_DATA7,
+ PA3_PF_USBH2_NXT,
+ PA4_PF_USBH2_STP,
+ PD19_AF_USBH2_DATA4,
+ PD20_AF_USBH2_DATA3,
+ PD21_AF_USBH2_DATA6,
+ PD22_AF_USBH2_DATA0,
+ PD23_AF_USBH2_DATA2,
+ PD24_AF_USBH2_DATA1,
+ PD26_AF_USBH2_DATA5,
};
static struct physmap_flash_data eukrea_cpuimx27_flash_data = {
@@ -111,15 +145,12 @@ static struct platform_device eukrea_cpuimx27_nor_mtd_device = {
.resource = &eukrea_cpuimx27_flash_resource,
};
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
};
-static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
+static const struct mxc_nand_platform_data
+cpuimx27_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -127,9 +158,11 @@ static struct mxc_nand_platform_data eukrea_cpuimx27_nand_board_info = {
static struct platform_device *platform_devices[] __initdata = {
&eukrea_cpuimx27_nor_mtd_device,
&mxc_fec_device,
+ &mxc_wdt,
+ &mxc_w1_master_device,
};
-static struct imxi2c_platform_data eukrea_cpuimx27_i2c_1_data = {
+static const struct imxi2c_platform_data cpuimx27_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -182,34 +215,83 @@ static struct platform_device serial_device = {
};
#endif
+#if defined(CONFIG_USB_ULPI)
+static struct mxc_usbh_platform_data otg_pdata = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+#endif
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx27_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx27_otg_mode);
+
static void __init eukrea_cpuimx27_init(void)
{
mxc_gpio_setup_multiple_pins(eukrea_cpuimx27_pins,
ARRAY_SIZE(eukrea_cpuimx27_pins), "CPUIMX27");
- mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
+ imx27_add_imx_uart0(&uart_pdata);
- mxc_register_device(&imx27_nand_device,
- &eukrea_cpuimx27_nand_board_info);
+ imx27_add_mxc_nand(&cpuimx27_nand_board_info);
i2c_register_board_info(0, eukrea_cpuimx27_i2c_devices,
ARRAY_SIZE(eukrea_cpuimx27_i2c_devices));
- mxc_register_device(&mxc_i2c_device0, &eukrea_cpuimx27_i2c_1_data);
+ imx27_add_i2c_imx1(&cpuimx27_i2c1_data);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
#if defined(CONFIG_MACH_EUKREA_CPUIMX27_USESDHC2)
/* SDHC2 can be used for Wifi */
mxc_register_device(&mxc_sdhc_device1, NULL);
+#endif
+#if defined(MACH_EUKREA_CPUIMX27_USEUART4)
/* in which case UART4 is also used for Bluetooth */
- mxc_register_device(&mxc_uart_device3, &uart_pdata[1]);
+ imx27_add_imx_uart3(&uart_pdata);
#endif
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
platform_device_register(&serial_device);
#endif
+#if defined(CONFIG_USB_ULPI)
+ if (otg_mode_host) {
+ otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_otg_host, &otg_pdata);
+ }
+
+ usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+ if (!otg_mode_host)
+ mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+
#ifdef CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD
eukrea_mbimx27_baseboard_init();
#endif
diff --git a/arch/arm/mach-mx2/mach-imx27lite.c b/arch/arm/mach-imx/mach-imx27lite.c
index b5710bf18b96..22a2b5d91213 100644
--- a/arch/arm/mach-mx2/mach-imx27lite.c
+++ b/arch/arm/mach-imx/mach-imx27lite.c
@@ -12,10 +12,6 @@
* 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/platform_device.h>
@@ -26,10 +22,9 @@
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx27.h>
-#include <mach/board-mx27lite.h>
+#include "devices-imx27.h"
#include "devices.h"
static unsigned int mx27lite_pins[] = {
@@ -59,7 +54,7 @@ static unsigned int mx27lite_pins[] = {
PF23_AIN_FEC_TX_EN,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -71,7 +66,7 @@ static void __init mx27lite_init(void)
{
mxc_gpio_setup_multiple_pins(mx27lite_pins, ARRAY_SIZE(mx27lite_pins),
"imx27lite");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx27_add_imx_uart0(&uart_pdata);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-mx1/mach-mx1ads.c b/arch/arm/mach-imx/mach-mx1ads.c
index 51f3cfd83db2..77a760cfadc0 100644
--- a/arch/arm/mach-mx1/mach-mx1ads.c
+++ b/arch/arm/mach-imx/mach-mx1ads.c
@@ -26,10 +26,10 @@
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/i2c.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx1.h>
#include <mach/irqs.h>
+#include "devices-imx1.h"
#include "devices.h"
static int mx1ads_pins[] = {
@@ -58,12 +58,12 @@ static int mx1ads_pins[] = {
* UARTs platform data
*/
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxuart_platform_data uart1_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
};
/*
@@ -75,8 +75,8 @@ static struct physmap_flash_data mx1ads_flash_data = {
};
static struct resource flash_resource = {
- .start = IMX_CS0_PHYS,
- .end = IMX_CS0_PHYS + SZ_32M - 1,
+ .start = MX1_CS0_PHYS,
+ .end = MX1_CS0_PHYS + SZ_32M - 1,
.flags = IORESOURCE_MEM,
};
@@ -98,7 +98,7 @@ static struct pcf857x_platform_data pcf857x_data[] = {
}
};
-static struct imxi2c_platform_data mx1ads_i2c_data = {
+static const struct imxi2c_platform_data mx1ads_i2c_data __initconst = {
.bitrate = 100000,
};
@@ -121,8 +121,8 @@ static void __init mx1ads_init(void)
ARRAY_SIZE(mx1ads_pins), "mx1ads");
/* UART */
- mxc_register_device(&imx_uart1_device, &uart_pdata[0]);
- mxc_register_device(&imx_uart2_device, &uart_pdata[1]);
+ imx1_add_imx_uart0(&uart0_pdata);
+ imx1_add_imx_uart1(&uart1_pdata);
/* Physmap flash */
mxc_register_device(&flash_device, &mx1ads_flash_data);
@@ -131,7 +131,7 @@ static void __init mx1ads_init(void)
i2c_register_board_info(0, mx1ads_i2c_devices,
ARRAY_SIZE(mx1ads_i2c_devices));
- mxc_register_device(&imx_i2c_device, &mx1ads_i2c_data);
+ imx1_add_i2c_imx(&mx1ads_i2c_data);
}
static void __init mx1ads_timer_init(void)
@@ -145,8 +145,8 @@ struct sys_timer mx1ads_timer = {
MACHINE_START(MX1ADS, "Freescale MX1ADS")
/* Maintainer: Sascha Hauer, Pengutronix */
- .phys_io = IMX_IO_PHYS,
- .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
+ .phys_io = MX1_IO_BASE_ADDR,
+ .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX1_PHYS_OFFSET + 0x100,
.map_io = mx1_map_io,
.init_irq = mx1_init_irq,
@@ -155,8 +155,8 @@ MACHINE_START(MX1ADS, "Freescale MX1ADS")
MACHINE_END
MACHINE_START(MXLADS, "Freescale MXLADS")
- .phys_io = IMX_IO_PHYS,
- .io_pg_offst = (IMX_IO_BASE >> 18) & 0xfffc,
+ .phys_io = MX1_IO_BASE_ADDR,
+ .io_pg_offst = (MX1_IO_BASE_ADDR_VIRT >> 18) & 0xfffc,
.boot_params = MX1_PHYS_OFFSET + 0x100,
.map_io = mx1_map_io,
.init_irq = mx1_init_irq,
diff --git a/arch/arm/mach-mx2/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 113e58d7cb40..96d7f8189f32 100644
--- a/arch/arm/mach-mx2/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -12,10 +12,6 @@
* 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/platform_device.h>
@@ -28,15 +24,49 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <mach/imx-uart.h>
#include <mach/imxfb.h>
#include <mach/iomux-mx21.h>
#include <mach/mxc_nand.h>
#include <mach/mmc.h>
-#include <mach/board-mx21ads.h>
+#include "devices-imx21.h"
#include "devices.h"
+/*
+ * Memory-mapped I/O on MX21ADS base board
+ */
+#define MX21ADS_MMIO_BASE_ADDR 0xf5000000
+#define MX21ADS_MMIO_SIZE SZ_16M
+
+#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
+ (MX21ADS_MMIO_BASE_ADDR + (offset))
+
+#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
+#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
+#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
+#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
+#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
+
+/* MX21ADS_IO_REG bit definitions */
+#define MX21ADS_IO_SD_WP 0x0001 /* read */
+#define MX21ADS_IO_TP6 0x0001 /* write */
+#define MX21ADS_IO_SW_SEL 0x0002 /* read */
+#define MX21ADS_IO_TP7 0x0002 /* write */
+#define MX21ADS_IO_RESET_E_UART 0x0004
+#define MX21ADS_IO_RESET_BASE 0x0008
+#define MX21ADS_IO_CSI_CTL2 0x0010
+#define MX21ADS_IO_CSI_CTL1 0x0020
+#define MX21ADS_IO_CSI_CTL0 0x0040
+#define MX21ADS_IO_UART1_EN 0x0080
+#define MX21ADS_IO_UART4_EN 0x0100
+#define MX21ADS_IO_LCDON 0x0200
+#define MX21ADS_IO_IRDA_EN 0x0400
+#define MX21ADS_IO_IRDA_FIR_SEL 0x0800
+#define MX21ADS_IO_IRDA_MD0_B 0x1000
+#define MX21ADS_IO_IRDA_MD1 0x2000
+#define MX21ADS_IO_LED4_ON 0x4000
+#define MX21ADS_IO_LED3_ON 0x8000
+
static unsigned int mx21ads_pins[] = {
/* CS8900A */
@@ -133,14 +163,13 @@ static struct platform_device mx21ads_nor_mtd_device = {
.resource = &mx21ads_flash_resource,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata_rts __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct imxuart_platform_data uart_norts_pdata = {
+static const struct imxuart_platform_data uart_pdata_norts __initconst = {
};
-
static int mx21ads_fb_init(struct platform_device *pdev)
{
u16 tmp;
@@ -227,7 +256,8 @@ static struct imxmmc_platform_data mx21ads_sdhc_pdata = {
.exit = mx21ads_sdhc_exit,
};
-static struct mxc_nand_platform_data mx21ads_nand_board_info = {
+static const struct mxc_nand_platform_data
+mx21ads_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -263,12 +293,12 @@ static void __init mx21ads_board_init(void)
mxc_gpio_setup_multiple_pins(mx21ads_pins, ARRAY_SIZE(mx21ads_pins),
"mx21ads");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_norts_pdata);
- mxc_register_device(&mxc_uart_device3, &uart_pdata);
+ imx21_add_imx_uart0(&uart_pdata_rts);
+ imx21_add_imx_uart2(&uart_pdata_norts);
+ imx21_add_imx_uart3(&uart_pdata_rts);
mxc_register_device(&mxc_fb_device, &mx21ads_fb_data);
mxc_register_device(&mxc_sdhc_device0, &mx21ads_sdhc_pdata);
- mxc_register_device(&imx21_nand_device, &mx21ads_nand_board_info);
+ imx21_add_mxc_nand(&mx21ads_nand_board_info);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-mx2/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index b2f4e0db3fb3..e66ffaa1c26c 100644
--- a/arch/arm/mach-mx2/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -12,23 +12,25 @@
* 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
+ */
+
+/*
+ * This machine is known as:
+ * - i.MX27 3-Stack Development System
+ * - i.MX27 Platform Development Kit (i.MX27 PDK)
*/
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/input/matrix_keypad.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx27.h>
-#include <mach/board-mx27pdk.h>
+#include "devices-imx27.h"
#include "devices.h"
static unsigned int mx27pdk_pins[] = {
@@ -58,7 +60,7 @@ static unsigned int mx27pdk_pins[] = {
PF23_AIN_FEC_TX_EN,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -66,12 +68,34 @@ static struct platform_device *platform_devices[] __initdata = {
&mxc_fec_device,
};
+/*
+ * Matrix keyboard
+ */
+
+static const uint32_t mx27_3ds_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_ENTER),
+ KEY(2, 0, KEY_F6),
+ KEY(2, 1, KEY_F8),
+ KEY(2, 2, KEY_F9),
+ KEY(2, 3, KEY_F10),
+};
+
+static struct matrix_keymap_data mx27_3ds_keymap_data = {
+ .keymap = mx27_3ds_keymap,
+ .keymap_size = ARRAY_SIZE(mx27_3ds_keymap),
+};
+
static void __init mx27pdk_init(void)
{
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
"mx27pdk");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx27_add_imx_uart0(&uart_pdata);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ mxc_register_device(&imx_kpp_device, &mx27_3ds_keymap_data);
}
static void __init mx27pdk_timer_init(void)
diff --git a/arch/arm/mach-mx2/mach-mx27ads.c b/arch/arm/mach-imx/mach-mx27ads.c
index 6ce323669e58..9c77da98a10e 100644
--- a/arch/arm/mach-mx2/mach-mx27ads.c
+++ b/arch/arm/mach-imx/mach-mx27ads.c
@@ -12,10 +12,6 @@
* 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/platform_device.h>
@@ -32,16 +28,44 @@
#include <asm/mach/time.h>
#include <asm/mach/map.h>
#include <mach/gpio.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx27.h>
-#include <mach/board-mx27ads.h>
#include <mach/mxc_nand.h>
-#include <mach/i2c.h>
#include <mach/imxfb.h>
#include <mach/mmc.h>
+#include "devices-imx27.h"
#include "devices.h"
+/*
+ * Base address of PBC controller, CS4
+ */
+#define PBC_BASE_ADDRESS 0xf4300000
+#define PBC_REG_ADDR(offset) (void __force __iomem *) \
+ (PBC_BASE_ADDRESS + (offset))
+
+/* When the PBC address connection is fixed in h/w, defined as 1 */
+#define PBC_ADDR_SH 0
+
+/* Offsets for the PBC Controller register */
+/*
+ * PBC Board version register offset
+ */
+#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
+/*
+ * PBC Board control register 1 set address.
+ */
+#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
+/*
+ * PBC Board control register 1 clear address.
+ */
+#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
+
+/* PBC Board Control Register 1 bit definitions */
+#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
+
+/* to determine the correct external crystal reference */
+#define CKIH_27MHZ_BIT_SET (1 << 3)
+
static unsigned int mx27ads_pins[] = {
/* UART0 */
PE12_PF_UART1_TXD,
@@ -141,7 +165,8 @@ static unsigned int mx27ads_pins[] = {
PB9_PF_SD2_CLK,
};
-static struct mxc_nand_platform_data mx27ads_nand_board_info = {
+static const struct mxc_nand_platform_data
+mx27ads_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -168,7 +193,7 @@ static struct platform_device mx27ads_nor_mtd_device = {
.resource = &mx27ads_flash_resource,
};
-static struct imxi2c_platform_data mx27ads_i2c_data = {
+static const struct imxi2c_platform_data mx27ads_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -263,20 +288,8 @@ static struct platform_device *platform_devices[] __initdata = {
&mxc_w1_master_device,
};
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
};
static void __init mx27ads_board_init(void)
@@ -284,18 +297,18 @@ static void __init mx27ads_board_init(void)
mxc_gpio_setup_multiple_pins(mx27ads_pins, ARRAY_SIZE(mx27ads_pins),
"mx27ads");
- mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
- mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
- mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
- mxc_register_device(&mxc_uart_device3, &uart_pdata[3]);
- mxc_register_device(&mxc_uart_device4, &uart_pdata[4]);
- mxc_register_device(&mxc_uart_device5, &uart_pdata[5]);
- mxc_register_device(&imx27_nand_device, &mx27ads_nand_board_info);
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+ imx27_add_imx_uart3(&uart_pdata);
+ imx27_add_imx_uart4(&uart_pdata);
+ imx27_add_imx_uart5(&uart_pdata);
+ imx27_add_mxc_nand(&mx27ads_nand_board_info);
/* only the i2c master 1 is used on this CPU card */
i2c_register_board_info(1, mx27ads_i2c_devices,
ARRAY_SIZE(mx27ads_i2c_devices));
- mxc_register_device(&mxc_i2c_device1, &mx27ads_i2c_data);
+ imx27_add_i2c_imx1(&mx27ads_i2c1_data);
mxc_register_device(&mxc_fb_device, &mx27ads_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
mxc_register_device(&mxc_sdhc_device1, &sdhc2_pdata);
@@ -342,4 +355,3 @@ MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
.init_machine = mx27ads_board_init,
.timer = &mx27ads_timer,
MACHINE_END
-
diff --git a/arch/arm/mach-mx2/mach-mxt_td60.c b/arch/arm/mach-imx/mach-mxt_td60.c
index bc3855992677..a3a1e452d4c5 100644
--- a/arch/arm/mach-mx2/mach-mxt_td60.c
+++ b/arch/arm/mach-imx/mach-mxt_td60.c
@@ -12,10 +12,6 @@
* 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/platform_device.h>
@@ -32,14 +28,13 @@
#include <asm/mach/time.h>
#include <asm/mach/map.h>
#include <linux/gpio.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx27.h>
#include <mach/mxc_nand.h>
-#include <mach/i2c.h>
#include <linux/i2c/pca953x.h>
#include <mach/imxfb.h>
#include <mach/mmc.h>
+#include "devices-imx27.h"
#include "devices.h"
static unsigned int mxt_td60_pins[] __initdata = {
@@ -128,12 +123,13 @@ static unsigned int mxt_td60_pins[] __initdata = {
PB9_PF_SD2_CLK,
};
-static struct mxc_nand_platform_data mxt_td60_nand_board_info = {
+static const struct mxc_nand_platform_data
+mxt_td60_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
-static struct imxi2c_platform_data mxt_td60_i2c_data = {
+static const struct imxi2c_platform_data mxt_td60_i2c0_data __initconst = {
.bitrate = 100000,
};
@@ -173,7 +169,7 @@ static struct i2c_board_info mxt_td60_i2c_devices[] = {
},
};
-static struct imxi2c_platform_data mxt_td60_i2c2_data = {
+static const struct imxi2c_platform_data mxt_td60_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -239,14 +235,8 @@ static struct platform_device *platform_devices[] __initdata = {
&mxc_fec_device,
};
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
};
static void __init mxt_td60_board_init(void)
@@ -254,10 +244,10 @@ static void __init mxt_td60_board_init(void)
mxc_gpio_setup_multiple_pins(mxt_td60_pins, ARRAY_SIZE(mxt_td60_pins),
"MXT_TD60");
- mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
- mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
- mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
- mxc_register_device(&imx27_nand_device, &mxt_td60_nand_board_info);
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
+ imx27_add_mxc_nand(&mxt_td60_nand_board_info);
i2c_register_board_info(0, mxt_td60_i2c_devices,
ARRAY_SIZE(mxt_td60_i2c_devices));
@@ -265,8 +255,8 @@ static void __init mxt_td60_board_init(void)
i2c_register_board_info(1, mxt_td60_i2c2_devices,
ARRAY_SIZE(mxt_td60_i2c2_devices));
- mxc_register_device(&mxc_i2c_device0, &mxt_td60_i2c_data);
- mxc_register_device(&mxc_i2c_device1, &mxt_td60_i2c2_data);
+ imx27_add_i2c_imx0(&mxt_td60_i2c0_data);
+ imx27_add_i2c_imx1(&mxt_td60_i2c1_data);
mxc_register_device(&mxc_fb_device, &mxt_td60_fb_data);
mxc_register_device(&mxc_sdhc_device0, &sdhc1_pdata);
diff --git a/arch/arm/mach-mx2/mach-pca100.c b/arch/arm/mach-imx/mach-pca100.c
index a87422ed4ff5..6c92deaf468f 100644
--- a/arch/arm/mach-mx2/mach-pca100.c
+++ b/arch/arm/mach-imx/mach-pca100.c
@@ -36,12 +36,7 @@
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/iomux-mx27.h>
-#include <mach/i2c.h>
#include <asm/mach/time.h>
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-#include <mach/spi.h>
-#endif
-#include <mach/imx-uart.h>
#include <mach/audmux.h>
#include <mach/ssi.h>
#include <mach/mxc_nand.h>
@@ -49,11 +44,16 @@
#include <mach/mmc.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include <mach/imxfb.h>
+#include "devices-imx27.h"
#include "devices.h"
#define OTG_PHY_CS_GPIO (GPIO_PORTB + 23)
#define USBH2_PHY_CS_GPIO (GPIO_PORTB + 24)
+#define SPI1_SS0 (GPIO_PORTD + 28)
+#define SPI1_SS1 (GPIO_PORTD + 27)
+#define SD2_CD (GPIO_PORTC + 29)
static int pca100_pins[] = {
/* UART1 */
@@ -68,6 +68,7 @@ static int pca100_pins[] = {
PB7_PF_SD2_D3,
PB8_PF_SD2_CMD,
PB9_PF_SD2_CLK,
+ SD2_CD | GPIO_GPIO | GPIO_IN,
/* FEC */
PD0_AIN_FEC_TXD0,
PD1_AIN_FEC_TXD1,
@@ -131,13 +132,42 @@ static int pca100_pins[] = {
PD23_AF_USBH2_DATA2,
PD24_AF_USBH2_DATA1,
PD26_AF_USBH2_DATA5,
+ /* display */
+ PA5_PF_LSCLK,
+ PA6_PF_LD0,
+ PA7_PF_LD1,
+ PA8_PF_LD2,
+ PA9_PF_LD3,
+ PA10_PF_LD4,
+ PA11_PF_LD5,
+ PA12_PF_LD6,
+ PA13_PF_LD7,
+ PA14_PF_LD8,
+ PA15_PF_LD9,
+ PA16_PF_LD10,
+ PA17_PF_LD11,
+ PA18_PF_LD12,
+ PA19_PF_LD13,
+ PA20_PF_LD14,
+ PA21_PF_LD15,
+ PA22_PF_LD16,
+ PA23_PF_LD17,
+ PA26_PF_PS,
+ PA28_PF_HSYNC,
+ PA29_PF_VSYNC,
+ PA31_PF_OE_ACD,
+ /* free GPIO */
+ GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN, /* GPIO0_IRQ */
+ GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN, /* GPIO1_IRQ */
+ GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN, /* GPIO2_IRQ */
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct mxc_nand_platform_data pca100_nand_board_info = {
+static const struct mxc_nand_platform_data
+pca100_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -148,7 +178,7 @@ static struct platform_device *platform_devices[] __initdata = {
&mxc_wdt,
};
-static struct imxi2c_platform_data pca100_i2c_1_data = {
+static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -189,9 +219,9 @@ static struct spi_board_info pca100_spi_board_info[] __initdata = {
},
};
-static int pca100_spi_cs[] = {GPIO_PORTD + 28, GPIO_PORTD + 27};
+static int pca100_spi_cs[] = {SPI1_SS0, SPI1_SS1};
-static struct spi_imx_master pca100_spi_0_data = {
+static const struct spi_imx_master pca100_spi0_data __initconst = {
.chipselect = pca100_spi_cs,
.num_chipselect = ARRAY_SIZE(pca100_spi_cs),
};
@@ -253,6 +283,7 @@ static struct imxmmc_platform_data sdhc_pdata = {
.exit = pca100_sdhc2_exit,
};
+#if defined(CONFIG_USB_ULPI)
static int otg_phy_init(struct platform_device *pdev)
{
gpio_set_value(OTG_PHY_CS_GPIO, 0);
@@ -276,6 +307,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
+#endif
static struct fsl_usb2_platform_data otg_device_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
@@ -297,6 +329,45 @@ static int __init pca100_otg_mode(char *options)
}
__setup("otg_mode=", pca100_otg_mode);
+/* framebuffer info */
+static struct imx_fb_videomode pca100_fb_modes[] = {
+ {
+ .mode = {
+ .name = "EMERGING-ETV570G0DHU",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39722, /* in ps (25.175 MHz) */
+ .hsync_len = 30,
+ .left_margin = 114,
+ .right_margin = 16,
+ .vsync_len = 3,
+ .upper_margin = 32,
+ .lower_margin = 0,
+ },
+ /*
+ * TFT
+ * Pixel pol active high
+ * HSYNC active low
+ * VSYNC active low
+ * use HSYNC for ACD count
+ * line clock disable while idle
+ * always enable line clock even if no data
+ */
+ .pcr = 0xf0c08080,
+ .bpp = 16,
+ },
+};
+
+static struct imx_fb_platform_data pca100_fb_data = {
+ .mode = pca100_fb_modes,
+ .num_modes = ARRAY_SIZE(pca100_fb_modes),
+
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00020010,
+};
+
static void __init pca100_init(void)
{
int ret;
@@ -320,33 +391,24 @@ static void __init pca100_init(void)
mxc_register_device(&imx_ssi_device0, &pca100_ssi_pdata);
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx27_add_imx_uart0(&uart_pdata);
- mxc_gpio_mode(GPIO_PORTC | 29 | GPIO_GPIO | GPIO_IN);
mxc_register_device(&mxc_sdhc_device1, &sdhc_pdata);
- mxc_register_device(&imx27_nand_device, &pca100_nand_board_info);
+ imx27_add_mxc_nand(&pca100_nand_board_info);
/* only the i2c master 1 is used on this CPU card */
i2c_register_board_info(1, pca100_i2c_devices,
ARRAY_SIZE(pca100_i2c_devices));
- mxc_register_device(&mxc_i2c_device1, &pca100_i2c_1_data);
-
- mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_OUT);
- mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_OUT);
-
- /* GPIO0_IRQ */
- mxc_gpio_mode(GPIO_PORTC | 31 | GPIO_GPIO | GPIO_IN);
- /* GPIO1_IRQ */
- mxc_gpio_mode(GPIO_PORTC | 25 | GPIO_GPIO | GPIO_IN);
- /* GPIO2_IRQ */
- mxc_gpio_mode(GPIO_PORTE | 5 | GPIO_GPIO | GPIO_IN);
+ imx27_add_i2c_imx1(&pca100_i2c1_data);
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
+ mxc_gpio_mode(GPIO_PORTD | 28 | GPIO_GPIO | GPIO_IN);
+ mxc_gpio_mode(GPIO_PORTD | 27 | GPIO_GPIO | GPIO_IN);
spi_register_board_info(pca100_spi_board_info,
ARRAY_SIZE(pca100_spi_board_info));
- mxc_register_device(&mxc_spi_device0, &pca100_spi_0_data);
+ imx27_add_spi_imx0(&pca100_spi_0_data);
#endif
gpio_request(OTG_PHY_CS_GPIO, "usb-otg-cs");
@@ -372,6 +434,8 @@ static void __init pca100_init(void)
mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
}
+ mxc_register_device(&mxc_fb_device, &pca100_fb_data);
+
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
}
diff --git a/arch/arm/mach-mx2/mach-pcm038.c b/arch/arm/mach-imx/mach-pcm038.c
index 36c89431679a..9212e8f37001 100644
--- a/arch/arm/mach-mx2/mach-pcm038.c
+++ b/arch/arm/mach-imx/mach-pcm038.c
@@ -35,14 +35,12 @@
#include <mach/board-pcm038.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/i2c.h>
#include <mach/iomux-mx27.h>
-#include <mach/imx-uart.h>
#include <mach/mxc_nand.h>
-#include <mach/spi.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx27.h"
#include "devices.h"
static int pcm038_pins[] = {
@@ -162,17 +160,12 @@ static struct platform_device pcm038_nor_mtd_device = {
.resource = &pcm038_flash_resource,
};
-static struct imxuart_platform_data uart_pdata[] = {
- {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- }, {
- .flags = IMXUART_HAVE_RTSCTS,
- },
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
};
-static struct mxc_nand_platform_data pcm038_nand_board_info = {
+static const struct mxc_nand_platform_data
+pcm038_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -192,7 +185,7 @@ static void __init pcm038_init_sram(void)
mx27_setup_weimcs(1, 0x0000d843, 0x22252521, 0x22220a00);
}
-static struct imxi2c_platform_data pcm038_i2c_1_data = {
+static const struct imxi2c_platform_data pcm038_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -215,7 +208,7 @@ static struct i2c_board_info pcm038_i2c_devices[] = {
static int pcm038_spi_cs[] = {GPIO_PORTD + 28};
-static struct spi_imx_master pcm038_spi_0_data = {
+static const struct spi_imx_master pcm038_spi0_data __initconst = {
.chipselect = pcm038_spi_cs,
.num_chipselect = ARRAY_SIZE(pcm038_spi_cs),
};
@@ -305,18 +298,18 @@ static void __init pcm038_init(void)
pcm038_init_sram();
- mxc_register_device(&mxc_uart_device0, &uart_pdata[0]);
- mxc_register_device(&mxc_uart_device1, &uart_pdata[1]);
- mxc_register_device(&mxc_uart_device2, &uart_pdata[2]);
+ imx27_add_imx_uart0(&uart_pdata);
+ imx27_add_imx_uart1(&uart_pdata);
+ imx27_add_imx_uart2(&uart_pdata);
mxc_gpio_mode(PE16_AF_OWIRE);
- mxc_register_device(&imx27_nand_device, &pcm038_nand_board_info);
+ imx27_add_mxc_nand(&pcm038_nand_board_info);
/* only the i2c master 1 is used on this CPU card */
i2c_register_board_info(1, pcm038_i2c_devices,
ARRAY_SIZE(pcm038_i2c_devices));
- mxc_register_device(&mxc_i2c_device1, &pcm038_i2c_1_data);
+ imx27_add_i2c_imx1(&pcm038_i2c1_data);
/* PE18 for user-LED D40 */
mxc_gpio_mode(GPIO_PORTE | 18 | GPIO_GPIO | GPIO_OUT);
@@ -326,7 +319,7 @@ static void __init pcm038_init(void)
/* MC13783 IRQ */
mxc_gpio_mode(GPIO_PORTB | 23 | GPIO_GPIO | GPIO_IN);
- mxc_register_device(&mxc_spi_device0, &pcm038_spi_0_data);
+ imx27_add_spi_imx0(&pcm038_spi0_data);
spi_register_board_info(pcm038_spi_board_info,
ARRAY_SIZE(pcm038_spi_board_info));
diff --git a/arch/arm/mach-mx1/mach-scb9328.c b/arch/arm/mach-imx/mach-scb9328.c
index 7587a7a12460..88bf0d1e26e6 100644
--- a/arch/arm/mach-mx1/mach-scb9328.c
+++ b/arch/arm/mach-imx/mach-scb9328.c
@@ -22,17 +22,17 @@
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx1.h>
+#include "devices-imx1.h"
#include "devices.h"
/*
* This scb9328 has a 32MiB flash
*/
static struct resource flash_resource = {
- .start = IMX_CS0_PHYS,
- .end = IMX_CS0_PHYS + (32 * 1024 * 1024) - 1,
+ .start = MX1_CS0_PHYS,
+ .end = MX1_CS0_PHYS + (32 * 1024 * 1024) - 1,
.flags = IORESOURCE_MEM,
};
@@ -70,13 +70,13 @@ static struct dm9000_plat_data dm9000_platdata = {
static struct resource dm9000x_resources[] = {
{
.name = "address area",
- .start = IMX_CS5_PHYS,
- .end = IMX_CS5_PHYS + 1,
+ .start = MX1_CS5_PHYS,
+ .end = MX1_CS5_PHYS + 1,
.flags = IORESOURCE_MEM, /* address access */
}, {
.name = "data area",
- .start = IMX_CS5_PHYS + 4,
- .end = IMX_CS5_PHYS + 5,
+ .start = MX1_CS5_PHYS + 4,
+ .end = MX1_CS5_PHYS + 5,
.flags = IORESOURCE_MEM, /* data access */
}, {
.start = IRQ_GPIOC(3),
@@ -108,14 +108,13 @@ static int uart1_mxc_init(struct platform_device *pdev)
ARRAY_SIZE(mxc_uart1_pins), "UART1");
}
-static int uart1_mxc_exit(struct platform_device *pdev)
+static void uart1_mxc_exit(struct platform_device *pdev)
{
mxc_gpio_release_multiple_pins(mxc_uart1_pins,
ARRAY_SIZE(mxc_uart1_pins));
- return 0;
}
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.init = uart1_mxc_init,
.exit = uart1_mxc_exit,
.flags = IMXUART_HAVE_RTSCTS,
@@ -131,7 +130,7 @@ static struct platform_device *devices[] __initdata = {
*/
static void __init scb9328_init(void)
{
- mxc_register_device(&imx_uart1_device, &uart_pdata);
+ imx1_add_imx_uart0(&uart_pdata);
printk(KERN_INFO"Scb9328: Adding devices\n");
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-mx1/generic.c b/arch/arm/mach-imx/mm-imx1.c
index 7f9fc1034c08..117ebf6bc951 100644
--- a/arch/arm/mach-mx1/generic.c
+++ b/arch/arm/mach-imx/mm-imx1.c
@@ -3,7 +3,7 @@
* Created: april 20th, 2004
* Copyright: Synertronixx GmbH
*
- * Common code for i.MX machines
+ * Common code for i.MX1 machines
*
* 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
@@ -14,11 +14,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
*/
#include <linux/kernel.h>
#include <linux/init.h>
@@ -31,23 +26,25 @@
static struct map_desc imx_io_desc[] __initdata = {
{
- .virtual = IMX_IO_BASE,
- .pfn = __phys_to_pfn(IMX_IO_PHYS),
- .length = IMX_IO_SIZE,
- .type = MT_DEVICE
+ .virtual = MX1_IO_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(MX1_IO_BASE_ADDR),
+ .length = MX1_IO_SIZE,
+ .type = MT_DEVICE
}
};
void __init mx1_map_io(void)
{
mxc_set_cpu_type(MXC_CPU_MX1);
- mxc_arch_reset_init(IO_ADDRESS(WDT_BASE_ADDR));
+ mxc_arch_reset_init(MX1_IO_ADDRESS(MX1_WDT_BASE_ADDR));
iotable_init(imx_io_desc, ARRAY_SIZE(imx_io_desc));
}
+int imx1_register_gpios(void);
+
void __init mx1_init_irq(void)
{
- mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
+ imx1_register_gpios();
+ mxc_init_irq(MX1_IO_ADDRESS(MX1_AVIC_BASE_ADDR));
}
-
diff --git a/arch/arm/mach-mx2/mm-imx21.c b/arch/arm/mach-imx/mm-imx21.c
index 64134314d012..68aa5d2ecdb1 100644
--- a/arch/arm/mach-mx2/mm-imx21.c
+++ b/arch/arm/mach-imx/mm-imx21.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/mach-mx2/mm-imx21.c
+ * arch/arm/mach-imx/mm-imx21.c
*
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
@@ -77,7 +77,10 @@ void __init mx21_map_io(void)
iotable_init(imx21_io_desc, ARRAY_SIZE(imx21_io_desc));
}
+int imx21_register_gpios(void);
+
void __init mx21_init_irq(void)
{
+ imx21_register_gpios();
mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
}
diff --git a/arch/arm/mach-mx2/mm-imx27.c b/arch/arm/mach-imx/mm-imx27.c
index 3366ed44cfd5..bcedce9c87dd 100644
--- a/arch/arm/mach-mx2/mm-imx27.c
+++ b/arch/arm/mach-imx/mm-imx27.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/mach-mx2/mm-imx27.c
+ * arch/arm/mach-imx/mm-imx27.c
*
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
@@ -77,7 +77,10 @@ void __init mx27_map_io(void)
iotable_init(imx27_io_desc, ARRAY_SIZE(imx27_io_desc));
}
+int imx27_register_gpios(void);
+
void __init mx27_init_irq(void)
{
+ imx27_register_gpios();
mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
}
diff --git a/arch/arm/mach-mx1/ksym_mx1.c b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
index b09ee12a4ff0..b09ee12a4ff0 100644
--- a/arch/arm/mach-mx1/ksym_mx1.c
+++ b/arch/arm/mach-imx/mx1-camera-fiq-ksym.c
diff --git a/arch/arm/mach-mx1/mx1_camera_fiq.S b/arch/arm/mach-imx/mx1-camera-fiq.S
index 9c69aa65bf17..9c69aa65bf17 100644
--- a/arch/arm/mach-mx1/mx1_camera_fiq.S
+++ b/arch/arm/mach-imx/mx1-camera-fiq.S
diff --git a/arch/arm/mach-mx2/pcm970-baseboard.c b/arch/arm/mach-imx/pcm970-baseboard.c
index f490a406d57e..f490a406d57e 100644
--- a/arch/arm/mach-mx2/pcm970-baseboard.c
+++ b/arch/arm/mach-imx/pcm970-baseboard.c
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
new file mode 100644
index 000000000000..afc17ce0bb54
--- /dev/null
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -0,0 +1,46 @@
+/*
+ * i.MX27 Power Management Routines
+ *
+ * Based on Freescale's BSP
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+#include <mach/mx27.h>
+
+static int mx27_suspend_enter(suspend_state_t state)
+{
+ u32 cscr;
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ /* Clear MPEN and SPEN to disable MPLL/SPLL */
+ cscr = __raw_readl(MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
+ cscr &= 0xFFFFFFFC;
+ __raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
+ /* Executes WFI */
+ arch_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct platform_suspend_ops mx27_suspend_ops = {
+ .enter = mx27_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init mx27_pm_init(void)
+{
+ suspend_set_ops(&mx27_suspend_ops);
+ return 0;
+}
+
+device_initcall(mx27_pm_init);
diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h
new file mode 100644
index 000000000000..5f96e1518aa9
--- /dev/null
+++ b/arch/arm/mach-integrator/common.h
@@ -0,0 +1 @@
+void integrator_reserve(void);
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index b02cfc06e0ae..edb0898ebfde 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -14,6 +14,7 @@
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/lmb.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/termios.h>
@@ -30,6 +31,7 @@
#include <asm/system.h>
#include <asm/leds.h>
#include <asm/mach/time.h>
+#include <asm/pgtable.h>
static struct amba_pl010_data integrator_uart_data;
@@ -215,3 +217,13 @@ void cm_control(u32 mask, u32 set)
}
EXPORT_SYMBOL(cm_control);
+
+/*
+ * We need to stop things allocating the low memory; ideally we need a
+ * better implementation of GFP_DMA which does not assume that DMA-able
+ * memory starts at zero.
+ */
+void __init integrator_reserve(void)
+{
+ lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
+}
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
index 227cf4d05088..6ab5a03ab9d8 100644
--- a/arch/arm/mach-integrator/integrator_ap.c
+++ b/arch/arm/mach-integrator/integrator_ap.c
@@ -48,6 +48,8 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
+#include "common.h"
+
/*
* All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx
* is the (PA >> 12).
@@ -502,6 +504,7 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = ap_map_io,
+ .reserve = integrator_reserve,
.init_irq = ap_init_irq,
.timer = &ap_timer,
.init_machine = ap_init,
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index cde57b2b83b5..05db40e3c4f7 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -43,6 +43,8 @@
#include <plat/timer-sp.h>
+#include "common.h"
+
#define INTCP_PA_FLASH_BASE 0x24000000
#define INTCP_FLASH_SIZE SZ_32M
@@ -601,6 +603,7 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")
.io_pg_offst = ((0xf1600000) >> 18) & 0xfffc,
.boot_params = 0x00000100,
.map_io = intcp_map_io,
+ .reserve = integrator_reserve,
.init_irq = intcp_init_irq,
.timer = &cp_timer,
.init_machine = intcp_init,
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h
index 25b1da9a5035..7415e4338651 100644
--- a/arch/arm/mach-iop13xx/include/mach/memory.h
+++ b/arch/arm/mach-iop13xx/include/mach/memory.h
@@ -69,6 +69,4 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x)
#endif /* CONFIG_ARCH_IOP13XX */
#endif /* !ASSEMBLY */
-#define PFN_TO_NID(addr) (0)
-
#endif
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c
index e3181534c7f9..333d04c53650 100644
--- a/arch/arm/mach-ixp4xx/common-pci.c
+++ b/arch/arm/mach-ixp4xx/common-pci.c
@@ -348,7 +348,7 @@ int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size)
* This is really ugly and we need a better way of specifying
* DMA-capable regions of memory.
*/
-void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size,
+void __init ixp4xx_adjust_zones(unsigned long *zone_size,
unsigned long *zhole_size)
{
unsigned int sz = SZ_64M >> PAGE_SHIFT;
@@ -356,7 +356,7 @@ void __init ixp4xx_adjust_zones(int node, unsigned long *zone_size,
/*
* Only adjust if > 64M on current system
*/
- if (node || (zone_size[0] <= sz))
+ if (zone_size[0] <= sz)
return;
zone_size[1] = zone_size[0] - sz;
diff --git a/arch/arm/mach-ixp4xx/include/mach/memory.h b/arch/arm/mach-ixp4xx/include/mach/memory.h
index 98f5e5e20980..0136eaa29224 100644
--- a/arch/arm/mach-ixp4xx/include/mach/memory.h
+++ b/arch/arm/mach-ixp4xx/include/mach/memory.h
@@ -16,10 +16,10 @@
#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
-void ixp4xx_adjust_zones(int node, unsigned long *size, unsigned long *holes);
+void ixp4xx_adjust_zones(unsigned long *size, unsigned long *holes);
-#define arch_adjust_zones(node, size, holes) \
- ixp4xx_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+ ixp4xx_adjust_zones(size, holes)
#define ISA_DMA_THRESHOLD (SZ_64M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M)
diff --git a/arch/arm/mach-l7200/Makefile b/arch/arm/mach-l7200/Makefile
deleted file mode 100644
index 4bd8ebd70e7b..000000000000
--- a/arch/arm/mach-l7200/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y := core.o
-obj-m :=
-obj-n :=
-obj- :=
-
diff --git a/arch/arm/mach-l7200/Makefile.boot b/arch/arm/mach-l7200/Makefile.boot
deleted file mode 100644
index 6c72ecbe6b64..000000000000
--- a/arch/arm/mach-l7200/Makefile.boot
+++ /dev/null
@@ -1,2 +0,0 @@
- zreladdr-y := 0xf0008000
-
diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c
deleted file mode 100644
index 50d23246d4f0..000000000000
--- a/arch/arm/mach-l7200/core.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * linux/arch/arm/mm/mm-lusl7200.c
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Extra MM routines for L7200 architecture
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/irq.h>
-#include <linux/device.h>
-
-#include <asm/types.h>
-#include <asm/irq.h>
-#include <asm/mach-types.h>
-#include <mach/hardware.h>
-#include <asm/page.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-/*
- * IRQ base register
- */
-#define IRQ_BASE (IO_BASE_2 + 0x1000)
-
-/*
- * Normal IRQ registers
- */
-#define IRQ_STATUS (*(volatile unsigned long *) (IRQ_BASE + 0x000))
-#define IRQ_RAWSTATUS (*(volatile unsigned long *) (IRQ_BASE + 0x004))
-#define IRQ_ENABLE (*(volatile unsigned long *) (IRQ_BASE + 0x008))
-#define IRQ_ENABLECLEAR (*(volatile unsigned long *) (IRQ_BASE + 0x00c))
-#define IRQ_SOFT (*(volatile unsigned long *) (IRQ_BASE + 0x010))
-#define IRQ_SOURCESEL (*(volatile unsigned long *) (IRQ_BASE + 0x018))
-
-/*
- * Fast IRQ registers
- */
-#define FIQ_STATUS (*(volatile unsigned long *) (IRQ_BASE + 0x100))
-#define FIQ_RAWSTATUS (*(volatile unsigned long *) (IRQ_BASE + 0x104))
-#define FIQ_ENABLE (*(volatile unsigned long *) (IRQ_BASE + 0x108))
-#define FIQ_ENABLECLEAR (*(volatile unsigned long *) (IRQ_BASE + 0x10c))
-#define FIQ_SOFT (*(volatile unsigned long *) (IRQ_BASE + 0x110))
-#define FIQ_SOURCESEL (*(volatile unsigned long *) (IRQ_BASE + 0x118))
-
-static void l7200_mask_irq(unsigned int irq)
-{
- IRQ_ENABLECLEAR = 1 << irq;
-}
-
-static void l7200_unmask_irq(unsigned int irq)
-{
- IRQ_ENABLE = 1 << irq;
-}
-
-static struct irq_chip l7200_irq_chip = {
- .ack = l7200_mask_irq,
- .mask = l7200_mask_irq,
- .unmask = l7200_unmask_irq
-};
-
-static void __init l7200_init_irq(void)
-{
- int irq;
-
- IRQ_ENABLECLEAR = 0xffffffff; /* clear all interrupt enables */
- FIQ_ENABLECLEAR = 0xffffffff; /* clear all fast interrupt enables */
-
- for (irq = 0; irq < NR_IRQS; irq++) {
- set_irq_chip(irq, &l7200_irq_chip);
- set_irq_flags(irq, IRQF_VALID);
- set_irq_handler(irq, handle_level_irq);
- }
-
- init_FIQ();
-}
-
-static struct map_desc l7200_io_desc[] __initdata = {
- { IO_BASE, IO_START, IO_SIZE, MT_DEVICE },
- { IO_BASE_2, IO_START_2, IO_SIZE_2, MT_DEVICE },
- { AUX_BASE, AUX_START, AUX_SIZE, MT_DEVICE },
- { FLASH1_BASE, FLASH1_START, FLASH1_SIZE, MT_DEVICE },
- { FLASH2_BASE, FLASH2_START, FLASH2_SIZE, MT_DEVICE }
-};
-
-static void __init l7200_map_io(void)
-{
- iotable_init(l7200_io_desc, ARRAY_SIZE(l7200_io_desc));
-}
-
-MACHINE_START(L7200, "LinkUp Systems L7200")
- /* Maintainer: Steve Hill / Scott McConnell */
- .phys_io = 0x80040000,
- .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc,
- .map_io = l7200_map_io,
- .init_irq = l7200_init_irq,
-MACHINE_END
-
diff --git a/arch/arm/mach-l7200/include/mach/aux_reg.h b/arch/arm/mach-l7200/include/mach/aux_reg.h
deleted file mode 100644
index 4671558cdd51..000000000000
--- a/arch/arm/mach-l7200/include/mach/aux_reg.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/aux_reg.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 08-02-2000 SJH Created file
- */
-#ifndef _ASM_ARCH_AUXREG_H
-#define _ASM_ARCH_AUXREG_H
-
-#include <mach/hardware.h>
-
-#define l7200aux_reg *((volatile unsigned int *) (AUX_BASE))
-
-/*
- * Auxillary register values
- */
-#define AUX_CLEAR 0x00000000
-#define AUX_DIAG_LED_ON 0x00000002
-#define AUX_RTS_UART1 0x00000004
-#define AUX_DTR_UART1 0x00000008
-#define AUX_KBD_COLUMN_12_HIGH 0x00000010
-#define AUX_KBD_COLUMN_12_OFF 0x00000020
-#define AUX_KBD_COLUMN_13_HIGH 0x00000040
-#define AUX_KBD_COLUMN_13_OFF 0x00000080
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/debug-macro.S b/arch/arm/mach-l7200/include/mach/debug-macro.S
deleted file mode 100644
index b69ed344c7c9..000000000000
--- a/arch/arm/mach-l7200/include/mach/debug-macro.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* arch/arm/mach-l7200/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- * Copyright (C) 1994-1999 Russell King
- * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
- .equ io_virt, IO_BASE
- .equ io_phys, IO_START
-
- .macro addruart, rx, tmp
- mrc p15, 0, \rx, c1, c0
- tst \rx, #1 @ MMU enabled?
- moveq \rx, #io_phys @ physical base address
- movne \rx, #io_virt @ virtual address
- add \rx, \rx, #0x00044000 @ UART1
-@ add \rx, \rx, #0x00045000 @ UART2
- .endm
-
- .macro senduart,rd,rx
- str \rd, [\rx, #0x0] @ UARTDR
- .endm
-
- .macro waituart,rd,rx
-1001: ldr \rd, [\rx, #0x18] @ UARTFLG
- tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
- bne 1001b
- .endm
-
- .macro busyuart,rd,rx
-1001: ldr \rd, [\rx, #0x18] @ UARTFLG
- tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
- bne 1001b
- .endm
diff --git a/arch/arm/mach-l7200/include/mach/entry-macro.S b/arch/arm/mach-l7200/include/mach/entry-macro.S
deleted file mode 100644
index 1726d91fc1d3..000000000000
--- a/arch/arm/mach-l7200/include/mach/entry-macro.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/entry-macro.S
- *
- * Low-level IRQ helper macros for L7200-based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <mach/hardware.h>
-
- .equ irq_base_addr, IO_BASE_2
-
- .macro disable_fiq
- .endm
-
- .macro get_irqnr_preamble, base, tmp
- .endm
-
- .macro arch_ret_to_user, tmp1, tmp2
- .endm
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- mov \irqstat, #irq_base_addr @ Virt addr IRQ regs
- add \irqstat, \irqstat, #0x00001000 @ Status reg
- ldr \irqstat, [\irqstat, #0] @ get interrupts
- mov \irqnr, #0
-1001: tst \irqstat, #1
- addeq \irqnr, \irqnr, #1
- moveq \irqstat, \irqstat, lsr #1
- tsteq \irqnr, #32
- beq 1001b
- teq \irqnr, #32
- .endm
-
diff --git a/arch/arm/mach-l7200/include/mach/gp_timers.h b/arch/arm/mach-l7200/include/mach/gp_timers.h
deleted file mode 100644
index 2b7086a26b81..000000000000
--- a/arch/arm/mach-l7200/include/mach/gp_timers.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/gp_timers.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 07-28-2000 SJH Created file
- * 08-02-2000 SJH Used structure for registers
- */
-#ifndef _ASM_ARCH_GPTIMERS_H
-#define _ASM_ARCH_GPTIMERS_H
-
-#include <mach/hardware.h>
-
-/*
- * Layout of L7200 general purpose timer registers
- */
-struct GPT_Regs {
- unsigned int TIMERLOAD;
- unsigned int TIMERVALUE;
- unsigned int TIMERCONTROL;
- unsigned int TIMERCLEAR;
-};
-
-#define GPT_BASE (IO_BASE_2 + 0x3000)
-#define l7200_timer1_regs ((volatile struct GPT_Regs *) (GPT_BASE))
-#define l7200_timer2_regs ((volatile struct GPT_Regs *) (GPT_BASE + 0x20))
-
-/*
- * General register values
- */
-#define GPT_PRESCALE_1 0x00000000
-#define GPT_PRESCALE_16 0x00000004
-#define GPT_PRESCALE_256 0x00000008
-#define GPT_MODE_FREERUN 0x00000000
-#define GPT_MODE_PERIODIC 0x00000040
-#define GPT_ENABLE 0x00000080
-#define GPT_BZTOG 0x00000100
-#define GPT_BZMOD 0x00000200
-#define GPT_LOAD_MASK 0x0000ffff
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/gpio.h b/arch/arm/mach-l7200/include/mach/gpio.h
deleted file mode 100644
index c7b0a5d7b8bb..000000000000
--- a/arch/arm/mach-l7200/include/mach/gpio.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************/
-/*
- * arch/arm/mach-l7200/include/mach/gpio.h
- *
- * Registers and helper functions for the L7200 Link-Up Systems
- * GPIO.
- *
- * (C) Copyright 2000, S A McConnell (samcconn@cotw.com)
- *
- * 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.
- */
-
-/****************************************************************************/
-
-#define GPIO_OFF 0x00005000 /* Offset from IO_START to the GPIO reg's. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define GPIO_START (IO_START_2 + GPIO_OFF) /* Physical addr of the GPIO reg. */
-#define GPIO_BASE (IO_BASE_2 + GPIO_OFF) /* Virtual addr of the GPIO reg. */
-
-/* Offsets from the start of the GPIO for all the registers. */
-#define PADR_OFF 0x000
-#define PADDR_OFF 0x004
-#define PASBSR_OFF 0x008
-#define PAEENR_OFF 0x00c
-#define PAESNR_OFF 0x010
-#define PAESTR_OFF 0x014
-#define PAIMR_OFF 0x018
-#define PAINT_OFF 0x01c
-
-#define PBDR_OFF 0x020
-#define PBDDR_OFF 0x024
-#define PBSBSR_OFF 0x028
-#define PBIMR_OFF 0x038
-#define PBINT_OFF 0x03c
-
-#define PCDR_OFF 0x040
-#define PCDDR_OFF 0x044
-#define PCSBSR_OFF 0x048
-#define PCIMR_OFF 0x058
-#define PCINT_OFF 0x05c
-
-#define PDDR_OFF 0x060
-#define PDDDR_OFF 0x064
-#define PDSBSR_OFF 0x068
-#define PDEENR_OFF 0x06c
-#define PDESNR_OFF 0x070
-#define PDESTR_OFF 0x074
-#define PDIMR_OFF 0x078
-#define PDINT_OFF 0x07c
-
-#define PEDR_OFF 0x080
-#define PEDDR_OFF 0x084
-#define PESBSR_OFF 0x088
-#define PEEENR_OFF 0x08c
-#define PEESNR_OFF 0x090
-#define PEESTR_OFF 0x094
-#define PEIMR_OFF 0x098
-#define PEINT_OFF 0x09c
-
-/* Define the GPIO registers for use by device drivers and the kernel. */
-#define PADR (*(volatile unsigned long *)(GPIO_BASE+PADR_OFF))
-#define PADDR (*(volatile unsigned long *)(GPIO_BASE+PADDR_OFF))
-#define PASBSR (*(volatile unsigned long *)(GPIO_BASE+PASBSR_OFF))
-#define PAEENR (*(volatile unsigned long *)(GPIO_BASE+PAEENR_OFF))
-#define PAESNR (*(volatile unsigned long *)(GPIO_BASE+PAESNR_OFF))
-#define PAESTR (*(volatile unsigned long *)(GPIO_BASE+PAESTR_OFF))
-#define PAIMR (*(volatile unsigned long *)(GPIO_BASE+PAIMR_OFF))
-#define PAINT (*(volatile unsigned long *)(GPIO_BASE+PAINT_OFF))
-
-#define PBDR (*(volatile unsigned long *)(GPIO_BASE+PBDR_OFF))
-#define PBDDR (*(volatile unsigned long *)(GPIO_BASE+PBDDR_OFF))
-#define PBSBSR (*(volatile unsigned long *)(GPIO_BASE+PBSBSR_OFF))
-#define PBIMR (*(volatile unsigned long *)(GPIO_BASE+PBIMR_OFF))
-#define PBINT (*(volatile unsigned long *)(GPIO_BASE+PBINT_OFF))
-
-#define PCDR (*(volatile unsigned long *)(GPIO_BASE+PCDR_OFF))
-#define PCDDR (*(volatile unsigned long *)(GPIO_BASE+PCDDR_OFF))
-#define PCSBSR (*(volatile unsigned long *)(GPIO_BASE+PCSBSR_OFF))
-#define PCIMR (*(volatile unsigned long *)(GPIO_BASE+PCIMR_OFF))
-#define PCINT (*(volatile unsigned long *)(GPIO_BASE+PCINT_OFF))
-
-#define PDDR (*(volatile unsigned long *)(GPIO_BASE+PDDR_OFF))
-#define PDDDR (*(volatile unsigned long *)(GPIO_BASE+PDDDR_OFF))
-#define PDSBSR (*(volatile unsigned long *)(GPIO_BASE+PDSBSR_OFF))
-#define PDEENR (*(volatile unsigned long *)(GPIO_BASE+PDEENR_OFF))
-#define PDESNR (*(volatile unsigned long *)(GPIO_BASE+PDESNR_OFF))
-#define PDESTR (*(volatile unsigned long *)(GPIO_BASE+PDESTR_OFF))
-#define PDIMR (*(volatile unsigned long *)(GPIO_BASE+PDIMR_OFF))
-#define PDINT (*(volatile unsigned long *)(GPIO_BASE+PDINT_OFF))
-
-#define PEDR (*(volatile unsigned long *)(GPIO_BASE+PEDR_OFF))
-#define PEDDR (*(volatile unsigned long *)(GPIO_BASE+PEDDR_OFF))
-#define PESBSR (*(volatile unsigned long *)(GPIO_BASE+PESBSR_OFF))
-#define PEEENR (*(volatile unsigned long *)(GPIO_BASE+PEEENR_OFF))
-#define PEESNR (*(volatile unsigned long *)(GPIO_BASE+PEESNR_OFF))
-#define PEESTR (*(volatile unsigned long *)(GPIO_BASE+PEESTR_OFF))
-#define PEIMR (*(volatile unsigned long *)(GPIO_BASE+PEIMR_OFF))
-#define PEINT (*(volatile unsigned long *)(GPIO_BASE+PEINT_OFF))
-
-#define VEE_EN 0x02
-#define BACKLIGHT_EN 0x04
diff --git a/arch/arm/mach-l7200/include/mach/hardware.h b/arch/arm/mach-l7200/include/mach/hardware.h
deleted file mode 100644
index c31909cfc254..000000000000
--- a/arch/arm/mach-l7200/include/mach/hardware.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/hardware.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- * Steve Hill (sjhill@cotw.com)
- *
- * This file contains the hardware definitions for the
- * LinkUp Systems L7200 SOC development board.
- *
- * Changelog:
- * 02-01-2000 RS Created L7200 version, derived from rpc code
- * 03-21-2000 SJH Cleaned up file
- * 04-21-2000 RS Changed mapping of I/O in virtual space
- * 04-25-2000 SJH Removed unused symbols and such
- * 05-05-2000 SJH Complete rewrite
- * 07-31-2000 SJH Added undocumented debug auxillary port to
- * get at last two columns for keyboard driver
- */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/* Hardware addresses of major areas.
- * *_START is the physical address
- * *_SIZE is the size of the region
- * *_BASE is the virtual address
- */
-#define RAM_START 0xf0000000
-#define RAM_SIZE 0x02000000
-#define RAM_BASE 0xc0000000
-
-#define IO_START 0x80000000 /* I/O */
-#define IO_SIZE 0x01000000
-#define IO_BASE 0xd0000000
-
-#define IO_START_2 0x90000000 /* I/O */
-#define IO_SIZE_2 0x01000000
-#define IO_BASE_2 0xd1000000
-
-#define AUX_START 0x1a000000 /* AUX PORT */
-#define AUX_SIZE 0x01000000
-#define AUX_BASE 0xd2000000
-
-#define FLASH1_START 0x00000000 /* FLASH BANK 1 */
-#define FLASH1_SIZE 0x01000000
-#define FLASH1_BASE 0xd3000000
-
-#define FLASH2_START 0x10000000 /* FLASH BANK 2 */
-#define FLASH2_SIZE 0x01000000
-#define FLASH2_BASE 0xd4000000
-
-#define ISA_START 0x20000000 /* ISA */
-#define ISA_SIZE 0x20000000
-#define ISA_BASE 0xe0000000
-
-#define PCIO_BASE IO_BASE
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/io.h b/arch/arm/mach-l7200/include/mach/io.h
deleted file mode 100644
index a770a89fb708..000000000000
--- a/arch/arm/mach-l7200/include/mach/io.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/io.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 03-21-2000 SJH Created from arch/arm/mach-nexuspci/include/mach/io.h
- * 08-31-2000 SJH Added in IO functions necessary for new drivers
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-/*
- * There are not real ISA nor PCI buses, so we fake it.
- */
-#define __io(a) __typesafe_io(a)
-#define __mem_pci(a) (a)
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/irqs.h b/arch/arm/mach-l7200/include/mach/irqs.h
deleted file mode 100644
index 7edffd713c5b..000000000000
--- a/arch/arm/mach-l7200/include/mach/irqs.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/irqs.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- * Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 01-02-2000 RS Create l7200 version
- * 03-28-2000 SJH Removed unused interrupt
- * 07-28-2000 SJH Added pseudo-keyboard interrupt
- */
-
-/*
- * NOTE: The second timer (Timer 2) is used as the keyboard
- * interrupt when the keyboard driver is enabled.
- */
-
-#define NR_IRQS 32
-
-#define IRQ_STWDOG 0 /* Watchdog timer */
-#define IRQ_PROG 1 /* Programmable interrupt */
-#define IRQ_DEBUG_RX 2 /* Comm Rx debug */
-#define IRQ_DEBUG_TX 3 /* Comm Tx debug */
-#define IRQ_GCTC1 4 /* Timer 1 */
-#define IRQ_GCTC2 5 /* Timer 2 / Keyboard */
-#define IRQ_DMA 6 /* DMA controller */
-#define IRQ_CLCD 7 /* Color LCD controller */
-#define IRQ_SM_RX 8 /* Smart card */
-#define IRQ_SM_TX 9 /* Smart cart */
-#define IRQ_SM_RST 10 /* Smart card */
-#define IRQ_SIB 11 /* Serial Interface Bus */
-#define IRQ_MMC 12 /* MultiMediaCard */
-#define IRQ_SSP1 13 /* Synchronous Serial Port 1 */
-#define IRQ_SSP2 14 /* Synchronous Serial Port 1 */
-#define IRQ_SPI 15 /* SPI slave */
-#define IRQ_UART_1 16 /* UART 1 */
-#define IRQ_UART_2 17 /* UART 2 */
-#define IRQ_IRDA 18 /* IRDA */
-#define IRQ_RTC_TICK 19 /* Real Time Clock tick */
-#define IRQ_RTC_ALARM 20 /* Real Time Clock alarm */
-#define IRQ_GPIO 21 /* General Purpose IO */
-#define IRQ_GPIO_DMA 22 /* General Purpose IO, DMA */
-#define IRQ_M2M 23 /* Memory to memory DMA */
-#define IRQ_RESERVED 24 /* RESERVED, don't use */
-#define IRQ_INTF 25 /* External active low interrupt */
-#define IRQ_INT0 26 /* External active low interrupt */
-#define IRQ_INT1 27 /* External active low interrupt */
-#define IRQ_INT2 28 /* External active low interrupt */
-#define IRQ_UCB1200 29 /* Interrupt generated by UCB1200*/
-#define IRQ_BAT_LO 30 /* Low batery or external power */
-#define IRQ_MEDIA_CHG 31 /* Media change interrupt */
-
-/*
- * This is the offset of the FIQ "IRQ" numbers
- */
-#define FIQ_START 64
diff --git a/arch/arm/mach-l7200/include/mach/memory.h b/arch/arm/mach-l7200/include/mach/memory.h
deleted file mode 100644
index 9fb40ed2f03b..000000000000
--- a/arch/arm/mach-l7200/include/mach/memory.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/memory.h
- *
- * Copyright (c) 2000 Steve Hill (sjhill@cotw.com)
- * Copyright (c) 2000 Rob Scott (rscott@mtrob.fdns.net)
- *
- * Changelog:
- * 03-13-2000 SJH Created
- * 04-13-2000 RS Changed bus macros for new addr
- * 05-03-2000 SJH Removed bus macros and fixed virt_to_phys macro
- */
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset on the L7200 SDB.
- */
-#define PHYS_OFFSET UL(0xf0000000)
-
-/*
- * Cache flushing area - ROM
- */
-#define FLUSH_BASE_PHYS 0x40000000
-#define FLUSH_BASE 0xdf000000
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/pmpcon.h b/arch/arm/mach-l7200/include/mach/pmpcon.h
deleted file mode 100644
index 3959871e8361..000000000000
--- a/arch/arm/mach-l7200/include/mach/pmpcon.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/****************************************************************************/
-/*
- * arch/arm/mach-l7200/include/mach/pmpcon.h
- *
- * Registers and helper functions for the L7200 Link-Up Systems
- * DC/DC converter register.
- *
- * (C) Copyright 2000, S A McConnell (samcconn@cotw.com)
- *
- * 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.
- */
-
-/****************************************************************************/
-
-#define PMPCON_OFF 0x00006000 /* Offset from IO_START_2. */
-
-/* IO_START_2 and IO_BASE_2 are defined in hardware.h */
-
-#define PMPCON_START (IO_START_2 + PMPCON_OFF) /* Physical address of reg. */
-#define PMPCON_BASE (IO_BASE_2 + PMPCON_OFF) /* Virtual address of reg. */
-
-
-#define PMPCON (*(volatile unsigned int *)(PMPCON_BASE))
-
-#define PWM2_50CYCLE 0x800
-#define CONTRAST 0x9
-
-#define PWM1H (CONTRAST)
-#define PWM1L (CONTRAST << 4)
-
-#define PMPCON_VALUE (PWM2_50CYCLE | PWM1L | PWM1H)
-
-/* PMPCON = 0x811; // too light and fuzzy
- * PMPCON = 0x844;
- * PMPCON = 0x866; // better color poor depth
- * PMPCON = 0x888; // Darker but better depth
- * PMPCON = 0x899; // Darker even better depth
- * PMPCON = 0x8aa; // too dark even better depth
- * PMPCON = 0X8cc; // Way too dark
- */
-
-/* As CONTRAST value increases the greater the depth perception and
- * the darker the colors.
- */
diff --git a/arch/arm/mach-l7200/include/mach/pmu.h b/arch/arm/mach-l7200/include/mach/pmu.h
deleted file mode 100644
index a2da7aedf208..000000000000
--- a/arch/arm/mach-l7200/include/mach/pmu.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************/
-/*
- * arch/arm/mach-l7200/include/mach/pmu.h
- *
- * Registers and helper functions for the L7200 Link-Up Systems
- * Power Management Unit (PMU).
- *
- * (C) Copyright 2000, S A McConnell (samcconn@cotw.com)
- *
- * 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.
- */
-
-/****************************************************************************/
-
-#define PMU_OFF 0x00050000 /* Offset from IO_START to the PMU registers. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define PMU_START (IO_START + PMU_OFF) /* Physical addr. of the PMU reg. */
-#define PMU_BASE (IO_BASE + PMU_OFF) /* Virtual addr. of the PMU reg. */
-
-
-/* Define the PMU registers for use by device drivers and the kernel. */
-
-typedef struct {
- unsigned int CURRENT; /* Current configuration register */
- unsigned int NEXT; /* Next configuration register */
- unsigned int reserved;
- unsigned int RUN; /* Run configuration register */
- unsigned int COMM; /* Configuration command register */
- unsigned int SDRAM; /* SDRAM configuration bypass register */
-} pmu_interface;
-
-#define PMU ((volatile pmu_interface *)(PMU_BASE))
-
-
-/* Macro's for reading the common register fields. */
-
-#define GET_TRANSOP(reg) ((reg >> 25) & 0x03) /* Bits 26-25 */
-#define GET_OSCEN(reg) ((reg >> 16) & 0x01)
-#define GET_OSCMUX(reg) ((reg >> 15) & 0x01)
-#define GET_PLLMUL(reg) ((reg >> 9) & 0x3f) /* Bits 14-9 */
-#define GET_PLLEN(reg) ((reg >> 8) & 0x01)
-#define GET_PLLMUX(reg) ((reg >> 7) & 0x01)
-#define GET_BCLK_DIV(reg) ((reg >> 3) & 0x03) /* Bits 4-3 */
-#define GET_SDRB_SEL(reg) ((reg >> 2) & 0x01)
-#define GET_SDRF_SEL(reg) ((reg >> 1) & 0x01)
-#define GET_FASTBUS(reg) (reg & 0x1)
-
-/* CFG_NEXT register */
-
-#define CFG_NEXT_CLOCKRECOVERY ((PMU->NEXT >> 18) & 0x7f) /* Bits 24-18 */
-#define CFG_NEXT_INTRET ((PMU->NEXT >> 17) & 0x01)
-#define CFG_NEXT_SDR_STOP ((PMU->NEXT >> 6) & 0x01)
-#define CFG_NEXT_SYSCLKEN ((PMU->NEXT >> 5) & 0x01)
-
-/* Useful field values that can be used to construct the
- * CFG_NEXT and CFG_RUN registers.
- */
-
-#define TRANSOP_NOP 0<<25 /* NOCHANGE_NOSTALL */
-#define NOCHANGE_STALL 1<<25
-#define CHANGE_NOSTALL 2<<25
-#define CHANGE_STALL 3<<25
-
-#define INTRET 1<<17
-#define OSCEN 1<<16
-#define OSCMUX 1<<15
-
-/* PLL frequencies */
-
-#define PLLMUL_0 0<<9 /* 3.6864 MHz */
-#define PLLMUL_1 1<<9 /* ?????? MHz */
-#define PLLMUL_5 5<<9 /* 18.432 MHz */
-#define PLLMUL_10 10<<9 /* 36.864 MHz */
-#define PLLMUL_18 18<<9 /* ?????? MHz */
-#define PLLMUL_20 20<<9 /* 73.728 MHz */
-#define PLLMUL_32 32<<9 /* ?????? MHz */
-#define PLLMUL_35 35<<9 /* 129.024 MHz */
-#define PLLMUL_36 36<<9 /* ?????? MHz */
-#define PLLMUL_39 39<<9 /* ?????? MHz */
-#define PLLMUL_40 40<<9 /* 147.456 MHz */
-
-/* Clock recovery times */
-
-#define CRCLOCK_1 1<<18
-#define CRCLOCK_2 2<<18
-#define CRCLOCK_4 4<<18
-#define CRCLOCK_8 8<<18
-#define CRCLOCK_16 16<<18
-#define CRCLOCK_32 32<<18
-#define CRCLOCK_63 63<<18
-#define CRCLOCK_127 127<<18
-
-#define PLLEN 1<<8
-#define PLLMUX 1<<7
-#define SDR_STOP 1<<6
-#define SYSCLKEN 1<<5
-
-#define BCLK_DIV_4 2<<3
-#define BCLK_DIV_2 1<<3
-#define BCLK_DIV_1 0<<3
-
-#define SDRB_SEL 1<<2
-#define SDRF_SEL 1<<1
-#define FASTBUS 1<<0
-
-
-/* CFG_SDRAM */
-
-#define SDRREFFQ 1<<0 /* Only if SDRSTOPRQ is not set. */
-#define SDRREFACK 1<<1 /* Read-only */
-#define SDRSTOPRQ 1<<2 /* Only if SDRREFFQ is not set. */
-#define SDRSTOPACK 1<<3 /* Read-only */
-#define PICEN 1<<4 /* Enable Co-procesor */
-#define PICTEST 1<<5
-
-#define GET_SDRREFFQ ((PMU->SDRAM >> 0) & 0x01)
-#define GET_SDRREFACK ((PMU->SDRAM >> 1) & 0x01) /* Read-only */
-#define GET_SDRSTOPRQ ((PMU->SDRAM >> 2) & 0x01)
-#define GET_SDRSTOPACK ((PMU->SDRAM >> 3) & 0x01) /* Read-only */
-#define GET_PICEN ((PMU->SDRAM >> 4) & 0x01)
-#define GET_PICTEST ((PMU->SDRAM >> 5) & 0x01)
diff --git a/arch/arm/mach-l7200/include/mach/serial.h b/arch/arm/mach-l7200/include/mach/serial.h
deleted file mode 100644
index adc05e5f8378..000000000000
--- a/arch/arm/mach-l7200/include/mach/serial.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/serial.h
- *
- * Copyright (c) 2000 Rob Scott (rscott@mtrob.fdns.net)
- * Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 03-20-2000 SJH Created
- * 03-26-2000 SJH Added flags for serial ports
- * 03-27-2000 SJH Corrected BASE_BAUD value
- * 04-14-2000 RS Made register addr dependent on IO_BASE
- * 05-03-2000 SJH Complete rewrite
- * 05-09-2000 SJH Stripped out architecture specific serial stuff
- * and placed it in a separate file
- * 07-28-2000 SJH Moved base baud rate variable
- */
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-/*
- * This assumes you have a 3.6864 MHz clock for your UART.
- */
-#define BASE_BAUD 3686400
-
-/*
- * Standard COM flags
- */
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-#define STD_SERIAL_PORT_DEFNS \
- /* MAGIC UART CLK PORT IRQ FLAGS */ \
- { 0, BASE_BAUD, UART1_BASE, IRQ_UART_1, STD_COM_FLAGS }, /* ttyLU0 */ \
- { 0, BASE_BAUD, UART2_BASE, IRQ_UART_2, STD_COM_FLAGS }, /* ttyLU1 */ \
-
-#define EXTRA_SERIAL_PORT_DEFNS
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/serial_l7200.h b/arch/arm/mach-l7200/include/mach/serial_l7200.h
deleted file mode 100644
index 645f1c5e568d..000000000000
--- a/arch/arm/mach-l7200/include/mach/serial_l7200.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/serial_l7200.h
- *
- * Copyright (c) 2000 Steven Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 05-09-2000 SJH Created
- */
-#ifndef __ASM_ARCH_SERIAL_L7200_H
-#define __ASM_ARCH_SERIAL_L7200_H
-
-#include <mach/memory.h>
-
-/*
- * This assumes you have a 3.6864 MHz clock for your UART.
- */
-#define BASE_BAUD 3686400
-
-/*
- * UART base register addresses
- */
-#define UART1_BASE (IO_BASE + 0x00044000)
-#define UART2_BASE (IO_BASE + 0x00045000)
-
-/*
- * UART register offsets
- */
-#define UARTDR 0x00 /* Tx/Rx data */
-#define RXSTAT 0x04 /* Rx status */
-#define H_UBRLCR 0x08 /* mode register high */
-#define M_UBRLCR 0x0C /* mode reg mid (MSB of baud)*/
-#define L_UBRLCR 0x10 /* mode reg low (LSB of baud)*/
-#define UARTCON 0x14 /* control register */
-#define UARTFLG 0x18 /* flag register */
-#define UARTINTSTAT 0x1C /* FIFO IRQ status register */
-#define UARTINTMASK 0x20 /* FIFO IRQ mask register */
-
-/*
- * UART baud rate register values
- */
-#define BR_110 0x827
-#define BR_1200 0x06e
-#define BR_2400 0x05f
-#define BR_4800 0x02f
-#define BR_9600 0x017
-#define BR_14400 0x00f
-#define BR_19200 0x00b
-#define BR_38400 0x005
-#define BR_57600 0x003
-#define BR_76800 0x002
-#define BR_115200 0x001
-
-/*
- * Receiver status register (RXSTAT) mask values
- */
-#define RXSTAT_NO_ERR 0x00 /* No error */
-#define RXSTAT_FRM_ERR 0x01 /* Framing error */
-#define RXSTAT_PAR_ERR 0x02 /* Parity error */
-#define RXSTAT_OVR_ERR 0x04 /* Overrun error */
-
-/*
- * High byte of UART bit rate and line control register (H_UBRLCR) values
- */
-#define UBRLCR_BRK 0x01 /* generate break on tx */
-#define UBRLCR_PEN 0x02 /* enable parity */
-#define UBRLCR_PDIS 0x00 /* disable parity */
-#define UBRLCR_EVEN 0x04 /* 1= even parity,0 = odd parity */
-#define UBRLCR_STP2 0x08 /* transmit 2 stop bits */
-#define UBRLCR_FIFO 0x10 /* enable FIFO */
-#define UBRLCR_LEN5 0x60 /* word length5 */
-#define UBRLCR_LEN6 0x40 /* word length6 */
-#define UBRLCR_LEN7 0x20 /* word length7 */
-#define UBRLCR_LEN8 0x00 /* word length8 */
-
-/*
- * UART control register (UARTCON) values
- */
-#define UARTCON_UARTEN 0x01 /* Enable UART */
-#define UARTCON_DMAONERR 0x08 /* Mask RxDmaRq when errors occur */
-
-/*
- * UART flag register (UARTFLG) mask values
- */
-#define UARTFLG_UTXFF 0x20 /* Transmit FIFO full */
-#define UARTFLG_URXFE 0x10 /* Receiver FIFO empty */
-#define UARTFLG_UBUSY 0x08 /* Transmitter busy */
-#define UARTFLG_DCD 0x04 /* Data carrier detect */
-#define UARTFLG_DSR 0x02 /* Data set ready */
-#define UARTFLG_CTS 0x01 /* Clear to send */
-
-/*
- * UART interrupt status/clear registers (UARTINTSTAT/CLR) values
- */
-#define UART_TXINT 0x01 /* TX interrupt */
-#define UART_RXINT 0x02 /* RX interrupt */
-#define UART_RXERRINT 0x04 /* RX error interrupt */
-#define UART_MSINT 0x08 /* Modem Status interrupt */
-#define UART_UDINT 0x10 /* UART Disabled interrupt */
-#define UART_ALLIRQS 0x1f /* All interrupts */
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/sib.h b/arch/arm/mach-l7200/include/mach/sib.h
deleted file mode 100644
index 965728712cf3..000000000000
--- a/arch/arm/mach-l7200/include/mach/sib.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/****************************************************************************/
-/*
- * arch/arm/mach-l7200/include/mach/sib.h
- *
- * Registers and helper functions for the Serial Interface Bus.
- *
- * (C) Copyright 2000, S A McConnell (samcconn@cotw.com)
- *
- * 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.
- */
-
-/****************************************************************************/
-
-#define SIB_OFF 0x00040000 /* Offset from IO_START to the SIB reg's. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define SIB_START (IO_START + SIB_OFF) /* Physical addr of the SIB reg. */
-#define SIB_BASE (IO_BASE + SIB_OFF) /* Virtual addr of the SIB reg. */
-
-/* Offsets from the start of the SIB for all the registers. */
-
-/* Define the SIB registers for use by device drivers and the kernel. */
-
-typedef struct
-{
- unsigned int MCCR; /* SIB Control Register Offset: 0x00 */
- unsigned int RES1; /* Reserved Offset: 0x04 */
- unsigned int MCDR0; /* SIB Data Register 0 Offset: 0x08 */
- unsigned int MCDR1; /* SIB Data Register 1 Offset: 0x0c */
- unsigned int MCDR2; /* SIB Data Register 2 (UCB1x00) Offset: 0x10 */
- unsigned int RES2; /* Reserved Offset: 0x14 */
- unsigned int MCSR; /* SIB Status Register Offset: 0x18 */
-} SIB_Interface;
-
-#define SIB ((volatile SIB_Interface *) (SIB_BASE))
-
-/* MCCR */
-
-#define INTERNAL_FREQ 9216000 /* Hertz */
-#define AUDIO_FREQ 5000 /* Hertz */
-#define TELECOM_FREQ 5000 /* Hertz */
-
-#define AUDIO_DIVIDE (INTERNAL_FREQ / (32 * AUDIO_FREQ))
-#define TELECOM_DIVIDE (INTERNAL_FREQ / (32 * TELECOM_FREQ))
-
-#define MCCR_ASD57 AUDIO_DIVIDE
-#define MCCR_TSD57 (TELECOM_DIVIDE << 8)
-#define MCCR_MCE (1 << 16) /* SIB enable */
-#define MCCR_ECS (1 << 17) /* External Clock Select */
-#define MCCR_ADM (1 << 18) /* A/D Data Sampling */
-#define MCCR_PMC (1 << 26) /* PIN Multiplexer Control */
-
-
-#define GET_ASD ((SIB->MCCR >> 0) & 0x3f) /* Audio Sample Rate Div. */
-#define GET_TSD ((SIB->MCCR >> 8) & 0x3f) /* Telcom Sample Rate Div. */
-#define GET_MCE ((SIB->MCCR >> 16) & 0x01) /* SIB Enable */
-#define GET_ECS ((SIB->MCCR >> 17) & 0x01) /* External Clock Select */
-#define GET_ADM ((SIB->MCCR >> 18) & 0x01) /* A/D Data Sampling Mode */
-#define GET_TTM ((SIB->MCCR >> 19) & 0x01) /* Telco Trans. FIFO I mask */
-#define GET_TRM ((SIB->MCCR >> 20) & 0x01) /* Telco Recv. FIFO I mask */
-#define GET_ATM ((SIB->MCCR >> 21) & 0x01) /* Audio Trans. FIFO I mask */
-#define GET_ARM ((SIB->MCCR >> 22) & 0x01) /* Audio Recv. FIFO I mask */
-#define GET_LBM ((SIB->MCCR >> 23) & 0x01) /* Loop Back Mode */
-#define GET_ECP ((SIB->MCCR >> 24) & 0x03) /* Extern. Clck Prescale sel */
-#define GET_PMC ((SIB->MCCR >> 26) & 0x01) /* PIN Multiplexer Control */
-#define GET_ERI ((SIB->MCCR >> 27) & 0x01) /* External Read Interrupt */
-#define GET_EWI ((SIB->MCCR >> 28) & 0x01) /* External Write Interrupt */
-
-/* MCDR0 */
-
-#define AUDIO_RECV ((SIB->MCDR0 >> 4) & 0xfff)
-#define AUDIO_WRITE(v) ((SIB->MCDR0 = (v & 0xfff) << 4))
-
-/* MCDR1 */
-
-#define TELECOM_RECV ((SIB->MCDR1 >> 2) & 032fff)
-#define TELECOM_WRITE(v) ((SIB->MCDR1 = (v & 0x3fff) << 2))
-
-
-/* MCSR */
-
-#define MCSR_ATU (1 << 4) /* Audio Transmit FIFO Underrun */
-#define MCSR_ARO (1 << 5) /* Audio Receive FIFO Underrun */
-#define MCSR_TTU (1 << 6) /* TELECOM Transmit FIFO Underrun */
-#define MCSR_TRO (1 << 7) /* TELECOM Receive FIFO Underrun */
-
-#define MCSR_CLEAR_UNDERUN_BITS (MCSR_ATU | MCSR_ARO | MCSR_TTU | MCSR_TRO)
-
-
-#define GET_ATS ((SIB->MCSR >> 0) & 0x01) /* Audio Transmit FIFO Service Req*/
-#define GET_ARS ((SIB->MCSR >> 1) & 0x01) /* Audio Recv FIFO Service Request*/
-#define GET_TTS ((SIB->MCSR >> 2) & 0x01) /* TELECOM Transmit FIFO Flag */
-#define GET_TRS ((SIB->MCSR >> 3) & 0x01) /* TELECOM Recv FIFO Service Req. */
-#define GET_ATU ((SIB->MCSR >> 4) & 0x01) /* Audio Transmit FIFO Underrun */
-#define GET_ARO ((SIB->MCSR >> 5) & 0x01) /* Audio Receive FIFO Underrun */
-#define GET_TTU ((SIB->MCSR >> 6) & 0x01) /* TELECOM Transmit FIFO Underrun */
-#define GET_TRO ((SIB->MCSR >> 7) & 0x01) /* TELECOM Receive FIFO Underrun */
-#define GET_ANF ((SIB->MCSR >> 8) & 0x01) /* Audio Transmit FIFO not full */
-#define GET_ANE ((SIB->MCSR >> 9) & 0x01) /* Audio Receive FIFO not empty */
-#define GET_TNF ((SIB->MCSR >> 10) & 0x01) /* Telecom Transmit FIFO not full */
-#define GET_TNE ((SIB->MCSR >> 11) & 0x01) /* Telecom Receive FIFO not empty */
-#define GET_CWC ((SIB->MCSR >> 12) & 0x01) /* Codec Write Complete */
-#define GET_CRC ((SIB->MCSR >> 13) & 0x01) /* Codec Read Complete */
-#define GET_ACE ((SIB->MCSR >> 14) & 0x01) /* Audio Codec Enabled */
-#define GET_TCE ((SIB->MCSR >> 15) & 0x01) /* Telecom Codec Enabled */
-
-/* MCDR2 */
-
-#define MCDR2_rW (1 << 16)
-
-#define WRITE_MCDR2(reg, data) (SIB->MCDR2 =((reg<<17)|MCDR2_rW|(data&0xffff)))
-#define MCDR2_WRITE_COMPLETE GET_CWC
-
-#define INITIATE_MCDR2_READ(reg) (SIB->MCDR2 = (reg << 17))
-#define MCDR2_READ_COMPLETE GET_CRC
-#define MCDR2_READ (SIB->MCDR2 & 0xffff)
diff --git a/arch/arm/mach-l7200/include/mach/sys-clock.h b/arch/arm/mach-l7200/include/mach/sys-clock.h
deleted file mode 100644
index e9729a35751d..000000000000
--- a/arch/arm/mach-l7200/include/mach/sys-clock.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************/
-/*
- * arch/arm/mach-l7200/include/mach/sys-clock.h
- *
- * Registers and helper functions for the L7200 Link-Up Systems
- * System clocks.
- *
- * (C) Copyright 2000, S A McConnell (samcconn@cotw.com)
- *
- * 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.
- */
-
-/****************************************************************************/
-
-#define SYS_CLOCK_OFF 0x00050030 /* Offset from IO_START. */
-
-/* IO_START and IO_BASE are defined in hardware.h */
-
-#define SYS_CLOCK_START (IO_START + SYS_CLOCK_OFF) /* Physical address */
-#define SYS_CLOCK_BASE (IO_BASE + SYS_CLOCK_OFF) /* Virtual address */
-
-/* Define the interface to the SYS_CLOCK */
-
-typedef struct
-{
- unsigned int ENABLE;
- unsigned int ESYNC;
- unsigned int SELECT;
-} sys_clock_interface;
-
-#define SYS_CLOCK ((volatile sys_clock_interface *)(SYS_CLOCK_BASE))
-
-//#define CLOCK_EN (*(volatile unsigned long *)(PMU_BASE+CLOCK_EN_OFF))
-//#define CLOCK_ESYNC (*(volatile unsigned long *)(PMU_BASE+CLOCK_ESYNC_OFF))
-//#define CLOCK_SEL (*(volatile unsigned long *)(PMU_BASE+CLOCK_SEL_OFF))
-
-/* SYS_CLOCK -> ENABLE */
-
-#define SYN_EN 1<<0
-#define B18M_EN 1<<1
-#define CLK3M6_EN 1<<2
-#define BUART_EN 1<<3
-#define CLK18MU_EN 1<<4
-#define FIR_EN 1<<5
-#define MIRN_EN 1<<6
-#define UARTM_EN 1<<7
-#define SIBADC_EN 1<<8
-#define ALTD_EN 1<<9
-#define CLCLK_EN 1<<10
-
-/* SYS_CLOCK -> SELECT */
-
-#define CLK18M_DIV 1<<0
-#define MIR_SEL 1<<1
-#define SSP_SEL 1<<4
-#define MM_DIV 1<<5
-#define MM_SEL 1<<6
-#define ADC_SEL_2 0<<7
-#define ADC_SEL_4 1<<7
-#define ADC_SEL_8 3<<7
-#define ADC_SEL_16 7<<7
-#define ADC_SEL_32 0x0f<<7
-#define ADC_SEL_64 0x1f<<7
-#define ADC_SEL_128 0x3f<<7
-#define ALTD_SEL 1<<13
diff --git a/arch/arm/mach-l7200/include/mach/system.h b/arch/arm/mach-l7200/include/mach/system.h
deleted file mode 100644
index e0dd3b6ae4aa..000000000000
--- a/arch/arm/mach-l7200/include/mach/system.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/system.h
- *
- * Copyright (c) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog
- * 03-21-2000 SJH Created
- * 04-26-2000 SJH Fixed functions
- * 05-03-2000 SJH Removed usage of obsolete 'iomd.h'
- * 05-31-2000 SJH Properly implemented 'arch_idle'
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/hardware.h>
-
-static inline void arch_idle(void)
-{
- *(unsigned long *)(IO_BASE + 0x50004) = 1; /* idle mode */
-}
-
-static inline void arch_reset(char mode, const char *cmd)
-{
- if (mode == 's') {
- cpu_reset(0);
- }
-}
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/time.h b/arch/arm/mach-l7200/include/mach/time.h
deleted file mode 100644
index 061771c2c2bd..000000000000
--- a/arch/arm/mach-l7200/include/mach/time.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/time.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- * Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 01-02-2000 RS Created l7200 version, derived from rpc code
- * 05-03-2000 SJH Complete rewrite
- */
-#ifndef _ASM_ARCH_TIME_H
-#define _ASM_ARCH_TIME_H
-
-#include <mach/irqs.h>
-
-/*
- * RTC base register address
- */
-#define RTC_BASE (IO_BASE_2 + 0x2000)
-
-/*
- * RTC registers
- */
-#define RTC_RTCDR (*(volatile unsigned char *) (RTC_BASE + 0x000))
-#define RTC_RTCMR (*(volatile unsigned char *) (RTC_BASE + 0x004))
-#define RTC_RTCS (*(volatile unsigned char *) (RTC_BASE + 0x008))
-#define RTC_RTCC (*(volatile unsigned char *) (RTC_BASE + 0x008))
-#define RTC_RTCDV (*(volatile unsigned char *) (RTC_BASE + 0x00c))
-#define RTC_RTCCR (*(volatile unsigned char *) (RTC_BASE + 0x010))
-
-/*
- * RTCCR register values
- */
-#define RTC_RATE_32 0x00 /* 32 Hz tick */
-#define RTC_RATE_64 0x10 /* 64 Hz tick */
-#define RTC_RATE_128 0x20 /* 128 Hz tick */
-#define RTC_RATE_256 0x30 /* 256 Hz tick */
-#define RTC_EN_ALARM 0x01 /* Enable alarm */
-#define RTC_EN_TIC 0x04 /* Enable counter */
-#define RTC_EN_STWDOG 0x08 /* Enable watchdog */
-
-/*
- * Handler for RTC timer interrupt
- */
-static irqreturn_t
-timer_interrupt(int irq, void *dev_id)
-{
- struct pt_regs *regs = get_irq_regs();
- do_timer(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(regs));
-#endif
- do_profile(regs);
- RTC_RTCC = 0; /* Clear interrupt */
-
- return IRQ_HANDLED;
-}
-
-/*
- * Set up RTC timer interrupt, and return the current time in seconds.
- */
-void __init time_init(void)
-{
- RTC_RTCC = 0; /* Clear interrupt */
-
- timer_irq.handler = timer_interrupt;
-
- setup_irq(IRQ_RTC_TICK, &timer_irq);
-
- RTC_RTCCR = RTC_RATE_128 | RTC_EN_TIC; /* Set rate and enable timer */
-}
-
-#endif
diff --git a/arch/arm/mach-l7200/include/mach/timex.h b/arch/arm/mach-l7200/include/mach/timex.h
deleted file mode 100644
index ffc96a63b5a2..000000000000
--- a/arch/arm/mach-l7200/include/mach/timex.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/timex.h
- *
- * Copyright (C) 2000 Rob Scott (rscott@mtrob.fdns.net)
- * Steve Hill (sjhill@cotw.com)
- *
- * 04-21-2000 RS Created file
- * 05-03-2000 SJH Tick rate was wrong
- *
- */
-
-/*
- * On the ARM720T, clock ticks are set to 128 Hz.
- *
- * NOTE: The actual RTC value is set in 'time.h' which
- * must be changed when choosing a different tick
- * rate. The value of HZ in 'param.h' must also
- * be changed to match below.
- */
-#define CLOCK_TICK_RATE 128
diff --git a/arch/arm/mach-l7200/include/mach/uncompress.h b/arch/arm/mach-l7200/include/mach/uncompress.h
deleted file mode 100644
index 591c962bb315..000000000000
--- a/arch/arm/mach-l7200/include/mach/uncompress.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/uncompress.h
- *
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- *
- * Changelog:
- * 05-01-2000 SJH Created
- * 05-13-2000 SJH Filled in function bodies
- * 07-26-2000 SJH Removed hard coded baud rate
- */
-
-#include <mach/hardware.h>
-
-#define IO_UART IO_START + 0x00044000
-
-#define __raw_writeb(v,p) (*(volatile unsigned char *)(p) = (v))
-#define __raw_readb(p) (*(volatile unsigned char *)(p))
-
-static inline void putc(int c)
-{
- while(__raw_readb(IO_UART + 0x18) & 0x20 ||
- __raw_readb(IO_UART + 0x18) & 0x08)
- barrier();
-
- __raw_writeb(c, IO_UART + 0x00);
-}
-
-static inline void flush(void)
-{
-}
-
-static __inline__ void arch_decomp_setup(void)
-{
- __raw_writeb(0x00, IO_UART + 0x08); /* Set HSB */
- __raw_writeb(0x00, IO_UART + 0x20); /* Disable IRQs */
- __raw_writeb(0x01, IO_UART + 0x14); /* Enable UART */
-}
-
-#define arch_decomp_wdog()
diff --git a/arch/arm/mach-l7200/include/mach/vmalloc.h b/arch/arm/mach-l7200/include/mach/vmalloc.h
deleted file mode 100644
index 85f0abbf15f1..000000000000
--- a/arch/arm/mach-l7200/include/mach/vmalloc.h
+++ /dev/null
@@ -1,4 +0,0 @@
-/*
- * arch/arm/mach-l7200/include/mach/vmalloc.h
- */
-#define VMALLOC_END (PAGE_OFFSET + 0x10000000)
diff --git a/arch/arm/mach-lh7a40x/include/mach/memory.h b/arch/arm/mach-lh7a40x/include/mach/memory.h
index 189d20e543e7..edb8f5faf5d5 100644
--- a/arch/arm/mach-lh7a40x/include/mach/memory.h
+++ b/arch/arm/mach-lh7a40x/include/mach/memory.h
@@ -19,50 +19,6 @@
*/
#define PHYS_OFFSET UL(0xc0000000)
-#ifdef CONFIG_DISCONTIGMEM
-
-/*
- * Given a kernel address, find the home node of the underlying memory.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-# define KVADDR_TO_NID(addr) \
- ( ((((unsigned long) (addr) - PAGE_OFFSET) >> 24) & 1)\
- | ((((unsigned long) (addr) - PAGE_OFFSET) >> 25) & ~1))
-# else /* 2 banks per node */
-# define KVADDR_TO_NID(addr) \
- (((unsigned long) (addr) - PAGE_OFFSET) >> 26)
-# endif
-
-/*
- * Given a page frame number, convert it to a node id.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-# define PFN_TO_NID(pfn) \
- (((((pfn) - PHYS_PFN_OFFSET) >> (24 - PAGE_SHIFT)) & 1)\
- | ((((pfn) - PHYS_PFN_OFFSET) >> (25 - PAGE_SHIFT)) & ~1))
-# else /* 2 banks per node */
-# define PFN_TO_NID(pfn) \
- (((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT))
-#endif
-
-/*
- * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
- * and returns the index corresponding to the appropriate page in the
- * node's mem_map.
- */
-
-# ifdef CONFIG_LH7A40X_ONE_BANK_PER_NODE
-# define LOCAL_MAP_NR(addr) \
- (((unsigned long)(addr) & 0x003fffff) >> PAGE_SHIFT)
-# else /* 2 banks per node */
-# define LOCAL_MAP_NR(addr) \
- (((unsigned long)(addr) & 0x01ffffff) >> PAGE_SHIFT)
-# endif
-
-#endif
-
/*
* Sparsemem version of the above
*/
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 47264a76eeb3..737cf3ea543b 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -10,6 +10,7 @@ config ARCH_MSM7X00A
select MSM_SMD
select MSM_SMD_PKG3
select CPU_V6
+ select MSM7200A_GPIO
config ARCH_MSM7X30
bool "MSM7x30"
@@ -18,6 +19,7 @@ config ARCH_MSM7X30
select MSM_VIC
select CPU_V7
select MSM_REMOTE_SPINLOCK_DEKKERS
+ select MSM7200A_GPIO
config ARCH_QSD8X50
bool "QSD8X50"
@@ -26,6 +28,8 @@ config ARCH_QSD8X50
select MSM_VIC
select CPU_V7
select MSM_REMOTE_SPINLOCK_LDREX
+ select MSM7200A_GPIO
+
endchoice
config MSM_SOC_REV_A
@@ -106,4 +110,7 @@ config MSM_SMD_PKG3
config MSM_SMD
bool
+config MSM7200A_GPIO
+ bool
+
endif
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 66677f0acaed..df7bf971258b 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -15,8 +15,8 @@ obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o
-obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o
+obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o board-trout-mmc.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
-
+obj-$(CONFIG_MSM7200A_GPIO) += msm7200a-gpio.o
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
index af5e85b91d02..6ca42fd5ce2a 100644
--- a/arch/arm/mach-msm/acpuclock-arm11.c
+++ b/arch/arm/mach-msm/acpuclock-arm11.c
@@ -17,7 +17,6 @@
*
*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/list.h>
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index e32981928c77..2db85d5dde0e 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -55,7 +55,29 @@ static void msm7x30_init_uart2(void)
}
#endif
-static struct platform_device *devices[] __initdata = {
+/*
+ * Early devices are those which provide a system service which will be
+ * required by one or more of the function calls in msm7x30_init.
+ * These devices must be probed and online first in order for
+ * the init routine to run successfully.
+ */
+static struct platform_device *early_devices[] __initdata = {
+ &msm_gpio_devices[0],
+ &msm_gpio_devices[1],
+ &msm_gpio_devices[2],
+ &msm_gpio_devices[3],
+ &msm_gpio_devices[4],
+ &msm_gpio_devices[5],
+ &msm_gpio_devices[6],
+ &msm_gpio_devices[7],
+};
+
+/*
+ * Late devices are those which are dependent upon services initialized
+ * by msm7x30_init, or which simply have no dependents and can have
+ * their initialization deferred.
+ */
+static struct platform_device *late_devices[] __initdata = {
#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
&msm_device_uart2,
#endif
@@ -69,11 +91,11 @@ static void __init msm7x30_init_irq(void)
static void __init msm7x30_init(void)
{
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ platform_add_devices(early_devices, ARRAY_SIZE(early_devices));
#ifdef CONFIG_SERIAL_MSM_CONSOLE
msm7x30_init_uart2();
#endif
-
+ platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
}
static void __init msm7x30_map_io(void)
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index e3cc80792d6c..508333c999ef 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -40,7 +40,29 @@ static struct msm_gpio uart3_config_data[] = {
{ GPIO_CFG(87, 1, GPIO_OUTPUT, GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
};
-static struct platform_device *devices[] __initdata = {
+/*
+ * Early devices are those which provide a system service which will be
+ * required by one or more of the function calls in qsd8x50_init.
+ * These devices must be probed and online first in order for
+ * the init routine to run successfully.
+ */
+static struct platform_device *early_devices[] __initdata = {
+ &msm_gpio_devices[0],
+ &msm_gpio_devices[1],
+ &msm_gpio_devices[2],
+ &msm_gpio_devices[3],
+ &msm_gpio_devices[4],
+ &msm_gpio_devices[5],
+ &msm_gpio_devices[6],
+ &msm_gpio_devices[7],
+};
+
+/*
+ * Late devices are those which are dependent upon services initialized
+ * by qsd8x50_init, or which simply have no dependents and can have
+ * their initialization deferred.
+ */
+static struct platform_device *late_devices[] __initdata = {
&msm_device_uart3,
};
@@ -64,8 +86,9 @@ static void __init qsd8x50_init_irq(void)
static void __init qsd8x50_init(void)
{
+ platform_add_devices(early_devices, ARRAY_SIZE(early_devices));
msm8x50_init_uart3();
- platform_add_devices(devices, ARRAY_SIZE(devices));
+ platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
}
MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c
new file mode 100644
index 000000000000..c50f3afc3134
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-gpio.c
@@ -0,0 +1,227 @@
+/*
+ * linux/arch/arm/mach-msm/gpio.c
+ *
+ * Copyright (C) 2005 HP Labs
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2009 Pavel Machek <pavel@ucw.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+
+#include "board-trout.h"
+
+static uint8_t trout_int_mask[2] = {
+ [0] = 0xff, /* mask all interrupts */
+ [1] = 0xff,
+};
+static uint8_t trout_sleep_int_mask[] = {
+ [0] = 0xff,
+ [1] = 0xff,
+};
+
+struct msm_gpio_chip {
+ struct gpio_chip chip;
+ void __iomem *reg; /* Base of register bank */
+ u8 shadow;
+};
+
+#define to_msm_gpio_chip(c) container_of(c, struct msm_gpio_chip, chip)
+
+static int msm_gpiolib_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
+ unsigned mask = 1 << offset;
+
+ return !!(readb(msm_gpio->reg) & mask);
+}
+
+static void msm_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
+ unsigned mask = 1 << offset;
+
+ if (val)
+ msm_gpio->shadow |= mask;
+ else
+ msm_gpio->shadow &= ~mask;
+
+ writeb(msm_gpio->shadow, msm_gpio->reg);
+}
+
+static int msm_gpiolib_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ msm_gpiolib_set(chip, offset, 0);
+ return 0;
+}
+
+static int msm_gpiolib_direction_output(struct gpio_chip *chip,
+ unsigned offset, int val)
+{
+ msm_gpiolib_set(chip, offset, val);
+ return 0;
+}
+
+#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
+ { \
+ .chip = { \
+ .label = name, \
+ .direction_input = msm_gpiolib_direction_input,\
+ .direction_output = msm_gpiolib_direction_output, \
+ .get = msm_gpiolib_get, \
+ .set = msm_gpiolib_set, \
+ .base = base_gpio, \
+ .ngpio = 8, \
+ }, \
+ .reg = (void *) reg_num + TROUT_CPLD_BASE, \
+ .shadow = shadow_val, \
+ }
+
+static struct msm_gpio_chip msm_gpio_banks[] = {
+#if defined(CONFIG_MSM_DEBUG_UART1)
+ /* H2W pins <-> UART1 */
+ TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x40),
+#else
+ /* H2W pins <-> UART3, Bluetooth <-> UART1 */
+ TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x80),
+#endif
+ /* I2C pull */
+ TROUT_GPIO_BANK("MISC3", 0x02, TROUT_GPIO_MISC3_BASE, 0x04),
+ TROUT_GPIO_BANK("MISC4", 0x04, TROUT_GPIO_MISC4_BASE, 0),
+ /* mmdi 32k en */
+ TROUT_GPIO_BANK("MISC5", 0x06, TROUT_GPIO_MISC5_BASE, 0x04),
+ TROUT_GPIO_BANK("INT2", 0x08, TROUT_GPIO_INT2_BASE, 0),
+ TROUT_GPIO_BANK("MISC1", 0x0a, TROUT_GPIO_MISC1_BASE, 0),
+ TROUT_GPIO_BANK("VIRTUAL", 0x12, TROUT_GPIO_VIRTUAL_BASE, 0),
+};
+
+static void trout_gpio_irq_ack(unsigned int irq)
+{
+ int bank = TROUT_INT_TO_BANK(irq);
+ uint8_t mask = TROUT_INT_TO_MASK(irq);
+ int reg = TROUT_BANK_TO_STAT_REG(bank);
+ /*printk(KERN_INFO "trout_gpio_irq_ack irq %d\n", irq);*/
+ writeb(mask, TROUT_CPLD_BASE + reg);
+}
+
+static void trout_gpio_irq_mask(unsigned int irq)
+{
+ unsigned long flags;
+ uint8_t reg_val;
+ int bank = TROUT_INT_TO_BANK(irq);
+ uint8_t mask = TROUT_INT_TO_MASK(irq);
+ int reg = TROUT_BANK_TO_MASK_REG(bank);
+
+ local_irq_save(flags);
+ reg_val = trout_int_mask[bank] |= mask;
+ /*printk(KERN_INFO "trout_gpio_irq_mask irq %d => %d:%02x\n",
+ irq, bank, reg_val);*/
+ writeb(reg_val, TROUT_CPLD_BASE + reg);
+ local_irq_restore(flags);
+}
+
+static void trout_gpio_irq_unmask(unsigned int irq)
+{
+ unsigned long flags;
+ uint8_t reg_val;
+ int bank = TROUT_INT_TO_BANK(irq);
+ uint8_t mask = TROUT_INT_TO_MASK(irq);
+ int reg = TROUT_BANK_TO_MASK_REG(bank);
+
+ local_irq_save(flags);
+ reg_val = trout_int_mask[bank] &= ~mask;
+ /*printk(KERN_INFO "trout_gpio_irq_unmask irq %d => %d:%02x\n",
+ irq, bank, reg_val);*/
+ writeb(reg_val, TROUT_CPLD_BASE + reg);
+ local_irq_restore(flags);
+}
+
+int trout_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+ unsigned long flags;
+ int bank = TROUT_INT_TO_BANK(irq);
+ uint8_t mask = TROUT_INT_TO_MASK(irq);
+
+ local_irq_save(flags);
+ if(on)
+ trout_sleep_int_mask[bank] &= ~mask;
+ else
+ trout_sleep_int_mask[bank] |= mask;
+ local_irq_restore(flags);
+ return 0;
+}
+
+static void trout_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ int j, m;
+ unsigned v;
+ int bank;
+ int stat_reg;
+ int int_base = TROUT_INT_START;
+ uint8_t int_mask;
+
+ for (bank = 0; bank < 2; bank++) {
+ stat_reg = TROUT_BANK_TO_STAT_REG(bank);
+ v = readb(TROUT_CPLD_BASE + stat_reg);
+ int_mask = trout_int_mask[bank];
+ if (v & int_mask) {
+ writeb(v & int_mask, TROUT_CPLD_BASE + stat_reg);
+ printk(KERN_ERR "trout_gpio_irq_handler: got masked "
+ "interrupt: %d:%02x\n", bank, v & int_mask);
+ }
+ v &= ~int_mask;
+ while (v) {
+ m = v & -v;
+ j = fls(m) - 1;
+ /*printk(KERN_INFO "msm_gpio_irq_handler %d:%02x %02x b"
+ "it %d irq %d\n", bank, v, m, j, int_base + j);*/
+ v &= ~m;
+ generic_handle_irq(int_base + j);
+ }
+ int_base += TROUT_INT_BANK0_COUNT;
+ }
+ desc->chip->ack(irq);
+}
+
+static struct irq_chip trout_gpio_irq_chip = {
+ .name = "troutgpio",
+ .ack = trout_gpio_irq_ack,
+ .mask = trout_gpio_irq_mask,
+ .unmask = trout_gpio_irq_unmask,
+ .set_wake = trout_gpio_irq_set_wake,
+};
+
+/*
+ * Called from the processor-specific init to enable GPIO pin support.
+ */
+int __init trout_init_gpio(void)
+{
+ int i;
+ for(i = TROUT_INT_START; i <= TROUT_INT_END; i++) {
+ set_irq_chip(i, &trout_gpio_irq_chip);
+ set_irq_handler(i, handle_edge_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
+ gpiochip_add(&msm_gpio_banks[i].chip);
+
+ set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH);
+ set_irq_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler);
+ set_irq_wake(MSM_GPIO_TO_INT(17), 1);
+
+ return 0;
+}
+
+postcore_initcall(trout_init_gpio);
+
diff --git a/arch/arm/mach-msm/board-trout-mmc.c b/arch/arm/mach-msm/board-trout-mmc.c
new file mode 100644
index 000000000000..7a773f8c13dc
--- /dev/null
+++ b/arch/arm/mach-msm/board-trout-mmc.c
@@ -0,0 +1,189 @@
+/* linux/arch/arm/mach-msm/board-trout-mmc.c
+** Author: Brian Swetland <swetland@google.com>
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+
+#include <asm/gpio.h>
+#include <asm/io.h>
+
+#include <mach/vreg.h>
+
+#include <mach/mmc.h>
+
+#include "devices.h"
+
+#include "board-trout.h"
+
+#include "proc_comm.h"
+
+#define DEBUG_SDSLOT_VDD 1
+
+extern int msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat,
+ unsigned int stat_irq, unsigned long stat_irq_flags);
+
+/* ---- COMMON ---- */
+static void config_gpio_table(uint32_t *table, int len)
+{
+ int n;
+ unsigned id;
+ for(n = 0; n < len; n++) {
+ id = table[n];
+ msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0);
+ }
+}
+
+/* ---- SDCARD ---- */
+
+static uint32_t sdcard_on_gpio_table[] = {
+ PCOM_GPIO_CFG(62, 2, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA), /* CLK */
+ PCOM_GPIO_CFG(63, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* CMD */
+ PCOM_GPIO_CFG(64, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT3 */
+ PCOM_GPIO_CFG(65, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_8MA), /* DAT2 */
+ PCOM_GPIO_CFG(66, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT1 */
+ PCOM_GPIO_CFG(67, 2, GPIO_OUTPUT, GPIO_PULL_UP, GPIO_4MA), /* DAT0 */
+};
+
+static uint32_t sdcard_off_gpio_table[] = {
+ PCOM_GPIO_CFG(62, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CLK */
+ PCOM_GPIO_CFG(63, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* CMD */
+ PCOM_GPIO_CFG(64, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT3 */
+ PCOM_GPIO_CFG(65, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT2 */
+ PCOM_GPIO_CFG(66, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT1 */
+ PCOM_GPIO_CFG(67, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_4MA), /* DAT0 */
+};
+
+static uint opt_disable_sdcard;
+
+static int __init trout_disablesdcard_setup(char *str)
+{
+ int cal = simple_strtol(str, NULL, 0);
+
+ opt_disable_sdcard = cal;
+ return 1;
+}
+
+__setup("board_trout.disable_sdcard=", trout_disablesdcard_setup);
+
+static struct vreg *vreg_sdslot; /* SD slot power */
+
+struct mmc_vdd_xlat {
+ int mask;
+ int level;
+};
+
+static struct mmc_vdd_xlat mmc_vdd_table[] = {
+ { MMC_VDD_165_195, 1800 },
+ { MMC_VDD_20_21, 2050 },
+ { MMC_VDD_21_22, 2150 },
+ { MMC_VDD_22_23, 2250 },
+ { MMC_VDD_23_24, 2350 },
+ { MMC_VDD_24_25, 2450 },
+ { MMC_VDD_25_26, 2550 },
+ { MMC_VDD_26_27, 2650 },
+ { MMC_VDD_27_28, 2750 },
+ { MMC_VDD_28_29, 2850 },
+ { MMC_VDD_29_30, 2950 },
+};
+
+static unsigned int sdslot_vdd = 0xffffffff;
+static unsigned int sdslot_vreg_enabled;
+
+static uint32_t trout_sdslot_switchvdd(struct device *dev, unsigned int vdd)
+{
+ int i, rc;
+
+ BUG_ON(!vreg_sdslot);
+
+ if (vdd == sdslot_vdd)
+ return 0;
+
+ sdslot_vdd = vdd;
+
+ if (vdd == 0) {
+#if DEBUG_SDSLOT_VDD
+ printk("%s: Disabling SD slot power\n", __func__);
+#endif
+ config_gpio_table(sdcard_off_gpio_table,
+ ARRAY_SIZE(sdcard_off_gpio_table));
+ vreg_disable(vreg_sdslot);
+ sdslot_vreg_enabled = 0;
+ return 0;
+ }
+
+ if (!sdslot_vreg_enabled) {
+ rc = vreg_enable(vreg_sdslot);
+ if (rc) {
+ printk(KERN_ERR "%s: Error enabling vreg (%d)\n",
+ __func__, rc);
+ }
+ config_gpio_table(sdcard_on_gpio_table,
+ ARRAY_SIZE(sdcard_on_gpio_table));
+ sdslot_vreg_enabled = 1;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(mmc_vdd_table); i++) {
+ if (mmc_vdd_table[i].mask == (1 << vdd)) {
+#if DEBUG_SDSLOT_VDD
+ printk("%s: Setting level to %u\n",
+ __func__, mmc_vdd_table[i].level);
+#endif
+ rc = vreg_set_level(vreg_sdslot,
+ mmc_vdd_table[i].level);
+ if (rc) {
+ printk(KERN_ERR
+ "%s: Error setting vreg level (%d)\n",
+ __func__, rc);
+ }
+ return 0;
+ }
+ }
+
+ printk(KERN_ERR "%s: Invalid VDD %d specified\n", __func__, vdd);
+ return 0;
+}
+
+static unsigned int trout_sdslot_status(struct device *dev)
+{
+ unsigned int status;
+
+ status = (unsigned int) gpio_get_value(TROUT_GPIO_SDMC_CD_N);
+ return (!status);
+}
+
+#define TROUT_MMC_VDD MMC_VDD_165_195 | MMC_VDD_20_21 | MMC_VDD_21_22 \
+ | MMC_VDD_22_23 | MMC_VDD_23_24 | MMC_VDD_24_25 \
+ | MMC_VDD_25_26 | MMC_VDD_26_27 | MMC_VDD_27_28 \
+ | MMC_VDD_28_29 | MMC_VDD_29_30
+
+static struct mmc_platform_data trout_sdslot_data = {
+ .ocr_mask = TROUT_MMC_VDD,
+ .status = trout_sdslot_status,
+ .translate_vdd = trout_sdslot_switchvdd,
+};
+
+int __init trout_init_mmc(unsigned int sys_rev)
+{
+ sdslot_vreg_enabled = 0;
+
+ vreg_sdslot = vreg_get(0, "gp6");
+ if (IS_ERR(vreg_sdslot))
+ return PTR_ERR(vreg_sdslot);
+
+ set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1);
+
+ if (!opt_disable_sdcard)
+ msm_add_sdcc(2, &trout_sdslot_data,
+ TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 0);
+ else
+ printk(KERN_INFO "trout: SD-Card interface disabled\n");
+ return 0;
+}
+
diff --git a/arch/arm/mach-msm/board-trout.c b/arch/arm/mach-msm/board-trout.c
index dca5a5f062dc..469e0be3499d 100644
--- a/arch/arm/mach-msm/board-trout.c
+++ b/arch/arm/mach-msm/board-trout.c
@@ -30,6 +30,8 @@
#include "devices.h"
#include "board-trout.h"
+extern int trout_init_mmc(unsigned int);
+
static struct platform_device *devices[] __initdata = {
&msm_device_uart3,
&msm_device_smd,
@@ -50,13 +52,21 @@ static void __init trout_fixup(struct machine_desc *desc, struct tag *tags,
{
mi->nr_banks = 1;
mi->bank[0].start = PHYS_OFFSET;
- mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
mi->bank[0].size = (101*1024*1024);
}
static void __init trout_init(void)
{
+ int rc;
+
platform_add_devices(devices, ARRAY_SIZE(devices));
+
+#ifdef CONFIG_MMC
+ rc = trout_init_mmc(system_rev);
+ if (rc)
+ printk(KERN_CRIT "%s: MMC init failure (%d)\n", __func__, rc);
+#endif
+
}
static struct map_desc trout_io_desc[] __initdata = {
diff --git a/arch/arm/mach-msm/board-trout.h b/arch/arm/mach-msm/board-trout.h
index 4f345a5a0a61..651851c3e1dd 100644
--- a/arch/arm/mach-msm/board-trout.h
+++ b/arch/arm/mach-msm/board-trout.h
@@ -1,5 +1,162 @@
+/* linux/arch/arm/mach-msm/board-trout.h
+** Author: Brian Swetland <swetland@google.com>
+*/
+#ifndef __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
+#define __ARCH_ARM_MACH_MSM_BOARD_TROUT_H
+
+#include <mach/board.h>
+
+#define MSM_SMI_BASE 0x00000000
+#define MSM_SMI_SIZE 0x00800000
+
+#define MSM_EBI_BASE 0x10000000
+#define MSM_EBI_SIZE 0x06e00000
+
+#define MSM_PMEM_GPU0_BASE 0x00000000
+#define MSM_PMEM_GPU0_SIZE 0x00700000
+
+#define MSM_PMEM_MDP_BASE 0x02000000
+#define MSM_PMEM_MDP_SIZE 0x00800000
+
+#define MSM_PMEM_ADSP_BASE 0x02800000
+#define MSM_PMEM_ADSP_SIZE 0x00800000
+
+#define MSM_PMEM_CAMERA_BASE 0x03000000
+#define MSM_PMEM_CAMERA_SIZE 0x00800000
+
+#define MSM_FB_BASE 0x03800000
+#define MSM_FB_SIZE 0x00100000
+
+#define MSM_LINUX_BASE MSM_EBI_BASE
+#define MSM_LINUX_SIZE 0x06500000
+
+#define MSM_PMEM_GPU1_SIZE 0x800000
+#define MSM_PMEM_GPU1_BASE (MSM_RAM_CONSOLE_BASE - MSM_PMEM_GPU1_SIZE)
+
+#define MSM_RAM_CONSOLE_BASE (MSM_EBI_BASE + 0x6d00000)
+#define MSM_RAM_CONSOLE_SIZE (128 * SZ_1K)
+
+#if (MSM_FB_BASE + MSM_FB_SIZE) >= (MSM_PMEM_GPU1_BASE)
+#error invalid memory map
+#endif
+
+#define DECLARE_MSM_IOMAP
+#include <mach/msm_iomap.h>
+
+#define TROUT_4_BALL_UP_0 1
+#define TROUT_4_BALL_LEFT_0 18
+#define TROUT_4_BALL_DOWN_0 57
+#define TROUT_4_BALL_RIGHT_0 91
+
+#define TROUT_5_BALL_UP_0 94
+#define TROUT_5_BALL_LEFT_0 18
+#define TROUT_5_BALL_DOWN_0 90
+#define TROUT_5_BALL_RIGHT_0 19
+
+#define TROUT_POWER_KEY 20
+
+#define TROUT_4_TP_LS_EN 19
+#define TROUT_5_TP_LS_EN 1
#define TROUT_CPLD_BASE 0xE8100000
#define TROUT_CPLD_START 0x98000000
#define TROUT_CPLD_SIZE SZ_4K
+#define TROUT_GPIO_CABLE_IN1 (83)
+#define TROUT_GPIO_CABLE_IN2 (49)
+
+#define TROUT_GPIO_START (128)
+
+#define TROUT_GPIO_INT_MASK0_REG (0x0c)
+#define TROUT_GPIO_INT_STAT0_REG (0x0e)
+#define TROUT_GPIO_INT_MASK1_REG (0x14)
+#define TROUT_GPIO_INT_STAT1_REG (0x10)
+
+#define TROUT_GPIO_HAPTIC_PWM (28)
+#define TROUT_GPIO_PS_HOLD (25)
+
+#define TROUT_GPIO_MISC2_BASE (TROUT_GPIO_START + 0x00)
+#define TROUT_GPIO_MISC3_BASE (TROUT_GPIO_START + 0x08)
+#define TROUT_GPIO_MISC4_BASE (TROUT_GPIO_START + 0x10)
+#define TROUT_GPIO_MISC5_BASE (TROUT_GPIO_START + 0x18)
+#define TROUT_GPIO_INT2_BASE (TROUT_GPIO_START + 0x20)
+#define TROUT_GPIO_MISC1_BASE (TROUT_GPIO_START + 0x28)
+#define TROUT_GPIO_VIRTUAL_BASE (TROUT_GPIO_START + 0x30)
+#define TROUT_GPIO_INT5_BASE (TROUT_GPIO_START + 0x48)
+
+#define TROUT_GPIO_CHARGER_EN (TROUT_GPIO_MISC2_BASE + 0)
+#define TROUT_GPIO_ISET (TROUT_GPIO_MISC2_BASE + 1)
+#define TROUT_GPIO_H2W_DAT_DIR (TROUT_GPIO_MISC2_BASE + 2)
+#define TROUT_GPIO_H2W_CLK_DIR (TROUT_GPIO_MISC2_BASE + 3)
+#define TROUT_GPIO_H2W_DAT_GPO (TROUT_GPIO_MISC2_BASE + 4)
+#define TROUT_GPIO_H2W_CLK_GPO (TROUT_GPIO_MISC2_BASE + 5)
+#define TROUT_GPIO_H2W_SEL0 (TROUT_GPIO_MISC2_BASE + 6)
+#define TROUT_GPIO_H2W_SEL1 (TROUT_GPIO_MISC2_BASE + 7)
+
+#define TROUT_GPIO_SPOTLIGHT_EN (TROUT_GPIO_MISC3_BASE + 0)
+#define TROUT_GPIO_FLASH_EN (TROUT_GPIO_MISC3_BASE + 1)
+#define TROUT_GPIO_I2C_PULL (TROUT_GPIO_MISC3_BASE + 2)
+#define TROUT_GPIO_TP_I2C_PULL (TROUT_GPIO_MISC3_BASE + 3)
+#define TROUT_GPIO_TP_EN (TROUT_GPIO_MISC3_BASE + 4)
+#define TROUT_GPIO_JOG_EN (TROUT_GPIO_MISC3_BASE + 5)
+#define TROUT_GPIO_UI_LED_EN (TROUT_GPIO_MISC3_BASE + 6)
+#define TROUT_GPIO_QTKEY_LED_EN (TROUT_GPIO_MISC3_BASE + 7)
+
+#define TROUT_GPIO_VCM_PWDN (TROUT_GPIO_MISC4_BASE + 0)
+#define TROUT_GPIO_USB_H2W_SW (TROUT_GPIO_MISC4_BASE + 1)
+#define TROUT_GPIO_COMPASS_RST_N (TROUT_GPIO_MISC4_BASE + 2)
+#define TROUT_GPIO_HAPTIC_EN_UP (TROUT_GPIO_MISC4_BASE + 3)
+#define TROUT_GPIO_HAPTIC_EN_MAIN (TROUT_GPIO_MISC4_BASE + 4)
+#define TROUT_GPIO_USB_PHY_RST_N (TROUT_GPIO_MISC4_BASE + 5)
+#define TROUT_GPIO_WIFI_PA_RESETX (TROUT_GPIO_MISC4_BASE + 6)
+#define TROUT_GPIO_WIFI_EN (TROUT_GPIO_MISC4_BASE + 7)
+
+#define TROUT_GPIO_BT_32K_EN (TROUT_GPIO_MISC5_BASE + 0)
+#define TROUT_GPIO_MAC_32K_EN (TROUT_GPIO_MISC5_BASE + 1)
+#define TROUT_GPIO_MDDI_32K_EN (TROUT_GPIO_MISC5_BASE + 2)
+#define TROUT_GPIO_COMPASS_32K_EN (TROUT_GPIO_MISC5_BASE + 3)
+
+#define TROUT_GPIO_NAVI_ACT_N (TROUT_GPIO_INT2_BASE + 0)
+#define TROUT_GPIO_COMPASS_IRQ (TROUT_GPIO_INT2_BASE + 1)
+#define TROUT_GPIO_SLIDING_DET (TROUT_GPIO_INT2_BASE + 2)
+#define TROUT_GPIO_AUD_HSMIC_DET_N (TROUT_GPIO_INT2_BASE + 3)
+#define TROUT_GPIO_SD_DOOR_N (TROUT_GPIO_INT2_BASE + 4)
+#define TROUT_GPIO_CAM_BTN_STEP1_N (TROUT_GPIO_INT2_BASE + 5)
+#define TROUT_GPIO_CAM_BTN_STEP2_N (TROUT_GPIO_INT2_BASE + 6)
+#define TROUT_GPIO_TP_ATT_N (TROUT_GPIO_INT2_BASE + 7)
+#define TROUT_GPIO_BANK0_FIRST_INT_SOURCE (TROUT_GPIO_NAVI_ACT_N)
+#define TROUT_GPIO_BANK0_LAST_INT_SOURCE (TROUT_GPIO_TP_ATT_N)
+
+#define TROUT_GPIO_H2W_DAT_GPI (TROUT_GPIO_MISC1_BASE + 0)
+#define TROUT_GPIO_H2W_CLK_GPI (TROUT_GPIO_MISC1_BASE + 1)
+#define TROUT_GPIO_CPLD128_VER_0 (TROUT_GPIO_MISC1_BASE + 4)
+#define TROUT_GPIO_CPLD128_VER_1 (TROUT_GPIO_MISC1_BASE + 5)
+#define TROUT_GPIO_CPLD128_VER_2 (TROUT_GPIO_MISC1_BASE + 6)
+#define TROUT_GPIO_CPLD128_VER_3 (TROUT_GPIO_MISC1_BASE + 7)
+
+#define TROUT_GPIO_SDMC_CD_N (TROUT_GPIO_VIRTUAL_BASE + 0)
+#define TROUT_GPIO_END (TROUT_GPIO_SDMC_CD_N)
+#define TROUT_GPIO_BANK1_FIRST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
+#define TROUT_GPIO_BANK1_LAST_INT_SOURCE (TROUT_GPIO_SDMC_CD_N)
+
+#define TROUT_GPIO_VIRTUAL_TO_REAL_OFFSET \
+ (TROUT_GPIO_INT5_BASE - TROUT_GPIO_VIRTUAL_BASE)
+
+#define TROUT_INT_START (NR_MSM_IRQS + NR_GPIO_IRQS)
+#define TROUT_INT_BANK0_COUNT (8)
+#define TROUT_INT_BANK1_START (TROUT_INT_START + TROUT_INT_BANK0_COUNT)
+#define TROUT_INT_BANK1_COUNT (1)
+#define TROUT_INT_END (TROUT_INT_START + TROUT_INT_BANK0_COUNT + \
+ TROUT_INT_BANK1_COUNT - 1)
+#define TROUT_GPIO_TO_INT(n) (((n) <= TROUT_GPIO_BANK0_LAST_INT_SOURCE) ? \
+ (TROUT_INT_START - TROUT_GPIO_BANK0_FIRST_INT_SOURCE + (n)) : \
+ (TROUT_INT_BANK1_START - TROUT_GPIO_BANK1_FIRST_INT_SOURCE + (n)))
+
+#define TROUT_INT_TO_BANK(n) ((n - TROUT_INT_START) / TROUT_INT_BANK0_COUNT)
+#define TROUT_INT_TO_MASK(n) (1U << ((n - TROUT_INT_START) & 7))
+#define TROUT_BANK_TO_MASK_REG(bank) \
+ (bank ? TROUT_GPIO_INT_MASK1_REG : TROUT_GPIO_INT_MASK0_REG)
+#define TROUT_BANK_TO_STAT_REG(bank) \
+ (bank ? TROUT_GPIO_INT_STAT1_REG : TROUT_GPIO_INT_STAT0_REG)
+
+#endif /* GUARD */
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 9cb1276ab749..c57210f4f06a 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -14,7 +14,6 @@
*
*/
-#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index b449e8ad2904..ef3185e52c57 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -126,3 +126,24 @@ struct clk msm_clocks_7x30[] = {
unsigned msm_num_clocks_7x30 = ARRAY_SIZE(msm_clocks_7x30);
+static struct msm7200a_gpio_platform_data gpio_platform_data[] = {
+ MSM7200A_GPIO_PLATFORM_DATA(0, 0, 15, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(1, 16, 43, INT_GPIO_GROUP2),
+ MSM7200A_GPIO_PLATFORM_DATA(2, 44, 67, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(3, 68, 94, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(4, 95, 106, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(5, 107, 133, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(6, 134, 150, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(7, 151, 181, INT_GPIO_GROUP1),
+};
+
+struct platform_device msm_gpio_devices[] = {
+ MSM7200A_GPIO_DEVICE(0, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(1, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(2, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(3, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(4, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(5, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(6, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(7, gpio_platform_data),
+};
diff --git a/arch/arm/mach-msm/devices-qsd8x50.c b/arch/arm/mach-msm/devices-qsd8x50.c
index 4d4a50785e34..2342654ae58d 100644
--- a/arch/arm/mach-msm/devices-qsd8x50.c
+++ b/arch/arm/mach-msm/devices-qsd8x50.c
@@ -90,3 +90,24 @@ struct clk msm_clocks_8x50[] = {
unsigned msm_num_clocks_8x50 = ARRAY_SIZE(msm_clocks_8x50);
+static struct msm7200a_gpio_platform_data gpio_platform_data[] = {
+ MSM7200A_GPIO_PLATFORM_DATA(0, 0, 15, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(1, 16, 42, INT_GPIO_GROUP2),
+ MSM7200A_GPIO_PLATFORM_DATA(2, 43, 67, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(3, 68, 94, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(4, 95, 103, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(5, 104, 121, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(6, 122, 152, INT_GPIO_GROUP1),
+ MSM7200A_GPIO_PLATFORM_DATA(7, 153, 164, INT_GPIO_GROUP1),
+};
+
+struct platform_device msm_gpio_devices[] = {
+ MSM7200A_GPIO_DEVICE(0, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(1, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(2, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(3, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(4, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(5, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(6, gpio_platform_data),
+ MSM7200A_GPIO_DEVICE(7, gpio_platform_data),
+};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 568443e76423..fd71edceb19b 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -17,6 +17,8 @@
#define __ARCH_ARM_MACH_MSM_DEVICES_H
#include "clock.h"
+#include "gpio_hw.h"
+#include "msm7200a-gpio.h"
extern struct platform_device msm_device_uart1;
extern struct platform_device msm_device_uart2;
@@ -44,4 +46,35 @@ extern unsigned msm_num_clocks_7x30;
extern struct clk msm_clocks_8x50[];
extern unsigned msm_num_clocks_8x50;
+#define MSM7200A_GPIO_PLATFORM_DATA(ix, begin, end, irq) \
+ [ix] = { \
+ .gpio_base = begin, \
+ .ngpio = end - begin + 1, \
+ .irq_base = MSM_GPIO_TO_INT(begin), \
+ .irq_summary = irq, \
+ .latch_level_irqs = false, \
+ .regs = { \
+ .in = GPIO_IN_ ## ix, \
+ .out = GPIO_OUT_ ## ix, \
+ .oe = GPIO_OE_ ## ix, \
+ .int_status = GPIO_INT_STATUS_ ## ix, \
+ .int_clear = GPIO_INT_CLEAR_ ## ix, \
+ .int_en = GPIO_INT_EN_ ## ix, \
+ .int_edge = GPIO_INT_EDGE_ ## ix, \
+ .int_pos = GPIO_INT_POS_ ## ix, \
+ }, \
+ }
+
+#define MSM7200A_GPIO_DEVICE(ix, pdata) \
+ { \
+ .name = "msm7200a-gpio", \
+ .id = ix, \
+ .num_resources = 0, \
+ .dev = { \
+ .platform_data = &pdata[ix], \
+ }, \
+ }
+
+extern struct platform_device msm_gpio_devices[];
+
#endif
diff --git a/arch/arm/mach-msm/gpio_hw-7x30.h b/arch/arm/mach-msm/gpio_hw-7x30.h
new file mode 100644
index 000000000000..8c28a3f72010
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw-7x30.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_7X30_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_7X30_H
+
+/* output value */
+#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
+#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 43-16 */
+#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-44 */
+#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
+#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
+#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 133-107 */
+#define GPIO_OUT_6 GPIO1_REG(0xC4) /* gpio 150-134 */
+#define GPIO_OUT_7 GPIO1_REG(0x214) /* gpio 181-151 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0 GPIO1_REG(0x10)
+#define GPIO_OE_1 GPIO2_REG(0x08)
+#define GPIO_OE_2 GPIO1_REG(0x14)
+#define GPIO_OE_3 GPIO1_REG(0x18)
+#define GPIO_OE_4 GPIO1_REG(0x1C)
+#define GPIO_OE_5 GPIO1_REG(0x54)
+#define GPIO_OE_6 GPIO1_REG(0xC8)
+#define GPIO_OE_7 GPIO1_REG(0x218)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0 GPIO1_REG(0x34)
+#define GPIO_IN_1 GPIO2_REG(0x20)
+#define GPIO_IN_2 GPIO1_REG(0x38)
+#define GPIO_IN_3 GPIO1_REG(0x3C)
+#define GPIO_IN_4 GPIO1_REG(0x40)
+#define GPIO_IN_5 GPIO1_REG(0x44)
+#define GPIO_IN_6 GPIO1_REG(0xCC)
+#define GPIO_IN_7 GPIO1_REG(0x21C)
+
+/* same pin map as above, 1=edge 0=level interrupt */
+#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
+#define GPIO_INT_EDGE_6 GPIO1_REG(0xD0)
+#define GPIO_INT_EDGE_7 GPIO1_REG(0x240)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0 GPIO1_REG(0x70)
+#define GPIO_INT_POS_1 GPIO2_REG(0x58)
+#define GPIO_INT_POS_2 GPIO1_REG(0x74)
+#define GPIO_INT_POS_3 GPIO1_REG(0x78)
+#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
+#define GPIO_INT_POS_6 GPIO1_REG(0xD4)
+#define GPIO_INT_POS_7 GPIO1_REG(0x228)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0 GPIO1_REG(0x80)
+#define GPIO_INT_EN_1 GPIO2_REG(0x60)
+#define GPIO_INT_EN_2 GPIO1_REG(0x84)
+#define GPIO_INT_EN_3 GPIO1_REG(0x88)
+#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
+#define GPIO_INT_EN_6 GPIO1_REG(0xD8)
+#define GPIO_INT_EN_7 GPIO1_REG(0x22C)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
+#define GPIO_INT_CLEAR_6 GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_7 GPIO1_REG(0x230)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
+#define GPIO_INT_STATUS_6 GPIO1_REG(0xE0)
+#define GPIO_INT_STATUS_7 GPIO1_REG(0x234)
+
+#endif
diff --git a/arch/arm/mach-msm/gpio_hw-7xxx.h b/arch/arm/mach-msm/gpio_hw-7xxx.h
new file mode 100644
index 000000000000..3408478ba9df
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw-7xxx.h
@@ -0,0 +1,84 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_7XXX_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_7XXX_H
+
+/* output value */
+#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
+#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */
+#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */
+#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
+#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
+#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 107-121 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0 GPIO1_REG(0x10)
+#define GPIO_OE_1 GPIO2_REG(0x08)
+#define GPIO_OE_2 GPIO1_REG(0x14)
+#define GPIO_OE_3 GPIO1_REG(0x18)
+#define GPIO_OE_4 GPIO1_REG(0x1C)
+#define GPIO_OE_5 GPIO1_REG(0x54)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0 GPIO1_REG(0x34)
+#define GPIO_IN_1 GPIO2_REG(0x20)
+#define GPIO_IN_2 GPIO1_REG(0x38)
+#define GPIO_IN_3 GPIO1_REG(0x3C)
+#define GPIO_IN_4 GPIO1_REG(0x40)
+#define GPIO_IN_5 GPIO1_REG(0x44)
+
+/* same pin map as above, 1=edge 0=level interrupt */
+#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
+#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
+#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
+#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
+#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0 GPIO1_REG(0x70)
+#define GPIO_INT_POS_1 GPIO2_REG(0x58)
+#define GPIO_INT_POS_2 GPIO1_REG(0x74)
+#define GPIO_INT_POS_3 GPIO1_REG(0x78)
+#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
+#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0 GPIO1_REG(0x80)
+#define GPIO_INT_EN_1 GPIO2_REG(0x60)
+#define GPIO_INT_EN_2 GPIO1_REG(0x84)
+#define GPIO_INT_EN_3 GPIO1_REG(0x88)
+#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
+#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
+#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
+#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
+#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
+#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
+#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
+#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
+#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
+#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
+
+#endif
diff --git a/arch/arm/mach-msm/gpio_hw-8x50.h b/arch/arm/mach-msm/gpio_hw-8x50.h
new file mode 100644
index 000000000000..94319435ae61
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw-8x50.h
@@ -0,0 +1,100 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_8X50_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_8X50_H
+
+/* output value */
+#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
+#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */
+#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */
+#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
+#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 103-95 */
+#define GPIO_OUT_5 GPIO1_REG(0x10) /* gpio 121-104 */
+#define GPIO_OUT_6 GPIO1_REG(0x14) /* gpio 152-122 */
+#define GPIO_OUT_7 GPIO1_REG(0x18) /* gpio 164-153 */
+
+/* same pin map as above, output enable */
+#define GPIO_OE_0 GPIO1_REG(0x20)
+#define GPIO_OE_1 GPIO2_REG(0x08)
+#define GPIO_OE_2 GPIO1_REG(0x24)
+#define GPIO_OE_3 GPIO1_REG(0x28)
+#define GPIO_OE_4 GPIO1_REG(0x2C)
+#define GPIO_OE_5 GPIO1_REG(0x30)
+#define GPIO_OE_6 GPIO1_REG(0x34)
+#define GPIO_OE_7 GPIO1_REG(0x38)
+
+/* same pin map as above, input read */
+#define GPIO_IN_0 GPIO1_REG(0x50)
+#define GPIO_IN_1 GPIO2_REG(0x20)
+#define GPIO_IN_2 GPIO1_REG(0x54)
+#define GPIO_IN_3 GPIO1_REG(0x58)
+#define GPIO_IN_4 GPIO1_REG(0x5C)
+#define GPIO_IN_5 GPIO1_REG(0x60)
+#define GPIO_IN_6 GPIO1_REG(0x64)
+#define GPIO_IN_7 GPIO1_REG(0x68)
+
+/* same pin map as above, 1=edge 0=level interrupt */
+#define GPIO_INT_EDGE_0 GPIO1_REG(0x70)
+#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
+#define GPIO_INT_EDGE_2 GPIO1_REG(0x74)
+#define GPIO_INT_EDGE_3 GPIO1_REG(0x78)
+#define GPIO_INT_EDGE_4 GPIO1_REG(0x7C)
+#define GPIO_INT_EDGE_5 GPIO1_REG(0x80)
+#define GPIO_INT_EDGE_6 GPIO1_REG(0x84)
+#define GPIO_INT_EDGE_7 GPIO1_REG(0x88)
+
+/* same pin map as above, 1=positive 0=negative */
+#define GPIO_INT_POS_0 GPIO1_REG(0x90)
+#define GPIO_INT_POS_1 GPIO2_REG(0x58)
+#define GPIO_INT_POS_2 GPIO1_REG(0x94)
+#define GPIO_INT_POS_3 GPIO1_REG(0x98)
+#define GPIO_INT_POS_4 GPIO1_REG(0x9C)
+#define GPIO_INT_POS_5 GPIO1_REG(0xA0)
+#define GPIO_INT_POS_6 GPIO1_REG(0xA4)
+#define GPIO_INT_POS_7 GPIO1_REG(0xA8)
+
+/* same pin map as above, interrupt enable */
+#define GPIO_INT_EN_0 GPIO1_REG(0xB0)
+#define GPIO_INT_EN_1 GPIO2_REG(0x60)
+#define GPIO_INT_EN_2 GPIO1_REG(0xB4)
+#define GPIO_INT_EN_3 GPIO1_REG(0xB8)
+#define GPIO_INT_EN_4 GPIO1_REG(0xBC)
+#define GPIO_INT_EN_5 GPIO1_REG(0xC0)
+#define GPIO_INT_EN_6 GPIO1_REG(0xC4)
+#define GPIO_INT_EN_7 GPIO1_REG(0xC8)
+
+/* same pin map as above, write 1 to clear interrupt */
+#define GPIO_INT_CLEAR_0 GPIO1_REG(0xD0)
+#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
+#define GPIO_INT_CLEAR_2 GPIO1_REG(0xD4)
+#define GPIO_INT_CLEAR_3 GPIO1_REG(0xD8)
+#define GPIO_INT_CLEAR_4 GPIO1_REG(0xDC)
+#define GPIO_INT_CLEAR_5 GPIO1_REG(0xE0)
+#define GPIO_INT_CLEAR_6 GPIO1_REG(0xE4)
+#define GPIO_INT_CLEAR_7 GPIO1_REG(0xE8)
+
+/* same pin map as above, 1=interrupt pending */
+#define GPIO_INT_STATUS_0 GPIO1_REG(0xF0)
+#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
+#define GPIO_INT_STATUS_2 GPIO1_REG(0xF4)
+#define GPIO_INT_STATUS_3 GPIO1_REG(0xF8)
+#define GPIO_INT_STATUS_4 GPIO1_REG(0xFC)
+#define GPIO_INT_STATUS_5 GPIO1_REG(0x100)
+#define GPIO_INT_STATUS_6 GPIO1_REG(0x104)
+#define GPIO_INT_STATUS_7 GPIO1_REG(0x108)
+
+#endif
diff --git a/arch/arm/mach-msm/gpio_hw.h b/arch/arm/mach-msm/gpio_hw.h
new file mode 100644
index 000000000000..627dea550ac3
--- /dev/null
+++ b/arch/arm/mach-msm/gpio_hw.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2007, Google, Inc.
+ * Copyright (c) 2008-2010, Code Aurora Forum. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __ARCH_ARM_MACH_MSM_GPIO_HW_H
+#define __ARCH_ARM_MACH_MSM_GPIO_HW_H
+
+#include <mach/msm_iomap.h>
+
+#if defined(CONFIG_ARCH_MSM7X30)
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0x400 + (off))
+#else
+#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
+#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
+#endif
+
+#if defined(CONFIG_ARCH_QSD8X50)
+#include "gpio_hw-8x50.h"
+#elif defined(CONFIG_ARCH_MSM7X30)
+#include "gpio_hw-7x30.h"
+#else
+#include "gpio_hw-7xxx.h"
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/include/mach/gpio.h b/arch/arm/mach-msm/include/mach/gpio.h
index 262b441b4374..ff80758e93b4 100644
--- a/arch/arm/mach-msm/include/mach/gpio.h
+++ b/arch/arm/mach-msm/include/mach/gpio.h
@@ -16,6 +16,15 @@
#ifndef __ASM_ARCH_MSM_GPIO_H
#define __ASM_ARCH_MSM_GPIO_H
+#define ARCH_NR_GPIOS 512
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+#define gpio_to_irq __gpio_to_irq
+
/**
* struct msm_gpio - GPIO pin description
* @gpio_cfg - configuration bitmap, as per gpio_tlmm_config()
diff --git a/arch/arm/mach-msm/msm7200a-gpio.c b/arch/arm/mach-msm/msm7200a-gpio.c
new file mode 100644
index 000000000000..a490765e29e4
--- /dev/null
+++ b/arch/arm/mach-msm/msm7200a-gpio.c
@@ -0,0 +1,421 @@
+/*
+ * Driver for Qualcomm MSM7200a and related SoC GPIO.
+ * Supported chipset families include:
+ * MSM7x01(a), MSM7x25, MSM7x27, MSM7x30, QSD8x50(a)
+ *
+ * Copyright (C) 2007 Google, Inc.
+ * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "msm7200a-gpio.h"
+
+enum {
+ IRQ_MASK_NORMAL = 0,
+ IRQ_MASK_WAKE_ON,
+ IRQ_MASK_MAX
+};
+
+struct msm_gpio_dev {
+ struct gpio_chip gpio_chip;
+ spinlock_t lock;
+ unsigned irq_base;
+ unsigned irq_summary;
+ bool latch_level_irqs;
+ struct msm7200a_gpio_regs regs;
+ u32 irq_masks[IRQ_MASK_MAX];
+ int nsuspend;
+};
+
+static inline struct msm_gpio_dev *to_msm_gpio_dev(struct gpio_chip *chip)
+{
+ return container_of(chip, struct msm_gpio_dev, gpio_chip);
+}
+
+/*
+ * This function assumes that msm_gpio_dev::lock is held.
+ */
+static inline void set_gpio_bit(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) | BIT(n), reg);
+}
+
+/*
+ * This function assumes that msm_gpio_dev::lock is held.
+ */
+static inline void clr_gpio_bit(unsigned n, void __iomem *reg)
+{
+ writel(readl(reg) & ~BIT(n), reg);
+}
+
+/*
+ * This function assumes that msm_gpio_dev::lock is held.
+ */
+static inline void
+msm_gpio_write(struct msm_gpio_dev *dev, unsigned n, unsigned on)
+{
+ if (on)
+ set_gpio_bit(n, dev->regs.out);
+ else
+ clr_gpio_bit(n, dev->regs.out);
+}
+
+static int gpio_chip_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ clr_gpio_bit(offset, msm_gpio->regs.oe);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return 0;
+}
+
+static int
+gpio_chip_direction_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ msm_gpio_write(msm_gpio, offset, value);
+ set_gpio_bit(offset, msm_gpio->regs.oe);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return 0;
+}
+
+static int gpio_chip_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip);
+
+ return readl(msm_gpio->regs.in) & BIT(offset) ? 1 : 0;
+}
+
+static void gpio_chip_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ msm_gpio_write(msm_gpio, offset, value);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+}
+
+static int gpio_chip_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct msm_gpio_dev *msm_gpio = to_msm_gpio_dev(chip);
+ return msm_gpio->irq_base + offset;
+}
+
+static void forget_level_irq(struct msm_gpio_dev *msm_gpio, unsigned offset)
+{
+ if (!msm_gpio->latch_level_irqs) {
+ unsigned v = readl(msm_gpio->regs.int_edge);
+ unsigned b = BIT(offset);
+
+ if (!(v & b))
+ writel(b, msm_gpio->regs.int_clear);
+ }
+}
+
+static void msm_gpio_irq_mask(unsigned int irq)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_dev *msm_gpio = get_irq_chip_data(irq);
+ unsigned offset = irq - msm_gpio->irq_base;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ forget_level_irq(msm_gpio, offset);
+ msm_gpio->irq_masks[IRQ_MASK_NORMAL] &= ~BIT(offset);
+ writel(msm_gpio->irq_masks[IRQ_MASK_NORMAL], msm_gpio->regs.int_en);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+}
+
+static void msm_gpio_irq_unmask(unsigned int irq)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_dev *msm_gpio = get_irq_chip_data(irq);
+ unsigned offset = irq - msm_gpio->irq_base;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ forget_level_irq(msm_gpio, offset);
+ msm_gpio->irq_masks[IRQ_MASK_NORMAL] |= BIT(offset);
+ writel(msm_gpio->irq_masks[IRQ_MASK_NORMAL], msm_gpio->regs.int_en);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+}
+
+static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+{
+ unsigned long irq_flags;
+ struct msm_gpio_dev *msm_gpio = get_irq_chip_data(irq);
+ unsigned offset = irq - msm_gpio->irq_base;
+
+ if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
+ return -EINVAL;
+
+ if ((flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) ==
+ (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW))
+ return -EINVAL;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+
+ if (flow_type & IRQ_TYPE_EDGE_BOTH) {
+ set_gpio_bit(offset, msm_gpio->regs.int_edge);
+ irq_desc[irq].handle_irq = handle_edge_irq;
+ } else {
+ clr_gpio_bit(offset, msm_gpio->regs.int_edge);
+ irq_desc[irq].handle_irq = handle_level_irq;
+ }
+
+ if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_RISING))
+ set_gpio_bit(offset, msm_gpio->regs.int_pos);
+ else
+ clr_gpio_bit(offset, msm_gpio->regs.int_pos);
+
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return 0;
+}
+
+static void msm_gpio_irq_mask_ack(unsigned int irq)
+{
+ msm_gpio_irq_mask(irq);
+}
+
+static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+ struct msm_gpio_dev *msm_gpio = get_irq_chip_data(irq);
+ unsigned offset = irq - msm_gpio->irq_base;
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ if (on)
+ msm_gpio->irq_masks[IRQ_MASK_WAKE_ON] |= BIT(offset);
+ else
+ msm_gpio->irq_masks[IRQ_MASK_WAKE_ON] &= ~BIT(offset);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return set_irq_wake(msm_gpio->irq_summary, on);
+}
+
+static irqreturn_t msm_gpio_irq_handler(int irq, void *dev)
+{
+ struct msm_gpio_dev *msm_gpio = dev;
+ unsigned e, s, triggered_irqs;
+ int b;
+
+ /*
+ * The int_status register latches trigger events whether or not
+ * the gpio line is enabled as an interrupt source. Therefore,
+ * the set of pins which defines the interrupts which need to fire
+ * is the intersection of int_status and int_en - int_status
+ * alone provides an incomplete picture.
+ */
+ spin_lock(&msm_gpio->lock);
+ s = readl(msm_gpio->regs.int_status);
+ e = readl(msm_gpio->regs.int_en);
+ triggered_irqs = s & e;
+ if (triggered_irqs)
+ writel(triggered_irqs, msm_gpio->regs.int_clear);
+ spin_unlock(&msm_gpio->lock);
+
+ if (!triggered_irqs)
+ return IRQ_NONE;
+
+ while (triggered_irqs) {
+ b = ffs(triggered_irqs) - 1;
+ triggered_irqs &= ~BIT(b);
+ generic_handle_irq(msm_gpio->irq_base + b);
+ }
+ return IRQ_HANDLED;
+}
+
+static struct irq_chip msm_gpio_irq_chip = {
+ .name = "msm_gpio",
+ .mask = msm_gpio_irq_mask,
+ .mask_ack = msm_gpio_irq_mask_ack,
+ .unmask = msm_gpio_irq_unmask,
+ .set_type = msm_gpio_irq_set_type,
+ .set_wake = msm_gpio_irq_set_wake,
+};
+
+static int __devinit msm_gpio_probe(struct platform_device *dev)
+{
+ struct msm_gpio_dev *msm_gpio;
+ struct msm7200a_gpio_platform_data *pdata = dev->dev.platform_data;
+ int i, irq, ret;
+
+ if (!pdata)
+ return -EINVAL;
+
+ msm_gpio = kzalloc(sizeof(struct msm_gpio_dev), GFP_KERNEL);
+ if (!msm_gpio)
+ return -ENOMEM;
+
+ spin_lock_init(&msm_gpio->lock);
+ platform_set_drvdata(dev, msm_gpio);
+
+ msm_gpio->regs = pdata->regs;
+ msm_gpio->gpio_chip.label = dev->name;
+ msm_gpio->gpio_chip.base = pdata->gpio_base;
+ msm_gpio->gpio_chip.ngpio = pdata->ngpio;
+ msm_gpio->gpio_chip.direction_input = gpio_chip_direction_input;
+ msm_gpio->gpio_chip.direction_output = gpio_chip_direction_output;
+ msm_gpio->gpio_chip.get = gpio_chip_get;
+ msm_gpio->gpio_chip.set = gpio_chip_set;
+ msm_gpio->gpio_chip.to_irq = gpio_chip_to_irq;
+ msm_gpio->irq_base = pdata->irq_base;
+ msm_gpio->irq_summary = pdata->irq_summary;
+ msm_gpio->latch_level_irqs = pdata->latch_level_irqs;
+
+ ret = gpiochip_add(&msm_gpio->gpio_chip);
+ if (ret < 0)
+ goto err_post_malloc;
+
+ for (i = 0; i < msm_gpio->gpio_chip.ngpio; ++i) {
+ irq = msm_gpio->irq_base + i;
+ set_irq_chip_data(irq, msm_gpio);
+ set_irq_chip(irq, &msm_gpio_irq_chip);
+ set_irq_handler(irq, handle_level_irq);
+ set_irq_flags(irq, IRQF_VALID);
+ }
+
+ /*
+ * We use a level-triggered interrupt because of the nature
+ * of the shared GPIO-group interrupt.
+ *
+ * Many GPIO chips may be sharing the same group IRQ line, and
+ * it is possible for GPIO interrupt to re-occur while the system
+ * is still servicing the group interrupt associated with it.
+ * The group IRQ line would not de-assert and re-assert, and
+ * we'd get no second edge to cause the group IRQ to be handled again.
+ *
+ * Using a level interrupt guarantees that the group IRQ handlers
+ * will continue to be called as long as any GPIO chip in the group
+ * is asserting, even if the condition began while the group
+ * handler was in mid-pass.
+ */
+ ret = request_irq(msm_gpio->irq_summary,
+ msm_gpio_irq_handler,
+ IRQF_SHARED | IRQF_TRIGGER_HIGH,
+ dev_name(&dev->dev),
+ msm_gpio);
+ if (ret < 0)
+ goto err_post_gpiochip_add;
+
+ return ret;
+err_post_gpiochip_add:
+ /*
+ * Under no circumstances should a line be held on a gpiochip
+ * which hasn't finished probing.
+ */
+ BUG_ON(gpiochip_remove(&msm_gpio->gpio_chip) < 0);
+err_post_malloc:
+ platform_set_drvdata(dev, NULL);
+ kfree(msm_gpio);
+ return ret;
+}
+
+static int __devexit msm_gpio_remove(struct platform_device *dev)
+{
+ struct msm_gpio_dev *msm_gpio = platform_get_drvdata(dev);
+ int ret = gpiochip_remove(&msm_gpio->gpio_chip);
+
+ if (ret < 0)
+ return ret;
+
+ free_irq(msm_gpio->irq_summary, msm_gpio);
+ kfree(msm_gpio);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int msm_gpio_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_gpio_dev *msm_gpio = platform_get_drvdata(pdev);
+ unsigned long irq_flags;
+ unsigned long irq_mask;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ if ((msm_gpio->nsuspend)++ == 0) {
+ irq_mask = msm_gpio->irq_masks[IRQ_MASK_NORMAL] &
+ msm_gpio->irq_masks[IRQ_MASK_WAKE_ON];
+ writel(irq_mask, msm_gpio->regs.int_en);
+ }
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return 0;
+}
+
+static int msm_gpio_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct msm_gpio_dev *msm_gpio = platform_get_drvdata(pdev);
+ unsigned long irq_flags;
+
+ spin_lock_irqsave(&msm_gpio->lock, irq_flags);
+ if (--(msm_gpio->nsuspend) == 0)
+ writel(msm_gpio->irq_masks[IRQ_MASK_NORMAL],
+ msm_gpio->regs.int_en);
+ spin_unlock_irqrestore(&msm_gpio->lock, irq_flags);
+
+ return 0;
+}
+#else
+#define msm_gpio_suspend NULL
+#define msm_gpio_resume NULL
+#endif
+
+static SIMPLE_DEV_PM_OPS(msm_gpio_pm_ops, msm_gpio_suspend, msm_gpio_resume);
+
+static struct platform_driver msm_gpio_driver = {
+ .probe = msm_gpio_probe,
+ .remove = __devexit_p(msm_gpio_remove),
+ .driver = {
+ .name = "msm7200a-gpio",
+ .owner = THIS_MODULE,
+ .pm = &msm_gpio_pm_ops,
+ },
+};
+
+static int __init msm_gpio_init(void)
+{
+ return platform_driver_register(&msm_gpio_driver);
+}
+
+static void __exit msm_gpio_exit(void)
+{
+ platform_driver_unregister(&msm_gpio_driver);
+}
+
+postcore_initcall(msm_gpio_init);
+module_exit(msm_gpio_exit);
+
+MODULE_AUTHOR("Gregory Bean <gbean@codeaurora.org>");
+MODULE_DESCRIPTION("Driver for Qualcomm MSM 7200a-family SoC GPIOs");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:msm7200a-gpio");
diff --git a/arch/arm/mach-msm/msm7200a-gpio.h b/arch/arm/mach-msm/msm7200a-gpio.h
new file mode 100644
index 000000000000..317c1fd22ecc
--- /dev/null
+++ b/arch/arm/mach-msm/msm7200a-gpio.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 __LINUX_MSM7200A_GPIO_H
+#define __LINUX_MSM7200A_GPIO_H
+
+/**
+ * struct msm7200a_gpio_regs - addresess of iomapped GPIO registers
+ * @in: GPIO_IN_n
+ * @out: GPIO_OUT_n
+ * @oe: GPIO_OE_n
+ * @int_status: GPIO_INT_STATUS_n
+ * @int_clear: GPIO_INT_CLEAR_n
+ * @int_en: GPIO_INT_EN_n
+ * @int_edge: GPIO_INT_EDGE_n
+ * @int_pos: GPIO_INT_POS_n
+ *
+ * Registers are not guaranteed to be packed in memory, or even
+ * located in a predictable pattern.
+ */
+struct msm7200a_gpio_regs {
+ void __iomem *in;
+ void __iomem *out;
+ void __iomem *oe;
+ void __iomem *int_status;
+ void __iomem *int_clear;
+ void __iomem *int_en;
+ void __iomem *int_edge;
+ void __iomem *int_pos;
+};
+
+/**
+ * struct msm7200a_gpio_platform_data - configuration for msm7200a-gpio
+ * @gpio_base: The first gpio to be assigned to the device. Corresponds
+ * directly to gpio_chip.base.
+ * @ngpio: The number of gpio lines to be managed by the device.
+ * Must be <= 32. Corresponds directly to gpio_chip.ngpio.
+ * @irq_base: The first irq to be assigned to the device. The gpio
+ * at 'gpio_base' will be assigned irq 'irq_base',
+ * gpio 'gpio_base + 1' will receive irq 'irq_base + 1',
+ * and so on.
+ * @irq_summary: The summary irq line which will be used by the device
+ * to notify the kernel when an interrupt occurs on
+ * any of its gpio lines. Most MSM SoCs have more
+ * than one gpio device sharing each of these.
+ * @latch_level_irqs: The MSM gpio hardware latches level interrupts,
+ * which is atypical. Setting this flag to false
+ * makes the driver compensate for this and produce
+ * the traditional unlatched behavior for level irqs.
+ * @regs: Addresses of the registers which control the gpios
+ * to be managed by the device.
+ */
+struct msm7200a_gpio_platform_data {
+ unsigned gpio_base;
+ unsigned ngpio;
+ unsigned irq_base;
+ unsigned irq_summary;
+ bool latch_level_irqs;
+ struct msm7200a_gpio_regs regs;
+};
+
+#endif
diff --git a/arch/arm/mach-mx1/Kconfig b/arch/arm/mach-mx1/Kconfig
deleted file mode 100644
index eb7660f5d4b7..000000000000
--- a/arch/arm/mach-mx1/Kconfig
+++ /dev/null
@@ -1,19 +0,0 @@
-if ARCH_MX1
-
-comment "MX1 platforms:"
-
-config MACH_MXLADS
- bool
-
-config ARCH_MX1ADS
- bool "MX1ADS platform"
- select MACH_MXLADS
- help
- Say Y here if you are using Motorola MX1ADS/MXLADS boards
-
-config MACH_SCB9328
- bool "Synertronixx scb9328"
- help
- Say Y here if you are using a Synertronixx scb9328 board
-
-endif
diff --git a/arch/arm/mach-mx1/Makefile b/arch/arm/mach-mx1/Makefile
deleted file mode 100644
index fc2ddf82441b..000000000000
--- a/arch/arm/mach-mx1/Makefile
+++ /dev/null
@@ -1,15 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-EXTRA_CFLAGS += -DIMX_NEEDS_DEPRECATED_SYMBOLS
-obj-y += generic.o clock.o devices.o
-
-# Support for CMOS sensor interface
-obj-$(CONFIG_MX1_VIDEO) += ksym_mx1.o mx1_camera_fiq.o
-
-# Specific board support
-obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
-obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
diff --git a/arch/arm/mach-mx1/Makefile.boot b/arch/arm/mach-mx1/Makefile.boot
deleted file mode 100644
index 8ed1492288a2..000000000000
--- a/arch/arm/mach-mx1/Makefile.boot
+++ /dev/null
@@ -1,4 +0,0 @@
- zreladdr-y := 0x08008000
-params_phys-y := 0x08000100
-initrd_phys-y := 0x08800000
-
diff --git a/arch/arm/mach-mx1/crm_regs.h b/arch/arm/mach-mx1/crm_regs.h
deleted file mode 100644
index 22e866ff0c09..000000000000
--- a/arch/arm/mach-mx1/crm_regs.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- *
- * This file may be distributed under the terms of the GNU General
- * Public License, version 2.
- */
-
-#ifndef __ARCH_ARM_MACH_MX1_CRM_REGS_H__
-#define __ARCH_ARM_MACH_MX1_CRM_REGS_H__
-
-#define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
-#define SCM_BASE IO_ADDRESS(SCM_BASE_ADDR)
-
-/* CCM register addresses */
-#define CCM_CSCR (CCM_BASE + 0x0)
-#define CCM_MPCTL0 (CCM_BASE + 0x4)
-#define CCM_MPCTL1 (CCM_BASE + 0x8)
-#define CCM_SPCTL0 (CCM_BASE + 0xC)
-#define CCM_SPCTL1 (CCM_BASE + 0x10)
-#define CCM_PCDR (CCM_BASE + 0x20)
-
-#define CCM_CSCR_CLKO_OFFSET 29
-#define CCM_CSCR_CLKO_MASK (0x7 << 29)
-#define CCM_CSCR_USB_OFFSET 26
-#define CCM_CSCR_USB_MASK (0x7 << 26)
-#define CCM_CSCR_SPLL_RESTART (1 << 22)
-#define CCM_CSCR_MPLL_RESTART (1 << 21)
-#define CCM_CSCR_OSC_EN_SHIFT 17
-#define CCM_CSCR_SYSTEM_SEL (1 << 16)
-#define CCM_CSCR_BCLK_OFFSET 10
-#define CCM_CSCR_BCLK_MASK (0xF << 10)
-#define CCM_CSCR_PRESC (1 << 15)
-#define CCM_CSCR_SPEN (1 << 1)
-#define CCM_CSCR_MPEN (1 << 0)
-
-#define CCM_PCDR_PCLK3_OFFSET 16
-#define CCM_PCDR_PCLK3_MASK (0x7F << 16)
-#define CCM_PCDR_PCLK2_OFFSET 4
-#define CCM_PCDR_PCLK2_MASK (0xF << 4)
-#define CCM_PCDR_PCLK1_OFFSET 0
-#define CCM_PCDR_PCLK1_MASK 0xF
-
-/* SCM register addresses */
-#define SCM_SIDR (SCM_BASE + 0x0)
-#define SCM_FMCR (SCM_BASE + 0x4)
-#define SCM_GPCR (SCM_BASE + 0x8)
-#define SCM_GCCR (SCM_BASE + 0xC)
-
-#define SCM_GCCR_DMA_CLK_EN_OFFSET 3
-#define SCM_GCCR_CSI_CLK_EN_OFFSET 2
-#define SCM_GCCR_MMA_CLK_EN_OFFSET 1
-#define SCM_GCCR_USBD_CLK_EN_OFFSET 0
-
-#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c
deleted file mode 100644
index b6be29d1cb08..000000000000
--- a/arch/arm/mach-mx1/devices.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
- * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
- * Copyright (c) 2008 Darius Augulis <darius.augulis@teltonika.lt>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <mach/irqs.h>
-#include <mach/hardware.h>
-
-#include "devices.h"
-
-static struct resource imx_csi_resources[] = {
- {
- .start = 0x00224000,
- .end = 0x00224010,
- .flags = IORESOURCE_MEM,
- }, {
- .start = CSI_INT,
- .end = CSI_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 imx_csi_dmamask = 0xffffffffUL;
-
-struct platform_device imx_csi_device = {
- .name = "mx1-camera",
- .id = 0, /* This is used to put cameras on this interface */
- .dev = {
- .dma_mask = &imx_csi_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .resource = imx_csi_resources,
- .num_resources = ARRAY_SIZE(imx_csi_resources),
-};
-
-static struct resource imx_i2c_resources[] = {
- {
- .start = 0x00217000,
- .end = 0x00217010,
- .flags = IORESOURCE_MEM,
- }, {
- .start = I2C_INT,
- .end = I2C_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_i2c_device = {
- .name = "imx-i2c",
- .id = 0,
- .resource = imx_i2c_resources,
- .num_resources = ARRAY_SIZE(imx_i2c_resources),
-};
-
-static struct resource imx_uart1_resources[] = {
- {
- .start = UART1_BASE_ADDR,
- .end = UART1_BASE_ADDR + 0xD0,
- .flags = IORESOURCE_MEM,
- }, {
- .start = UART1_MINT_RX,
- .end = UART1_MINT_RX,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = UART1_MINT_TX,
- .end = UART1_MINT_TX,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = UART1_MINT_RTS,
- .end = UART1_MINT_RTS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_uart1_device = {
- .name = "imx-uart",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_uart1_resources),
- .resource = imx_uart1_resources,
-};
-
-static struct resource imx_uart2_resources[] = {
- {
- .start = UART2_BASE_ADDR,
- .end = UART2_BASE_ADDR + 0xD0,
- .flags = IORESOURCE_MEM,
- }, {
- .start = UART2_MINT_RX,
- .end = UART2_MINT_RX,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = UART2_MINT_TX,
- .end = UART2_MINT_TX,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = UART2_MINT_RTS,
- .end = UART2_MINT_RTS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_uart2_device = {
- .name = "imx-uart",
- .id = 1,
- .num_resources = ARRAY_SIZE(imx_uart2_resources),
- .resource = imx_uart2_resources,
-};
-
-static struct resource imx_rtc_resources[] = {
- {
- .start = 0x00204000,
- .end = 0x00204024,
- .flags = IORESOURCE_MEM,
- }, {
- .start = RTC_INT,
- .end = RTC_INT,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = RTC_SAMINT,
- .end = RTC_SAMINT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_rtc_device = {
- .name = "rtc-imx",
- .id = 0,
- .resource = imx_rtc_resources,
- .num_resources = ARRAY_SIZE(imx_rtc_resources),
-};
-
-static struct resource imx_wdt_resources[] = {
- {
- .start = 0x00201000,
- .end = 0x00201008,
- .flags = IORESOURCE_MEM,
- }, {
- .start = WDT_INT,
- .end = WDT_INT,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_wdt_device = {
- .name = "imx-wdt",
- .id = 0,
- .resource = imx_wdt_resources,
- .num_resources = ARRAY_SIZE(imx_wdt_resources),
-};
-
-static struct resource imx_usb_resources[] = {
- {
- .start = 0x00212000,
- .end = 0x00212148,
- .flags = IORESOURCE_MEM,
- }, {
- .start = USBD_INT0,
- .end = USBD_INT0,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT1,
- .end = USBD_INT1,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT2,
- .end = USBD_INT2,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT3,
- .end = USBD_INT3,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT4,
- .end = USBD_INT4,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT5,
- .end = USBD_INT5,
- .flags = IORESOURCE_IRQ,
- }, {
- .start = USBD_INT6,
- .end = USBD_INT6,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device imx_usb_device = {
- .name = "imx_udc",
- .id = 0,
- .num_resources = ARRAY_SIZE(imx_usb_resources),
- .resource = imx_usb_resources,
-};
-
-/* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
- {
- .chip.label = "gpio-0",
- .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR),
- .irq = GPIO_INT_PORTA,
- .virtual_irq_start = MXC_GPIO_IRQ_START,
- }, {
- .chip.label = "gpio-1",
- .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x100),
- .irq = GPIO_INT_PORTB,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
- }, {
- .chip.label = "gpio-2",
- .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x200),
- .irq = GPIO_INT_PORTC,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
- }, {
- .chip.label = "gpio-3",
- .base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ADDR + 0x300),
- .irq = GPIO_INT_PORTD,
- .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
- }
-};
-
-int __init mxc_register_gpios(void)
-{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
-}
diff --git a/arch/arm/mach-mx1/devices.h b/arch/arm/mach-mx1/devices.h
deleted file mode 100644
index 0da5d7cce3a2..000000000000
--- a/arch/arm/mach-mx1/devices.h
+++ /dev/null
@@ -1,7 +0,0 @@
-extern struct platform_device imx_csi_device;
-extern struct platform_device imx_i2c_device;
-extern struct platform_device imx_uart1_device;
-extern struct platform_device imx_uart2_device;
-extern struct platform_device imx_rtc_device;
-extern struct platform_device imx_wdt_device;
-extern struct platform_device imx_usb_device;
diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c
deleted file mode 100644
index 1c0c835b2252..000000000000
--- a/arch/arm/mach-mx2/serial.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <mach/hardware.h>
-#include <mach/imx-uart.h>
-#include "devices.h"
-
-static struct resource uart0[] = {
- {
- .start = MX2x_UART1_BASE_ADDR,
- .end = MX2x_UART1_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_UART1,
- .end = MX2x_INT_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
- .id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
-};
-
-static struct resource uart1[] = {
- {
- .start = MX2x_UART2_BASE_ADDR,
- .end = MX2x_UART2_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_UART2,
- .end = MX2x_INT_UART2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
-};
-
-static struct resource uart2[] = {
- {
- .start = MX2x_UART3_BASE_ADDR,
- .end = MX2x_UART3_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_UART3,
- .end = MX2x_INT_UART3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
- .id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
-};
-
-static struct resource uart3[] = {
- {
- .start = MX2x_UART4_BASE_ADDR,
- .end = MX2x_UART4_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX2x_INT_UART4,
- .end = MX2x_INT_UART4,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device3 = {
- .name = "imx-uart",
- .id = 3,
- .resource = uart3,
- .num_resources = ARRAY_SIZE(uart3),
-};
-
-#ifdef CONFIG_MACH_MX27
-static struct resource uart4[] = {
- {
- .start = MX27_UART5_BASE_ADDR,
- .end = MX27_UART5_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_UART5,
- .end = MX27_INT_UART5,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device4 = {
- .name = "imx-uart",
- .id = 4,
- .resource = uart4,
- .num_resources = ARRAY_SIZE(uart4),
-};
-
-static struct resource uart5[] = {
- {
- .start = MX27_UART6_BASE_ADDR,
- .end = MX27_UART6_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MX27_INT_UART6,
- .end = MX27_INT_UART6,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device5 = {
- .name = "imx-uart",
- .id = 5,
- .resource = uart5,
- .num_resources = ARRAY_SIZE(uart5),
-};
-#endif
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
index 54d217314ee9..67e0b54218ae 100644
--- a/arch/arm/mach-mx25/Kconfig
+++ b/arch/arm/mach-mx25/Kconfig
@@ -4,5 +4,28 @@ comment "MX25 platforms:"
config MACH_MX25_3DS
bool "Support MX25PDK (3DS) Platform"
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+
+config MACH_EUKREA_CPUIMX25
+ bool "Support Eukrea CPUIMX25 Platform"
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select MXC_ULPI if USB_ULPI
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX25
+ default MACH_EUKREA_MBIMXSD_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD_BASEBOARD
+ prompt "Eukrea MBIMXSD development board"
+ bool
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
index 10cebc5ced8c..87ffb9c2f90a 100644
--- a/arch/arm/mach-mx25/Makefile
+++ b/arch/arm/mach-mx25/Makefile
@@ -1,3 +1,5 @@
obj-y := mm.o devices.o
obj-$(CONFIG_ARCH_MX25) += clock.o
-obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25pdk.o
+obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-cpuimx25.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD) += eukrea_mbimxsd-baseboard.o
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
index 155014993b13..1a58cae4d5e8 100644
--- a/arch/arm/mach-mx25/clock.c
+++ b/arch/arm/mach-mx25/clock.c
@@ -109,6 +109,16 @@ static unsigned long get_rate_uart(struct clk *clk)
return get_rate_per(15);
}
+static unsigned long get_rate_ssi2(struct clk *clk)
+{
+ return get_rate_per(14);
+}
+
+static unsigned long get_rate_ssi1(struct clk *clk)
+{
+ return get_rate_per(13);
+}
+
static unsigned long get_rate_i2c(struct clk *clk)
{
return get_rate_per(6);
@@ -129,9 +139,17 @@ static unsigned long get_rate_lcdc(struct clk *clk)
return get_rate_per(7);
}
+static unsigned long get_rate_csi(struct clk *clk)
+{
+ return get_rate_per(0);
+}
+
static unsigned long get_rate_otg(struct clk *clk)
{
- return 48000000; /* FIXME */
+ unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+ unsigned long rate = get_rate_upll();
+
+ return (cctl & (1 << 23)) ? 0 : rate / ((0x3F & (cctl >> 16)) + 1);
}
static int clk_cgcr_enable(struct clk *clk)
@@ -166,14 +184,40 @@ static void clk_cgcr_disable(struct clk *clk)
.secondary = s, \
}
+/*
+ * Note: the following IPG clock gating bits are wrongly marked "Reserved" in
+ * the i.MX25 Reference Manual Rev 1, table 15-13. The information below is
+ * taken from the Freescale released BSP.
+ *
+ * bit reg offset clock
+ *
+ * 0 CGCR1 0 AUDMUX
+ * 12 CGCR1 12 ESAI
+ * 16 CGCR1 16 GPIO1
+ * 17 CGCR1 17 GPIO2
+ * 18 CGCR1 18 GPIO3
+ * 23 CGCR1 23 I2C1
+ * 24 CGCR1 24 I2C2
+ * 25 CGCR1 25 I2C3
+ * 27 CGCR1 27 IOMUXC
+ * 28 CGCR1 28 KPP
+ * 30 CGCR1 30 OWIRE
+ * 36 CGCR2 4 RTIC
+ * 51 CGCR2 19 WDOG
+ */
+
DEFINE_CLOCK(gpt_clk, 0, CCM_CGCR0, 5, get_rate_gpt, NULL, NULL);
DEFINE_CLOCK(uart_per_clk, 0, CCM_CGCR0, 15, get_rate_uart, NULL, NULL);
+DEFINE_CLOCK(ssi1_per_clk, 0, CCM_CGCR0, 13, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(ssi2_per_clk, 0, CCM_CGCR0, 14, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi1_clk, 0, CCM_CGCR1, 5, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi2_clk, 0, CCM_CGCR1, 6, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(cspi3_clk, 0, CCM_CGCR1, 7, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(fec_ahb_clk, 0, CCM_CGCR0, 23, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_ahb_clk, 0, CCM_CGCR0, 24, NULL, NULL, NULL);
DEFINE_CLOCK(lcdc_per_clk, 0, CCM_CGCR0, 7, NULL, NULL, &lcdc_ahb_clk);
+DEFINE_CLOCK(csi_ahb_clk, 0, CCM_CGCR0, 18, get_rate_csi, NULL, NULL);
+DEFINE_CLOCK(csi_per_clk, 0, CCM_CGCR0, 0, get_rate_csi, NULL, &csi_ahb_clk);
DEFINE_CLOCK(uart1_clk, 0, CCM_CGCR2, 14, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart2_clk, 0, CCM_CGCR2, 15, get_rate_uart, NULL, &uart_per_clk);
DEFINE_CLOCK(uart3_clk, 0, CCM_CGCR2, 16, get_rate_uart, NULL, &uart_per_clk);
@@ -191,6 +235,11 @@ DEFINE_CLOCK(i2c_clk, 0, CCM_CGCR0, 6, get_rate_i2c, NULL, NULL);
DEFINE_CLOCK(fec_clk, 0, CCM_CGCR1, 15, get_rate_ipg, NULL, &fec_ahb_clk);
DEFINE_CLOCK(dryice_clk, 0, CCM_CGCR1, 8, get_rate_ipg, NULL, NULL);
DEFINE_CLOCK(lcdc_clk, 0, CCM_CGCR1, 29, get_rate_lcdc, NULL, &lcdc_per_clk);
+DEFINE_CLOCK(wdt_clk, 0, CCM_CGCR2, 19, get_rate_ipg, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk, 0, CCM_CGCR2, 11, get_rate_ssi1, NULL, &ssi1_per_clk);
+DEFINE_CLOCK(ssi2_clk, 1, CCM_CGCR2, 12, get_rate_ssi2, NULL, &ssi2_per_clk);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGCR1, 0, NULL, NULL, NULL);
+DEFINE_CLOCK(csi_clk, 0, CCM_CGCR1, 4, get_rate_csi, NULL, &csi_per_clk);
#define _REGISTER_CLOCK(d, n, c) \
{ \
@@ -217,7 +266,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
_REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
- _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+ _REGISTER_CLOCK("imx-keypad", NULL, kpp_clk)
_REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
_REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
_REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
@@ -225,6 +274,11 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
_REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
_REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
+ _REGISTER_CLOCK("imx-wdt.0", NULL, wdt_clk)
+ _REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+ _REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+ _REGISTER_CLOCK("mx2-camera.0", NULL, csi_clk)
+ _REGISTER_CLOCK(NULL, "audmux", audmux_clk)
};
int __init mx25_clocks_init(void)
@@ -239,8 +293,9 @@ int __init mx25_clocks_init(void)
__raw_writel((0xf << 16) | (3 << 26), CRM_BASE + CCM_CGCR1);
__raw_writel((1 << 5), CRM_BASE + CCM_CGCR2);
- /* Clock source for lcdc is upll */
- __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7), CRM_BASE + 0x64);
+ /* Clock source for lcdc and csi is upll */
+ __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0),
+ CRM_BASE + 0x64);
mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
diff --git a/arch/arm/mach-mx25/devices-imx25.h b/arch/arm/mach-mx25/devices-imx25.h
new file mode 100644
index 000000000000..2025cb947fcf
--- /dev/null
+++ b/arch/arm/mach-mx25/devices-imx25.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx25.h>
+#include <mach/devices-common.h>
+
+#define imx25_add_imx_i2c0(pdata) \
+ imx_add_imx_i2c(0, MX25_I2C1_BASE_ADDR, SZ_16K, MX25_INT_I2C1, pdata)
+#define imx25_add_imx_i2c1(pdata) \
+ imx_add_imx_i2c(1, MX25_I2C2_BASE_ADDR, SZ_16K, MX25_INT_I2C2, pdata)
+#define imx25_add_imx_i2c2(pdata) \
+ imx_add_imx_i2c(2, MX25_I2C3_BASE_ADDR, SZ_16K, MX25_INT_I2C3, pdata)
+
+#define imx25_add_imx_uart0(pdata) \
+ imx_add_imx_uart_1irq(0, MX25_UART1_BASE_ADDR, SZ_16K, MX25_INT_UART1, pdata)
+#define imx25_add_imx_uart1(pdata) \
+ imx_add_imx_uart_1irq(1, MX25_UART2_BASE_ADDR, SZ_16K, MX25_INT_UART2, pdata)
+#define imx25_add_imx_uart2(pdata) \
+ imx_add_imx_uart_1irq(2, MX25_UART3_BASE_ADDR, SZ_16K, MX25_INT_UART3, pdata)
+#define imx25_add_imx_uart3(pdata) \
+ imx_add_imx_uart_1irq(3, MX25_UART4_BASE_ADDR, SZ_16K, MX25_INT_UART4, pdata)
+#define imx25_add_imx_uart4(pdata) \
+ imx_add_imx_uart_1irq(4, MX25_UART5_BASE_ADDR, SZ_16K, MX25_INT_UART5, pdata)
+
+#define imx25_add_mxc_nand(pdata) \
+ imx_add_mxc_nand_v21(MX25_NFC_BASE_ADDR, MX25_INT_NANDFC, pdata)
+
+#define imx25_add_spi_imx0(pdata) \
+ imx_add_spi_imx(0, MX25_CSPI1_BASE_ADDR, SZ_16K, MX25_INT_CSPI1, pdata)
+#define imx25_add_spi_imx1(pdata) \
+ imx_add_spi_imx(1, MX25_CSPI2_BASE_ADDR, SZ_16K, MX25_INT_CSPI2, pdata)
+#define imx25_add_spi_imx2(pdata) \
+ imx_add_spi_imx(2, MX25_CSPI3_BASE_ADDR, SZ_16K, MX25_INT_CSPI3, pdata)
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
index 3a405fa400eb..3468eb15b236 100644
--- a/arch/arm/mach-mx25/devices.c
+++ b/arch/arm/mach-mx25/devices.c
@@ -22,103 +22,6 @@
#include <mach/mx25.h>
#include <mach/irqs.h>
-static struct resource uart0[] = {
- {
- .start = 0x43f90000,
- .end = 0x43f93fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 45,
- .end = 45,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
- .id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
-};
-
-static struct resource uart1[] = {
- {
- .start = 0x43f94000,
- .end = 0x43f97fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 32,
- .end = 32,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
-};
-
-static struct resource uart2[] = {
- {
- .start = 0x5000c000,
- .end = 0x5000ffff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 18,
- .end = 18,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
- .id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
-};
-
-static struct resource uart3[] = {
- {
- .start = 0x50008000,
- .end = 0x5000bfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 5,
- .end = 5,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device3 = {
- .name = "imx-uart",
- .id = 3,
- .resource = uart3,
- .num_resources = ARRAY_SIZE(uart3),
-};
-
-static struct resource uart4[] = {
- {
- .start = 0x5002c000,
- .end = 0x5002ffff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 40,
- .end = 40,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device4 = {
- .name = "imx-uart",
- .id = 4,
- .resource = uart4,
- .num_resources = ARRAY_SIZE(uart4),
-};
-
-#define MX25_OTG_BASE_ADDR 0x53FF4000
-
static u64 otg_dmamask = DMA_BIT_MASK(32);
static struct resource mxc_otg_resources[] = {
@@ -181,63 +84,6 @@ struct platform_device mxc_usbh2 = {
.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
};
-static struct resource mxc_spi_resources0[] = {
- {
- .start = 0x43fa4000,
- .end = 0x43fa7fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 14,
- .end = 14,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_spi_device0 = {
- .name = "spi_imx",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_spi_resources0),
- .resource = mxc_spi_resources0,
-};
-
-static struct resource mxc_spi_resources1[] = {
- {
- .start = 0x50010000,
- .end = 0x50013fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 13,
- .end = 13,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_spi_device1 = {
- .name = "spi_imx",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_spi_resources1),
- .resource = mxc_spi_resources1,
-};
-
-static struct resource mxc_spi_resources2[] = {
- {
- .start = 0x50004000,
- .end = 0x50007fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_spi_device2 = {
- .name = "spi_imx",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_spi_resources2),
- .resource = mxc_spi_resources2,
-};
-
static struct resource mxc_pwm_resources0[] = {
{
.start = 0x53fe0000,
@@ -333,63 +179,6 @@ struct platform_device mxc_pwm_device3 = {
.resource = mxc_pwm_resources3,
};
-static struct resource mxc_i2c_1_resources[] = {
- {
- .start = 0x43f80000,
- .end = 0x43f83fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 3,
- .end = 3,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_i2c_device0 = {
- .name = "imx-i2c",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
- .resource = mxc_i2c_1_resources,
-};
-
-static struct resource mxc_i2c_2_resources[] = {
- {
- .start = 0x43f98000,
- .end = 0x43f9bfff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 4,
- .end = 4,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_i2c_device1 = {
- .name = "imx-i2c",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
- .resource = mxc_i2c_2_resources,
-};
-
-static struct resource mxc_i2c_3_resources[] = {
- {
- .start = 0x43f84000,
- .end = 0x43f87fff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = 10,
- .end = 10,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-struct platform_device mxc_i2c_device2 = {
- .name = "imx-i2c",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_i2c_3_resources),
- .resource = mxc_i2c_3_resources,
-};
-
static struct mxc_gpio_port imx_gpio_ports[] = {
{
.chip.label = "gpio-0",
@@ -414,7 +203,7 @@ static struct mxc_gpio_port imx_gpio_ports[] = {
}
};
-int __init mxc_register_gpios(void)
+int __init imx25_register_gpios(void)
{
return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
}
@@ -439,26 +228,6 @@ struct platform_device mx25_fec_device = {
.resource = mx25_fec_resources,
};
-static struct resource mxc_nand_resources[] = {
- {
- .start = MX25_NFC_BASE_ADDR,
- .end = MX25_NFC_BASE_ADDR + 0x1fff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = MX25_INT_NANDFC,
- .end = MX25_INT_NANDFC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_nand_device = {
- .name = "mxc_nand",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_nand_resources),
- .resource = mxc_nand_resources,
-};
-
static struct resource mx25_rtc_resources[] = {
{
.start = MX25_DRYICE_BASE_ADDR,
@@ -515,3 +284,83 @@ struct platform_device mxc_wdt = {
.num_resources = ARRAY_SIZE(mxc_wdt_resources),
.resource = mxc_wdt_resources,
};
+
+static struct resource mx25_kpp_resources[] = {
+ {
+ .start = MX25_KPP_BASE_ADDR,
+ .end = MX25_KPP_BASE_ADDR + 0xf,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_KPP,
+ .end = MX25_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mx25_kpp_device = {
+ .name = "imx-keypad",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(mx25_kpp_resources),
+ .resource = mx25_kpp_resources,
+};
+
+static struct resource imx_ssi_resources0[] = {
+ {
+ .start = MX25_SSI1_BASE_ADDR,
+ .end = MX25_SSI1_BASE_ADDR + 0x3fff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX25_INT_SSI1,
+ .end = MX25_INT_SSI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource imx_ssi_resources1[] = {
+ {
+ .start = MX25_SSI2_BASE_ADDR,
+ .end = MX25_SSI2_BASE_ADDR + 0x3fff,
+ .flags = IORESOURCE_MEM
+ }, {
+ .start = MX25_INT_SSI2,
+ .end = MX25_INT_SSI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device imx_ssi_device0 = {
+ .name = "imx-ssi",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(imx_ssi_resources0),
+ .resource = imx_ssi_resources0,
+};
+
+struct platform_device imx_ssi_device1 = {
+ .name = "imx-ssi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(imx_ssi_resources1),
+ .resource = imx_ssi_resources1,
+};
+
+static struct resource mx25_csi_resources[] = {
+ {
+ .start = MX25_CSI_BASE_ADDR,
+ .end = MX25_CSI_BASE_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX25_INT_CSI,
+ .flags = IORESOURCE_IRQ
+ },
+};
+
+struct platform_device mx25_csi_device = {
+ .name = "mx2-camera",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mx25_csi_resources),
+ .resource = mx25_csi_resources,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
index cee12c0a0be6..4aceb68e35a7 100644
--- a/arch/arm/mach-mx25/devices.h
+++ b/arch/arm/mach-mx25/devices.h
@@ -1,24 +1,16 @@
-extern struct platform_device mxc_uart_device0;
-extern struct platform_device mxc_uart_device1;
-extern struct platform_device mxc_uart_device2;
-extern struct platform_device mxc_uart_device3;
-extern struct platform_device mxc_uart_device4;
extern struct platform_device mxc_otg;
extern struct platform_device otg_udc_device;
extern struct platform_device mxc_usbh2;
-extern struct platform_device mxc_spi_device0;
-extern struct platform_device mxc_spi_device1;
-extern struct platform_device mxc_spi_device2;
extern struct platform_device mxc_pwm_device0;
extern struct platform_device mxc_pwm_device1;
extern struct platform_device mxc_pwm_device2;
extern struct platform_device mxc_pwm_device3;
extern struct platform_device mxc_keypad_device;
-extern struct platform_device mxc_i2c_device0;
-extern struct platform_device mxc_i2c_device1;
-extern struct platform_device mxc_i2c_device2;
extern struct platform_device mx25_fec_device;
-extern struct platform_device mxc_nand_device;
extern struct platform_device mx25_rtc_device;
extern struct platform_device mx25_fb_device;
extern struct platform_device mxc_wdt;
+extern struct platform_device mx25_kpp_device;
+extern struct platform_device imx_ssi_device0;
+extern struct platform_device imx_ssi_device1;
+extern struct platform_device mx25_csi_device;
diff --git a/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
new file mode 100644
index 000000000000..f07b1f95ac76
--- /dev/null
+++ b/arch/arm/mach-mx25/eukrea_mbimxsd-baseboard.c
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <video/platform_lcd.h>
+
+#include <mach/board-eukrea_cpuimx25.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx25.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/mx25.h>
+#include <mach/imx-uart.h>
+#include <mach/imxfb.h>
+#include <mach/ssi.h>
+#include <mach/audmux.h>
+
+#include "devices-imx25.h"
+#include "devices.h"
+
+static struct pad_desc eukrea_mbimxsd_pads[] = {
+ /* LCD */
+ MX25_PAD_LD0__LD0,
+ MX25_PAD_LD1__LD1,
+ MX25_PAD_LD2__LD2,
+ MX25_PAD_LD3__LD3,
+ MX25_PAD_LD4__LD4,
+ MX25_PAD_LD5__LD5,
+ MX25_PAD_LD6__LD6,
+ MX25_PAD_LD7__LD7,
+ MX25_PAD_LD8__LD8,
+ MX25_PAD_LD9__LD9,
+ MX25_PAD_LD10__LD10,
+ MX25_PAD_LD11__LD11,
+ MX25_PAD_LD12__LD12,
+ MX25_PAD_LD13__LD13,
+ MX25_PAD_LD14__LD14,
+ MX25_PAD_LD15__LD15,
+ MX25_PAD_GPIO_E__LD16,
+ MX25_PAD_GPIO_F__LD17,
+ MX25_PAD_HSYNC__HSYNC,
+ MX25_PAD_VSYNC__VSYNC,
+ MX25_PAD_LSCLK__LSCLK,
+ MX25_PAD_OE_ACD__OE_ACD,
+ MX25_PAD_CONTRAST__CONTRAST,
+ /* LCD_PWR */
+ MX25_PAD_PWM__GPIO_1_26,
+ /* LED */
+ MX25_PAD_POWER_FAIL__GPIO_3_19,
+ /* SWITCH */
+ MX25_PAD_VSTBY_ACK__GPIO_3_18,
+ /* UART2 */
+ MX25_PAD_UART2_RTS__UART2_RTS,
+ MX25_PAD_UART2_CTS__UART2_CTS,
+ MX25_PAD_UART2_TXD__UART2_TXD,
+ MX25_PAD_UART2_RXD__UART2_RXD,
+ /* SD1 */
+ MX25_PAD_SD1_CMD__SD1_CMD,
+ MX25_PAD_SD1_CLK__SD1_CLK,
+ MX25_PAD_SD1_DATA0__SD1_DATA0,
+ MX25_PAD_SD1_DATA1__SD1_DATA1,
+ MX25_PAD_SD1_DATA2__SD1_DATA2,
+ MX25_PAD_SD1_DATA3__SD1_DATA3,
+ /* SD1 CD */
+ MX25_PAD_DE_B__GPIO_2_20,
+ /* I2S */
+ MX25_PAD_KPP_COL3__AUD5_TXFS,
+ MX25_PAD_KPP_COL2__AUD5_TXC,
+ MX25_PAD_KPP_COL1__AUD5_RXD,
+ MX25_PAD_KPP_COL0__AUD5_TXD,
+};
+
+#define GPIO_LED1 83
+#define GPIO_SWITCH1 82
+#define GPIO_SD1CD 52
+#define GPIO_LCDPWR 26
+
+static struct imx_fb_videomode eukrea_mximxsd_modes[] = {
+ {
+ .mode = {
+ .name = "CMO-QVGA",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6500),
+ .left_margin = 30,
+ .right_margin = 38,
+ .upper_margin = 20,
+ .lower_margin = 3,
+ .hsync_len = 15,
+ .vsync_len = 4,
+ },
+ .bpp = 16,
+ .pcr = 0xCAD08B80,
+ },
+};
+
+static struct imx_fb_platform_data eukrea_mximxsd_fb_pdata = {
+ .mode = eukrea_mximxsd_modes,
+ .num_modes = ARRAY_SIZE(eukrea_mximxsd_modes),
+ .pwmr = 0x00A903FF,
+ .lscr1 = 0x00120300,
+ .dmacr = 0x00040060,
+};
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ else
+ gpio_direction_output(GPIO_LCDPWR, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+ .set_power = eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimxsd_lcd_power_data,
+};
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device eukrea_mbimxsd_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_button_data,
+ }
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+ &eukrea_mbimxsd_button_device,
+ &eukrea_mbimxsd_lcd_powerdev,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+ .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx25 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+ /* SSI unit master I2S codec connected to SSI_AUD5*/
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN |
+ MXC_AUDMUX_V2_PTCR_TFSDIR |
+ MXC_AUDMUX_V2_PTCR_TFSEL(4) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR |
+ MXC_AUDMUX_V2_PTCR_TCSEL(4),
+ MXC_AUDMUX_V2_PDCR_RXDSEL(4)
+ );
+ mxc_audmux_v2_configure_port(4,
+ MXC_AUDMUX_V2_PTCR_SYN,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+ );
+#endif
+
+ imx25_add_imx_uart1(&uart_pdata);
+ mxc_register_device(&mx25_fb_device, &eukrea_mximxsd_fb_pdata);
+ mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ gpio_request(GPIO_LCDPWR, "LCDPWR");
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ gpio_free(GPIO_SWITCH1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
diff --git a/arch/arm/mach-mx25/mach-cpuimx25.c b/arch/arm/mach-mx25/mach-cpuimx25.c
new file mode 100644
index 000000000000..d39f9ccd4be0
--- /dev/null
+++ b/arch/arm/mach-mx25/mach-cpuimx25.c
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2009 Sascha Hauer, <kernel@pengutronix.de>
+ * Copyright 2010 Eric Bénard - Eukréa Electromatique, <eric@eukrea.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 Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/fec.h>
+#include <linux/platform_device.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
+
+#include <mach/board-eukrea_cpuimx25.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/memory.h>
+#include <asm/mach/map.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+#include <mach/mxc_nand.h>
+#include <mach/imxfb.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+#include <mach/iomux-mx25.h>
+
+#include "devices-imx25.h"
+#include "devices.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct pad_desc eukrea_cpuimx25_pads[] = {
+ /* FEC - RMII */
+ MX25_PAD_FEC_MDC__FEC_MDC,
+ MX25_PAD_FEC_MDIO__FEC_MDIO,
+ MX25_PAD_FEC_TDATA0__FEC_TDATA0,
+ MX25_PAD_FEC_TDATA1__FEC_TDATA1,
+ MX25_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX25_PAD_FEC_RDATA0__FEC_RDATA0,
+ MX25_PAD_FEC_RDATA1__FEC_RDATA1,
+ MX25_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX25_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ /* I2C1 */
+ MX25_PAD_I2C1_CLK__I2C1_CLK,
+ MX25_PAD_I2C1_DAT__I2C1_DAT,
+};
+
+static struct fec_platform_data mx25_fec_pdata = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static const struct mxc_nand_platform_data
+eukrea_cpuimx25_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static const struct imxi2c_platform_data
+eukrea_cpuimx25_i2c0_data __initconst = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info eukrea_cpuimx25_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ },
+};
+
+static struct mxc_usbh_platform_data otg_pdata = {
+ .portsc = MXC_EHCI_MODE_UTMI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+ .portsc = MXC_EHCI_MODE_SERIAL,
+ .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
+ MXC_EHCI_IPPUE_DOWN,
+};
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx25_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx25_otg_mode);
+
+static void __init eukrea_cpuimx25_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx25_pads,
+ ARRAY_SIZE(eukrea_cpuimx25_pads)))
+ printk(KERN_ERR "error setting cpuimx25 pads !\n");
+
+ imx25_add_imx_uart0(&uart_pdata);
+ imx25_add_mxc_nand(&eukrea_cpuimx25_nand_board_info);
+ mxc_register_device(&mx25_rtc_device, NULL);
+ mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+
+ i2c_register_board_info(0, eukrea_cpuimx25_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx25_i2c_devices));
+ imx25_add_imx_i2c0(&eukrea_cpuimx25_i2c0_data);
+
+#if defined(CONFIG_USB_ULPI)
+ if (otg_mode_host) {
+ otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_otg, &otg_pdata);
+ }
+ mxc_register_device(&mxc_usbh2, &usbh2_pdata);
+#endif
+ if (!otg_mode_host)
+ mxc_register_device(&otg_udc_device, &otg_device_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD
+ eukrea_mbimxsd_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx25_timer_init(void)
+{
+ mx25_clocks_init();
+}
+
+static struct sys_timer eukrea_cpuimx25_timer = {
+ .init = eukrea_cpuimx25_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX25, "Eukrea CPUIMX25")
+ /* Maintainer: Eukrea Electromatique */
+ .phys_io = MX25_AIPS1_BASE_ADDR,
+ .io_pg_offst = ((MX25_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX25_PHYS_OFFSET + 0x100,
+ .map_io = mx25_map_io,
+ .init_irq = mx25_init_irq,
+ .init_machine = eukrea_cpuimx25_init,
+ .timer = &eukrea_cpuimx25_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx25/mach-mx25pdk.c b/arch/arm/mach-mx25/mach-mx25_3ds.c
index 83d74109e7d8..62bc21f11a71 100644
--- a/arch/arm/mach-mx25/mach-mx25pdk.c
+++ b/arch/arm/mach-mx25/mach-mx25_3ds.c
@@ -16,6 +16,12 @@
* Boston, MA 02110-1301, USA.
*/
+/*
+ * This machine is known as:
+ * - i.MX25 3-Stack Development System
+ * - i.MX25 Platform Development Kit (i.MX25 PDK)
+ */
+
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
@@ -24,6 +30,7 @@
#include <linux/gpio.h>
#include <linux/fec.h>
#include <linux/platform_device.h>
+#include <linux/input/matrix_keypad.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -32,14 +39,14 @@
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/mx25.h>
-#include <mach/mxc_nand.h>
#include <mach/imxfb.h>
-#include "devices.h"
#include <mach/iomux-mx25.h>
-static struct imxuart_platform_data uart_pdata = {
+#include "devices-imx25.h"
+#include "devices.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -80,6 +87,16 @@ static struct pad_desc mx25pdk_pads[] = {
MX25_PAD_LSCLK__LSCLK,
MX25_PAD_OE_ACD__OE_ACD,
MX25_PAD_CONTRAST__CONTRAST,
+
+ /* Keypad */
+ MX25_PAD_KPP_ROW0__KPP_ROW0,
+ MX25_PAD_KPP_ROW1__KPP_ROW1,
+ MX25_PAD_KPP_ROW2__KPP_ROW2,
+ MX25_PAD_KPP_ROW3__KPP_ROW3,
+ MX25_PAD_KPP_COL0__KPP_COL0,
+ MX25_PAD_KPP_COL1__KPP_COL1,
+ MX25_PAD_KPP_COL2__KPP_COL2,
+ MX25_PAD_KPP_COL3__KPP_COL3,
};
static struct fec_platform_data mx25_fec_pdata = {
@@ -103,7 +120,8 @@ static void __init mx25pdk_fec_reset(void)
gpio_set_value(FEC_RESET_B_GPIO, 1);
}
-static struct mxc_nand_platform_data mx25pdk_nand_board_info = {
+static const struct mxc_nand_platform_data
+mx25pdk_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
.flash_bbt = 1,
@@ -137,19 +155,45 @@ static struct imx_fb_platform_data mx25pdk_fb_pdata = {
.dmacr = 0x00020010,
};
+static const uint32_t mx25pdk_keymap[] = {
+ KEY(0, 0, KEY_UP),
+ KEY(0, 1, KEY_DOWN),
+ KEY(0, 2, KEY_VOLUMEDOWN),
+ KEY(0, 3, KEY_HOME),
+ KEY(1, 0, KEY_RIGHT),
+ KEY(1, 1, KEY_LEFT),
+ KEY(1, 2, KEY_ENTER),
+ KEY(1, 3, KEY_VOLUMEUP),
+ KEY(2, 0, KEY_F6),
+ KEY(2, 1, KEY_F8),
+ KEY(2, 2, KEY_F9),
+ KEY(2, 3, KEY_F10),
+ KEY(3, 0, KEY_F1),
+ KEY(3, 1, KEY_F2),
+ KEY(3, 2, KEY_F3),
+ KEY(3, 3, KEY_POWER),
+};
+
+static struct matrix_keymap_data mx25pdk_keymap_data = {
+ .keymap = mx25pdk_keymap,
+ .keymap_size = ARRAY_SIZE(mx25pdk_keymap),
+};
+
static void __init mx25pdk_init(void)
{
mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
ARRAY_SIZE(mx25pdk_pads));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx25_add_imx_uart0(&uart_pdata);
mxc_register_device(&mxc_usbh2, NULL);
- mxc_register_device(&mxc_nand_device, &mx25pdk_nand_board_info);
+ imx25_add_mxc_nand(&mx25pdk_nand_board_info);
mxc_register_device(&mx25_rtc_device, NULL);
mxc_register_device(&mx25_fb_device, &mx25pdk_fb_pdata);
+ mxc_register_device(&mxc_wdt, NULL);
mx25pdk_fec_reset();
mxc_register_device(&mx25_fec_device, &mx25_fec_pdata);
+ mxc_register_device(&mx25_kpp_device, &mx25pdk_keymap_data);
}
static void __init mx25pdk_timer_init(void)
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-mx25/mm.c
index a7e587ff3e9e..593e14545f5a 100644
--- a/arch/arm/mach-mx25/mm.c
+++ b/arch/arm/mach-mx25/mm.c
@@ -14,10 +14,6 @@
* 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/mm.h>
@@ -69,8 +65,11 @@ void __init mx25_map_io(void)
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+int imx25_register_gpios(void);
+
void __init mx25_init_irq(void)
{
+ imx25_register_gpios();
mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT);
}
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index 344753fdf25e..e063657e1bf4 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -15,6 +15,8 @@ comment "MX3 platforms:"
config MACH_MX31ADS
bool "Support MX31ADS platforms"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
default y
help
Include support for MX31ADS platform. This includes specific
@@ -34,6 +36,9 @@ config MACH_MX31ADS_WM1133_EV1
config MACH_PCM037
bool "Support Phytec pcm037 (i.MX31) platforms"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm037 platform. This includes
@@ -42,6 +47,7 @@ config MACH_PCM037
config MACH_PCM037_EET
bool "Support pcm037 EET board extensions"
depends on MACH_PCM037
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Add support for PCM037 EET baseboard extensions. If you are using the
OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel
@@ -51,6 +57,9 @@ config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
select ARCH_MX31
select MXC_ULPI if USB_ULPI
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for MX31 LITEKIT platform. This includes specific
configurations for the board and its peripherals.
@@ -58,6 +67,10 @@ config MACH_MX31LITE
config MACH_MX31_3DS
bool "Support MX31PDK (3DS)"
select ARCH_MX31
+ select MXC_DEBUG_BOARD
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select IMX_HAVE_PLATFORM_SPI_IMX
help
Include support for MX31PDK (3DS) platform. This includes specific
configurations for the board and its peripherals.
@@ -74,6 +87,9 @@ config MACH_MX31_3DS_MXC_NAND_USE_BBT
config MACH_MX31MOBOARD
bool "Support mx31moboard platforms (EPFL Mobots group)"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
Include support for mx31moboard platform. This includes specific
@@ -82,6 +98,8 @@ config MACH_MX31MOBOARD
config MACH_MX31LILLY
bool "Support MX31 LILLY-1131 platforms (INCO startec)"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_SPI_IMX
select MXC_ULPI if USB_ULPI
help
Include support for mx31 based LILLY1131 modules. This includes
@@ -90,6 +108,7 @@ config MACH_MX31LILLY
config MACH_QONG
bool "Support Dave/DENX QongEVB-LITE platform"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for Dave/DENX QongEVB-LITE platform. This includes
specific configurations for the board and its peripherals.
@@ -97,6 +116,9 @@ config MACH_QONG
config MACH_PCM043
bool "Support Phytec pcm043 (i.MX35) platforms"
select ARCH_MX35
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
select MXC_ULPI if USB_ULPI
help
Include support for Phytec pcm043 platform. This includes
@@ -105,6 +127,9 @@ config MACH_PCM043
config MACH_ARMADILLO5X0
bool "Support Atmark Armadillo-500 Development Base Board"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MXC_NAND
select MXC_ULPI if USB_ULPI
help
Include support for Atmark Armadillo-500 platform. This includes
@@ -113,6 +138,7 @@ config MACH_ARMADILLO5X0
config MACH_MX35_3DS
bool "Support MX35PDK platform"
select ARCH_MX35
+ select IMX_HAVE_PLATFORM_IMX_UART
default n
help
Include support for MX35PDK platform. This includes specific
@@ -121,8 +147,34 @@ config MACH_MX35_3DS
config MACH_KZM_ARM11_01
bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
select ARCH_MX31
+ select IMX_HAVE_PLATFORM_IMX_UART
help
Include support for KZM-ARM11-01. This includes specific
configurations for the board and its peripherals.
+config MACH_EUKREA_CPUIMX35
+ bool "Support Eukrea CPUIMX35 Platform"
+ select ARCH_MX35
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_MXC_NAND
+ select MXC_ULPI if USB_ULPI
+ help
+ Include support for Eukrea CPUIMX35 platform. This includes
+ specific configurations for the board and its peripherals.
+
+choice
+ prompt "Baseboard"
+ depends on MACH_EUKREA_CPUIMX35
+ default MACH_EUKREA_MBIMXSD_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD_BASEBOARD
+ prompt "Eukrea MBIMXSD development board"
+ bool
+ help
+ This adds board specific devices that can be found on Eukrea's
+ MBIMXSD evaluation board.
+
+endchoice
+
endif
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 5d650fda5d5d..54bc935acdc6 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -22,5 +22,7 @@ obj-$(CONFIG_MACH_MX31MOBOARD) += mach-mx31moboard.o mx31moboard-devboard.o \
obj-$(CONFIG_MACH_QONG) += mach-qong.o
obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o
obj-$(CONFIG_MACH_ARMADILLO5X0) += mach-armadillo5x0.o
-obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35pdk.o
+obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD) += eukrea_mbimxsd-baseboard.o
diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c
index 9f3e943e2232..28be011dace6 100644
--- a/arch/arm/mach-mx3/clock-imx35.c
+++ b/arch/arm/mach-mx3/clock-imx35.c
@@ -359,7 +359,7 @@ DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
-DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, NULL, NULL);
+DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, get_rate_ahb, NULL);
DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL);
DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL);
DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL);
diff --git a/arch/arm/mach-mx3/devices-imx31.h b/arch/arm/mach-mx3/devices-imx31.h
new file mode 100644
index 000000000000..3b1a44a20585
--- /dev/null
+++ b/arch/arm/mach-mx3/devices-imx31.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx31.h>
+#include <mach/devices-common.h>
+
+#define imx31_add_imx_i2c0(pdata) \
+ imx_add_imx_i2c(0, MX31_I2C1_BASE_ADDR, SZ_4K, MX31_INT_I2C1, pdata)
+#define imx31_add_imx_i2c1(pdata) \
+ imx_add_imx_i2c(1, MX31_I2C2_BASE_ADDR, SZ_4K, MX31_INT_I2C2, pdata)
+#define imx31_add_imx_i2c2(pdata) \
+ imx_add_imx_i2c(2, MX31_I2C3_BASE_ADDR, SZ_4K, MX31_INT_I2C3, pdata)
+
+#define imx31_add_imx_uart0(pdata) \
+ imx_add_imx_uart_1irq(0, MX31_UART1_BASE_ADDR, SZ_16K, MX31_INT_UART1, pdata)
+#define imx31_add_imx_uart1(pdata) \
+ imx_add_imx_uart_1irq(1, MX31_UART2_BASE_ADDR, SZ_16K, MX31_INT_UART2, pdata)
+#define imx31_add_imx_uart2(pdata) \
+ imx_add_imx_uart_1irq(2, MX31_UART3_BASE_ADDR, SZ_16K, MX31_INT_UART3, pdata)
+#define imx31_add_imx_uart3(pdata) \
+ imx_add_imx_uart_1irq(3, MX31_UART4_BASE_ADDR, SZ_16K, MX31_INT_UART4, pdata)
+#define imx31_add_imx_uart4(pdata) \
+ imx_add_imx_uart_1irq(4, MX31_UART5_BASE_ADDR, SZ_16K, MX31_INT_UART5, pdata)
+
+#define imx31_add_mxc_nand(pdata) \
+ imx_add_mxc_nand_v1(MX31_NFC_BASE_ADDR, MX31_INT_NANDFC, pdata)
+
+#define imx31_add_spi_imx0(pdata) \
+ imx_add_spi_imx(0, MX31_CSPI1_BASE_ADDR, SZ_4K, MX31_INT_CSPI1, pdata)
+#define imx31_add_spi_imx1(pdata) \
+ imx_add_spi_imx(1, MX31_CSPI2_BASE_ADDR, SZ_4K, MX31_INT_CSPI2, pdata)
+#define imx31_add_spi_imx2(pdata) \
+ imx_add_spi_imx(2, MX31_CSPI3_BASE_ADDR, SZ_4K, MX31_INT_CSPI3, pdata)
diff --git a/arch/arm/mach-mx3/devices-imx35.h b/arch/arm/mach-mx3/devices-imx35.h
new file mode 100644
index 000000000000..536d9b9a250b
--- /dev/null
+++ b/arch/arm/mach-mx3/devices-imx35.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/mx35.h>
+#include <mach/devices-common.h>
+
+#define imx35_add_imx_i2c0(pdata) \
+ imx_add_imx_i2c(0, MX35_I2C1_BASE_ADDR, SZ_4K, MX35_INT_I2C1, pdata)
+#define imx35_add_imx_i2c1(pdata) \
+ imx_add_imx_i2c(1, MX35_I2C2_BASE_ADDR, SZ_4K, MX35_INT_I2C2, pdata)
+#define imx35_add_imx_i2c2(pdata) \
+ imx_add_imx_i2c(2, MX35_I2C3_BASE_ADDR, SZ_4K, MX35_INT_I2C3, pdata)
+
+#define imx35_add_imx_uart0(pdata) \
+ imx_add_imx_uart_1irq(0, MX35_UART1_BASE_ADDR, SZ_16K, MX35_INT_UART1, pdata)
+#define imx35_add_imx_uart1(pdata) \
+ imx_add_imx_uart_1irq(1, MX35_UART2_BASE_ADDR, SZ_16K, MX35_INT_UART2, pdata)
+#define imx35_add_imx_uart2(pdata) \
+ imx_add_imx_uart_1irq(2, MX35_UART3_BASE_ADDR, SZ_16K, MX35_INT_UART3, pdata)
+
+#define imx35_add_mxc_nand(pdata) \
+ imx_add_mxc_nand_v21(MX35_NFC_BASE_ADDR, MX35_INT_NANDFC, pdata)
+
+#define imx35_add_spi_imx0(pdata) \
+ imx_add_spi_imx(0, MX35_CSPI1_BASE_ADDR, SZ_4K, MX35_INT_CSPI1, pdata)
+#define imx35_add_spi_imx1(pdata) \
+ imx_add_spi_imx(1, MX35_CSPI2_BASE_ADDR, SZ_4K, MX35_INT_CSPI2, pdata)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index db7acd6e9101..a4fd1a26fc91 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -25,108 +25,10 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/mx3_camera.h>
#include "devices.h"
-static struct resource uart0[] = {
- {
- .start = UART1_BASE_ADDR,
- .end = UART1_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART1,
- .end = MXC_INT_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
- .id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
-};
-
-static struct resource uart1[] = {
- {
- .start = UART2_BASE_ADDR,
- .end = UART2_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART2,
- .end = MXC_INT_UART2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
-};
-
-static struct resource uart2[] = {
- {
- .start = UART3_BASE_ADDR,
- .end = UART3_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART3,
- .end = MXC_INT_UART3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
- .id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
-};
-
-#ifdef CONFIG_ARCH_MX31
-static struct resource uart3[] = {
- {
- .start = UART4_BASE_ADDR,
- .end = UART4_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART4,
- .end = MXC_INT_UART4,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device3 = {
- .name = "imx-uart",
- .id = 3,
- .resource = uart3,
- .num_resources = ARRAY_SIZE(uart3),
-};
-
-static struct resource uart4[] = {
- {
- .start = UART5_BASE_ADDR,
- .end = UART5_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART5,
- .end = MXC_INT_UART5,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device4 = {
- .name = "imx-uart",
- .id = 4,
- .resource = uart4,
- .num_resources = ARRAY_SIZE(uart4),
-};
-#endif /* CONFIG_ARCH_MX31 */
-
/* GPIO port description */
static struct mxc_gpio_port imx_gpio_ports[] = {
{
@@ -147,7 +49,7 @@ static struct mxc_gpio_port imx_gpio_ports[] = {
}
};
-int __init mxc_register_gpios(void)
+int __init imx3x_register_gpios(void)
{
return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
}
@@ -167,82 +69,6 @@ struct platform_device mxc_w1_master_device = {
.resource = mxc_w1_master_resources,
};
-static struct resource mxc_nand_resources[] = {
- {
- .start = 0, /* runtime dependent */
- .end = 0,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_NANDFC,
- .end = MXC_INT_NANDFC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_nand_device = {
- .name = "mxc_nand",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_nand_resources),
- .resource = mxc_nand_resources,
-};
-
-static struct resource mxc_i2c0_resources[] = {
- {
- .start = I2C_BASE_ADDR,
- .end = I2C_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_I2C,
- .end = MXC_INT_I2C,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device0 = {
- .name = "imx-i2c",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_i2c0_resources),
- .resource = mxc_i2c0_resources,
-};
-
-static struct resource mxc_i2c1_resources[] = {
- {
- .start = I2C2_BASE_ADDR,
- .end = I2C2_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_I2C2,
- .end = MXC_INT_I2C2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device1 = {
- .name = "imx-i2c",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_i2c1_resources),
- .resource = mxc_i2c1_resources,
-};
-
-static struct resource mxc_i2c2_resources[] = {
- {
- .start = I2C3_BASE_ADDR,
- .end = I2C3_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_I2C3,
- .end = MXC_INT_I2C3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_i2c_device2 = {
- .name = "imx-i2c",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_i2c2_resources),
- .resource = mxc_i2c2_resources,
-};
-
#ifdef CONFIG_ARCH_MX31
static struct resource mxcsdhc0_resources[] = {
{
@@ -455,68 +281,7 @@ struct platform_device mxc_usbh2 = {
.num_resources = ARRAY_SIZE(mxc_usbh2_resources),
};
-/*
- * SPI master controller
- * 3 channels
- */
-static struct resource mxc_spi_0_resources[] = {
- {
- .start = CSPI1_BASE_ADDR,
- .end = CSPI1_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_CSPI1,
- .end = MXC_INT_CSPI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource mxc_spi_1_resources[] = {
- {
- .start = CSPI2_BASE_ADDR,
- .end = CSPI2_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_CSPI2,
- .end = MXC_INT_CSPI2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct resource mxc_spi_2_resources[] = {
- {
- .start = CSPI3_BASE_ADDR,
- .end = CSPI3_BASE_ADDR + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_CSPI3,
- .end = MXC_INT_CSPI3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_spi_device0 = {
- .name = "spi_imx",
- .id = 0,
- .num_resources = ARRAY_SIZE(mxc_spi_0_resources),
- .resource = mxc_spi_0_resources,
-};
-
-struct platform_device mxc_spi_device1 = {
- .name = "spi_imx",
- .id = 1,
- .num_resources = ARRAY_SIZE(mxc_spi_1_resources),
- .resource = mxc_spi_1_resources,
-};
-
-struct platform_device mxc_spi_device2 = {
- .name = "spi_imx",
- .id = 2,
- .num_resources = ARRAY_SIZE(mxc_spi_2_resources),
- .resource = mxc_spi_2_resources,
-};
-
-#ifdef CONFIG_ARCH_MX35
+#if defined(CONFIG_ARCH_MX35)
static struct resource mxc_fec_resources[] = {
{
.start = MXC_FEC_BASE_ADDR,
@@ -628,16 +393,15 @@ struct platform_device imx_kpp_device = {
static int __init mx3_devices_init(void)
{
+#if defined(CONFIG_ARCH_MX31)
if (cpu_is_mx31()) {
- mxc_nand_resources[0].start = MX31_NFC_BASE_ADDR;
- mxc_nand_resources[0].end = MX31_NFC_BASE_ADDR + 0xfff;
imx_wdt_resources[0].start = MX31_WDOG_BASE_ADDR;
imx_wdt_resources[0].end = MX31_WDOG_BASE_ADDR + 0x3fff;
mxc_register_device(&mxc_rnga_device, NULL);
}
+#endif
+#if defined(CONFIG_ARCH_MX35)
if (cpu_is_mx35()) {
- mxc_nand_resources[0].start = MX35_NFC_BASE_ADDR;
- mxc_nand_resources[0].end = MX35_NFC_BASE_ADDR + 0x1fff;
otg_resources[0].start = MX35_OTG_BASE_ADDR;
otg_resources[0].end = MX35_OTG_BASE_ADDR + 0x1ff;
otg_resources[1].start = MXC_INT_USBOTG;
@@ -653,6 +417,7 @@ static int __init mx3_devices_init(void)
imx_wdt_resources[0].start = MX35_WDOG_BASE_ADDR;
imx_wdt_resources[0].end = MX35_WDOG_BASE_ADDR + 0x3fff;
}
+#endif
return 0;
}
diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h
index 2c3c8646a29e..e5535234839f 100644
--- a/arch/arm/mach-mx3/devices.h
+++ b/arch/arm/mach-mx3/devices.h
@@ -1,14 +1,4 @@
-
-extern struct platform_device mxc_uart_device0;
-extern struct platform_device mxc_uart_device1;
-extern struct platform_device mxc_uart_device2;
-extern struct platform_device mxc_uart_device3;
-extern struct platform_device mxc_uart_device4;
extern struct platform_device mxc_w1_master_device;
-extern struct platform_device mxc_nand_device;
-extern struct platform_device mxc_i2c_device0;
-extern struct platform_device mxc_i2c_device1;
-extern struct platform_device mxc_i2c_device2;
extern struct platform_device mx3_ipu;
extern struct platform_device mx3_fb;
extern struct platform_device mx3_camera;
@@ -20,9 +10,6 @@ extern struct platform_device mxc_otg_host;
extern struct platform_device mxc_usbh1;
extern struct platform_device mxc_usbh2;
extern struct platform_device mxc_rnga_device;
-extern struct platform_device mxc_spi_device0;
-extern struct platform_device mxc_spi_device1;
-extern struct platform_device mxc_spi_device2;
extern struct platform_device imx_ssi_device0;
extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_ssi_device1;
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
new file mode 100644
index 000000000000..368a603accfe
--- /dev/null
+++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <video/platform_lcd.h>
+#include <linux/i2c.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-eukrea_cpuimx35.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx35.h>
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/audmux.h>
+#include <mach/ssi.h>
+
+#include "devices-imx35.h"
+#include "devices.h"
+
+static const struct fb_videomode fb_modedb[] = {
+ {
+ .name = "CMO_QVGA",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6500),
+ .left_margin = 68,
+ .right_margin = 20,
+ .upper_margin = 15,
+ .lower_margin = 4,
+ .hsync_len = 30,
+ .vsync_len = 3,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct ipu_platform_data mx3_ipu_data = {
+ .irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata = {
+ .dma_dev = &mx3_ipu.dev,
+ .name = "CMO_QVGA",
+ .mode = fb_modedb,
+ .num_modes = ARRAY_SIZE(fb_modedb),
+};
+
+static struct pad_desc eukrea_mbimxsd_pads[] = {
+ /* LCD */
+ MX35_PAD_LD0__IPU_DISPB_DAT_0,
+ MX35_PAD_LD1__IPU_DISPB_DAT_1,
+ MX35_PAD_LD2__IPU_DISPB_DAT_2,
+ MX35_PAD_LD3__IPU_DISPB_DAT_3,
+ MX35_PAD_LD4__IPU_DISPB_DAT_4,
+ MX35_PAD_LD5__IPU_DISPB_DAT_5,
+ MX35_PAD_LD6__IPU_DISPB_DAT_6,
+ MX35_PAD_LD7__IPU_DISPB_DAT_7,
+ MX35_PAD_LD8__IPU_DISPB_DAT_8,
+ MX35_PAD_LD9__IPU_DISPB_DAT_9,
+ MX35_PAD_LD10__IPU_DISPB_DAT_10,
+ MX35_PAD_LD11__IPU_DISPB_DAT_11,
+ MX35_PAD_LD12__IPU_DISPB_DAT_12,
+ MX35_PAD_LD13__IPU_DISPB_DAT_13,
+ MX35_PAD_LD14__IPU_DISPB_DAT_14,
+ MX35_PAD_LD15__IPU_DISPB_DAT_15,
+ MX35_PAD_LD16__IPU_DISPB_DAT_16,
+ MX35_PAD_LD17__IPU_DISPB_DAT_17,
+ MX35_PAD_D3_HSYNC__IPU_DISPB_D3_HSYNC,
+ MX35_PAD_D3_FPSHIFT__IPU_DISPB_D3_CLK,
+ MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+ MX35_PAD_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+ /* Backlight */
+ MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+ /* LCD_PWR */
+ MX35_PAD_D3_CLS__GPIO1_4,
+ /* LED */
+ MX35_PAD_LD23__GPIO3_29,
+ /* SWITCH */
+ MX35_PAD_LD19__GPIO3_25,
+ /* UART2 */
+ MX35_PAD_CTS2__UART2_CTS,
+ MX35_PAD_RTS2__UART2_RTS,
+ MX35_PAD_TXD2__UART2_TXD_MUX,
+ MX35_PAD_RXD2__UART2_RXD_MUX,
+ /* I2S */
+ MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+ MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+ MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+ MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+};
+
+#define GPIO_LED1 (2 * 32 + 29)
+#define GPIO_SWITCH1 (2 * 32 + 25)
+#define GPIO_LCDPWR (4)
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+ unsigned int power)
+{
+ if (power)
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ else
+ gpio_direction_output(GPIO_LCDPWR, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+ .set_power = eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+ .name = "platform-lcd",
+ .dev.platform_data = &eukrea_mbimxsd_lcd_power_data,
+};
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+ {
+ .name = "led1",
+ .default_trigger = "heartbeat",
+ .active_low = 1,
+ .gpio = GPIO_LED1,
+ },
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+ .leds = eukrea_mbimxsd_leds,
+ .num_leds = ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_led_info,
+ },
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+ {
+ .gpio = GPIO_SWITCH1,
+ .code = BTN_0,
+ .desc = "BP1",
+ .active_low = 1,
+ .wakeup = 1,
+ },
+};
+
+static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
+ .buttons = eukrea_mbimxsd_gpio_buttons,
+ .nbuttons = ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device eukrea_mbimxsd_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &eukrea_mbimxsd_button_data,
+ }
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+ &eukrea_mbimxsd_leds_gpio,
+ &eukrea_mbimxsd_button_device,
+ &eukrea_mbimxsd_lcd_powerdev,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("tlv320aic23", 0x1a),
+ },
+};
+
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata = {
+ .flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx35 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd_baseboard_init(void)
+{
+ if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+ ARRAY_SIZE(eukrea_mbimxsd_pads)))
+ printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+ /* SSI unit master I2S codec connected to SSI_AUD4 */
+ mxc_audmux_v2_configure_port(0,
+ MXC_AUDMUX_V2_PTCR_SYN |
+ MXC_AUDMUX_V2_PTCR_TFSDIR |
+ MXC_AUDMUX_V2_PTCR_TFSEL(3) |
+ MXC_AUDMUX_V2_PTCR_TCLKDIR |
+ MXC_AUDMUX_V2_PTCR_TCSEL(3),
+ MXC_AUDMUX_V2_PDCR_RXDSEL(3)
+ );
+ mxc_audmux_v2_configure_port(3,
+ MXC_AUDMUX_V2_PTCR_SYN,
+ MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+ );
+#endif
+
+ imx35_add_imx_uart1(&uart_pdata);
+ mxc_register_device(&mx3_ipu, &mx3_ipu_data);
+ mxc_register_device(&mx3_fb, &mx3fb_pdata);
+
+ mxc_register_device(&imx_ssi_device0, &eukrea_mbimxsd_ssi_pdata);
+
+ gpio_request(GPIO_LED1, "LED1");
+ gpio_direction_output(GPIO_LED1, 1);
+ gpio_free(GPIO_LED1);
+
+ gpio_request(GPIO_SWITCH1, "SWITCH1");
+ gpio_direction_input(GPIO_SWITCH1);
+ gpio_free(GPIO_SWITCH1);
+
+ gpio_request(GPIO_LCDPWR, "LCDPWR");
+ gpio_direction_output(GPIO_LCDPWR, 1);
+ gpio_free(GPIO_SWITCH1);
+
+ i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+ ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+}
diff --git a/arch/arm/mach-mx3/mach-armadillo5x0.c b/arch/arm/mach-mx3/mach-armadillo5x0.c
index 5f72ec91af2d..96aadcadb4ff 100644
--- a/arch/arm/mach-mx3/mach-armadillo5x0.c
+++ b/arch/arm/mach-mx3/mach-armadillo5x0.c
@@ -48,16 +48,14 @@
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
-#include <mach/board-armadillo5x0.h>
#include <mach/mmc.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
#include "crm_regs.h"
@@ -301,7 +299,8 @@ static struct platform_device armadillo5x0_button_device = {
/*
* NAND Flash
*/
-static struct mxc_nand_platform_data armadillo5x0_nand_flash_pdata = {
+static const struct mxc_nand_platform_data
+armadillo5x0_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -493,13 +492,12 @@ static struct platform_device armadillo5x0_smc911x_device = {
};
/* UART device data */
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static struct platform_device *devices[] __initdata = {
&armadillo5x0_smc911x_device,
- &mxc_i2c_device1,
&armadillo5x0_button_device,
};
@@ -512,10 +510,11 @@ static void __init armadillo5x0_init(void)
ARRAY_SIZE(armadillo5x0_pins), "armadillo5x0");
platform_add_devices(devices, ARRAY_SIZE(devices));
+ imx31_add_imx_i2c1(NULL);
/* Register UART */
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
/* SMSC9118 IRQ pin */
gpio_direction_input(MX31_PIN_GPIO1_0);
@@ -532,7 +531,7 @@ static void __init armadillo5x0_init(void)
&armadillo5x0_nor_flash_pdata);
/* Register NAND Flash */
- mxc_register_device(&mxc_nand_device, &armadillo5x0_nand_flash_pdata);
+ imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
/* set NAND page size to 2k if not configured via boot mode pins */
__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR);
diff --git a/arch/arm/mach-mx3/mach-cpuimx35.c b/arch/arm/mach-mx3/mach-cpuimx35.c
new file mode 100644
index 000000000000..4f6146d31328
--- /dev/null
+++ b/arch/arm/mach-mx3/mach-cpuimx35.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/fsl_devices.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/board-eukrea_cpuimx35.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/mxc_nand.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx35.h"
+#include "devices.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data
+eukrea_cpuimx35_i2c0_data __initconst = {
+ .bitrate = 50000,
+};
+
+#define TSC2007_IRQGPIO (2 * 32 + 2)
+static int ts_get_pendown_state(void)
+{
+ int val = 0;
+ gpio_free(TSC2007_IRQGPIO);
+ gpio_request(TSC2007_IRQGPIO, NULL);
+ gpio_direction_input(TSC2007_IRQGPIO);
+
+ val = gpio_get_value(TSC2007_IRQGPIO);
+
+ gpio_free(TSC2007_IRQGPIO);
+ gpio_request(TSC2007_IRQGPIO, NULL);
+
+ return val ? 0 : 1;
+}
+
+static int ts_init(void)
+{
+ gpio_request(TSC2007_IRQGPIO, NULL);
+ return 0;
+}
+
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+ .get_pendown_state = ts_get_pendown_state,
+ .init_platform_hw = ts_init,
+};
+
+static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ }, {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = gpio_to_irq(TSC2007_IRQGPIO),
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &mxc_fec_device,
+ &imx_wdt_device0,
+};
+
+static struct pad_desc eukrea_cpuimx35_pads[] = {
+ /* UART1 */
+ MX35_PAD_CTS1__UART1_CTS,
+ MX35_PAD_RTS1__UART1_RTS,
+ MX35_PAD_TXD1__UART1_TXD_MUX,
+ MX35_PAD_RXD1__UART1_RXD_MUX,
+ /* FEC */
+ MX35_PAD_FEC_TX_CLK__FEC_TX_CLK,
+ MX35_PAD_FEC_RX_CLK__FEC_RX_CLK,
+ MX35_PAD_FEC_RX_DV__FEC_RX_DV,
+ MX35_PAD_FEC_COL__FEC_COL,
+ MX35_PAD_FEC_RDATA0__FEC_RDATA_0,
+ MX35_PAD_FEC_TDATA0__FEC_TDATA_0,
+ MX35_PAD_FEC_TX_EN__FEC_TX_EN,
+ MX35_PAD_FEC_MDC__FEC_MDC,
+ MX35_PAD_FEC_MDIO__FEC_MDIO,
+ MX35_PAD_FEC_TX_ERR__FEC_TX_ERR,
+ MX35_PAD_FEC_RX_ERR__FEC_RX_ERR,
+ MX35_PAD_FEC_CRS__FEC_CRS,
+ MX35_PAD_FEC_RDATA1__FEC_RDATA_1,
+ MX35_PAD_FEC_TDATA1__FEC_TDATA_1,
+ MX35_PAD_FEC_RDATA2__FEC_RDATA_2,
+ MX35_PAD_FEC_TDATA2__FEC_TDATA_2,
+ MX35_PAD_FEC_RDATA3__FEC_RDATA_3,
+ MX35_PAD_FEC_TDATA3__FEC_TDATA_3,
+ /* I2C1 */
+ MX35_PAD_I2C1_CLK__I2C1_SCL,
+ MX35_PAD_I2C1_DAT__I2C1_SDA,
+ /* TSC2007 IRQ */
+ MX35_PAD_ATA_DA2__GPIO3_2,
+};
+
+static const struct mxc_nand_platform_data
+eukrea_cpuimx35_nand_board_info __initconst = {
+ .width = 1,
+ .hw_ecc = 1,
+ .flash_bbt = 1,
+};
+
+static struct mxc_usbh_platform_data otg_pdata = {
+ .portsc = MXC_EHCI_MODE_UTMI,
+ .flags = MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh1_pdata = {
+ .portsc = MXC_EHCI_MODE_SERIAL,
+ .flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
+ MXC_EHCI_IPPUE_DOWN,
+};
+
+static struct fsl_usb2_platform_data otg_device_pdata = {
+ .operating_mode = FSL_USB2_DR_DEVICE,
+ .phy_mode = FSL_USB2_PHY_UTMI,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx35_otg_mode(char *options)
+{
+ if (!strcmp(options, "host"))
+ otg_mode_host = 1;
+ else if (!strcmp(options, "device"))
+ otg_mode_host = 0;
+ else
+ pr_info("otg_mode neither \"host\" nor \"device\". "
+ "Defaulting to device\n");
+ return 0;
+}
+__setup("otg_mode=", eukrea_cpuimx35_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
+ ARRAY_SIZE(eukrea_cpuimx35_pads));
+
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ imx35_add_imx_uart0(&uart_pdata);
+ imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
+
+ i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices,
+ ARRAY_SIZE(eukrea_cpuimx35_i2c_devices));
+ imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
+
+#if defined(CONFIG_USB_ULPI)
+ if (otg_mode_host) {
+ otg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+ USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+ mxc_register_device(&mxc_otg_host, &otg_pdata);
+ }
+ mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+#endif
+ if (!otg_mode_host)
+ mxc_register_device(&mxc_otg_udc_device, &otg_device_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD_BASEBOARD
+ eukrea_mbimxsd_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx35_timer_init(void)
+{
+ mx35_clocks_init();
+}
+
+struct sys_timer eukrea_cpuimx35_timer = {
+ .init = eukrea_cpuimx35_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
+ /* Maintainer: Eukrea Electromatique */
+ .phys_io = MX35_AIPS1_BASE_ADDR,
+ .io_pg_offst = ((MX35_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = MX3x_PHYS_OFFSET + 0x100,
+ .map_io = mx35_map_io,
+ .init_irq = mx35_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &eukrea_cpuimx35_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mach-kzm_arm11_01.c b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
index f085d5d1a6de..5b23e416d6c7 100644
--- a/arch/arm/mach-mx3/mach-kzm_arm11_01.c
+++ b/arch/arm/mach-mx3/mach-kzm_arm11_01.c
@@ -16,10 +16,6 @@
* 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/gpio.h>
@@ -37,13 +33,12 @@
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <mach/board-kzmarm11.h>
#include <mach/clock.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/memory.h>
+#include "devices-imx31.h"
#include "devices.h"
#define KZM_ARM11_IO_ADDRESS(x) ( \
@@ -51,6 +46,23 @@
IMX_IO_ADDRESS(x, MX31_CS5) ?: \
MX31_IO_ADDRESS(x))
+/*
+ * KZM-ARM11-01 Board Control Registers on FPGA
+ */
+#define KZM_ARM11_CTL1 (MX31_CS4_BASE_ADDR + 0x1000)
+#define KZM_ARM11_CTL2 (MX31_CS4_BASE_ADDR + 0x1001)
+#define KZM_ARM11_RSW1 (MX31_CS4_BASE_ADDR + 0x1002)
+#define KZM_ARM11_BACK_LIGHT (MX31_CS4_BASE_ADDR + 0x1004)
+#define KZM_ARM11_FPGA_REV (MX31_CS4_BASE_ADDR + 0x1008)
+#define KZM_ARM11_7SEG_LED (MX31_CS4_BASE_ADDR + 0x1010)
+#define KZM_ARM11_LEDS (MX31_CS4_BASE_ADDR + 0x1020)
+#define KZM_ARM11_DIPSW2 (MX31_CS4_BASE_ADDR + 0x1003)
+
+/*
+ * External UART for touch panel on FPGA
+ */
+#define KZM_ARM11_16550 (MX31_CS4_BASE_ADDR + 0x1050)
+
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
/*
* KZM-ARM11-01 has an external UART on FPGA
@@ -173,15 +185,14 @@ static inline int kzm_init_smsc9118(void)
#endif
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
static void __init kzm_init_imx_uart(void)
{
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
}
#else
static inline void kzm_init_imx_uart(void)
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index 58e57291b79d..6fe69e124d30 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -10,10 +10,6 @@
* 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/delay.h>
@@ -22,7 +18,6 @@
#include <linux/clk.h>
#include <linux/irq.h>
#include <linux/gpio.h>
-#include <linux/smsc911x.h>
#include <linux/platform_device.h>
#include <linux/mfd/mc13783.h>
#include <linux/spi/spi.h>
@@ -37,19 +32,47 @@
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/board-mx31_3ds.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
-#include <mach/mxc_nand.h>
-#include <mach/spi.h>
+#include <mach/3ds_debugboard.h>
+
+#include "devices-imx31.h"
#include "devices.h"
-/*!
- * @file mx31_3ds.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
+/* Definitions for components on the Debug board */
+
+/* Base address of CPLD controller on the Debug board */
+#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(MX3x_CS5_BASE_ADDR)
+
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR MX3x_CS5_BASE_ADDR
+
+/* CPLD config and interrupt base address */
+#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
+
+/* status, interrupt */
+#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10)
+#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38)
+#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40)
+#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48)
+/* CPLD code version */
+#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50)
+/* magic word for debug CPLD */
+#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58)
+
+/* CPLD IRQ line for external uart, external ethernet etc */
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
+
+#define MXC_MAX_EXP_IO_LINES 16
+
+/*
+ * This file contains the board-specific initialization routines.
*/
static int mx31_3ds_pins[] = {
@@ -145,7 +168,7 @@ static int spi1_internal_chipselect[] = {
MXC_SPI_CS(2),
};
-static struct spi_imx_master spi1_pdata = {
+static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi1_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
};
@@ -165,7 +188,8 @@ static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
/*
* NAND Flash
*/
-static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
+static const struct mxc_nand_platform_data
+mx31_3ds_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
@@ -182,8 +206,10 @@ static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
-static void mx31_3ds_usbotg_init(void)
+static int mx31_3ds_usbotg_init(void)
{
+ int err;
+
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
@@ -197,10 +223,25 @@ static void mx31_3ds_usbotg_init(void)
mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
- gpio_request(USBOTG_RST_B, "otgusb-reset");
- gpio_direction_output(USBOTG_RST_B, 0);
+ err = gpio_request(USBOTG_RST_B, "otgusb-reset");
+ if (err) {
+ pr_err("Failed to request the USB OTG reset gpio\n");
+ return err;
+ }
+
+ err = gpio_direction_output(USBOTG_RST_B, 0);
+ if (err) {
+ pr_err("Failed to drive the USB OTG reset gpio\n");
+ goto usbotg_free_reset;
+ }
+
mdelay(1);
gpio_set_value(USBOTG_RST_B, 1);
+ return 0;
+
+usbotg_free_reset:
+ gpio_free(USBOTG_RST_B);
+ return err;
}
static struct fsl_usb2_platform_data usbotg_pdata = {
@@ -208,178 +249,16 @@ static struct fsl_usb2_platform_data usbotg_pdata = {
.phy_mode = FSL_USB2_PHY_ULPI,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
/*
- * Support for the SMSC9217 on the Debug board.
- */
-
-static struct smsc911x_platform_config smsc911x_config = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
- .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
- .flags = SMSC911X_USE_16BIT | SMSC911X_FORCE_INTERNAL_PHY,
- .phy_interface = PHY_INTERFACE_MODE_MII,
-};
-
-static struct resource smsc911x_resources[] = {
- {
- .start = LAN9217_BASE_ADDR,
- .end = LAN9217_BASE_ADDR + 0xff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = EXPIO_INT_ENET,
- .end = EXPIO_INT_ENET,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device smsc911x_device = {
- .name = "smsc911x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smsc911x_resources),
- .resource = smsc911x_resources,
- .dev = {
- .platform_data = &smsc911x_config,
- },
-};
-
-/*
- * Routines for the CPLD on the debug board. It contains a CPLD handling
- * LEDs, switches, interrupts for Ethernet.
- */
-
-static void mx31_3ds_expio_irq_handler(uint32_t irq, struct irq_desc *desc)
-{
- uint32_t imr_val;
- uint32_t int_valid;
- uint32_t expio_irq;
-
- imr_val = __raw_readw(CPLD_INT_MASK_REG);
- int_valid = __raw_readw(CPLD_INT_STATUS_REG) & ~imr_val;
-
- expio_irq = MXC_EXP_IO_BASE;
- for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
- if ((int_valid & 1) == 0)
- continue;
- generic_handle_irq(expio_irq);
- }
-}
-
-/*
- * Disable an expio pin's interrupt by setting the bit in the imr.
- * @param irq an expio virtual irq number
- */
-static void expio_mask_irq(uint32_t irq)
-{
- uint16_t reg;
- uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
- /* mask the interrupt */
- reg = __raw_readw(CPLD_INT_MASK_REG);
- reg |= 1 << expio;
- __raw_writew(reg, CPLD_INT_MASK_REG);
-}
-
-/*
- * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
- * @param irq an expanded io virtual irq number
- */
-static void expio_ack_irq(uint32_t irq)
-{
- uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
- /* clear the interrupt status */
- __raw_writew(1 << expio, CPLD_INT_RESET_REG);
- __raw_writew(0, CPLD_INT_RESET_REG);
- /* mask the interrupt */
- expio_mask_irq(irq);
-}
-
-/*
- * Enable a expio pin's interrupt by clearing the bit in the imr.
- * @param irq a expio virtual irq number
- */
-static void expio_unmask_irq(uint32_t irq)
-{
- uint16_t reg;
- uint32_t expio = MXC_IRQ_TO_EXPIO(irq);
-
- /* unmask the interrupt */
- reg = __raw_readw(CPLD_INT_MASK_REG);
- reg &= ~(1 << expio);
- __raw_writew(reg, CPLD_INT_MASK_REG);
-}
-
-static struct irq_chip expio_irq_chip = {
- .ack = expio_ack_irq,
- .mask = expio_mask_irq,
- .unmask = expio_unmask_irq,
-};
-
-static int __init mx31_3ds_init_expio(void)
-{
- int i;
- int ret;
-
- /* Check if there's a debug board connected */
- if ((__raw_readw(CPLD_MAGIC_NUMBER1_REG) != 0xAAAA) ||
- (__raw_readw(CPLD_MAGIC_NUMBER2_REG) != 0x5555) ||
- (__raw_readw(CPLD_MAGIC_NUMBER3_REG) != 0xCAFE)) {
- /* No Debug board found */
- return -ENODEV;
- }
-
- pr_info("i.MX31 3DS Debug board detected, rev = 0x%04X\n",
- __raw_readw(CPLD_CODE_VER_REG));
-
- /*
- * Configure INT line as GPIO input
- */
- ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1), "sms9217-irq");
- if (ret)
- pr_warning("could not get LAN irq gpio\n");
- else
- gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_1));
-
- /* Disable the interrupts and clear the status */
- __raw_writew(0, CPLD_INT_MASK_REG);
- __raw_writew(0xFFFF, CPLD_INT_RESET_REG);
- __raw_writew(0, CPLD_INT_RESET_REG);
- __raw_writew(0x1F, CPLD_INT_MASK_REG);
- for (i = MXC_EXP_IO_BASE;
- i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
- i++) {
- set_irq_chip(i, &expio_irq_chip);
- set_irq_handler(i, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
- }
- set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(EXPIO_PARENT_INT, mx31_3ds_expio_irq_handler);
-
- return 0;
-}
-
-/*
- * This structure defines the MX31 memory map.
- */
-static struct map_desc mx31_3ds_io_desc[] __initdata = {
- {
- .virtual = MX31_CS5_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(MX31_CS5_BASE_ADDR),
- .length = MX31_CS5_SIZE,
- .type = MT_DEVICE,
- },
-};
-
-/*
* Set up static virtual mappings.
*/
static void __init mx31_3ds_map_io(void)
{
mx31_map_io();
- iotable_init(mx31_3ds_io_desc, ARRAY_SIZE(mx31_3ds_io_desc));
}
/*!
@@ -390,10 +269,10 @@ static void __init mxc_board_init(void)
mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
"mx31_3ds");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_nand_device, &imx31_3ds_nand_flash_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
- mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+ imx31_add_spi_imx0(&spi1_pdata);
spi_register_board_info(mx31_3ds_spi_devs,
ARRAY_SIZE(mx31_3ds_spi_devs));
@@ -402,8 +281,9 @@ static void __init mxc_board_init(void)
mx31_3ds_usbotg_init();
mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
- if (!mx31_3ds_init_expio())
- platform_device_register(&smsc911x_device);
+ if (!mxc_expio_init(CS5_BASE_ADDR, EXPIO_PARENT_INT))
+ printk(KERN_WARNING "Init of the debugboard failed, all "
+ "devices on the board are unusable.\n");
}
static void __init mx31_3ds_timer_init(void)
diff --git a/arch/arm/mach-mx3/mach-mx31ads.c b/arch/arm/mach-mx3/mach-mx31ads.c
index b3d1a1895c20..94b3e7c42404 100644
--- a/arch/arm/mach-mx3/mach-mx31ads.c
+++ b/arch/arm/mach-mx3/mach-mx31ads.c
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -33,8 +29,6 @@
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/board-mx31ads.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -43,14 +37,45 @@
#include <linux/mfd/wm8350/pmic.h>
#endif
+#include "devices-imx31.h"
#include "devices.h"
-/*!
- * @file mx31ads.c
- *
- * @brief This file contains the board-specific initialization routines.
- *
- * @ingroup System
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+/* Offsets for the PBC Controller register */
+
+/* PBC Board interrupt status register */
+#define PBC_INTSTATUS 0x000016
+
+/* PBC Board interrupt current status register */
+#define PBC_INTCURR_STATUS 0x000018
+
+/* PBC Interrupt mask register set address */
+#define PBC_INTMASK_SET 0x00001A
+
+/* PBC Interrupt mask register clear address */
+#define PBC_INTMASK_CLEAR 0x00001C
+
+/* External UART A */
+#define PBC_SC16C652_UARTA 0x010000
+
+/* External UART B */
+#define PBC_SC16C652_UARTB 0x010010
+
+#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11)
+
+#define MXC_MAX_EXP_IO_LINES 16
+/*
+ * This file contains the board-specific initialization routines.
*/
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
@@ -98,7 +123,7 @@ static inline int mxc_init_extuart(void)
#endif
#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -112,7 +137,7 @@ static unsigned int uart_pins[] = {
static inline void mxc_init_imx_uart(void)
{
mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), "uart-0");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
}
#else /* !SERIAL_IMX */
static inline void mxc_init_imx_uart(void)
@@ -475,7 +500,7 @@ static void mxc_init_i2c(void)
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1));
mxc_iomux_mode(IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1));
- mxc_register_device(&mxc_i2c_device1, NULL);
+ imx31_add_imx_i2c1(NULL);
}
#else
static void mxc_init_i2c(void)
diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c
index b2c7f512070f..8f66f65e80e2 100644
--- a/arch/arm/mach-mx3/mach-mx31lilly.c
+++ b/arch/arm/mach-mx3/mach-mx31lilly.c
@@ -18,10 +18,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -46,10 +42,10 @@
#include <mach/common.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lilly.h>
-#include <mach/spi.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
/*
@@ -269,12 +265,12 @@ static int spi_internal_chipselect[] = {
MXC_SPI_CS(2),
};
-static struct spi_imx_master spi0_pdata = {
+static const struct spi_imx_master spi0_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
};
-static struct spi_imx_master spi1_pdata = {
+static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
};
@@ -289,6 +285,7 @@ static struct spi_board_info mc13783_dev __initdata = {
.bus_num = 1,
.chip_select = 0,
.platform_data = &mc13783_pdata,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
};
static struct platform_device *devices[] __initdata = {
@@ -331,8 +328,8 @@ static void __init mx31lilly_board_init(void)
mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS1__SS1, "SPI2_SS1");
mxc_iomux_alloc_pin(MX31_PIN_CSPI2_SS2__SS2, "SPI2_SS2");
- mxc_register_device(&mxc_spi_device0, &spi0_pdata);
- mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+ imx31_add_spi_imx0(&spi0_pdata);
+ imx31_add_spi_imx1(&spi1_pdata);
spi_register_board_info(&mc13783_dev, 1);
platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-mx3/mach-mx31lite.c b/arch/arm/mach-mx3/mach-mx31lite.c
index 2b6d11400877..da236c497d2a 100644
--- a/arch/arm/mach-mx3/mach-mx31lite.c
+++ b/arch/arm/mach-mx3/mach-mx31lite.c
@@ -13,10 +13,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -42,14 +38,12 @@
#include <mach/hardware.h>
#include <mach/common.h>
#include <mach/board-mx31lite.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/irqs.h>
-#include <mach/mxc_nand.h>
-#include <mach/spi.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
/*
@@ -69,7 +63,8 @@ static unsigned int mx31lite_pins[] = {
MX31_PIN_CSPI2_SS2__SS2,
};
-static struct mxc_nand_platform_data mx31lite_nand_board_info = {
+static const struct mxc_nand_platform_data
+mx31lite_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
@@ -112,7 +107,7 @@ static int spi_internal_chipselect[] = {
MXC_SPI_CS(0),
};
-static struct spi_imx_master spi1_pdata = {
+static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
};
@@ -253,9 +248,9 @@ static void __init mxc_board_init(void)
/* NOR and NAND flash */
platform_device_register(&physmap_flash_device);
- mxc_register_device(&mxc_nand_device, &mx31lite_nand_board_info);
+ imx31_add_mxc_nand(&mx31lite_nand_board_info);
- mxc_register_device(&mxc_spi_device1, &spi1_pdata);
+ imx31_add_spi_imx1(&spi1_pdata);
spi_register_board_info(&mc13783_spi_dev, 1);
#if defined(CONFIG_USB_ULPI)
diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c
index 62b5e40165df..67776bc61c33 100644
--- a/arch/arm/mach-mx3/mach-mx31moboard.c
+++ b/arch/arm/mach-mx3/mach-mx31moboard.c
@@ -10,10 +10,6 @@
* 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/delay.h>
@@ -42,16 +38,15 @@
#include <mach/board-mx31moboard.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/ipu.h>
-#include <mach/i2c.h>
#include <mach/mmc.h>
#include <mach/mxc_ehci.h>
#include <mach/mx3_camera.h>
#include <mach/spi.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
static unsigned int moboard_pins[] = {
@@ -130,24 +125,36 @@ static struct platform_device mx31moboard_flash = {
static int moboard_uart0_init(struct platform_device *pdev)
{
- gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
- gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
- return 0;
+ int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
+ if (ret)
+ return ret;
+
+ ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+ if (ret)
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+
+ return ret;
+}
+
+static void moboard_uart0_exit(struct platform_device *pdev)
+{
+ gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
}
-static struct imxuart_platform_data uart0_pdata = {
+static const struct imxuart_platform_data uart0_pdata __initconst = {
.init = moboard_uart0_init,
+ .exit = moboard_uart0_exit,
};
-static struct imxuart_platform_data uart4_pdata = {
+static const struct imxuart_platform_data uart4_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
-static struct imxi2c_platform_data moboard_i2c0_pdata = {
+static const struct imxi2c_platform_data moboard_i2c0_data __initconst = {
.bitrate = 400000,
};
-static struct imxi2c_platform_data moboard_i2c1_pdata = {
+static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
.bitrate = 100000,
};
@@ -156,7 +163,7 @@ static int moboard_spi1_cs[] = {
MXC_SPI_CS(2),
};
-static struct spi_imx_master moboard_spi1_master = {
+static const struct spi_imx_master moboard_spi1_pdata __initconst = {
.chipselect = moboard_spi1_cs,
.num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
};
@@ -286,7 +293,7 @@ static int moboard_spi2_cs[] = {
MXC_SPI_CS(1),
};
-static struct spi_imx_master moboard_spi2_master = {
+static const struct spi_imx_master moboard_spi2_pdata __initconst = {
.chipselect = moboard_spi2_cs,
.num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
};
@@ -499,15 +506,14 @@ static void __init mxc_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_uart_device0, &uart0_pdata);
-
- mxc_register_device(&mxc_uart_device4, &uart4_pdata);
+ imx31_add_imx_uart0(&uart0_pdata);
+ imx31_add_imx_uart4(&uart4_pdata);
- mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
- mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
+ imx31_add_imx_i2c0(&moboard_i2c0_data);
+ imx31_add_imx_i2c1(&moboard_i2c1_data);
- mxc_register_device(&mxc_spi_device1, &moboard_spi1_master);
- mxc_register_device(&mxc_spi_device2, &moboard_spi2_master);
+ imx31_add_spi_imx1(&moboard_spi1_pdata);
+ imx31_add_spi_imx2(&moboard_spi2_pdata);
gpio_request(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3), "pmic-irq");
gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_GPIO1_3));
diff --git a/arch/arm/mach-mx3/mach-mx35pdk.c b/arch/arm/mach-mx3/mach-mx35_3ds.c
index bcac84d4dca4..1c30d7212f17 100644
--- a/arch/arm/mach-mx3/mach-mx35pdk.c
+++ b/arch/arm/mach-mx3/mach-mx35_3ds.c
@@ -12,10 +12,12 @@
* 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
+ */
+
+/*
+ * This machine is known as:
+ * - i.MX35 3-Stack Development System
+ * - i.MX35 Platform Development Kit (i.MX35 PDK)
*/
#include <linux/types.h>
@@ -32,12 +34,12 @@
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx35.h>
+#include "devices-imx35.h"
#include "devices.h"
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -90,7 +92,7 @@ static void __init mxc_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx35_add_imx_uart0(&uart_pdata);
mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
}
diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c
index cce410662383..8a292dd1a714 100644
--- a/arch/arm/mach-mx3/mach-pcm037.c
+++ b/arch/arm/mach-mx3/mach-pcm037.c
@@ -10,10 +10,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -43,20 +39,17 @@
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
#include <asm/mach/map.h>
-#include <mach/board-pcm037.h>
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/i2c.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/ipu.h>
#include <mach/mmc.h>
#include <mach/mx3_camera.h>
#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
#include "pcm037.h"
@@ -225,7 +218,7 @@ static struct platform_device pcm037_flash = {
.num_resources = 1,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -279,16 +272,17 @@ static struct platform_device pcm037_sram_device = {
.resource = &pcm038_sram_resource,
};
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
+static const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
-static struct imxi2c_platform_data pcm037_i2c_1_data = {
+static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = {
.bitrate = 100000,
};
-static struct imxi2c_platform_data pcm037_i2c_2_data = {
+static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
.bitrate = 20000,
};
@@ -545,6 +539,7 @@ static struct platform_device pcm970_sja1000 = {
.num_resources = ARRAY_SIZE(pcm970_sja1000_resources),
};
+#if defined(CONFIG_USB_ULPI)
static struct mxc_usbh_platform_data otg_pdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
@@ -554,6 +549,7 @@ static struct mxc_usbh_platform_data usbh2_pdata = {
.portsc = MXC_EHCI_MODE_ULPI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
};
+#endif
static struct fsl_usb2_platform_data otg_device_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
@@ -581,7 +577,6 @@ __setup("otg_mode=", pcm037_otg_mode);
static void __init mxc_board_init(void)
{
int ret;
- u32 tmp;
mxc_iomux_set_gpr(MUX_PGP_UH2, 1);
@@ -614,9 +609,10 @@ static void __init mxc_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
+ /* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */
+ imx31_add_imx_uart1(&uart_pdata);
+ imx31_add_imx_uart2(&uart_pdata);
mxc_register_device(&mxc_w1_master_device, NULL);
@@ -634,10 +630,10 @@ static void __init mxc_board_init(void)
i2c_register_board_info(1, pcm037_i2c_devices,
ARRAY_SIZE(pcm037_i2c_devices));
- mxc_register_device(&mxc_i2c_device1, &pcm037_i2c_1_data);
- mxc_register_device(&mxc_i2c_device2, &pcm037_i2c_2_data);
+ imx31_add_imx_i2c1(&pcm037_i2c1_data);
+ imx31_add_imx_i2c2(&pcm037_i2c2_data);
- mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+ imx31_add_mxc_nand(&pcm037_nand_board_info);
mxc_register_device(&mxcsdhc_device0, &sdhc_pdata);
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
mxc_register_device(&mx3_fb, &mx3fb_pdata);
diff --git a/arch/arm/mach-mx3/mach-pcm037_eet.c b/arch/arm/mach-mx3/mach-pcm037_eet.c
index 8d386000fc40..c8b98218efee 100644
--- a/arch/arm/mach-mx3/mach-pcm037_eet.c
+++ b/arch/arm/mach-mx3/mach-pcm037_eet.c
@@ -13,9 +13,6 @@
#include <linux/spi/spi.h>
#include <mach/common.h>
-#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
-#include <mach/spi.h>
-#endif
#include <mach/iomux-mx3.h>
#include <asm/mach-types.h>
@@ -64,7 +61,7 @@ static struct spi_board_info pcm037_spi_dev[] = {
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
-struct spi_imx_master pcm037_spi1_master = {
+static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
.chipselect = pcm037_spi1_cs,
.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
};
@@ -184,7 +181,7 @@ static int eet_init_devices(void)
/* SPI */
spi_register_board_info(pcm037_spi_dev, ARRAY_SIZE(pcm037_spi_dev));
#if defined(CONFIG_SPI_IMX) || defined(CONFIG_SPI_IMX_MODULE)
- mxc_register_device(&mxc_spi_device0, &pcm037_spi1_master);
+ imx35_add_spi_imx0(&pcm037_spi1_pdata);
#endif
platform_device_register(&pcm037_gpio_keys_device);
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index 78d9185a9d4b..b92f624c755e 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -10,10 +10,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -40,19 +36,15 @@
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
-#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-#include <mach/i2c.h>
-#endif
#include <mach/iomux-mx35.h>
#include <mach/ipu.h>
#include <mach/mx3fb.h>
-#include <mach/mxc_nand.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
#include <mach/ssi.h>
+#include "devices-imx35.h"
#include "devices.h"
static const struct fb_videomode fb_modedb[] = {
@@ -122,12 +114,12 @@ static struct platform_device pcm043_flash = {
.num_resources = 1,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
-static struct imxi2c_platform_data pcm043_i2c_1_data = {
+static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
.bitrate = 50000,
};
@@ -304,11 +296,13 @@ static struct imx_ssi_platform_data pcm043_ssi_pdata = {
.flags = IMX_SSI_USE_AC97,
};
-static struct mxc_nand_platform_data pcm037_nand_board_info = {
+static const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
.width = 1,
.hw_ecc = 1,
};
+#if defined(CONFIG_USB_ULPI)
static struct mxc_usbh_platform_data otg_pdata = {
.portsc = MXC_EHCI_MODE_UTMI,
.flags = MXC_EHCI_INTERFACE_DIFF_UNI,
@@ -319,6 +313,7 @@ static struct mxc_usbh_platform_data usbh1_pdata = {
.flags = MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY |
MXC_EHCI_IPPUE_DOWN,
};
+#endif
static struct fsl_usb2_platform_data otg_device_pdata = {
.operating_mode = FSL_USB2_DR_DEVICE,
@@ -361,17 +356,17 @@ static void __init mxc_board_init(void)
platform_add_devices(devices, ARRAY_SIZE(devices));
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_nand_device, &pcm037_nand_board_info);
+ imx35_add_imx_uart0(&uart_pdata);
+ imx35_add_mxc_nand(&pcm037_nand_board_info);
mxc_register_device(&imx_ssi_device0, &pcm043_ssi_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ imx35_add_imx_uart1(&uart_pdata);
#if defined CONFIG_I2C_IMX || defined CONFIG_I2C_IMX_MODULE
i2c_register_board_info(0, pcm043_i2c_devices,
ARRAY_SIZE(pcm043_i2c_devices));
- mxc_register_device(&mxc_i2c_device0, &pcm043_i2c_1_data);
+ imx35_add_imx_i2c0(&pcm043_i2c0_data);
#endif
mxc_register_device(&mx3_ipu, &mx3_ipu_data);
diff --git a/arch/arm/mach-mx3/mach-qong.c b/arch/arm/mach-mx3/mach-qong.c
index e5b5b8323a17..d44ac70222a5 100644
--- a/arch/arm/mach-mx3/mach-qong.c
+++ b/arch/arm/mach-mx3/mach-qong.c
@@ -10,10 +10,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/types.h>
@@ -34,9 +30,9 @@
#include <mach/common.h>
#include <asm/page.h>
#include <asm/setup.h>
-#include <mach/board-qong.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
+
+#include "devices-imx31.h"
#include "devices.h"
/* FPGA defines */
@@ -62,7 +58,7 @@
* This file contains the board-specific initialization routines.
*/
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -73,11 +69,11 @@ static int uart_pins[] = {
MX31_PIN_RXD1__RXD1
};
-static inline void mxc_init_imx_uart(void)
+static inline void __init mxc_init_imx_uart(void)
{
mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
"uart-0");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
}
static struct resource dnet_resources[] = {
@@ -116,7 +112,7 @@ static struct physmap_flash_data qong_flash_data = {
static struct resource qong_flash_resource = {
.start = MX31_CS0_BASE_ADDR,
- .end = MX31_CS0_BASE_ADDR + QONG_NOR_SIZE - 1,
+ .end = MX31_CS0_BASE_ADDR + SZ_128M - 1,
.flags = IORESOURCE_MEM,
};
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 6858a4f9806c..a378fba49a8b 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -14,10 +14,6 @@
* 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/mm.h>
@@ -97,8 +93,11 @@ void __init mx35_map_io(void)
}
#endif
+int imx3x_register_gpios(void);
+
void __init mx31_init_irq(void)
{
+ imx3x_register_gpios();
mxc_init_irq(IO_ADDRESS(AVIC_BASE_ADDR));
}
diff --git a/arch/arm/mach-mx3/mx31lilly-db.c b/arch/arm/mach-mx3/mx31lilly-db.c
index 7aebd74a12e8..827fd3c80201 100644
--- a/arch/arm/mach-mx3/mx31lilly-db.c
+++ b/arch/arm/mach-mx3/mx31lilly-db.c
@@ -18,10 +18,6 @@
* 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>
@@ -36,13 +32,13 @@
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lilly.h>
#include <mach/mmc.h>
#include <mach/mx3fb.h>
#include <mach/ipu.h>
+#include "devices-imx31.h"
#include "devices.h"
/*
@@ -96,7 +92,7 @@ static unsigned int lilly_db_board_pins[] __initdata = {
};
/* UART */
-static struct imxuart_platform_data uart_pdata __initdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -217,9 +213,9 @@ void __init mx31lilly_db_init(void)
mxc_iomux_setup_multiple_pins(lilly_db_board_pins,
ARRAY_SIZE(lilly_db_board_pins),
"development board pins");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
- mxc_register_device(&mxc_uart_device2, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
+ imx31_add_imx_uart2(&uart_pdata);
mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
mx31lilly_init_fb();
}
diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c
index 5f05bfbec380..7b0e74e275ba 100644
--- a/arch/arm/mach-mx3/mx31lite-db.c
+++ b/arch/arm/mach-mx3/mx31lite-db.c
@@ -18,10 +18,6 @@
* 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>
@@ -37,12 +33,11 @@
#include <mach/hardware.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31lite.h>
#include <mach/mmc.h>
-#include <mach/spi.h>
+#include "devices-imx31.h"
#include "devices.h"
/*
@@ -76,7 +71,7 @@ static unsigned int litekit_db_board_pins[] __initdata = {
};
/* UART */
-static struct imxuart_platform_data uart_pdata __initdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -161,7 +156,7 @@ static int spi_internal_chipselect[] = {
MXC_SPI_CS(2),
};
-static struct spi_imx_master spi0_pdata = {
+static const struct spi_imx_master spi0_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
};
@@ -201,9 +196,9 @@ void __init mx31lite_db_init(void)
mxc_iomux_setup_multiple_pins(litekit_db_board_pins,
ARRAY_SIZE(litekit_db_board_pins),
"development board pins");
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+ imx31_add_imx_uart0(&uart_pdata);
mxc_register_device(&mxcsdhc_device0, &mmc_pdata);
- mxc_register_device(&mxc_spi_device0, &spi0_pdata);
+ imx31_add_spi_imx0(&spi0_pdata);
platform_device_register(&litekit_led_device);
mxc_register_device(&imx_wdt_device0, NULL);
mxc_register_device(&imx_rtc_device0, NULL);
diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c
index 582299cb2c08..fc395a7a8599 100644
--- a/arch/arm/mach-mx3/mx31moboard-devboard.c
+++ b/arch/arm/mach-mx3/mx31moboard-devboard.c
@@ -10,10 +10,6 @@
* 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/gpio.h>
@@ -27,13 +23,13 @@
#include <linux/usb/otg.h>
#include <mach/common.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/hardware.h>
#include <mach/mmc.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
+#include "devices-imx31.h"
#include "devices.h"
static unsigned int devboard_pins[] = {
@@ -56,7 +52,7 @@ static unsigned int devboard_pins[] = {
MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -230,7 +226,7 @@ void __init mx31moboard_devboard_init(void)
mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins),
"devboard");
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
+ imx31_add_imx_uart1(&uart_pdata);
mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata);
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c
index 4930f8c27e66..0551eb39d97e 100644
--- a/arch/arm/mach-mx3/mx31moboard-marxbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c
@@ -10,10 +10,6 @@
* 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/delay.h>
diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c
index 293eea6d9d97..40c3e7564cb6 100644
--- a/arch/arm/mach-mx3/mx31moboard-smartbot.c
+++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c
@@ -10,10 +10,6 @@
* 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/delay.h>
@@ -30,7 +26,6 @@
#include <mach/common.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
#include <mach/iomux-mx3.h>
#include <mach/board-mx31moboard.h>
#include <mach/mxc_ehci.h>
@@ -38,6 +33,7 @@
#include <media/soc_camera.h>
+#include "devices-imx31.h"
#include "devices.h"
static unsigned int smartbot_pins[] = {
@@ -59,7 +55,7 @@ static unsigned int smartbot_pins[] = {
MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
};
-static struct imxuart_platform_data uart_pdata = {
+static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -183,8 +179,7 @@ void __init mx31moboard_smartbot_init(int board)
mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
"smartbot");
- mxc_register_device(&mxc_uart_device1, &uart_pdata);
-
+ imx31_add_imx_uart1(&uart_pdata);
switch (board) {
case MX31SMARTBOT:
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index ed885f9d7b73..6e384d92e625 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/io.h>
@@ -21,6 +22,7 @@
#include <mach/hardware.h>
#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
+#include <mach/i2c.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h>
@@ -64,6 +66,18 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_EIM_D27__UART3_RTS,
MX51_PAD_EIM_D24__UART3_CTS,
+ /* I2C1 */
+ MX51_PAD_EIM_D16__I2C1_SDA,
+ MX51_PAD_EIM_D19__I2C1_SCL,
+
+ /* I2C2 */
+ MX51_PAD_KEY_COL4__I2C2_SCL,
+ MX51_PAD_KEY_COL5__I2C2_SDA,
+
+ /* HSI2C */
+ MX51_PAD_I2C1_CLK__HSI2C_CLK,
+ MX51_PAD_I2C1_DAT__HSI2C_DAT,
+
/* USB HOST1 */
MX51_PAD_USBH1_CLK__USBH1_CLK,
MX51_PAD_USBH1_DIR__USBH1_DIR,
@@ -78,7 +92,7 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_USBH1_DATA7__USBH1_DATA7,
/* USB HUB reset line*/
- MX51_PAD_GPIO_1_7__GPIO1_7,
+ MX51_PAD_GPIO_1_7__GPIO_1_7,
};
/* Serial ports */
@@ -99,6 +113,14 @@ static inline void mxc_init_imx_uart(void)
}
#endif /* SERIAL_IMX */
+static struct imxi2c_platform_data babbage_i2c_data = {
+ .bitrate = 100000,
+};
+
+static struct imxi2c_platform_data babbage_hsi2c_data = {
+ .bitrate = 400000,
+};
+
static int gpio_usbh1_active(void)
{
struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27;
@@ -230,6 +252,10 @@ static void __init mxc_board_init(void)
mxc_init_imx_uart();
platform_add_devices(devices, ARRAY_SIZE(devices));
+ mxc_register_device(&mxc_i2c_device0, &babbage_i2c_data);
+ mxc_register_device(&mxc_i2c_device1, &babbage_i2c_data);
+ mxc_register_device(&mxc_hsi2c_device, &babbage_hsi2c_data);
+
if (otg_mode_host)
mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
else {
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index d9f612d3370e..fd24092154b5 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -798,6 +798,14 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+/* I2C */
+DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG9_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG10_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+DEFINE_CLOCK(hsi2c_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG11_OFFSET,
+ NULL, NULL, &ipg_clk, NULL);
+
/* FEC */
DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
NULL, NULL, &ipg_clk, NULL);
@@ -815,6 +823,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+ _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+ _REGISTER_CLOCK("imx-i2c.2", NULL, hsi2c_clk)
_REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
_REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
_REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 7130449aacdc..fa118646c99e 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -93,6 +93,64 @@ struct platform_device mxc_fec_device = {
.resource = mxc_fec_resources,
};
+static struct resource mxc_i2c0_resources[] = {
+ {
+ .start = MX51_I2C1_BASE_ADDR,
+ .end = MX51_I2C1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_I2C1,
+ .end = MX51_MXC_INT_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_i2c_device0 = {
+ .name = "imx-i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_i2c0_resources),
+ .resource = mxc_i2c0_resources,
+};
+
+static struct resource mxc_i2c1_resources[] = {
+ {
+ .start = MX51_I2C2_BASE_ADDR,
+ .end = MX51_I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = MX51_MXC_INT_I2C2,
+ .end = MX51_MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_i2c_device1 = {
+ .name = "imx-i2c",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(mxc_i2c1_resources),
+ .resource = mxc_i2c1_resources,
+};
+
+static struct resource mxc_hsi2c_resources[] = {
+ {
+ .start = MX51_HSI2C_DMA_BASE_ADDR,
+ .end = MX51_HSI2C_DMA_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_HS_I2C,
+ .end = MX51_MXC_INT_HS_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_hsi2c_device = {
+ .name = "imx-i2c",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(mxc_hsi2c_resources),
+ .resource = mxc_hsi2c_resources
+};
+
static u64 usb_dma_mask = DMA_BIT_MASK(32);
static struct resource usbotg_resources[] = {
@@ -195,7 +253,7 @@ static struct mxc_gpio_port mxc_gpio_ports[] = {
},
};
-int __init mxc_register_gpios(void)
+int __init imx51_register_gpios(void)
{
return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
}
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
index c879ae71cd5b..a853933682e7 100644
--- a/arch/arm/mach-mx5/devices.h
+++ b/arch/arm/mach-mx5/devices.h
@@ -6,3 +6,6 @@ extern struct platform_device mxc_usbdr_host_device;
extern struct platform_device mxc_usbh1_device;
extern struct platform_device mxc_usbdr_udc_device;
extern struct platform_device mxc_wdt;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_hsi2c_device;
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
index b7677ef80cc4..2f79722508cf 100644
--- a/arch/arm/mach-mx5/mm.c
+++ b/arch/arm/mach-mx5/mm.c
@@ -65,6 +65,8 @@ void __init mx51_map_io(void)
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+int imx51_register_gpios(void);
+
void __init mx51_init_irq(void)
{
unsigned long tzic_addr;
@@ -79,5 +81,6 @@ void __init mx51_init_irq(void)
if (!tzic_virt)
panic("unable to map TZIC interrupt controller\n");
+ imx51_register_gpios();
tzic_init_irq(tzic_virt);
}
diff --git a/arch/arm/mach-mxc91231/crm_regs.h b/arch/arm/mach-mxc91231/crm_regs.h
index ce4f59058189..b989baccd675 100644
--- a/arch/arm/mach-mxc91231/crm_regs.h
+++ b/arch/arm/mach-mxc91231/crm_regs.h
@@ -11,11 +11,6 @@
* 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 _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
diff --git a/arch/arm/mach-mxc91231/devices.c b/arch/arm/mach-mxc91231/devices.c
index 353bd977b393..027af4f0d18a 100644
--- a/arch/arm/mach-mxc91231/devices.c
+++ b/arch/arm/mach-mxc91231/devices.c
@@ -135,7 +135,7 @@ static struct mxc_gpio_port mxc_gpio_ports[] = {
},
};
-int __init mxc_register_gpios(void)
+int __init mxc91231_register_gpios(void)
{
return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
}
diff --git a/arch/arm/mach-mxc91231/mm.c b/arch/arm/mach-mxc91231/mm.c
index 6becda3ff331..aeccfd755fee 100644
--- a/arch/arm/mach-mxc91231/mm.c
+++ b/arch/arm/mach-mxc91231/mm.c
@@ -15,11 +15,6 @@
* 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/mm.h>
@@ -88,7 +83,10 @@ void __init mxc91231_map_io(void)
iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
}
+int mxc91231_register_gpios(void);
+
void __init mxc91231_init_irq(void)
{
+ mxc91231_register_gpios();
mxc_init_irq(MXC91231_IO_ADDRESS(MXC91231_AVIC_BASE_ADDR));
}
diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig
index b18d7c28ab7a..3b02d3b944af 100644
--- a/arch/arm/mach-omap1/Kconfig
+++ b/arch/arm/mach-omap1/Kconfig
@@ -1,3 +1,7 @@
+if ARCH_OMAP1
+
+menu "TI OMAP1 specific features"
+
comment "OMAP Core Type"
depends on ARCH_OMAP1
@@ -224,6 +228,12 @@ config OMAP_ARM_120MHZ
help
Enable 120MHz clock for OMAP CPU. If unsure, say N.
+config OMAP_ARM_96MHZ
+ bool "OMAP ARM 96 MHz CPU"
+ depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
+ help
+ Enable 96MHz clock for OMAP CPU. If unsure, say N.
+
config OMAP_ARM_60MHZ
bool "OMAP ARM 60 MHz CPU"
depends on ARCH_OMAP1 && (ARCH_OMAP15XX || ARCH_OMAP16XX || ARCH_OMAP730 || ARCH_OMAP850)
@@ -237,3 +247,6 @@ config OMAP_ARM_30MHZ
help
Enable 30MHz clock for OMAP CPU. If unsure, say N.
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile
index ea231c7a550a..facfaeb1ae5c 100644
--- a/arch/arm/mach-omap1/Makefile
+++ b/arch/arm/mach-omap1/Makefile
@@ -23,6 +23,9 @@ obj-y += $(i2c-omap-m) $(i2c-omap-y)
led-y := leds.o
+usb-fs-$(CONFIG_USB) := usb.o
+obj-y += $(usb-fs-m) $(usb-fs-y)
+
# Specific board support
obj-$(CONFIG_MACH_OMAP_H2) += board-h2.o board-h2-mmc.o
obj-$(CONFIG_MACH_OMAP_INNOVATOR) += board-innovator.o
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c
index fdd1dd53fa9c..41992ab71961 100644
--- a/arch/arm/mach-omap1/board-ams-delta.c
+++ b/arch/arm/mach-omap1/board-ams-delta.c
@@ -235,7 +235,7 @@ static void __init ams_delta_init(void)
/* Clear latch2 (NAND, LCD, modem enable) */
ams_delta_latch2_write(~0, 0);
- omap_usb_init(&ams_delta_usb_config);
+ omap1_usb_init(&ams_delta_usb_config);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
#ifdef CONFIG_AMS_DELTA_FIQ
@@ -301,6 +301,7 @@ MACHINE_START(AMS_DELTA, "Amstrad E3 (Delta)")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = ams_delta_map_io,
+ .reserve = omap_reserve,
.init_irq = ams_delta_init_irq,
.init_machine = ams_delta_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-fsample.c b/arch/arm/mach-omap1/board-fsample.c
index 096f2ed102cb..180ce79e5eac 100644
--- a/arch/arm/mach-omap1/board-fsample.c
+++ b/arch/arm/mach-omap1/board-fsample.c
@@ -292,6 +292,18 @@ static void __init omap_fsample_init(void)
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+ /* Mux pins for keypad */
+ omap_cfg_reg(E2_7XX_KBR0);
+ omap_cfg_reg(J7_7XX_KBR1);
+ omap_cfg_reg(E1_7XX_KBR2);
+ omap_cfg_reg(F3_7XX_KBR3);
+ omap_cfg_reg(D2_7XX_KBR4);
+ omap_cfg_reg(C2_7XX_KBC0);
+ omap_cfg_reg(D3_7XX_KBC1);
+ omap_cfg_reg(E4_7XX_KBC2);
+ omap_cfg_reg(F4_7XX_KBC3);
+ omap_cfg_reg(E3_7XX_KBC4);
+
platform_add_devices(devices, ARRAY_SIZE(devices));
omap_board_config = fsample_config;
@@ -378,6 +390,7 @@ MACHINE_START(OMAP_FSAMPLE, "OMAP730 F-Sample")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_fsample_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_fsample_init_irq,
.init_machine = omap_fsample_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-generic.c b/arch/arm/mach-omap1/board-generic.c
index e1195a3467b8..93b9ab8fc3be 100644
--- a/arch/arm/mach-omap1/board-generic.c
+++ b/arch/arm/mach-omap1/board-generic.c
@@ -72,12 +72,12 @@ static void __init omap_generic_init(void)
omap_cfg_reg(UART3_TX);
omap_cfg_reg(UART3_RX);
- omap_usb_init(&generic1510_usb_config);
+ omap1_usb_init(&generic1510_usb_config);
}
#endif
#if defined(CONFIG_ARCH_OMAP16XX)
if (!cpu_is_omap1510()) {
- omap_usb_init(&generic1610_usb_config);
+ omap1_usb_init(&generic1610_usb_config);
}
#endif
@@ -98,6 +98,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_generic_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_generic_init_irq,
.init_machine = omap_generic_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c
index d1100e4f65ac..d2cda58bcc48 100644
--- a/arch/arm/mach-omap1/board-h2.c
+++ b/arch/arm/mach-omap1/board-h2.c
@@ -292,15 +292,6 @@ static struct platform_device h2_kp_device = {
#define H2_IRDA_FIRSEL_GPIO_PIN 17
-#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
-static int h2_transceiver_mode(struct device *dev, int state)
-{
- /* SIR when low, else MIR/FIR when HIGH */
- gpio_set_value(H2_IRDA_FIRSEL_GPIO_PIN, !(state & IR_SIRMODE));
- return 0;
-}
-#endif
-
static struct omap_irda_config h2_irda_data = {
.transceiver_cap = IR_SIRMODE | IR_MIRMODE | IR_FIRMODE,
.rx_channel = OMAP_DMA_UART3_RX,
@@ -437,14 +428,18 @@ static void __init h2_init(void)
/* omap_cfg_reg(U19_ARMIO1); */ /* CD */
omap_cfg_reg(BALLOUT_V8_ARMIO3); /* WP */
- /* Irda */
-#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
- omap_writel(omap_readl(FUNC_MUX_CTRL_A) | 7, FUNC_MUX_CTRL_A);
- if (gpio_request(H2_IRDA_FIRSEL_GPIO_PIN, "IRDA mode") < 0)
- BUG();
- gpio_direction_output(H2_IRDA_FIRSEL_GPIO_PIN, 0);
- h2_irda_data.transceiver_mode = h2_transceiver_mode;
-#endif
+ /* Mux pins for keypad */
+ omap_cfg_reg(F18_1610_KBC0);
+ omap_cfg_reg(D20_1610_KBC1);
+ omap_cfg_reg(D19_1610_KBC2);
+ omap_cfg_reg(E18_1610_KBC3);
+ omap_cfg_reg(C21_1610_KBC4);
+ omap_cfg_reg(G18_1610_KBR0);
+ omap_cfg_reg(F19_1610_KBR1);
+ omap_cfg_reg(H14_1610_KBR2);
+ omap_cfg_reg(E20_1610_KBR3);
+ omap_cfg_reg(E19_1610_KBR4);
+ omap_cfg_reg(N19_1610_KBR5);
platform_add_devices(h2_devices, ARRAY_SIZE(h2_devices));
omap_board_config = h2_config;
@@ -452,7 +447,7 @@ static void __init h2_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, h2_i2c_board_info,
ARRAY_SIZE(h2_i2c_board_info));
- omap_usb_init(&h2_usb_config);
+ omap1_usb_init(&h2_usb_config);
h2_mmc_init();
}
@@ -467,6 +462,7 @@ MACHINE_START(OMAP_H2, "TI-H2")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = h2_map_io,
+ .reserve = omap_reserve,
.init_irq = h2_init_irq,
.init_machine = h2_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-h3.c b/arch/arm/mach-omap1/board-h3.c
index a53ab8297d25..c2ef4ff846c7 100644
--- a/arch/arm/mach-omap1/board-h3.c
+++ b/arch/arm/mach-omap1/board-h3.c
@@ -397,6 +397,19 @@ static void __init h3_init(void)
/* GPIO10 pullup/down register, Enable pullup on GPIO10 */
omap_cfg_reg(V2_1710_GPIO10);
+ /* Mux pins for keypad */
+ omap_cfg_reg(F18_1610_KBC0);
+ omap_cfg_reg(D20_1610_KBC1);
+ omap_cfg_reg(D19_1610_KBC2);
+ omap_cfg_reg(E18_1610_KBC3);
+ omap_cfg_reg(C21_1610_KBC4);
+ omap_cfg_reg(G18_1610_KBR0);
+ omap_cfg_reg(F19_1610_KBR1);
+ omap_cfg_reg(H14_1610_KBR2);
+ omap_cfg_reg(E20_1610_KBR3);
+ omap_cfg_reg(E19_1610_KBR4);
+ omap_cfg_reg(N19_1610_KBR5);
+
platform_add_devices(devices, ARRAY_SIZE(devices));
spi_register_board_info(h3_spi_board_info,
ARRAY_SIZE(h3_spi_board_info));
@@ -405,7 +418,7 @@ static void __init h3_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 100, h3_i2c_board_info,
ARRAY_SIZE(h3_i2c_board_info));
- omap_usb_init(&h3_usb_config);
+ omap1_usb_init(&h3_usb_config);
h3_mmc_init();
}
@@ -437,6 +450,7 @@ MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = h3_map_io,
+ .reserve = omap_reserve,
.init_irq = h3_init_irq,
.init_machine = h3_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-htcherald.c b/arch/arm/mach-omap1/board-htcherald.c
index 8e313b4b99a9..311899ff5ffc 100644
--- a/arch/arm/mach-omap1/board-htcherald.c
+++ b/arch/arm/mach-omap1/board-htcherald.c
@@ -287,7 +287,7 @@ static void __init htcherald_init(void)
htcherald_disable_watchdog();
htcherald_usb_enable();
- omap_usb_init(&htcherald_usb_config);
+ omap1_usb_init(&htcherald_usb_config);
}
static void __init htcherald_init_irq(void)
@@ -304,6 +304,7 @@ MACHINE_START(HERALD, "HTC Herald")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = htcherald_map_io,
+ .reserve = omap_reserve,
.init_irq = htcherald_init_irq,
.init_machine = htcherald_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 5d12fd35681b..3daf87ad2576 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -422,13 +422,13 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
- omap_usb_init(&innovator1510_usb_config);
+ omap1_usb_init(&innovator1510_usb_config);
innovator_config[1].data = &innovator1510_lcd_config;
}
#endif
#ifdef CONFIG_ARCH_OMAP16XX
if (cpu_is_omap1610()) {
- omap_usb_init(&h2_usb_config);
+ omap1_usb_init(&h2_usb_config);
innovator_config[1].data = &innovator1610_lcd_config;
}
#endif
@@ -463,6 +463,7 @@ MACHINE_START(OMAP_INNOVATOR, "TI-Innovator")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = innovator_map_io,
+ .reserve = omap_reserve,
.init_irq = innovator_init_irq,
.init_machine = innovator_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 71e1a3fad0ea..51a4539aecf5 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -32,7 +32,6 @@
#include <plat/board.h>
#include <plat/keypad.h>
#include <plat/common.h>
-#include <plat/dsp_common.h>
#include <plat/hwa742.h>
#include <plat/lcd_mipid.h>
#include <plat/mmc.h>
@@ -242,138 +241,6 @@ static inline void nokia770_mmc_init(void)
}
#endif
-#if defined(CONFIG_OMAP_DSP)
-/*
- * audio power control
- */
-#define HEADPHONE_GPIO 14
-#define AMPLIFIER_CTRL_GPIO 58
-
-static struct clk *dspxor_ck;
-static DEFINE_MUTEX(audio_pwr_lock);
-/*
- * audio_pwr_state
- * +--+-------------------------+---------------------------------------+
- * |-1|down |power-up request -> 0 |
- * +--+-------------------------+---------------------------------------+
- * | 0|up |power-down(1) request -> 1 |
- * | | |power-down(2) request -> (ignore) |
- * +--+-------------------------+---------------------------------------+
- * | 1|up, |power-up request -> 0 |
- * | |received down(1) request |power-down(2) request -> -1 |
- * +--+-------------------------+---------------------------------------+
- */
-static int audio_pwr_state = -1;
-
-static inline void aic23_power_up(void)
-{
-}
-static inline void aic23_power_down(void)
-{
-}
-
-/*
- * audio_pwr_up / down should be called under audio_pwr_lock
- */
-static void nokia770_audio_pwr_up(void)
-{
- clk_enable(dspxor_ck);
-
- /* Turn on codec */
- aic23_power_up();
-
- if (gpio_get_value(HEADPHONE_GPIO))
- /* HP not connected, turn on amplifier */
- gpio_set_value(AMPLIFIER_CTRL_GPIO, 1);
- else
- /* HP connected, do not turn on amplifier */
- printk("HP connected\n");
-}
-
-static void codec_delayed_power_down(struct work_struct *work)
-{
- mutex_lock(&audio_pwr_lock);
- if (audio_pwr_state == -1)
- aic23_power_down();
- clk_disable(dspxor_ck);
- mutex_unlock(&audio_pwr_lock);
-}
-
-static DECLARE_DELAYED_WORK(codec_power_down_work, codec_delayed_power_down);
-
-static void nokia770_audio_pwr_down(void)
-{
- /* Turn off amplifier */
- gpio_set_value(AMPLIFIER_CTRL_GPIO, 0);
-
- /* Turn off codec: schedule delayed work */
- schedule_delayed_work(&codec_power_down_work, HZ / 20); /* 50ms */
-}
-
-static int
-nokia770_audio_pwr_up_request(struct dsp_kfunc_device *kdev, int stage)
-{
- mutex_lock(&audio_pwr_lock);
- if (audio_pwr_state == -1)
- nokia770_audio_pwr_up();
- /* force audio_pwr_state = 0, even if it was 1. */
- audio_pwr_state = 0;
- mutex_unlock(&audio_pwr_lock);
- return 0;
-}
-
-static int
-nokia770_audio_pwr_down_request(struct dsp_kfunc_device *kdev, int stage)
-{
- mutex_lock(&audio_pwr_lock);
- switch (stage) {
- case 1:
- if (audio_pwr_state == 0)
- audio_pwr_state = 1;
- break;
- case 2:
- if (audio_pwr_state == 1) {
- nokia770_audio_pwr_down();
- audio_pwr_state = -1;
- }
- break;
- }
- mutex_unlock(&audio_pwr_lock);
- return 0;
-}
-
-static struct dsp_kfunc_device nokia770_audio_device = {
- .name = "audio",
- .type = DSP_KFUNC_DEV_TYPE_AUDIO,
- .enable = nokia770_audio_pwr_up_request,
- .disable = nokia770_audio_pwr_down_request,
-};
-
-static __init int omap_dsp_init(void)
-{
- int ret;
-
- dspxor_ck = clk_get(0, "dspxor_ck");
- if (IS_ERR(dspxor_ck)) {
- printk(KERN_ERR "couldn't acquire dspxor_ck\n");
- return PTR_ERR(dspxor_ck);
- }
-
- ret = dsp_kfunc_device_register(&nokia770_audio_device);
- if (ret) {
- printk(KERN_ERR
- "KFUNC device registration faild: %s\n",
- nokia770_audio_device.name);
- goto out;
- }
- return 0;
- out:
- return ret;
-}
-#else
-#define omap_dsp_init() do {} while (0)
-#endif /* CONFIG_OMAP_DSP */
-
static void __init omap_nokia770_init(void)
{
platform_add_devices(nokia770_devices, ARRAY_SIZE(nokia770_devices));
@@ -382,11 +249,10 @@ static void __init omap_nokia770_init(void)
omap_gpio_init();
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
- omap_dsp_init();
hwa742_dev_init();
ads7846_dev_init();
mipid_dev_init();
- omap_usb_init(&nokia770_usb_config);
+ omap1_usb_init(&nokia770_usb_config);
nokia770_mmc_init();
}
@@ -400,6 +266,7 @@ MACHINE_START(NOKIA770, "Nokia 770")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_nokia770_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_nokia770_init_irq,
.init_machine = omap_nokia770_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 80d862001def..679740cc1e90 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -560,7 +560,7 @@ static void __init osk_init(void)
l |= (3 << 1);
omap_writel(l, USB_TRANSCEIVER_CTRL);
- omap_usb_init(&osk_usb_config);
+ omap1_usb_init(&osk_usb_config);
/* irq for tps65010 chip */
/* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */
@@ -584,6 +584,7 @@ MACHINE_START(OMAP_OSK, "TI-OSK")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = osk_map_io,
+ .reserve = omap_reserve,
.init_irq = osk_init_irq,
.init_machine = osk_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmte.c b/arch/arm/mach-omap1/board-palmte.c
index 569b4c9085cd..782bb257a85d 100644
--- a/arch/arm/mach-omap1/board-palmte.c
+++ b/arch/arm/mach-omap1/board-palmte.c
@@ -213,90 +213,6 @@ static struct omap_lcd_config palmte_lcd_config __initdata = {
.ctrl_name = "internal",
};
-#ifdef CONFIG_APM
-/*
- * Values measured in 10 minute intervals averaged over 10 samples.
- * May differ slightly from device to device but should be accurate
- * enough to give basic idea of battery life left and trigger
- * potential alerts.
- */
-static const int palmte_battery_sample[] = {
- 2194, 2157, 2138, 2120,
- 2104, 2089, 2075, 2061,
- 2048, 2038, 2026, 2016,
- 2008, 1998, 1989, 1980,
- 1970, 1958, 1945, 1928,
- 1910, 1888, 1860, 1827,
- 1791, 1751, 1709, 1656,
-};
-
-#define INTERVAL 10
-#define BATTERY_HIGH_TRESHOLD 66
-#define BATTERY_LOW_TRESHOLD 33
-
-static void palmte_get_power_status(struct apm_power_info *info, int *battery)
-{
- int charging, batt, hi, lo, mid;
-
- charging = !gpio_get_value(PALMTE_DC_GPIO);
- batt = battery[0];
- if (charging)
- batt -= 60;
-
- hi = ARRAY_SIZE(palmte_battery_sample);
- lo = 0;
-
- info->battery_flag = 0;
- info->units = APM_UNITS_MINS;
-
- if (batt > palmte_battery_sample[lo]) {
- info->battery_life = 100;
- info->time = INTERVAL * ARRAY_SIZE(palmte_battery_sample);
- } else if (batt <= palmte_battery_sample[hi - 1]) {
- info->battery_life = 0;
- info->time = 0;
- } else {
- while (hi > lo + 1) {
- mid = (hi + lo) >> 1;
- if (batt <= palmte_battery_sample[mid])
- lo = mid;
- else
- hi = mid;
- }
-
- mid = palmte_battery_sample[lo] - palmte_battery_sample[hi];
- hi = palmte_battery_sample[lo] - batt;
- info->battery_life = 100 - (100 * lo + 100 * hi / mid) /
- ARRAY_SIZE(palmte_battery_sample);
- info->time = INTERVAL * (ARRAY_SIZE(palmte_battery_sample) -
- lo) - INTERVAL * hi / mid;
- }
-
- if (charging) {
- info->ac_line_status = APM_AC_ONLINE;
- info->battery_status = APM_BATTERY_STATUS_CHARGING;
- info->battery_flag |= APM_BATTERY_FLAG_CHARGING;
- } else {
- info->ac_line_status = APM_AC_OFFLINE;
- if (info->battery_life > BATTERY_HIGH_TRESHOLD)
- info->battery_status = APM_BATTERY_STATUS_HIGH;
- else if (info->battery_life > BATTERY_LOW_TRESHOLD)
- info->battery_status = APM_BATTERY_STATUS_LOW;
- else
- info->battery_status = APM_BATTERY_STATUS_CRITICAL;
- }
-
- if (info->battery_life > BATTERY_HIGH_TRESHOLD)
- info->battery_flag |= APM_BATTERY_FLAG_HIGH;
- else if (info->battery_life > BATTERY_LOW_TRESHOLD)
- info->battery_flag |= APM_BATTERY_FLAG_LOW;
- else
- info->battery_flag |= APM_BATTERY_FLAG_CRITICAL;
-}
-#else
-#define palmte_get_power_status NULL
-#endif
-
static struct omap_board_config_kernel palmte_config[] __initdata = {
{ OMAP_TAG_LCD, &palmte_lcd_config },
};
@@ -359,7 +275,7 @@ static void __init omap_palmte_init(void)
spi_register_board_info(palmte_spi_info, ARRAY_SIZE(palmte_spi_info));
palmte_misc_gpio_setup();
omap_serial_init();
- omap_usb_init(&palmte_usb_config);
+ omap1_usb_init(&palmte_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
}
@@ -373,6 +289,7 @@ MACHINE_START(OMAP_PALMTE, "OMAP310 based Palm Tungsten E")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_palmte_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_palmte_init_irq,
.init_machine = omap_palmte_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmtt.c b/arch/arm/mach-omap1/board-palmtt.c
index 6ad49a2cc1a0..0b35ef54a64f 100644
--- a/arch/arm/mach-omap1/board-palmtt.c
+++ b/arch/arm/mach-omap1/board-palmtt.c
@@ -307,7 +307,7 @@ static void __init omap_palmtt_init(void)
spi_register_board_info(palmtt_boardinfo,ARRAY_SIZE(palmtt_boardinfo));
omap_serial_init();
- omap_usb_init(&palmtt_usb_config);
+ omap1_usb_init(&palmtt_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
}
@@ -321,6 +321,7 @@ MACHINE_START(OMAP_PALMTT, "OMAP1510 based Palm Tungsten|T")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_palmtt_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_palmtt_init_irq,
.init_machine = omap_palmtt_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index 6641de9257ef..66362903b6e2 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -325,7 +325,7 @@ omap_palmz71_init(void)
spi_register_board_info(palmz71_boardinfo,
ARRAY_SIZE(palmz71_boardinfo));
- omap_usb_init(&palmz71_usb_config);
+ omap1_usb_init(&palmz71_usb_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
palmz71_gpio_setup(0);
@@ -338,10 +338,12 @@ omap_palmz71_map_io(void)
}
MACHINE_START(OMAP_PALMZ71, "OMAP310 based Palm Zire71")
- .phys_io = 0xfff00000,
- .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
- .boot_params = 0x10000100,.map_io = omap_palmz71_map_io,
- .init_irq = omap_palmz71_init_irq,
- .init_machine = omap_palmz71_init,
- .timer = &omap_timer,
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,
+ .map_io = omap_palmz71_map_io,
+ .reserve = omap_reserve,
+ .init_irq = omap_palmz71_init_irq,
+ .init_machine = omap_palmz71_init,
+ .timer = &omap_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-perseus2.c b/arch/arm/mach-omap1/board-perseus2.c
index e854d5741c88..34ab354758b0 100644
--- a/arch/arm/mach-omap1/board-perseus2.c
+++ b/arch/arm/mach-omap1/board-perseus2.c
@@ -260,6 +260,18 @@ static void __init omap_perseus2_init(void)
omap_cfg_reg(L3_1610_FLASH_CS2B_OE);
omap_cfg_reg(M8_1610_FLASH_CS2B_WE);
+ /* Mux pins for keypad */
+ omap_cfg_reg(E2_7XX_KBR0);
+ omap_cfg_reg(J7_7XX_KBR1);
+ omap_cfg_reg(E1_7XX_KBR2);
+ omap_cfg_reg(F3_7XX_KBR3);
+ omap_cfg_reg(D2_7XX_KBR4);
+ omap_cfg_reg(C2_7XX_KBC0);
+ omap_cfg_reg(D3_7XX_KBC1);
+ omap_cfg_reg(E4_7XX_KBC2);
+ omap_cfg_reg(F4_7XX_KBC3);
+ omap_cfg_reg(E3_7XX_KBC4);
+
platform_add_devices(devices, ARRAY_SIZE(devices));
omap_board_config = perseus2_config;
@@ -339,6 +351,7 @@ MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_perseus2_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_perseus2_init_irq,
.init_machine = omap_perseus2_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/board-sx1.c b/arch/arm/mach-omap1/board-sx1.c
index 2fb1e5f8e2ec..2eb148b8de93 100644
--- a/arch/arm/mach-omap1/board-sx1.c
+++ b/arch/arm/mach-omap1/board-sx1.c
@@ -392,7 +392,7 @@ static void __init omap_sx1_init(void)
omap_board_config_size = ARRAY_SIZE(sx1_config);
omap_serial_init();
omap_register_i2c_bus(1, 100, NULL, 0);
- omap_usb_init(&sx1_usb_config);
+ omap1_usb_init(&sx1_usb_config);
sx1_mmc_init();
/* turn on USB power */
@@ -423,7 +423,8 @@ MACHINE_START(SX1, "OMAP310 based Siemens SX1")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = omap_sx1_map_io,
- .init_irq = omap_sx1_init_irq,
+ .reserve = omap_reserve,
+ .init_irq = omap_sx1_init_irq,
.init_machine = omap_sx1_init,
.timer = &omap_timer,
MACHINE_END
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index 87b9436fe7c0..6b3cf14bc757 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -198,7 +198,7 @@ static void __init voiceblue_init(void)
omap_board_config = voiceblue_config;
omap_board_config_size = ARRAY_SIZE(voiceblue_config);
omap_serial_init();
- omap_usb_init(&voiceblue_usb_config);
+ omap1_usb_init(&voiceblue_usb_config);
omap_register_i2c_bus(1, 100, NULL, 0);
/* There is a good chance board is going up, so enable power LED
@@ -287,6 +287,7 @@ MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
.io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = voiceblue_map_io,
+ .reserve = omap_reserve,
.init_irq = voiceblue_init_irq,
.init_machine = voiceblue_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap1/clock.c b/arch/arm/mach-omap1/clock.c
index 6bbb1b8b8294..b8c7fb9d7921 100644
--- a/arch/arm/mach-omap1/clock.c
+++ b/arch/arm/mach-omap1/clock.c
@@ -11,7 +11,6 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
-#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/errno.h>
@@ -34,9 +33,9 @@
__u32 arm_idlect1_mask;
struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
-/*-------------------------------------------------------------------------
+/*
* Omap1 specific clock functions
- *-------------------------------------------------------------------------*/
+ */
unsigned long omap1_uart_recalc(struct clk *clk)
{
@@ -523,7 +522,8 @@ const struct clkops clkops_dspck = {
.disable = omap1_clk_disable_dsp_domain,
};
-static int omap1_clk_enable_uart_functional(struct clk *clk)
+/* XXX SYSC register handling does not belong in the clock framework */
+static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
{
int ret;
struct uart_clk *uclk;
@@ -539,7 +539,8 @@ static int omap1_clk_enable_uart_functional(struct clk *clk)
return ret;
}
-static void omap1_clk_disable_uart_functional(struct clk *clk)
+/* XXX SYSC register handling does not belong in the clock framework */
+static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
{
struct uart_clk *uclk;
@@ -550,9 +551,10 @@ static void omap1_clk_disable_uart_functional(struct clk *clk)
omap1_clk_disable_generic(clk);
}
-const struct clkops clkops_uart = {
- .enable = omap1_clk_enable_uart_functional,
- .disable = omap1_clk_disable_uart_functional,
+/* XXX SYSC register handling does not belong in the clock framework */
+const struct clkops clkops_uart_16xx = {
+ .enable = omap1_clk_enable_uart_functional_16xx,
+ .disable = omap1_clk_disable_uart_functional_16xx,
};
long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
@@ -572,9 +574,9 @@ int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
return ret;
}
-/*-------------------------------------------------------------------------
+/*
* Omap1 clock reset and init functions
- *-------------------------------------------------------------------------*/
+ */
#ifdef CONFIG_OMAP_RESET_CLOCKS
diff --git a/arch/arm/mach-omap1/clock.h b/arch/arm/mach-omap1/clock.h
index 75d0d7d90bff..eaf09efb91ca 100644
--- a/arch/arm/mach-omap1/clock.h
+++ b/arch/arm/mach-omap1/clock.h
@@ -107,7 +107,7 @@ extern struct clk *api_ck_p, *ck_dpll1_p, *ck_ref_p;
extern const struct clkops clkops_dspck;
extern const struct clkops clkops_dummy;
-extern const struct clkops clkops_uart;
+extern const struct clkops clkops_uart_16xx;
extern const struct clkops clkops_generic;
#endif
diff --git a/arch/arm/mach-omap1/clock_data.c b/arch/arm/mach-omap1/clock_data.c
index aa8558adbf1c..af54114b8f08 100644
--- a/arch/arm/mach-omap1/clock_data.c
+++ b/arch/arm/mach-omap1/clock_data.c
@@ -8,6 +8,10 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
+ *
+ * To do:
+ * - Clocks that are only available on some chips should be marked with the
+ * chips that they are present on.
*/
#include <linux/kernel.h>
@@ -23,9 +27,49 @@
#include "clock.h"
-/*------------------------------------------------------------------------
+/* Some ARM_IDLECT1 bit shifts - used in struct arm_idlect1_clk */
+#define IDL_CLKOUT_ARM_SHIFT 12
+#define IDLTIM_ARM_SHIFT 9
+#define IDLAPI_ARM_SHIFT 8
+#define IDLIF_ARM_SHIFT 6
+#define IDLLB_ARM_SHIFT 4 /* undocumented? */
+#define OMAP1510_IDLLCD_ARM_SHIFT 3 /* undocumented? */
+#define IDLPER_ARM_SHIFT 2
+#define IDLXORP_ARM_SHIFT 1
+#define IDLWDT_ARM_SHIFT 0
+
+/* Some MOD_CONF_CTRL_0 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_UART3_CLK_MODE_R 31
+#define CONF_MOD_UART2_CLK_MODE_R 30
+#define CONF_MOD_UART1_CLK_MODE_R 29
+#define CONF_MOD_MMC_SD_CLK_REQ_R 23
+#define CONF_MOD_MCBSP3_AUXON 20
+
+/* Some MOD_CONF_CTRL_1 bit shifts - used in struct clk.enable_bit */
+#define CONF_MOD_SOSSI_CLK_EN_R 16
+
+/* Some OTG_SYSCON_2-specific bit fields */
+#define OTG_SYSCON_2_UHOST_EN_SHIFT 8
+
+/* Some SOFT_REQ_REG bit fields - used in struct clk.enable_bit */
+#define SOFT_MMC2_DPLL_REQ_SHIFT 13
+#define SOFT_MMC_DPLL_REQ_SHIFT 12
+#define SOFT_UART3_DPLL_REQ_SHIFT 11
+#define SOFT_UART2_DPLL_REQ_SHIFT 10
+#define SOFT_UART1_DPLL_REQ_SHIFT 9
+#define SOFT_USB_OTG_DPLL_REQ_SHIFT 8
+#define SOFT_CAM_DPLL_REQ_SHIFT 7
+#define SOFT_COM_MCKO_REQ_SHIFT 6
+#define SOFT_PERIPH_REQ_SHIFT 5 /* sys_ck gate for UART2 ? */
+#define USB_REQ_EN_SHIFT 4
+#define SOFT_USB_REQ_SHIFT 3 /* sys_ck gate for USB host? */
+#define SOFT_SDW_REQ_SHIFT 2 /* sys_ck gate for Bluetooth? */
+#define SOFT_COM_REQ_SHIFT 1 /* sys_ck gate for com proc? */
+#define SOFT_DPLL_REQ_SHIFT 0
+
+/*
* Omap1 clocks
- *-------------------------------------------------------------------------*/
+ */
static struct clk ck_ref = {
.name = "ck_ref",
@@ -54,7 +98,7 @@ static struct arm_idlect1_clk ck_dpll1out = {
.enable_bit = EN_CKOUT_ARM,
.recalc = &followparent_recalc,
},
- .idlect_shift = 12,
+ .idlect_shift = IDL_CLKOUT_ARM_SHIFT,
};
static struct clk sossi_ck = {
@@ -63,7 +107,7 @@ static struct clk sossi_ck = {
.parent = &ck_dpll1out.clk,
.flags = CLOCK_NO_IDLE_PARENT | ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_1),
- .enable_bit = 16,
+ .enable_bit = CONF_MOD_SOSSI_CLK_EN_R,
.recalc = &omap1_sossi_recalc,
.set_rate = &omap1_set_sossi_rate,
};
@@ -91,7 +135,7 @@ static struct arm_idlect1_clk armper_ck = {
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
- .idlect_shift = 2,
+ .idlect_shift = IDLPER_ARM_SHIFT,
};
/*
@@ -118,7 +162,7 @@ static struct arm_idlect1_clk armxor_ck = {
.enable_bit = EN_XORPCK,
.recalc = &followparent_recalc,
},
- .idlect_shift = 1,
+ .idlect_shift = IDLXORP_ARM_SHIFT,
};
static struct arm_idlect1_clk armtim_ck = {
@@ -131,7 +175,7 @@ static struct arm_idlect1_clk armtim_ck = {
.enable_bit = EN_TIMCK,
.recalc = &followparent_recalc,
},
- .idlect_shift = 9,
+ .idlect_shift = IDLTIM_ARM_SHIFT,
};
static struct arm_idlect1_clk armwdt_ck = {
@@ -145,7 +189,7 @@ static struct arm_idlect1_clk armwdt_ck = {
.fixed_div = 14,
.recalc = &omap_fixed_divisor_recalc,
},
- .idlect_shift = 0,
+ .idlect_shift = IDLWDT_ARM_SHIFT,
};
static struct clk arminth_ck16xx = {
@@ -212,7 +256,6 @@ static struct clk dsptim_ck = {
.recalc = &followparent_recalc,
};
-/* Tie ARM_IDLECT1:IDLIF_ARM to this logical clock structure */
static struct arm_idlect1_clk tc_ck = {
.clk = {
.name = "tc_ck",
@@ -224,7 +267,7 @@ static struct arm_idlect1_clk tc_ck = {
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
- .idlect_shift = 6,
+ .idlect_shift = IDLIF_ARM_SHIFT,
};
static struct clk arminth_ck1510 = {
@@ -304,7 +347,7 @@ static struct arm_idlect1_clk api_ck = {
.enable_bit = EN_APICK,
.recalc = &followparent_recalc,
},
- .idlect_shift = 8,
+ .idlect_shift = IDLAPI_ARM_SHIFT,
};
static struct arm_idlect1_clk lb_ck = {
@@ -317,7 +360,7 @@ static struct arm_idlect1_clk lb_ck = {
.enable_bit = EN_LBCK,
.recalc = &followparent_recalc,
},
- .idlect_shift = 4,
+ .idlect_shift = IDLLB_ARM_SHIFT,
};
static struct clk rhea1_ck = {
@@ -359,9 +402,15 @@ static struct arm_idlect1_clk lcd_ck_1510 = {
.round_rate = omap1_clk_round_rate_ckctl_arm,
.set_rate = omap1_clk_set_rate_ckctl_arm,
},
- .idlect_shift = 3,
+ .idlect_shift = OMAP1510_IDLLCD_ARM_SHIFT,
};
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
static struct clk uart1_1510 = {
.name = "uart1_ck",
.ops = &clkops_null,
@@ -370,25 +419,37 @@ static struct clk uart1_1510 = {
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
+ .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
static struct uart_clk uart1_16xx = {
.clk = {
.name = "uart1_ck",
- .ops = &clkops_uart,
+ .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 29,
+ .enable_bit = CONF_MOD_UART1_CLK_MODE_R,
},
.sysc_addr = 0xfffb0054,
};
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
static struct clk uart2_ck = {
.name = "uart2_ck",
.ops = &clkops_null,
@@ -397,11 +458,17 @@ static struct clk uart2_ck = {
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
+ .enable_bit = CONF_MOD_UART2_CLK_MODE_R,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX does this need SYSC register handling?
+ */
static struct clk uart3_1510 = {
.name = "uart3_ck",
.ops = &clkops_null,
@@ -410,21 +477,27 @@ static struct clk uart3_1510 = {
.rate = 12000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
+ .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
.set_rate = &omap1_set_uart_rate,
.recalc = &omap1_uart_recalc,
};
+/*
+ * XXX The enable_bit here is misused - it simply switches between 12MHz
+ * and 48MHz. Reimplement with clksel.
+ *
+ * XXX SYSC register handling does not belong in the clock framework
+ */
static struct uart_clk uart3_16xx = {
.clk = {
.name = "uart3_ck",
- .ops = &clkops_uart,
+ .ops = &clkops_uart_16xx,
/* Direct from ULPD, no real parent */
.parent = &armper_ck.clk,
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 31,
+ .enable_bit = CONF_MOD_UART3_CLK_MODE_R,
},
.sysc_addr = 0xfffb9854,
};
@@ -457,7 +530,7 @@ static struct clk usb_hhc_ck16xx = {
/* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
.flags = ENABLE_REG_32BIT,
.enable_reg = OMAP1_IO_ADDRESS(OTG_BASE + 0x08), /* OTG_SYSCON_2 */
- .enable_bit = 8 /* UHOST_EN */,
+ .enable_bit = OTG_SYSCON_2_UHOST_EN_SHIFT
};
static struct clk usb_dc_ck = {
@@ -466,7 +539,7 @@ static struct clk usb_dc_ck = {
/* Direct from ULPD, no parent */
.rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
- .enable_bit = 4,
+ .enable_bit = USB_REQ_EN_SHIFT,
};
static struct clk usb_dc_ck7xx = {
@@ -475,7 +548,25 @@ static struct clk usb_dc_ck7xx = {
/* Direct from ULPD, no parent */
.rate = 48000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
- .enable_bit = 8,
+ .enable_bit = SOFT_USB_OTG_DPLL_REQ_SHIFT,
+};
+
+static struct clk uart1_7xx = {
+ .name = "uart1_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 12000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = 9,
+};
+
+static struct clk uart2_7xx = {
+ .name = "uart2_ck",
+ .ops = &clkops_generic,
+ /* Direct from ULPD, no parent */
+ .rate = 12000000,
+ .enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
+ .enable_bit = 11,
};
static struct clk mclk_1510 = {
@@ -484,7 +575,7 @@ static struct clk mclk_1510 = {
/* Direct from ULPD, no parent. May be enabled by ext hardware. */
.rate = 12000000,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
- .enable_bit = 6,
+ .enable_bit = SOFT_COM_MCKO_REQ_SHIFT,
};
static struct clk mclk_16xx = {
@@ -524,9 +615,13 @@ static struct clk mmc1_ck = {
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(MOD_CONF_CTRL_0),
- .enable_bit = 23,
+ .enable_bit = CONF_MOD_MMC_SD_CLK_REQ_R,
};
+/*
+ * XXX MOD_CONF_CTRL_0 bit 20 is defined in the 1510 TRM as
+ * CONF_MOD_MCBSP3_AUXON ??
+ */
static struct clk mmc2_ck = {
.name = "mmc2_ck",
.ops = &clkops_generic,
@@ -546,7 +641,7 @@ static struct clk mmc3_ck = {
.rate = 48000000,
.flags = ENABLE_REG_32BIT | CLOCK_NO_IDLE_PARENT,
.enable_reg = OMAP1_IO_ADDRESS(SOFT_REQ_REG),
- .enable_bit = 12,
+ .enable_bit = SOFT_MMC_DPLL_REQ_SHIFT,
};
static struct clk virtual_ck_mpu = {
@@ -620,7 +715,9 @@ static struct omap_clk omap_clks[] = {
/* ULPD clocks */
CLK(NULL, "uart1_ck", &uart1_1510, CK_1510 | CK_310),
CLK(NULL, "uart1_ck", &uart1_16xx.clk, CK_16XX),
+ CLK(NULL, "uart1_ck", &uart1_7xx, CK_7XX),
CLK(NULL, "uart2_ck", &uart2_ck, CK_16XX | CK_1510 | CK_310),
+ CLK(NULL, "uart2_ck", &uart2_7xx, CK_7XX),
CLK(NULL, "uart3_ck", &uart3_1510, CK_1510 | CK_310),
CLK(NULL, "uart3_ck", &uart3_16xx.clk, CK_16XX),
CLK(NULL, "usb_clko", &usb_clko, CK_16XX | CK_1510 | CK_310),
diff --git a/arch/arm/mach-omap1/devices.c b/arch/arm/mach-omap1/devices.c
index 379100c17639..aa0725608fb1 100644
--- a/arch/arm/mach-omap1/devices.c
+++ b/arch/arm/mach-omap1/devices.c
@@ -63,44 +63,7 @@ static void omap_init_rtc(void)
static inline void omap_init_rtc(void) {}
#endif
-#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
-
-#if defined(CONFIG_ARCH_OMAP15XX)
-# define OMAP1_MBOX_SIZE 0x23
-# define INT_DSP_MAILBOX1 INT_1510_DSP_MAILBOX1
-#elif defined(CONFIG_ARCH_OMAP16XX)
-# define OMAP1_MBOX_SIZE 0x2f
-# define INT_DSP_MAILBOX1 INT_1610_DSP_MAILBOX1
-#endif
-
-#define OMAP1_MBOX_BASE OMAP16XX_MAILBOX_BASE
-
-static struct resource mbox_resources[] = {
- {
- .start = OMAP1_MBOX_BASE,
- .end = OMAP1_MBOX_BASE + OMAP1_MBOX_SIZE,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_DSP_MAILBOX1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device mbox_device = {
- .name = "omap1-mailbox",
- .id = -1,
- .num_resources = ARRAY_SIZE(mbox_resources),
- .resource = mbox_resources,
-};
-
-static inline void omap_init_mbox(void)
-{
- platform_device_register(&mbox_device);
-}
-#else
static inline void omap_init_mbox(void) { }
-#endif
/*-------------------------------------------------------------------------*/
@@ -230,42 +193,7 @@ static inline void omap_init_spi100k(void)
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_OMAP_STI)
-
-#define OMAP1_STI_BASE 0xfffea000
-#define OMAP1_STI_CHANNEL_BASE (OMAP1_STI_BASE + 0x400)
-
-static struct resource sti_resources[] = {
- {
- .start = OMAP1_STI_BASE,
- .end = OMAP1_STI_BASE + SZ_1K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP1_STI_CHANNEL_BASE,
- .end = OMAP1_STI_CHANNEL_BASE + SZ_1K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_1610_STI,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static struct platform_device sti_device = {
- .name = "sti",
- .id = -1,
- .num_resources = ARRAY_SIZE(sti_resources),
- .resource = sti_resources,
-};
-
-static inline void omap_init_sti(void)
-{
- platform_device_register(&sti_device);
-}
-#else
static inline void omap_init_sti(void) {}
-#endif
/*-------------------------------------------------------------------------*/
diff --git a/arch/arm/mach-omap1/io.c b/arch/arm/mach-omap1/io.c
index d9b8d82530ae..0ce3fec2d257 100644
--- a/arch/arm/mach-omap1/io.c
+++ b/arch/arm/mach-omap1/io.c
@@ -22,7 +22,6 @@
extern void omap_check_revision(void);
extern void omap_sram_init(void);
-extern void omapfb_reserve_sdram(void);
/*
* The machine specific code may provide the extra mapping besides the
@@ -122,7 +121,6 @@ void __init omap1_map_common_io(void)
#endif
omap_sram_init();
- omapfb_reserve_sdram();
}
/*
diff --git a/arch/arm/mach-omap1/mcbsp.c b/arch/arm/mach-omap1/mcbsp.c
index e9bdff192f82..b3a796a6da03 100644
--- a/arch/arm/mach-omap1/mcbsp.c
+++ b/arch/arm/mach-omap1/mcbsp.c
@@ -23,7 +23,6 @@
#include <plat/mux.h>
#include <plat/cpu.h>
#include <plat/mcbsp.h>
-#include <plat/dsp_common.h>
#define DPS_RSTCT2_PER_EN (1 << 0)
#define DSP_RSTCT2_WD_PER_EN (1 << 1)
@@ -46,7 +45,6 @@ static void omap1_mcbsp_request(unsigned int id)
clk_enable(api_clk);
clk_enable(dsp_clk);
- omap_dsp_request_mem();
/*
* DSP external peripheral reset
* FIXME: This should be moved to dsp code
@@ -62,7 +60,6 @@ static void omap1_mcbsp_free(unsigned int id)
{
if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3) {
if (--dsp_use == 0) {
- omap_dsp_release_mem();
if (!IS_ERR(api_clk)) {
clk_disable(api_clk);
clk_put(api_clk);
diff --git a/arch/arm/mach-omap1/mux.c b/arch/arm/mach-omap1/mux.c
index 84341377232d..7835add00344 100644
--- a/arch/arm/mach-omap1/mux.c
+++ b/arch/arm/mach-omap1/mux.c
@@ -70,6 +70,10 @@ MUX_CFG_7XX("SPI_7XX_3", 6, 13, 4, 12, 1, 0)
MUX_CFG_7XX("SPI_7XX_4", 6, 17, 4, 16, 1, 0)
MUX_CFG_7XX("SPI_7XX_5", 8, 25, 0, 24, 0, 0)
MUX_CFG_7XX("SPI_7XX_6", 9, 5, 0, 4, 0, 0)
+
+/* UART pins */
+MUX_CFG_7XX("UART_7XX_1", 3, 21, 0, 20, 0, 0)
+MUX_CFG_7XX("UART_7XX_2", 8, 1, 6, 0, 0, 0)
};
#define OMAP7XX_PINS_SZ ARRAY_SIZE(omap7xx_pins)
#else
@@ -440,7 +444,7 @@ int __init_or_module omap1_cfg_reg(const struct pin_config *cfg)
}
#endif
-#ifdef CONFIG_OMAP_MUX_ERRORS
+#ifdef CONFIG_OMAP_MUX_WARNINGS
return warn ? -ETXTBSY : 0;
#else
return 0;
diff --git a/arch/arm/mach-omap1/serial.c b/arch/arm/mach-omap1/serial.c
index 349de90194e3..b78d0749f13d 100644
--- a/arch/arm/mach-omap1/serial.c
+++ b/arch/arm/mach-omap1/serial.c
@@ -122,6 +122,13 @@ void __init omap_serial_init(void)
for (i = 0; i < ARRAY_SIZE(serial_platform_data) - 1; i++) {
+ /* Don't look at UARTs higher than 2 for omap7xx */
+ if (cpu_is_omap7xx() && i > 1) {
+ serial_platform_data[i].membase = NULL;
+ serial_platform_data[i].mapbase = 0;
+ continue;
+ }
+
/* Static mapping, never released */
serial_platform_data[i].membase =
ioremap(serial_platform_data[i].mapbase, SZ_2K);
diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c
new file mode 100644
index 000000000000..19de03b074e3
--- /dev/null
+++ b/arch/arm/mach-omap1/usb.c
@@ -0,0 +1,530 @@
+/*
+ * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+
+#include <plat/mux.h>
+#include <plat/usb.h>
+
+/* These routines should handle the standard chip-specific modes
+ * for usb0/1/2 ports, covering basic mux and transceiver setup.
+ *
+ * Some board-*.c files will need to set up additional mux options,
+ * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
+ */
+
+/* TESTED ON:
+ * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
+ * - 5912 OSK UDC, with *nonstandard* A-to-A cable
+ * - 1510 Innovator UDC with bundled usb0 cable
+ * - 1510 Innovator OHCI with bundled usb1/usb2 cable
+ * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
+ * - 1710 custom development board using alternate pin group
+ * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
+ */
+
+#define INT_USB_IRQ_GEN IH2_BASE + 20
+#define INT_USB_IRQ_NISO IH2_BASE + 30
+#define INT_USB_IRQ_ISO IH2_BASE + 29
+#define INT_USB_IRQ_HGEN INT_USB_HHC_1
+#define INT_USB_IRQ_OTG IH2_BASE + 8
+
+#ifdef CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+ /* order is significant! */
+ { /* registers */
+ .start = UDC_BASE,
+ .end = UDC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, { /* general IRQ */
+ .start = INT_USB_IRQ_GEN,
+ .flags = IORESOURCE_IRQ,
+ }, { /* PIO IRQ */
+ .start = INT_USB_IRQ_NISO,
+ .flags = IORESOURCE_IRQ,
+ }, { /* SOF IRQ */
+ .start = INT_USB_IRQ_ISO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+ .name = "omap_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+};
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+ /* IRQ numbers for omap7xx */
+ if(cpu_is_omap7xx()) {
+ udc_resources[1].start = INT_7XX_USB_GENI;
+ udc_resources[2].start = INT_7XX_USB_NON_ISO;
+ udc_resources[3].start = INT_7XX_USB_ISO;
+ }
+ pdata->udc_device = &udc_device;
+}
+
+#else
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = OMAP_OHCI_BASE,
+ .end = OMAP_OHCI_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_IRQ_HGEN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+ if (cpu_is_omap7xx())
+ ohci_resources[1].start = INT_7XX_USB_HHC_1;
+ pdata->ohci_device = &ohci_device;
+}
+
+#else
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+ /* order is significant! */
+ {
+ .start = OTG_BASE,
+ .end = OTG_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_USB_IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device otg_device = {
+ .name = "omap_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(otg_resources),
+ .resource = otg_resources,
+};
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+ if (cpu_is_omap7xx())
+ otg_resources[1].start = INT_7XX_USB_OTG;
+ pdata->otg_device = &otg_device;
+}
+
+#else
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+u32 __init omap1_usb0_init(unsigned nwires, unsigned is_device)
+{
+ u32 syscon1 = 0;
+
+ if (nwires == 0) {
+ if (!cpu_is_omap15xx()) {
+ u32 l;
+
+ /* pulldown D+/D- */
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ return 0;
+ }
+
+ if (is_device) {
+ if (cpu_is_omap7xx()) {
+ omap_cfg_reg(AA17_7XX_USB_DM);
+ omap_cfg_reg(W16_7XX_USB_PU_EN);
+ omap_cfg_reg(W17_7XX_USB_VBUSI);
+ omap_cfg_reg(W18_7XX_USB_DMCK_OUT);
+ omap_cfg_reg(W19_7XX_USB_DCRST);
+ } else
+ omap_cfg_reg(W4_USB_PUEN);
+ }
+
+ if (nwires == 2) {
+ u32 l;
+
+ // omap_cfg_reg(P9_USB_DP);
+ // omap_cfg_reg(R8_USB_DM);
+
+ if (cpu_is_omap15xx()) {
+ /* This works on 1510-Innovator */
+ return 0;
+ }
+
+ /* NOTES:
+ * - peripheral should configure VBUS detection!
+ * - only peripherals may use the internal D+/D- pulldowns
+ * - OTG support on this port not yet written
+ */
+
+ /* Don't do this for omap7xx -- it causes USB to not work correctly */
+ if (!cpu_is_omap7xx()) {
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~(7 << 4);
+ if (!is_device)
+ l |= (3 << 1);
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ return 3 << 16;
+ }
+
+ /* alternate pin config, external transceiver */
+ if (cpu_is_omap15xx()) {
+ printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
+ return 0;
+ }
+
+ omap_cfg_reg(V6_USB0_TXD);
+ omap_cfg_reg(W9_USB0_TXEN);
+ omap_cfg_reg(W5_USB0_SE0);
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB0_RCV);
+
+ /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
+ * may be able to use I2C requests to set those bits along
+ * with VBUS switching and overcurrent detection.
+ */
+
+ if (nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ {
+ u32 l;
+
+ omap_cfg_reg(AA9_USB0_VP);
+ omap_cfg_reg(R9_USB0_VM);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 0, nwires);
+ }
+
+ return syscon1 << 16;
+}
+
+u32 __init omap1_usb1_init(unsigned nwires)
+{
+ u32 syscon1 = 0;
+
+ if (!cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ if (nwires == 0)
+ return 0;
+
+ /* external transceiver */
+ omap_cfg_reg(USB1_TXD);
+ omap_cfg_reg(USB1_TXEN);
+ if (nwires != 3)
+ omap_cfg_reg(USB1_RCV);
+
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB1_SEO);
+ omap_cfg_reg(USB1_SPEED);
+ // SUSP
+ } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
+ omap_cfg_reg(W13_1610_USB1_SE0);
+ omap_cfg_reg(R13_1610_USB1_SPEED);
+ // SUSP
+ } else if (cpu_is_omap1710()) {
+ omap_cfg_reg(R13_1710_USB1_SE0);
+ // SUSP
+ } else {
+ pr_debug("usb%d cpu unrecognized\n", 1);
+ return 0;
+ }
+
+ switch (nwires) {
+ case 2:
+ goto bad;
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 6:
+ syscon1 = 3;
+ omap_cfg_reg(USB1_VP);
+ omap_cfg_reg(USB1_VM);
+ if (!cpu_is_omap15xx()) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB1_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+bad:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 1, nwires);
+ }
+
+ return syscon1 << 20;
+}
+
+u32 __init omap1_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ u32 syscon1 = 0;
+
+ /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
+ if (alt_pingroup || nwires == 0)
+ return 0;
+
+ if (!cpu_is_omap15xx() && nwires != 6) {
+ u32 l;
+
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l &= ~CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+
+ /* external transceiver */
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB2_TXD);
+ omap_cfg_reg(USB2_TXEN);
+ omap_cfg_reg(USB2_SEO);
+ if (nwires != 3)
+ omap_cfg_reg(USB2_RCV);
+ /* there is no USB2_SPEED */
+ } else if (cpu_is_omap16xx()) {
+ omap_cfg_reg(V6_USB2_TXD);
+ omap_cfg_reg(W9_USB2_TXEN);
+ omap_cfg_reg(W5_USB2_SE0);
+ if (nwires != 3)
+ omap_cfg_reg(Y5_USB2_RCV);
+ // FIXME omap_cfg_reg(USB2_SPEED);
+ } else {
+ pr_debug("usb%d cpu unrecognized\n", 1);
+ return 0;
+ }
+
+ // omap_cfg_reg(USB2_SUSP);
+
+ switch (nwires) {
+ case 2:
+ goto bad;
+ case 3:
+ syscon1 = 2;
+ break;
+ case 4:
+ syscon1 = 1;
+ break;
+ case 5:
+ goto bad;
+ case 6:
+ syscon1 = 3;
+ if (cpu_is_omap15xx()) {
+ omap_cfg_reg(USB2_VP);
+ omap_cfg_reg(USB2_VM);
+ } else {
+ u32 l;
+
+ omap_cfg_reg(AA9_USB2_VP);
+ omap_cfg_reg(R9_USB2_VM);
+ l = omap_readl(USB_TRANSCEIVER_CTRL);
+ l |= CONF_USB2_UNI_R;
+ omap_writel(l, USB_TRANSCEIVER_CTRL);
+ }
+ break;
+ default:
+bad:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 2, nwires);
+ }
+
+ return syscon1 << 24;
+}
+
+#ifdef CONFIG_ARCH_OMAP15XX
+
+/* ULPD_DPLL_CTRL */
+#define DPLL_IOB (1 << 13)
+#define DPLL_PLL_ENABLE (1 << 4)
+#define DPLL_LOCK (1 << 0)
+
+/* ULPD_APLL_CTRL */
+#define APLL_NDPLL_SWITCH (1 << 0)
+
+static void __init omap_1510_usb_init(struct omap_usb_config *config)
+{
+ unsigned int val;
+ u16 w;
+
+ config->usb0_init(config->pins[0], is_usb0_device(config));
+ config->usb1_init(config->pins[1]);
+ config->usb2_init(config->pins[2], 0);
+
+ val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
+ val |= (config->hmc_mode << 1);
+ omap_writel(val, MOD_CONF_CTRL_0);
+
+ printk("USB: hmc %d", config->hmc_mode);
+ if (config->pins[0])
+ printk(", usb0 %d wires%s", config->pins[0],
+ is_usb0_device(config) ? " (dev)" : "");
+ if (config->pins[1])
+ printk(", usb1 %d wires", config->pins[1]);
+ if (config->pins[2])
+ printk(", usb2 %d wires", config->pins[2]);
+ printk("\n");
+
+ /* use DPLL for 48 MHz function clock */
+ pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL),
+ omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ));
+
+ w = omap_readw(ULPD_APLL_CTRL);
+ w &= ~APLL_NDPLL_SWITCH;
+ omap_writew(w, ULPD_APLL_CTRL);
+
+ w = omap_readw(ULPD_DPLL_CTRL);
+ w |= DPLL_IOB | DPLL_PLL_ENABLE;
+ omap_writew(w, ULPD_DPLL_CTRL);
+
+ w = omap_readw(ULPD_SOFT_REQ);
+ w |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
+ omap_writew(w, ULPD_SOFT_REQ);
+
+ while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK))
+ cpu_relax();
+
+#ifdef CONFIG_USB_GADGET_OMAP
+ if (config->register_dev) {
+ int status;
+
+ udc_device.dev.platform_data = config;
+ status = platform_device_register(&udc_device);
+ if (status)
+ pr_debug("can't register UDC device, %d\n", status);
+ /* udc driver gates 48MHz by D+ pullup */
+ }
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ if (config->register_host) {
+ int status;
+
+ ohci_device.dev.platform_data = config;
+ status = platform_device_register(&ohci_device);
+ if (status)
+ pr_debug("can't register OHCI device, %d\n", status);
+ /* hcd explicitly gates 48MHz */
+ }
+#endif
+}
+
+#else
+static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
+#endif
+
+void __init omap1_usb_init(struct omap_usb_config *pdata)
+{
+ pdata->usb0_init = omap1_usb0_init;
+ pdata->usb1_init = omap1_usb1_init;
+ pdata->usb2_init = omap1_usb2_init;
+ udc_device_init(pdata);
+ ohci_device_init(pdata);
+ otg_device_init(pdata);
+
+ if (cpu_is_omap7xx() || cpu_is_omap16xx())
+ omap_otg_init(pdata);
+ else if (cpu_is_omap15xx())
+ omap_1510_usb_init(pdata);
+ else
+ printk(KERN_ERR "USB: No init for your chip yet\n");
+}
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index b31b6f123122..b48bacf0a7aa 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -1,22 +1,77 @@
+if ARCH_OMAP2PLUS
+
+menu "TI OMAP2/3/4 Specific Features"
+
+config ARCH_OMAP2PLUS_TYPICAL
+ bool "Typical OMAP configuration"
+ default y
+ select AEABI
+ select REGULATOR
+ select PM
+ select PM_RUNTIME
+ select VFP
+ select NEON if ARCH_OMAP3 || ARCH_OMAP4
+ select SERIAL_8250
+ select SERIAL_CORE_CONSOLE
+ select SERIAL_8250_CONSOLE
+ select I2C
+ select I2C_OMAP
+ select MFD
+ select MENELAUS if ARCH_OMAP2
+ select TWL4030_CORE if ARCH_OMAP3 || ARCH_OMAP4
+ select TWL4030_POWER if ARCH_OMAP3 || ARCH_OMAP4
+ help
+ Compile a kernel suitable for booting most boards
+
+config ARCH_OMAP2
+ bool "TI OMAP2"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V6
+
+config ARCH_OMAP3
+ bool "TI OMAP3"
+ depends on ARCH_OMAP2PLUS
+ default y
+ select CPU_V7
+ select USB_ARCH_HAS_EHCI
+ select ARM_L1_CACHE_SHIFT_6
+
+config ARCH_OMAP4
+ bool "TI OMAP4"
+ default y
+ depends on ARCH_OMAP2PLUS
+ select CPU_V7
+ select ARM_GIC
+
comment "OMAP Core Type"
depends on ARCH_OMAP2
config ARCH_OMAP2420
bool "OMAP2420 support"
depends on ARCH_OMAP2
+ default y
select OMAP_DM_TIMER
select ARCH_OMAP_OTG
config ARCH_OMAP2430
bool "OMAP2430 support"
depends on ARCH_OMAP2
+ default y
select ARCH_OMAP_OTG
config ARCH_OMAP3430
bool "OMAP3430 support"
depends on ARCH_OMAP3
+ default y
select ARCH_OMAP_OTG
+config OMAP_PACKAGE_ZAF
+ bool
+
+config OMAP_PACKAGE_ZAC
+ bool
+
config OMAP_PACKAGE_CBC
bool
@@ -35,6 +90,7 @@ comment "OMAP Board Type"
config MACH_OMAP_GENERIC
bool "Generic OMAP board"
depends on ARCH_OMAP2
+ default y
config MACH_OMAP2_TUSB6010
bool
@@ -44,60 +100,75 @@ config MACH_OMAP2_TUSB6010
config MACH_OMAP_H4
bool "OMAP 2420 H4 board"
depends on ARCH_OMAP2
+ default y
+ select OMAP_PACKAGE_ZAF
select OMAP_DEBUG_DEVICES
config MACH_OMAP_APOLLON
bool "OMAP 2420 Apollon board"
depends on ARCH_OMAP2
+ default y
+ select OMAP_PACKAGE_ZAC
config MACH_OMAP_2430SDP
bool "OMAP 2430 SDP board"
depends on ARCH_OMAP2
+ default y
+ select OMAP_PACKAGE_ZAC
config MACH_OMAP3_BEAGLE
bool "OMAP3 BEAGLE board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_DEVKIT8000
bool "DEVKIT8000 board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CUS
select OMAP_MUX
config MACH_OMAP_LDP
bool "OMAP3 LDP board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OVERO
bool "Gumstix Overo board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP3EVM
bool "OMAP 3530 EVM board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP3517EVM
bool "OMAP3517/ AM3517 EVM board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP3_PANDORA
bool "OMAP3 Pandora"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP3_TOUCHBOOK
bool "OMAP3 Touch Book"
depends on ARCH_OMAP3
+ default y
select BACKLIGHT_CLASS_DEVICE
config MACH_OMAP_3430SDP
bool "OMAP 3430 SDP board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_NOKIA_N800
@@ -112,6 +183,8 @@ config MACH_NOKIA_N810_WIMAX
config MACH_NOKIA_N8X0
bool "Nokia N800/N810"
depends on ARCH_OMAP2420
+ default y
+ select OMAP_PACKAGE_ZAC
select MACH_NOKIA_N800
select MACH_NOKIA_N810
select MACH_NOKIA_N810_WIMAX
@@ -119,42 +192,55 @@ config MACH_NOKIA_N8X0
config MACH_NOKIA_RX51
bool "Nokia RX-51 board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP_ZOOM2
bool "OMAP3 Zoom2 board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_OMAP_ZOOM3
bool "OMAP3630 Zoom3 board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBP
config MACH_CM_T35
bool "CompuLab CM-T35 module"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CUS
select OMAP_MUX
config MACH_IGEP0020
bool "IGEP v2 board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBB
config MACH_SBC3530
bool "OMAP3 SBC STALKER board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CUS
select OMAP_MUX
config MACH_OMAP_3630SDP
bool "OMAP3630 SDP board"
depends on ARCH_OMAP3
+ default y
select OMAP_PACKAGE_CBP
config MACH_OMAP_4430SDP
bool "OMAP 4430 SDP board"
+ default y
+ depends on ARCH_OMAP4
+
+config MACH_OMAP4_PANDA
+ bool "OMAP4 Panda Board"
+ default y
depends on ARCH_OMAP4
config OMAP3_EMU
@@ -176,3 +262,6 @@ config OMAP3_SDRC_AC_TIMING
wish to say no. Selecting yes without understanding what is
going on could result in system crashes;
+endmenu
+
+endif
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index ea52b034e963..2c2b46997346 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o
+obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer-gp.o pm.o
omap-2-3-common = irq.o sdrc.o
hwmod-common = omap_hwmod.o \
@@ -15,13 +15,14 @@ clock-common = clock.o clock_common_data.o \
obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(prcm-common) $(hwmod-common)
-obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common)
+obj-$(CONFIG_ARCH_OMAP4) += $(prcm-common) $(hwmod-common)
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
# SMP support ONLY available for OMAP4
obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
+obj-$(CONFIG_HOTPLUG_CPU) += omap-hotplug.o
obj-$(CONFIG_ARCH_OMAP4) += omap44xx-smc.o omap4-common.o
AFLAGS_omap44xx-smc.o :=-Wa,-march=armv7-a
@@ -36,6 +37,8 @@ AFLAGS_sram243x.o :=-Wa,-march=armv6
AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
# Pin multiplexing
+obj-$(CONFIG_ARCH_OMAP2420) += mux2420.o
+obj-$(CONFIG_ARCH_OMAP2430) += mux2430.o
obj-$(CONFIG_ARCH_OMAP3) += mux34xx.o
# SMS/SDRC
@@ -47,6 +50,7 @@ ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
AFLAGS_sleep24xx.o :=-Wa,-march=armv6
@@ -89,7 +93,10 @@ obj-$(CONFIG_OMAP3_EMU) += emu.o
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
-obj-$(CONFIG_OMAP_IOMMU) := iommu2.o omap-iommu.o
+obj-$(CONFIG_OMAP_IOMMU) += iommu2.o
+
+iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o
+obj-y += $(iommu-m) $(iommu-y)
i2c-omap-$(CONFIG_I2C_OMAP) := i2c.o
obj-y += $(i2c-omap-m) $(i2c-omap-y)
@@ -140,12 +147,16 @@ obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \
hsmmc.o
obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \
hsmmc.o
+obj-$(CONFIG_MACH_OMAP4_PANDA) += board-omap4panda.o \
+ hsmmc.o
obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o \
hsmmc.o
# Platform specific device init code
+usbfs-$(CONFIG_ARCH_OMAP_OTG) := usb-fs.o
+obj-y += $(usbfs-m) $(usbfs-y)
obj-y += usb-musb.o
obj-$(CONFIG_MACH_OMAP2_TUSB6010) += usb-tusb6010.o
obj-y += usb-ehci.o
diff --git a/arch/arm/mach-omap2/board-2430sdp.c b/arch/arm/mach-omap2/board-2430sdp.c
index a11a575745e4..8538e4131d27 100644
--- a/arch/arm/mach-omap2/board-2430sdp.c
+++ b/arch/arm/mach-omap2/board-2430sdp.c
@@ -31,13 +31,13 @@
#include <asm/mach/map.h>
#include <mach/gpio.h>
-#include <plat/mux.h>
#include <plat/board.h>
#include <plat/common.h>
#include <plat/gpmc.h>
#include <plat/usb.h>
#include <plat/gpmc-smc91x.h>
+#include "mux.h"
#include "hsmmc.h"
#define SDP2430_CS0_BASE 0x04000000
@@ -122,11 +122,7 @@ static struct omap_smc91x_platform_data board_smc91x_data = {
static void __init board_smc91x_init(void)
{
- if (omap_rev() > OMAP3430_REV_ES1_0)
- board_smc91x_data.gpio_irq = 6;
- else
- board_smc91x_data.gpio_irq = 29;
-
+ omap_mux_init_gpio(149, OMAP_PIN_INPUT);
gpmc_smc91x_init(&board_smc91x_data);
}
@@ -217,17 +213,30 @@ static struct omap_usb_config sdp2430_usb_config __initdata = {
.pins[0] = 3,
};
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init omap_2430sdp_init(void)
{
int ret;
+ omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+
omap2430_i2c_init();
platform_add_devices(sdp2430_devices, ARRAY_SIZE(sdp2430_devices));
omap_serial_init();
omap2_hsmmc_init(mmc);
- omap_usb_init(&sdp2430_usb_config);
+ omap2_usbfs_init(&sdp2430_usb_config);
+
+ omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
usb_musb_init(&musb_board_data);
+
board_smc91x_init();
/* Turn off secondary LCD backlight */
@@ -248,6 +257,7 @@ MACHINE_START(OMAP_2430SDP, "OMAP2430 sdp2430 board")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_2430sdp_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_2430sdp_init_irq,
.init_machine = omap_2430sdp_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
index f474a80b8867..ecdd2c3ea693 100644
--- a/arch/arm/mach-omap2/board-3430sdp.c
+++ b/arch/arm/mach-omap2/board-3430sdp.c
@@ -803,18 +803,13 @@ static void __init omap_3430sdp_init(void)
usb_ehci_init(&ehci_pdata);
}
-static void __init omap_3430sdp_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP_3430SDP, "OMAP3430 3430SDP board")
/* Maintainer: Syed Khasim - Texas Instruments Inc */
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap_3430sdp_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_3430sdp_init_irq,
.init_machine = omap_3430sdp_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-3630sdp.c b/arch/arm/mach-omap2/board-3630sdp.c
index 504d2bd222fe..b9da1f44fe85 100644
--- a/arch/arm/mach-omap2/board-3630sdp.c
+++ b/arch/arm/mach-omap2/board-3630sdp.c
@@ -18,7 +18,6 @@
#include <plat/common.h>
#include <plat/board.h>
#include <plat/gpmc-smc91x.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#include <mach/board-zoom.h>
@@ -66,12 +65,6 @@ static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
.reset_gpio_port[2] = -EINVAL
};
-static void __init omap_sdp_map_io(void)
-{
- omap2_set_globals_36xx();
- omap34xx_map_common_io();
-}
-
static struct omap_board_config_kernel sdp_config[] __initdata = {
};
@@ -107,7 +100,8 @@ MACHINE_START(OMAP_3630SDP, "OMAP 3630SDP board")
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap_sdp_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_sdp_init_irq,
.init_machine = omap_sdp_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index e4a5d66b83b8..9447644774c2 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -21,6 +21,7 @@
#include <linux/spi/spi.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
+#include <linux/leds.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
@@ -40,6 +41,54 @@
#define ETH_KS8851_POWER_ON 48
#define ETH_KS8851_QUART 138
+static struct gpio_led sdp4430_gpio_leds[] = {
+ {
+ .name = "omap4:green:debug0",
+ .gpio = 61,
+ },
+ {
+ .name = "omap4:green:debug1",
+ .gpio = 30,
+ },
+ {
+ .name = "omap4:green:debug2",
+ .gpio = 7,
+ },
+ {
+ .name = "omap4:green:debug3",
+ .gpio = 8,
+ },
+ {
+ .name = "omap4:green:debug4",
+ .gpio = 50,
+ },
+ {
+ .name = "omap4:blue:user",
+ .gpio = 169,
+ },
+ {
+ .name = "omap4:red:user",
+ .gpio = 170,
+ },
+ {
+ .name = "omap4:green:user",
+ .gpio = 139,
+ },
+
+};
+
+static struct gpio_led_platform_data sdp4430_led_data = {
+ .leds = sdp4430_gpio_leds,
+ .num_leds = ARRAY_SIZE(sdp4430_gpio_leds),
+};
+
+static struct platform_device sdp4430_leds_gpio = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &sdp4430_led_data,
+ },
+};
static struct spi_board_info sdp4430_spi_board_info[] __initdata = {
{
.modalias = "ks8851",
@@ -112,6 +161,7 @@ static struct platform_device sdp4430_lcd_device = {
static struct platform_device *sdp4430_devices[] __initdata = {
&sdp4430_lcd_device,
+ &sdp4430_leds_gpio,
};
static struct omap_lcd_config sdp4430_lcd_config __initdata = {
@@ -156,14 +206,16 @@ static struct omap2_hsmmc_info mmc[] = {
{} /* Terminator */
};
-static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
+static struct regulator_consumer_supply sdp4430_vaux_supply[] = {
{
.supply = "vmmc",
- .dev_name = "mmci-omap-hs.0",
+ .dev_name = "mmci-omap-hs.1",
},
+};
+static struct regulator_consumer_supply sdp4430_vmmc_supply[] = {
{
.supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
+ .dev_name = "mmci-omap-hs.0",
},
};
@@ -210,6 +262,8 @@ static struct regulator_init_data sdp4430_vaux1 = {
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
+ .num_consumer_supplies = 1,
+ .consumer_supplies = sdp4430_vaux_supply,
};
static struct regulator_init_data sdp4430_vaux2 = {
@@ -250,7 +304,7 @@ static struct regulator_init_data sdp4430_vmmc = {
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = 2,
+ .num_consumer_supplies = 1,
.consumer_supplies = sdp4430_vmmc_supply,
};
@@ -353,6 +407,11 @@ static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = {
.platform_data = &sdp4430_twldata,
},
};
+static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("tmp105", 0x48),
+ },
+};
static int __init omap4_i2c_init(void)
{
/*
@@ -362,7 +421,8 @@ static int __init omap4_i2c_init(void)
omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo,
ARRAY_SIZE(sdp4430_i2c_boardinfo));
omap_register_i2c_bus(2, 400, NULL, 0);
- omap_register_i2c_bus(3, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
+ ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
omap_register_i2c_bus(4, 400, NULL, 0);
return 0;
}
@@ -402,6 +462,7 @@ MACHINE_START(OMAP_4430SDP, "OMAP4430 4430SDP board")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_4430sdp_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_4430sdp_init_irq,
.init_machine = omap_4430sdp_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
index af383a876943..4d0f58592864 100644
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ b/arch/arm/mach-omap2/board-am3517evm.c
@@ -461,17 +461,12 @@ static void __init am3517_evm_init(void)
am3517_evm_ethernet_init(&am3517_evm_emac_pdata);
}
-static void __init am3517_evm_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = am3517_evm_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = am3517_evm_init_irq,
.init_machine = am3517_evm_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-apollon.c b/arch/arm/mach-omap2/board-apollon.c
index aa69fb999748..c6421a72514a 100644
--- a/arch/arm/mach-omap2/board-apollon.c
+++ b/arch/arm/mach-omap2/board-apollon.c
@@ -35,13 +35,14 @@
#include <mach/gpio.h>
#include <plat/led.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
#include <plat/gpmc.h>
#include <plat/control.h>
+#include "mux.h"
+
/* LED & Switch macros */
#define LED0_GPIO13 13
#define LED1_GPIO14 14
@@ -244,7 +245,7 @@ static inline void __init apollon_init_smc91x(void)
apollon_smc91x_resources[0].end = base + 0x30f;
udelay(100);
- omap_cfg_reg(W4__24XX_GPIO74);
+ omap_mux_init_gpio(74, 0);
if (gpio_request(APOLLON_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
APOLLON_ETHR_GPIO_IRQ);
@@ -286,15 +287,15 @@ static void __init omap_apollon_init_irq(void)
static void __init apollon_led_init(void)
{
/* LED0 - AA10 */
- omap_cfg_reg(AA10_242X_GPIO13);
+ omap_mux_init_signal("vlynq_clk.gpio_13", 0);
gpio_request(LED0_GPIO13, "LED0");
gpio_direction_output(LED0_GPIO13, 0);
/* LED1 - AA6 */
- omap_cfg_reg(AA6_242X_GPIO14);
+ omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
gpio_request(LED1_GPIO14, "LED1");
gpio_direction_output(LED1_GPIO14, 0);
/* LED2 - AA4 */
- omap_cfg_reg(AA4_242X_GPIO15);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
gpio_request(LED2_GPIO15, "LED2");
gpio_direction_output(LED2_GPIO15, 0);
}
@@ -303,22 +304,35 @@ static void __init apollon_usb_init(void)
{
/* USB device */
/* DEVICE_SUSPEND */
- omap_cfg_reg(P21_242X_GPIO12);
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
gpio_request(12, "USB suspend");
gpio_direction_output(12, 0);
- omap_usb_init(&apollon_usb_config);
+ omap2_usbfs_init(&apollon_usb_config);
}
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init omap_apollon_init(void)
{
u32 v;
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
+
apollon_led_init();
apollon_flash_init();
apollon_usb_init();
/* REVISIT: where's the correct place */
- omap_cfg_reg(W19_24XX_SYS_NIRQ);
+ omap_mux_init_signal("sys_nirq", OMAP_PULL_ENA | OMAP_PULL_UP);
+
+ /* LCD PWR_EN */
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
/* Use Interal loop-back in MMC/SDIO Module Input Clock selection */
v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
@@ -346,6 +360,7 @@ MACHINE_START(OMAP_APOLLON, "OMAP24xx Apollon")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_apollon_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_apollon_init_irq,
.init_machine = omap_apollon_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-cm-t35.c b/arch/arm/mach-omap2/board-cm-t35.c
index e679a2cc86c3..b910f72f43cc 100644
--- a/arch/arm/mach-omap2/board-cm-t35.c
+++ b/arch/arm/mach-omap2/board-cm-t35.c
@@ -708,12 +708,6 @@ static void __init cm_t35_init_irq(void)
omap_gpio_init();
}
-static void __init cm_t35_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
static struct omap_board_mux board_mux[] __initdata = {
/* nCS and IRQ for CM-T35 ethernet */
OMAP3_MUX(GPMC_NCS5, OMAP_MUX_MODE0),
@@ -836,7 +830,8 @@ MACHINE_START(CM_T35, "Compulab CM-T35")
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = cm_t35_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = cm_t35_init_irq,
.init_machine = cm_t35_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c
index 77022b588816..45f79fdb3efb 100644
--- a/arch/arm/mach-omap2/board-devkit8000.c
+++ b/arch/arm/mach-omap2/board-devkit8000.c
@@ -33,6 +33,7 @@
#include <linux/i2c/twl.h>
#include <mach/hardware.h>
+#include <mach/id.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -126,54 +127,50 @@ static struct omap2_hsmmc_info mmc[] = {
},
{} /* Terminator */
};
-static struct omap_board_config_kernel devkit8000_config[] __initdata = {
-};
static int devkit8000_panel_enable_lcd(struct omap_dss_device *dssdev)
{
twl_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80, REG_GPIODATADIR1);
twl_i2c_write_u8(TWL4030_MODULE_LED, 0x0, 0x0);
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 1);
return 0;
}
static void devkit8000_panel_disable_lcd(struct omap_dss_device *dssdev)
{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 0);
}
+
static int devkit8000_panel_enable_dvi(struct omap_dss_device *dssdev)
{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 1);
return 0;
}
static void devkit8000_panel_disable_dvi(struct omap_dss_device *dssdev)
{
+ if (gpio_is_valid(dssdev->reset_gpio))
+ gpio_set_value(dssdev->reset_gpio, 0);
}
-static int devkit8000_panel_enable_tv(struct omap_dss_device *dssdev)
-{
-
- return 0;
-}
-
-static void devkit8000_panel_disable_tv(struct omap_dss_device *dssdev)
-{
-}
-
+static struct regulator_consumer_supply devkit8000_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0");
-static struct regulator_consumer_supply devkit8000_vmmc1_supply = {
- .supply = "vmmc",
-};
-
-static struct regulator_consumer_supply devkit8000_vsim_supply = {
- .supply = "vmmc_aux",
-};
+/* ads7846 on SPI */
+static struct regulator_consumer_supply devkit8000_vio_supply =
+ REGULATOR_SUPPLY("vcc", "spi2.0");
static struct omap_dss_device devkit8000_lcd_device = {
.name = "lcd",
- .driver_name = "innolux_at_panel",
+ .driver_name = "generic_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
+ .reset_gpio = -EINVAL, /* will be replaced */
.platform_enable = devkit8000_panel_enable_lcd,
.platform_disable = devkit8000_panel_disable_lcd,
};
@@ -182,6 +179,7 @@ static struct omap_dss_device devkit8000_dvi_device = {
.driver_name = "generic_panel",
.type = OMAP_DISPLAY_TYPE_DPI,
.phy.dpi.data_lines = 24,
+ .reset_gpio = -EINVAL, /* will be replaced */
.platform_enable = devkit8000_panel_enable_dvi,
.platform_disable = devkit8000_panel_disable_dvi,
};
@@ -191,8 +189,6 @@ static struct omap_dss_device devkit8000_tv_device = {
.driver_name = "venc",
.type = OMAP_DISPLAY_TYPE_VENC,
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .platform_enable = devkit8000_panel_enable_tv,
- .platform_disable = devkit8000_panel_disable_tv,
};
@@ -216,10 +212,8 @@ static struct platform_device devkit8000_dss_device = {
},
};
-static struct regulator_consumer_supply devkit8000_vdda_dac_supply = {
- .supply = "vdda_dac",
- .dev = &devkit8000_dss_device.dev,
-};
+static struct regulator_consumer_supply devkit8000_vdda_dac_supply =
+ REGULATOR_SUPPLY("vdda_dac", "omapdss");
static int board_keymap[] = {
KEY(0, 0, KEY_1),
@@ -266,7 +260,21 @@ static int devkit8000_twl_gpio_setup(struct device *dev,
/* link regulators to MMC adapters */
devkit8000_vmmc1_supply.dev = mmc[0].dev;
- devkit8000_vsim_supply.dev = mmc[0].dev;
+
+ /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+ gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
+ /* gpio + 1 is "LCD_PWREN" (out, active high) */
+ devkit8000_lcd_device.reset_gpio = gpio + 1;
+ gpio_request(devkit8000_lcd_device.reset_gpio, "LCD_PWREN");
+ /* Disable until needed */
+ gpio_direction_output(devkit8000_lcd_device.reset_gpio, 0);
+
+ /* gpio + 7 is "DVI_PD" (out, active low) */
+ devkit8000_dvi_device.reset_gpio = gpio + 7;
+ gpio_request(devkit8000_dvi_device.reset_gpio, "DVI PowerDown");
+ /* Disable until needed */
+ gpio_direction_output(devkit8000_dvi_device.reset_gpio, 0);
return 0;
}
@@ -282,16 +290,8 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = {
.setup = devkit8000_twl_gpio_setup,
};
-static struct regulator_consumer_supply devkit8000_vpll2_supplies[] = {
- {
- .supply = "vdvi",
- .dev = &devkit8000_lcd_device.dev,
- },
- {
- .supply = "vdds_dsi",
- .dev = &devkit8000_dss_device.dev,
- }
-};
+static struct regulator_consumer_supply devkit8000_vpll1_supply =
+ REGULATOR_SUPPLY("vdds_dsi", "omapdss");
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
static struct regulator_init_data devkit8000_vmmc1 = {
@@ -308,21 +308,6 @@ static struct regulator_init_data devkit8000_vmmc1 = {
.consumer_supplies = &devkit8000_vmmc1_supply,
};
-/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
-static struct regulator_init_data devkit8000_vsim = {
- .constraints = {
- .min_uV = 1800000,
- .max_uV = 3000000,
- .valid_modes_mask = REGULATOR_MODE_NORMAL
- | REGULATOR_MODE_STANDBY,
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
- | REGULATOR_CHANGE_MODE
- | REGULATOR_CHANGE_STATUS,
- },
- .num_consumer_supplies = 1,
- .consumer_supplies = &devkit8000_vsim_supply,
-};
-
/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
static struct regulator_init_data devkit8000_vdac = {
.constraints = {
@@ -337,10 +322,9 @@ static struct regulator_init_data devkit8000_vdac = {
.consumer_supplies = &devkit8000_vdda_dac_supply,
};
-/* VPLL2 for digital video outputs */
-static struct regulator_init_data devkit8000_vpll2 = {
+/* VPLL1 for digital video outputs */
+static struct regulator_init_data devkit8000_vpll1 = {
.constraints = {
- .name = "VDVI",
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
@@ -348,8 +332,23 @@ static struct regulator_init_data devkit8000_vpll2 = {
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
- .num_consumer_supplies = ARRAY_SIZE(devkit8000_vpll2_supplies),
- .consumer_supplies = devkit8000_vpll2_supplies,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &devkit8000_vpll1_supply,
+};
+
+/* VAUX4 for ads7846 and nubs */
+static struct regulator_init_data devkit8000_vio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &devkit8000_vio_supply,
};
static struct twl4030_usb_data devkit8000_usb_data = {
@@ -374,15 +373,15 @@ static struct twl4030_platform_data devkit8000_twldata = {
.gpio = &devkit8000_gpio_data,
.codec = &devkit8000_codec_data,
.vmmc1 = &devkit8000_vmmc1,
- .vsim = &devkit8000_vsim,
.vdac = &devkit8000_vdac,
- .vpll2 = &devkit8000_vpll2,
+ .vpll1 = &devkit8000_vpll1,
+ .vio = &devkit8000_vio,
.keypad = &devkit8000_kp_data,
};
static struct i2c_board_info __initdata devkit8000_i2c_boardinfo[] = {
{
- I2C_BOARD_INFO("twl4030", 0x48),
+ I2C_BOARD_INFO("tps65930", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = INT_34XX_SYS_NIRQ,
.platform_data = &devkit8000_twldata,
@@ -464,8 +463,6 @@ static struct platform_device keys_gpio = {
static void __init devkit8000_init_irq(void)
{
- omap_board_config = devkit8000_config;
- omap_board_config_size = ARRAY_SIZE(devkit8000_config);
omap2_init_common_hw(mt46h32m32lf6_sdrc_params,
mt46h32m32lf6_sdrc_params);
omap_init_irq();
@@ -560,6 +557,9 @@ static struct platform_device omap_dm9000_dev = {
static void __init omap_dm9000_init(void)
{
+ unsigned char *eth_addr = omap_dm9000_platdata.dev_addr;
+ struct omap_die_id odi;
+
if (gpio_request(OMAP_DM9000_GPIO_IRQ, "dm9000 irq") < 0) {
printk(KERN_ERR "Failed to request GPIO%d for dm9000 IRQ\n",
OMAP_DM9000_GPIO_IRQ);
@@ -567,6 +567,16 @@ static void __init omap_dm9000_init(void)
}
gpio_direction_input(OMAP_DM9000_GPIO_IRQ);
+
+ /* init the mac address using DIE id */
+ omap_get_die_id(&odi);
+
+ eth_addr[0] = 0x02; /* locally administered */
+ eth_addr[1] = odi.id_1 & 0xff;
+ eth_addr[2] = (odi.id_0 & 0xff000000) >> 24;
+ eth_addr[3] = (odi.id_0 & 0x00ff0000) >> 16;
+ eth_addr[4] = (odi.id_0 & 0x0000ff00) >> 8;
+ eth_addr[5] = (odi.id_0 & 0x000000ff);
}
static struct platform_device *devkit8000_devices[] __initdata = {
@@ -797,8 +807,6 @@ static void __init devkit8000_init(void)
devkit8000_i2c_init();
platform_add_devices(devkit8000_devices,
ARRAY_SIZE(devkit8000_devices));
- omap_board_config = devkit8000_config;
- omap_board_config_size = ARRAY_SIZE(devkit8000_config);
spi_register_board_info(devkit8000_spi_board_info,
ARRAY_SIZE(devkit8000_spi_board_info));
@@ -814,17 +822,12 @@ static void __init devkit8000_init(void)
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
-static void __init devkit8000_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(DEVKIT8000, "OMAP3 Devkit8000")
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = devkit8000_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = devkit8000_init_irq,
.init_machine = devkit8000_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 16cc06860670..3482b99e8c86 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -26,7 +26,6 @@
#include <asm/mach/map.h>
#include <mach/gpio.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
@@ -59,6 +58,7 @@ MACHINE_START(OMAP_GENERIC, "Generic OMAP24xx")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_generic_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_generic_init_irq,
.init_machine = omap_generic_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c
index 0665f2c8dc8e..e09bd686389f 100644
--- a/arch/arm/mach-omap2/board-h4.c
+++ b/arch/arm/mach-omap2/board-h4.c
@@ -33,7 +33,6 @@
#include <plat/control.h>
#include <mach/gpio.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
#include <plat/common.h>
@@ -42,6 +41,8 @@
#include <plat/dma.h>
#include <plat/gpmc.h>
+#include "mux.h"
+
#define H4_FLASH_CS 0
#define H4_SMC91X_CS 1
@@ -246,7 +247,7 @@ static inline void __init h4_init_debug(void)
udelay(100);
- omap_cfg_reg(M15_24XX_GPIO92);
+ omap_mux_init_gpio(92, 0);
if (debug_card_init(cs_mem_base, H4_ETHR_GPIO_IRQ) < 0)
gpmc_cs_free(eth_cs);
@@ -272,27 +273,6 @@ static struct omap_lcd_config h4_lcd_config __initdata = {
};
static struct omap_usb_config h4_usb_config __initdata = {
-#ifdef CONFIG_MACH_OMAP2_H4_USB1
- /* NOTE: usb1 could also be used with 3 wire signaling */
- .pins[1] = 4,
-#endif
-
-#ifdef CONFIG_MACH_OMAP_H4_OTG
- /* S1.10 ON -- USB OTG port
- * usb0 switched to Mini-AB port and isp1301 transceiver;
- * S2.POS3 = OFF, S2.POS4 = ON ... to allow battery charging
- */
- .otg = 1,
- .pins[0] = 4,
-#ifdef CONFIG_USB_GADGET_OMAP
- /* use OTG cable, or standard A-to-MiniB */
- .hmc_mode = 0x14, /* 0:dev/otg 1:host 2:disable */
-#elif defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
- /* use OTG cable, or NONSTANDARD (B-to-MiniB) */
- .hmc_mode = 0x11, /* 0:host 1:host 2:disable */
-#endif /* XX */
-
-#else
/* S1.10 OFF -- usb "download port"
* usb0 switched to Mini-B port and isp1105 transceiver;
* S2.POS3 = ON, S2.POS4 = OFF ... to enable battery charging
@@ -301,7 +281,6 @@ static struct omap_usb_config h4_usb_config __initdata = {
.pins[0] = 3,
/* .hmc_mode = 0x14,*/ /* 0:dev 1:host 2:disable */
.hmc_mode = 0x00, /* 0:dev|otg 1:disable 2:disable */
-#endif
};
static struct omap_board_config_kernel h4_config[] = {
@@ -338,31 +317,54 @@ static struct i2c_board_info __initdata h4_i2c_board_info[] = {
},
};
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init omap_h4_init(void)
{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAF);
+
/*
* Make sure the serial ports are muxed on at this point.
* You have to mux them off in device drivers later on
* if not needed.
*/
-#if defined(CONFIG_OMAP_IR) || defined(CONFIG_OMAP_IR_MODULE)
- omap_cfg_reg(K15_24XX_UART3_TX);
- omap_cfg_reg(K14_24XX_UART3_RX);
-#endif
#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
+ omap_mux_init_gpio(88, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(89, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_gpio(124, OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("mcbsp2_dr.gpio_11", OMAP_PULL_ENA | OMAP_PULL_UP);
if (omap_has_menelaus()) {
+ omap_mux_init_signal("sdrc_a14.gpio0",
+ OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
+ omap_mux_init_signal("gpio_98", 0);
row_gpios[5] = 0;
col_gpios[2] = 15;
col_gpios[6] = 18;
+ } else {
+ omap_mux_init_signal("gpio_96", OMAP_PULL_ENA | OMAP_PULL_UP);
+ omap_mux_init_signal("gpio_100", 0);
+ omap_mux_init_signal("gpio_98", 0);
}
+ omap_mux_init_signal("gpio_90", 0);
+ omap_mux_init_signal("gpio_91", 0);
+ omap_mux_init_signal("gpio_36", 0);
+ omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
+ omap_mux_init_signal("gpio_97", 0);
#endif
i2c_register_board_info(1, h4_i2c_board_info,
ARRAY_SIZE(h4_i2c_board_info));
platform_add_devices(h4_devices, ARRAY_SIZE(h4_devices));
- omap_usb_init(&h4_usb_config);
+ omap2_usbfs_init(&h4_usb_config);
omap_serial_init();
}
@@ -378,6 +380,7 @@ MACHINE_START(OMAP_H4, "OMAP2420 H4 board")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = omap_h4_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_h4_init_irq,
.init_machine = omap_h4_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-igep0020.c b/arch/arm/mach-omap2/board-igep0020.c
index d55c57b761a9..175f04339761 100644
--- a/arch/arm/mach-omap2/board-igep0020.c
+++ b/arch/arm/mach-omap2/board-igep0020.c
@@ -532,17 +532,12 @@ static void __init igep2_init(void)
pr_warning("IGEP v2: Could not obtain gpio GPIO_WIFI_NRESET\n");
}
-static void __init igep2_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(IGEP0020, "IGEP v2 board")
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = igep2_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = igep2_init_irq,
.init_machine = igep2_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index fefd7e6e9779..07e1f731ffc7 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -406,17 +406,12 @@ static void __init omap_ldp_init(void)
ldp_vmmc1_supply.dev = mmc[0].dev;
}
-static void __init omap_ldp_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP_LDP, "OMAP LDP board")
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap_ldp_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_ldp_init_irq,
.init_machine = omap_ldp_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 3ccc34ebdcc7..a3e2b49aa39f 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -33,6 +33,8 @@
#include <plat/mmc.h>
#include <plat/serial.h>
+#include "mux.h"
+
static int slot1_cover_open;
static int slot2_cover_open;
static struct device *mmc_device;
@@ -649,8 +651,17 @@ static void __init n8x0_init_irq(void)
omap_gpio_init();
}
+#ifdef CONFIG_OMAP_MUX
+static struct omap_board_mux board_mux[] __initdata = {
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define board_mux NULL
+#endif
+
static void __init n8x0_init_machine(void)
{
+ omap2420_mux_init(board_mux, OMAP_PACKAGE_ZAC);
/* FIXME: add n810 spi devices */
spi_register_board_info(n800_spi_board_info,
ARRAY_SIZE(n800_spi_board_info));
@@ -667,6 +678,7 @@ MACHINE_START(NOKIA_N800, "Nokia N800")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
+ .reserve = omap_reserve,
.init_irq = n8x0_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap_timer,
@@ -677,6 +689,7 @@ MACHINE_START(NOKIA_N810, "Nokia N810")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
+ .reserve = omap_reserve,
.init_irq = n8x0_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap_timer,
@@ -687,6 +700,7 @@ MACHINE_START(NOKIA_N810_WIMAX, "Nokia N810 WiMAX")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = n8x0_map_io,
+ .reserve = omap_reserve,
.init_irq = n8x0_init_irq,
.init_machine = n8x0_init_machine,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index 69b154cdc75d..6a6d2d7a04c6 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -507,18 +507,13 @@ static void __init omap3_beagle_init(void)
beagle_display_init();
}
-static void __init omap3_beagle_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP3_BEAGLE, "OMAP3 Beagle Board")
/* Maintainer: Syed Mohammed Khasim - http://beagleboard.org */
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap3_beagle_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap3_beagle_init_irq,
.init_machine = omap3_beagle_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index b95261013812..6494dbdfc391 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -715,18 +715,13 @@ static void __init omap3_evm_init(void)
omap3_evm_display_init();
}
-static void __init omap3_evm_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP3EVM, "OMAP3 EVM")
/* Maintainer: Syed Mohammed Khasim - Texas Instruments */
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap3_evm_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap3_evm_init_irq,
.init_machine = omap3_evm_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index db06dc910ba7..55836fa35060 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -25,6 +25,9 @@
#include <linux/spi/ads7846.h>
#include <linux/regulator/machine.h>
#include <linux/i2c/twl.h>
+#include <linux/spi/wl12xx.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/nand.h>
#include <linux/leds.h>
#include <linux/input.h>
#include <linux/input/matrix_keypad.h>
@@ -41,15 +44,49 @@
#include <plat/mcspi.h>
#include <plat/usb.h>
#include <plat/display.h>
+#include <plat/nand.h>
#include "mux.h"
#include "sdram-micron-mt46h32m32lf-6.h"
#include "hsmmc.h"
+#define PANDORA_WIFI_IRQ_GPIO 21
+#define PANDORA_WIFI_NRESET_GPIO 23
#define OMAP3_PANDORA_TS_GPIO 94
-/* hardware debounce: (value + 1) * 31us */
-#define GPIO_DEBOUNCE_TIME 127
+#define NAND_BLOCK_SIZE SZ_128K
+
+static struct mtd_partition omap3pandora_nand_partitions[] = {
+ {
+ .name = "xloader",
+ .offset = 0,
+ .size = 4 * NAND_BLOCK_SIZE,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "uboot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 15 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "uboot-env",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "boot",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 80 * NAND_BLOCK_SIZE,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct omap_nand_platform_data pandora_nand_data = {
+ .cs = 0,
+ .devsize = 1, /* '0' for 8-bit, '1' for 16-bit device */
+ .parts = omap3pandora_nand_partitions,
+ .nr_parts = ARRAY_SIZE(omap3pandora_nand_partitions),
+};
static struct gpio_led pandora_gpio_leds[] = {
{
@@ -88,6 +125,7 @@ static struct platform_device pandora_leds_gpio = {
.type = ev_type, \
.code = ev_code, \
.active_low = act_low, \
+ .debounce_interval = 4, \
.desc = "btn " descr, \
}
@@ -99,14 +137,14 @@ static struct gpio_keys_button pandora_gpio_keys[] = {
GPIO_BUTTON_LOW(103, KEY_DOWN, "down"),
GPIO_BUTTON_LOW(96, KEY_LEFT, "left"),
GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"),
- GPIO_BUTTON_LOW(109, KEY_KP1, "game 1"),
- GPIO_BUTTON_LOW(111, KEY_KP2, "game 2"),
- GPIO_BUTTON_LOW(106, KEY_KP3, "game 3"),
- GPIO_BUTTON_LOW(101, KEY_KP4, "game 4"),
- GPIO_BUTTON_LOW(102, BTN_TL, "l"),
- GPIO_BUTTON_LOW(97, BTN_TL2, "l2"),
- GPIO_BUTTON_LOW(105, BTN_TR, "r"),
- GPIO_BUTTON_LOW(107, BTN_TR2, "r2"),
+ GPIO_BUTTON_LOW(109, KEY_PAGEUP, "game 1"),
+ GPIO_BUTTON_LOW(111, KEY_END, "game 2"),
+ GPIO_BUTTON_LOW(106, KEY_PAGEDOWN, "game 3"),
+ GPIO_BUTTON_LOW(101, KEY_HOME, "game 4"),
+ GPIO_BUTTON_LOW(102, KEY_RIGHTSHIFT, "l"),
+ GPIO_BUTTON_LOW(97, KEY_KPPLUS, "l2"),
+ GPIO_BUTTON_LOW(105, KEY_RIGHTCTRL, "r"),
+ GPIO_BUTTON_LOW(107, KEY_KPMINUS, "r2"),
GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"),
GPIO_BUTTON_LOW(99, KEY_MENU, "menu"),
GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"),
@@ -127,14 +165,7 @@ static struct platform_device pandora_keys_gpio = {
},
};
-static void __init pandora_keys_gpio_init(void)
-{
- /* set debounce time for GPIO banks 4 and 6 */
- gpio_set_debounce(32 * 3, GPIO_DEBOUNCE_TIME);
- gpio_set_debounce(32 * 5, GPIO_DEBOUNCE_TIME);
-}
-
-static int board_keymap[] = {
+static const uint32_t board_keymap[] = {
/* row, col, code */
KEY(0, 0, KEY_9),
KEY(0, 1, KEY_8),
@@ -255,12 +286,33 @@ static struct omap2_hsmmc_info omap3pandora_mmc[] = {
static int omap3pandora_twl_gpio_setup(struct device *dev,
unsigned gpio, unsigned ngpio)
{
+ int ret, gpio_32khz;
+
/* gpio + {0,1} is "mmc{0,1}_cd" (input/IRQ) */
omap3pandora_mmc[0].gpio_cd = gpio + 0;
omap3pandora_mmc[1].gpio_cd = gpio + 1;
omap2_hsmmc_init(omap3pandora_mmc);
+ /* gpio + 13 drives 32kHz buffer for wifi module */
+ gpio_32khz = gpio + 13;
+ ret = gpio_request(gpio_32khz, "wifi 32kHz");
+ if (ret < 0) {
+ pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret);
+ goto fail;
+ }
+
+ ret = gpio_direction_output(gpio_32khz, 1);
+ if (ret < 0) {
+ pr_err("Cannot set GPIO line %d, ret=%d\n", gpio_32khz, ret);
+ goto fail_direction;
+ }
+
return 0;
+
+fail_direction:
+ gpio_free(gpio_32khz);
+fail:
+ return -ENODEV;
}
static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
@@ -539,10 +591,67 @@ static void __init omap3pandora_init_irq(void)
omap_gpio_init();
}
+static void pandora_wl1251_set_power(bool enable)
+{
+ /*
+ * Keep power always on until wl1251_sdio driver learns to re-init
+ * the chip after powering it down and back up.
+ */
+}
+
+static struct wl12xx_platform_data pandora_wl1251_pdata = {
+ .set_power = pandora_wl1251_set_power,
+ .use_eeprom = true,
+};
+
+static struct platform_device pandora_wl1251_data = {
+ .name = "wl1251_data",
+ .id = -1,
+ .dev = {
+ .platform_data = &pandora_wl1251_pdata,
+ },
+};
+
+static void pandora_wl1251_init(void)
+{
+ int ret;
+
+ ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq");
+ if (ret < 0)
+ goto fail;
+
+ ret = gpio_direction_input(PANDORA_WIFI_IRQ_GPIO);
+ if (ret < 0)
+ goto fail_irq;
+
+ pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
+ if (pandora_wl1251_pdata.irq < 0)
+ goto fail_irq;
+
+ ret = gpio_request(PANDORA_WIFI_NRESET_GPIO, "wl1251 nreset");
+ if (ret < 0)
+ goto fail_irq;
+
+ /* start powered so that it probes with MMC subsystem */
+ ret = gpio_direction_output(PANDORA_WIFI_NRESET_GPIO, 1);
+ if (ret < 0)
+ goto fail_nreset;
+
+ return;
+
+fail_nreset:
+ gpio_free(PANDORA_WIFI_NRESET_GPIO);
+fail_irq:
+ gpio_free(PANDORA_WIFI_IRQ_GPIO);
+fail:
+ printk(KERN_ERR "wl1251 board initialisation failed\n");
+}
+
static struct platform_device *omap3pandora_devices[] __initdata = {
&pandora_leds_gpio,
&pandora_keys_gpio,
&pandora_dss_device,
+ &pandora_wl1251_data,
};
static const struct ehci_hcd_omap_platform_data ehci_pdata __initconst = {
@@ -575,6 +684,7 @@ static void __init omap3pandora_init(void)
{
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
omap3pandora_i2c_init();
+ pandora_wl1251_init();
platform_add_devices(omap3pandora_devices,
ARRAY_SIZE(omap3pandora_devices));
omap_serial_init();
@@ -582,25 +692,20 @@ static void __init omap3pandora_init(void)
ARRAY_SIZE(omap3pandora_spi_board_info));
omap3pandora_ads7846_init();
usb_ehci_init(&ehci_pdata);
- pandora_keys_gpio_init();
usb_musb_init(&musb_board_data);
+ gpmc_nand_init(&pandora_nand_data);
/* Ensure SDRC pins are mux'd for self-refresh */
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
-static void __init omap3pandora_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP3_PANDORA, "Pandora Handheld Console")
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap3pandora_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap3pandora_init_irq,
.init_machine = omap3pandora_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3stalker.c b/arch/arm/mach-omap2/board-omap3stalker.c
index a04cffd691c5..bcd01d278c65 100644
--- a/arch/arm/mach-omap2/board-omap3stalker.c
+++ b/arch/arm/mach-omap2/board-omap3stalker.c
@@ -652,18 +652,12 @@ static void __init omap3_stalker_init(void)
omap_mux_init_signal("sdr_cke1", OMAP_PIN_OUTPUT);
}
-static void __init omap3_stalker_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(SBC3530, "OMAP3 STALKER")
/* Maintainer: Jason Lam -lzg@ema-tech.com */
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap3_stalker_map_io,
+ .map_io = omap3_map_io,
.init_irq = omap3_stalker_init_irq,
.init_machine = omap3_stalker_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap3touchbook.c b/arch/arm/mach-omap2/board-omap3touchbook.c
index 2f5f8233dd5b..69d431bd05db 100644
--- a/arch/arm/mach-omap2/board-omap3touchbook.c
+++ b/arch/arm/mach-omap2/board-omap3touchbook.c
@@ -559,18 +559,13 @@ static void __init omap3_touchbook_init(void)
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
}
-static void __init omap3_touchbook_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(TOUCHBOOK, "OMAP3 touchbook Board")
/* Maintainer: Gregoire Gentil - http://www.alwaysinnovating.com */
.phys_io = 0x48000000,
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap3_touchbook_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap3_touchbook_init_irq,
.init_machine = omap3_touchbook_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
new file mode 100644
index 000000000000..c03d1d56db56
--- /dev/null
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -0,0 +1,304 @@
+/*
+ * Board support file for OMAP4430 based PandaBoard.
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * Author: David Anders <x0132446@ti.com>
+ *
+ * Based on mach-omap2/board-4430sdp.c
+ *
+ * Author: Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Based on mach-omap2/board-3430sdp.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/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.h>
+#include <linux/i2c/twl.h>
+#include <linux/regulator/machine.h>
+
+#include <mach/hardware.h>
+#include <mach/omap4-common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <plat/board.h>
+#include <plat/common.h>
+#include <plat/control.h>
+#include <plat/timer-gp.h>
+#include <plat/usb.h>
+#include <plat/mmc.h>
+#include "hsmmc.h"
+
+
+static void __init omap4_panda_init_irq(void)
+{
+ omap2_init_common_hw(NULL, NULL);
+ gic_init_irq();
+ omap_gpio_init();
+}
+
+static struct omap_musb_board_data musb_board_data = {
+ .interface_type = MUSB_INTERFACE_UTMI,
+ .mode = MUSB_PERIPHERAL,
+ .power = 100,
+};
+
+static struct omap2_hsmmc_info mmc[] = {
+ {
+ .mmc = 1,
+ .wires = 8,
+ .gpio_wp = -EINVAL,
+ },
+ {} /* Terminator */
+};
+
+static struct regulator_consumer_supply omap4_panda_vmmc_supply[] = {
+ {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.0",
+ },
+ {
+ .supply = "vmmc",
+ .dev_name = "mmci-omap-hs.1",
+ },
+};
+
+static int omap4_twl6030_hsmmc_late_init(struct device *dev)
+{
+ int ret = 0;
+ struct platform_device *pdev = container_of(dev,
+ struct platform_device, dev);
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ /* Setting MMC1 Card detect Irq */
+ if (pdev->id == 0)
+ pdata->slots[0].card_detect_irq = TWL6030_IRQ_BASE +
+ MMCDETECT_INTR_OFFSET;
+ return ret;
+}
+
+static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
+{
+ struct omap_mmc_platform_data *pdata = dev->platform_data;
+
+ pdata->init = omap4_twl6030_hsmmc_late_init;
+}
+
+static int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
+{
+ struct omap2_hsmmc_info *c;
+
+ omap2_hsmmc_init(controllers);
+ for (c = controllers; c->mmc; c++)
+ omap4_twl6030_hsmmc_set_late_init(c->dev);
+
+ return 0;
+}
+
+static struct regulator_init_data omap4_panda_vaux1 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vaux2 = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vaux3 = {
+ .constraints = {
+ .min_uV = 1000000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+/* VMMC1 for MMC1 card */
+static struct regulator_init_data omap4_panda_vmmc = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 3000000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 2,
+ .consumer_supplies = omap4_panda_vmmc_supply,
+};
+
+static struct regulator_init_data omap4_panda_vpp = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 2500000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vusim = {
+ .constraints = {
+ .min_uV = 1200000,
+ .max_uV = 2900000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vana = {
+ .constraints = {
+ .min_uV = 2100000,
+ .max_uV = 2100000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vcxio = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vdac = {
+ .constraints = {
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct regulator_init_data omap4_panda_vusb = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = true,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+};
+
+static struct twl4030_platform_data omap4_panda_twldata = {
+ .irq_base = TWL6030_IRQ_BASE,
+ .irq_end = TWL6030_IRQ_END,
+
+ /* Regulators */
+ .vmmc = &omap4_panda_vmmc,
+ .vpp = &omap4_panda_vpp,
+ .vusim = &omap4_panda_vusim,
+ .vana = &omap4_panda_vana,
+ .vcxio = &omap4_panda_vcxio,
+ .vdac = &omap4_panda_vdac,
+ .vusb = &omap4_panda_vusb,
+ .vaux1 = &omap4_panda_vaux1,
+ .vaux2 = &omap4_panda_vaux2,
+ .vaux3 = &omap4_panda_vaux3,
+};
+
+static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("twl6030", 0x48),
+ .flags = I2C_CLIENT_WAKE,
+ .irq = OMAP44XX_IRQ_SYS_1N,
+ .platform_data = &omap4_panda_twldata,
+ },
+};
+static int __init omap4_panda_i2c_init(void)
+{
+ /*
+ * Phoenix Audio IC needs I2C1 to
+ * start with 400 KHz or less
+ */
+ omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
+ ARRAY_SIZE(omap4_panda_i2c_boardinfo));
+ omap_register_i2c_bus(2, 400, NULL, 0);
+ omap_register_i2c_bus(3, 400, NULL, 0);
+ omap_register_i2c_bus(4, 400, NULL, 0);
+ return 0;
+}
+static void __init omap4_panda_init(void)
+{
+ int status;
+
+ omap4_panda_i2c_init();
+ omap_serial_init();
+ omap4_twl6030_hsmmc_init(mmc);
+ /* OMAP4 Panda uses internal transceiver so register nop transceiver */
+ usb_nop_xceiv_register();
+ /* FIXME: allow multi-omap to boot until musb is updated for omap4 */
+ if (!cpu_is_omap44xx())
+ usb_musb_init(&musb_board_data);
+}
+
+static void __init omap4_panda_map_io(void)
+{
+ omap2_set_globals_443x();
+ omap44xx_map_common_io();
+}
+
+MACHINE_START(OMAP4_PANDA, "OMAP4 Panda board")
+ /* Maintainer: David Anders - Texas Instruments Inc */
+ .phys_io = 0x48000000,
+ .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
+ .boot_params = 0x80000100,
+ .map_io = omap4_panda_map_io,
+ .init_irq = omap4_panda_init_irq,
+ .init_machine = omap4_panda_init,
+ .timer = &omap_timer,
+MACHINE_END
diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
index 79ac41400c21..c1bbb481a504 100644
--- a/arch/arm/mach-omap2/board-overo.c
+++ b/arch/arm/mach-omap2/board-overo.c
@@ -166,9 +166,26 @@ static struct platform_device overo_smsc911x_device = {
},
};
+static struct platform_device overo_smsc911x2_device = {
+ .name = "smsc911x",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(overo_smsc911x2_resources),
+ .resource = overo_smsc911x2_resources,
+ .dev = {
+ .platform_data = &overo_smsc911x_config,
+ },
+};
+
+static struct platform_device *smsc911x_devices[] = {
+ &overo_smsc911x_device,
+ &overo_smsc911x2_device,
+};
+
static inline void __init overo_init_smsc911x(void)
{
- unsigned long cs_mem_base;
+ unsigned long cs_mem_base, cs_mem_base2;
+
+ /* set up first smsc911x chip */
if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
@@ -189,7 +206,28 @@ static inline void __init overo_init_smsc911x(void)
overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
overo_smsc911x_resources[1].end = 0;
- platform_device_register(&overo_smsc911x_device);
+ /* set up second smsc911x chip */
+
+ if (gpmc_cs_request(OVERO_SMSC911X2_CS, SZ_16M, &cs_mem_base2) < 0) {
+ printk(KERN_ERR "Failed request for GPMC mem for smsc911x2\n");
+ return;
+ }
+
+ overo_smsc911x2_resources[0].start = cs_mem_base2 + 0x0;
+ overo_smsc911x2_resources[0].end = cs_mem_base2 + 0xff;
+
+ if ((gpio_request(OVERO_SMSC911X2_GPIO, "SMSC911X2 IRQ") == 0) &&
+ (gpio_direction_input(OVERO_SMSC911X2_GPIO) == 0)) {
+ gpio_export(OVERO_SMSC911X2_GPIO, 0);
+ } else {
+ printk(KERN_ERR "could not obtain gpio for SMSC911X2 IRQ\n");
+ return;
+ }
+
+ overo_smsc911x2_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X2_GPIO);
+ overo_smsc911x2_resources[1].end = 0;
+
+ platform_add_devices(smsc911x_devices, ARRAY_SIZE(smsc911x_devices));
}
#else
@@ -484,17 +522,12 @@ static void __init overo_init(void)
"OVERO_GPIO_USBH_CPEN\n");
}
-static void __init overo_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OVERO, "Gumstix Overo")
.phys_io = 0x48000000,
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = overo_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = overo_init_irq,
.init_machine = overo_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index abdf321c2d41..a3a396ca2d32 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -25,7 +25,6 @@
#include <linux/mmc/host.h>
#include <plat/mcspi.h>
-#include <plat/mux.h>
#include <plat/board.h>
#include <plat/common.h>
#include <plat/dma.h>
@@ -33,6 +32,11 @@
#include <plat/onenand.h>
#include <plat/gpmc-smc91x.h>
+#include <sound/tlv320aic3x.h>
+#include <sound/tpa6130a2-plat.h>
+
+#include <../drivers/staging/iio/light/tsl2563.h>
+
#include "mux.h"
#include "hsmmc.h"
@@ -51,6 +55,12 @@ enum {
static struct wl12xx_platform_data wl1251_pdata;
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+static struct tsl2563_platform_data rx51_tsl2563_platform_data = {
+ .cover_comp_gain = 16,
+};
+#endif
+
static struct omap2_mcspi_device_config wl1251_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1,
@@ -300,48 +310,29 @@ static struct omap2_hsmmc_info mmc[] __initdata = {
{} /* Terminator */
};
-static struct regulator_consumer_supply rx51_vmmc1_supply = {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.0",
-};
+static struct regulator_consumer_supply rx51_vmmc1_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0");
-static struct regulator_consumer_supply rx51_vaux3_supply = {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
-};
+static struct regulator_consumer_supply rx51_vaux3_supply =
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1");
-static struct regulator_consumer_supply rx51_vsim_supply = {
- .supply = "vmmc_aux",
- .dev_name = "mmci-omap-hs.1",
-};
+static struct regulator_consumer_supply rx51_vsim_supply =
+ REGULATOR_SUPPLY("vmmc_aux", "mmci-omap-hs.1");
static struct regulator_consumer_supply rx51_vmmc2_supplies[] = {
/* tlv320aic3x analog supplies */
- {
- .supply = "AVDD",
- .dev_name = "2-0018",
- },
- {
- .supply = "DRVDD",
- .dev_name = "2-0018",
- },
+ REGULATOR_SUPPLY("AVDD", "2-0018"),
+ REGULATOR_SUPPLY("DRVDD", "2-0018"),
+ /* tpa6130a2 */
+ REGULATOR_SUPPLY("Vdd", "2-0060"),
/* Keep vmmc as last item. It is not iterated for newer boards */
- {
- .supply = "vmmc",
- .dev_name = "mmci-omap-hs.1",
- },
+ REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1"),
};
static struct regulator_consumer_supply rx51_vio_supplies[] = {
/* tlv320aic3x digital supplies */
- {
- .supply = "IOVDD",
- .dev_name = "2-0018"
- },
- {
- .supply = "DVDD",
- .dev_name = "2-0018"
- },
+ REGULATOR_SUPPLY("IOVDD", "2-0018"),
+ REGULATOR_SUPPLY("DVDD", "2-0018"),
};
#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
@@ -362,6 +353,7 @@ static struct regulator_init_data rx51_vaux1 = {
.name = "V28",
.min_uV = 2800000,
.max_uV = 2800000,
+ .always_on = true, /* due battery cover sensor */
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
@@ -707,6 +699,15 @@ static struct twl4030_platform_data rx51_twldata __initdata = {
.vio = &rx51_vio,
};
+static struct aic3x_pdata rx51_aic3x_data __initdata = {
+ .gpio_reset = 60,
+};
+
+static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata = {
+ .id = TPA6130A2,
+ .power_gpio = 98,
+};
+
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
{
I2C_BOARD_INFO("twl5030", 0x48),
@@ -719,7 +720,18 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
{
I2C_BOARD_INFO("tlv320aic3x", 0x18),
+ .platform_data = &rx51_aic3x_data,
+ },
+#if defined(CONFIG_SENSORS_TSL2563) || defined(CONFIG_SENSORS_TSL2563_MODULE)
+ {
+ I2C_BOARD_INFO("tsl2563", 0x29),
+ .platform_data = &rx51_tsl2563_platform_data,
},
+#endif
+ {
+ I2C_BOARD_INFO("tpa6130a2", 0x60),
+ .platform_data = &rx51_tpa6130a2_data,
+ }
};
static int __init rx51_i2c_init(void)
diff --git a/arch/arm/mach-omap2/board-rx51-video.c b/arch/arm/mach-omap2/board-rx51-video.c
index b743a4f42649..5a1005ba9815 100644
--- a/arch/arm/mach-omap2/board-rx51-video.c
+++ b/arch/arm/mach-omap2/board-rx51-video.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <asm/mach-types.h>
-#include <plat/mux.h>
#include <plat/display.h>
#include <plat/vram.h>
#include <plat/mcspi.h>
diff --git a/arch/arm/mach-omap2/board-rx51.c b/arch/arm/mach-omap2/board-rx51.c
index 1b86b5bb87a2..a58e8cb1a7fc 100644
--- a/arch/arm/mach-omap2/board-rx51.c
+++ b/arch/arm/mach-omap2/board-rx51.c
@@ -143,7 +143,7 @@ static void __init rx51_init(void)
static void __init rx51_map_io(void)
{
- omap2_set_globals_343x();
+ omap2_set_globals_3xxx();
rx51_video_mem_init();
omap34xx_map_common_io();
}
@@ -154,6 +154,7 @@ MACHINE_START(NOKIA_RX51, "Nokia RX-51 board")
.io_pg_offst = ((0xfa000000) >> 18) & 0xfffc,
.boot_params = 0x80000100,
.map_io = rx51_map_io,
+ .reserve = omap_reserve,
.init_irq = rx51_init_irq,
.init_machine = rx51_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom2.c b/arch/arm/mach-omap2/board-zoom2.c
index 803ef14cbf2d..7f792812e4f7 100644
--- a/arch/arm/mach-omap2/board-zoom2.c
+++ b/arch/arm/mach-omap2/board-zoom2.c
@@ -71,6 +71,19 @@ static struct twl4030_platform_data zoom2_twldata = {
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 162 */
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN POWER ENABLE - GPIO 101 */
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC3 CMD */
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 CLK */
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 DAT[0-3] */
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -84,17 +97,12 @@ static void __init omap_zoom2_init(void)
zoom_debugboard_init();
}
-static void __init omap_zoom2_map_io(void)
-{
- omap2_set_globals_343x();
- omap34xx_map_common_io();
-}
-
MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
.phys_io = ZOOM_UART_BASE,
.io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap_zoom2_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_zoom2_init_irq,
.init_machine = omap_zoom2_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/board-zoom3.c b/arch/arm/mach-omap2/board-zoom3.c
index 33147042485f..a55a05734a8f 100644
--- a/arch/arm/mach-omap2/board-zoom3.c
+++ b/arch/arm/mach-omap2/board-zoom3.c
@@ -25,12 +25,6 @@
#include "mux.h"
#include "sdram-hynix-h8mbx00u0mer-0em.h"
-static void __init omap_zoom_map_io(void)
-{
- omap2_set_globals_36xx();
- omap34xx_map_common_io();
-}
-
static struct omap_board_config_kernel zoom_config[] __initdata = {
};
@@ -46,6 +40,19 @@ static void __init omap_zoom_init_irq(void)
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
+ /* WLAN IRQ - GPIO 162 */
+ OMAP3_MUX(MCBSP1_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN POWER ENABLE - GPIO 101 */
+ OMAP3_MUX(CAM_D2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
+ /* WLAN SDIO: MMC3 CMD */
+ OMAP3_MUX(MCSPI1_CS1, OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 CLK */
+ OMAP3_MUX(ETK_CLK, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ /* WLAN SDIO: MMC3 DAT[0-3] */
+ OMAP3_MUX(ETK_D3, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D4, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D5, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
+ OMAP3_MUX(ETK_D6, OMAP_MUX_MODE2 | OMAP_PIN_INPUT_PULLUP),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
@@ -76,7 +83,8 @@ MACHINE_START(OMAP_ZOOM3, "OMAP Zoom3 board")
.phys_io = ZOOM_UART_BASE,
.io_pg_offst = (ZOOM_UART_VIRT >> 18) & 0xfffc,
.boot_params = 0x80000100,
- .map_io = omap_zoom_map_io,
+ .map_io = omap3_map_io,
+ .reserve = omap_reserve,
.init_irq = omap_zoom_init_irq,
.init_machine = omap_zoom_init,
.timer = &omap_timer,
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index 41b155acfca7..c226798e9ac6 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -1408,7 +1408,7 @@ static struct clk ts_fck = {
static struct clk usbtll_fck = {
.name = "usbtll_fck",
- .ops = &clkops_omap2_dflt,
+ .ops = &clkops_omap2_dflt_wait,
.parent = &dpll5_m2_ck,
.enable_reg = OMAP_CM_REGADDR(CORE_MOD, OMAP3430ES2_CM_FCLKEN3),
.enable_bit = OMAP3430ES2_EN_USBTLL_SHIFT,
diff --git a/arch/arm/mach-omap2/cm.c b/arch/arm/mach-omap2/cm.c
index 2d83565d2be2..721c3b66740a 100644
--- a/arch/arm/mach-omap2/cm.c
+++ b/arch/arm/mach-omap2/cm.c
@@ -50,15 +50,15 @@ int omap2_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)
cm_idlest_reg = cm_idlest_offs[idlest_id - 1];
+ mask = 1 << idlest_shift;
+
if (cpu_is_omap24xx())
- ena = idlest_shift;
+ ena = mask;
else if (cpu_is_omap34xx())
ena = 0;
else
BUG();
- mask = 1 << idlest_shift;
-
/* XXX should be OMAP2 CM */
omap_test_timeout(((cm_read_mod_reg(prcm_mod, cm_idlest_reg) & mask) == ena),
MAX_MODULE_READY_TIME, i);
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 03e6c9ed82a4..162a9be3cbb1 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -25,7 +25,6 @@
#include <plat/control.h>
#include <plat/tc.h>
#include <plat/board.h>
-#include <plat/mux.h>
#include <mach/gpio.h>
#include <plat/mmc.h>
#include <plat/dma.h>
@@ -230,64 +229,7 @@ static inline void omap_init_mbox(void)
static inline void omap_init_mbox(void) { }
#endif /* CONFIG_OMAP_MBOX_FWK */
-#if defined(CONFIG_OMAP_STI)
-
-#if defined(CONFIG_ARCH_OMAP2)
-
-#define OMAP2_STI_BASE 0x48068000
-#define OMAP2_STI_CHANNEL_BASE 0x54000000
-#define OMAP2_STI_IRQ 4
-
-static struct resource sti_resources[] = {
- {
- .start = OMAP2_STI_BASE,
- .end = OMAP2_STI_BASE + 0x7ff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP2_STI_CHANNEL_BASE,
- .end = OMAP2_STI_CHANNEL_BASE + SZ_64K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP2_STI_IRQ,
- .flags = IORESOURCE_IRQ,
- }
-};
-#elif defined(CONFIG_ARCH_OMAP3)
-
-#define OMAP3_SDTI_BASE 0x54500000
-#define OMAP3_SDTI_CHANNEL_BASE 0x54600000
-
-static struct resource sti_resources[] = {
- {
- .start = OMAP3_SDTI_BASE,
- .end = OMAP3_SDTI_BASE + 0xFFF,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = OMAP3_SDTI_CHANNEL_BASE,
- .end = OMAP3_SDTI_CHANNEL_BASE + SZ_1M - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-#endif
-
-static struct platform_device sti_device = {
- .name = "sti",
- .id = -1,
- .num_resources = ARRAY_SIZE(sti_resources),
- .resource = sti_resources,
-};
-
-static inline void omap_init_sti(void)
-{
- platform_device_register(&sti_device);
-}
-#else
static inline void omap_init_sti(void) {}
-#endif
#if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE)
@@ -672,19 +614,19 @@ static inline void omap2_mmc_mux(struct omap_mmc_platform_data *mmc_controller,
OMAP_PIN_INPUT_PULLUP);
if (cpu_is_omap2420() && controller_nr == 0) {
- omap_cfg_reg(H18_24XX_MMC_CMD);
- omap_cfg_reg(H15_24XX_MMC_CLKI);
- omap_cfg_reg(G19_24XX_MMC_CLKO);
- omap_cfg_reg(F20_24XX_MMC_DAT0);
- omap_cfg_reg(F19_24XX_MMC_DAT_DIR0);
- omap_cfg_reg(G18_24XX_MMC_CMD_DIR);
+ omap_mux_init_signal("sdmmc_cmd", 0);
+ omap_mux_init_signal("sdmmc_clki", 0);
+ omap_mux_init_signal("sdmmc_clko", 0);
+ omap_mux_init_signal("sdmmc_dat0", 0);
+ omap_mux_init_signal("sdmmc_dat_dir0", 0);
+ omap_mux_init_signal("sdmmc_cmd_dir", 0);
if (mmc_controller->slots[0].wires == 4) {
- omap_cfg_reg(H14_24XX_MMC_DAT1);
- omap_cfg_reg(E19_24XX_MMC_DAT2);
- omap_cfg_reg(D19_24XX_MMC_DAT3);
- omap_cfg_reg(E20_24XX_MMC_DAT_DIR1);
- omap_cfg_reg(F18_24XX_MMC_DAT_DIR2);
- omap_cfg_reg(E18_24XX_MMC_DAT_DIR3);
+ omap_mux_init_signal("sdmmc_dat1", 0);
+ omap_mux_init_signal("sdmmc_dat2", 0);
+ omap_mux_init_signal("sdmmc_dat3", 0);
+ omap_mux_init_signal("sdmmc_dat_dir1", 0);
+ omap_mux_init_signal("sdmmc_dat_dir2", 0);
+ omap_mux_init_signal("sdmmc_dat_dir3", 0);
}
/*
diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c
index 7951ae1447ee..79c478c4cb1c 100644
--- a/arch/arm/mach-omap2/i2c.c
+++ b/arch/arm/mach-omap2/i2c.c
@@ -21,32 +21,19 @@
#include <plat/cpu.h>
#include <plat/i2c.h>
-#include <plat/mux.h>
#include "mux.h"
void __init omap2_i2c_mux_pins(int bus_id)
{
- if (cpu_is_omap24xx()) {
- const int omap24xx_pins[][2] = {
- { M19_24XX_I2C1_SCL, L15_24XX_I2C1_SDA },
- { J15_24XX_I2C2_SCL, H19_24XX_I2C2_SDA },
- };
- int scl, sda;
-
- scl = omap24xx_pins[bus_id - 1][0];
- sda = omap24xx_pins[bus_id - 1][1];
- omap_cfg_reg(sda);
- omap_cfg_reg(scl);
- }
+ char mux_name[sizeof("i2c2_scl.i2c2_scl")];
/* First I2C bus is not muxable */
- if (cpu_is_omap34xx() && bus_id > 1) {
- char mux_name[sizeof("i2c2_scl.i2c2_scl")];
+ if (bus_id == 1)
+ return;
- sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
- omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
- sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
- omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
- }
+ sprintf(mux_name, "i2c%i_scl.i2c%i_scl", bus_id, bus_id);
+ omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
+ sprintf(mux_name, "i2c%i_sda.i2c%i_sda", bus_id, bus_id);
+ omap_mux_init_signal(mux_name, OMAP_PIN_INPUT);
}
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index 37b8a1a4adf8..fd1904b013fa 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -25,6 +25,8 @@
#include <plat/control.h>
#include <plat/cpu.h>
+#include <mach/id.h>
+
static struct omap_chip_id omap_chip;
static unsigned int omap_revision;
@@ -102,30 +104,36 @@ static struct omap_id omap_ids[] __initdata = {
static void __iomem *tap_base;
static u16 tap_prod_id;
-void __init omap24xx_check_revision(void)
+void omap_get_die_id(struct omap_die_id *odi)
+{
+ odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
+ odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
+ odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
+ odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
+}
+
+static void __init omap24xx_check_revision(void)
{
int i, j;
u32 idcode, prod_id;
u16 hawkeye;
u8 dev_type, rev;
+ struct omap_die_id odi;
idcode = read_tap_reg(OMAP_TAP_IDCODE);
prod_id = read_tap_reg(tap_prod_id);
hawkeye = (idcode >> 12) & 0xffff;
rev = (idcode >> 28) & 0x0f;
dev_type = (prod_id >> 16) & 0x0f;
+ omap_get_die_id(&odi);
pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
- pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_0));
+ pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
- read_tap_reg(OMAP_TAP_DIE_ID_1),
- (read_tap_reg(OMAP_TAP_DIE_ID_1) >> 28) & 0xf);
- pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_2));
- pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n",
- read_tap_reg(OMAP_TAP_DIE_ID_3));
+ odi.id_1, (odi.id_1 >> 28) & 0xf);
+ pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
+ pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
prod_id, dev_type);
@@ -164,7 +172,7 @@ void __init omap24xx_check_revision(void)
omap3_features |= OMAP3_HAS_ ##feat; \
}
-void __init omap3_check_features(void)
+static void __init omap3_check_features(void)
{
u32 status;
@@ -179,6 +187,8 @@ void __init omap3_check_features(void)
OMAP3_CHECK_FEATURE(status, ISP);
if (cpu_is_omap3630())
omap3_features |= OMAP3_HAS_192MHZ_CLK;
+ if (!cpu_is_omap3505() && !cpu_is_omap3517())
+ omap3_features |= OMAP3_HAS_IO_WAKEUP;
/*
* TODO: Get additional info (where applicable)
@@ -186,7 +196,7 @@ void __init omap3_check_features(void)
*/
}
-void __init omap3_check_revision(void)
+static void __init omap3_check_revision(void)
{
u32 cpuid, idcode;
u16 hawkeye;
@@ -267,7 +277,7 @@ void __init omap3_check_revision(void)
}
}
-void __init omap4_check_revision(void)
+static void __init omap4_check_revision(void)
{
u32 idcode;
u16 hawkeye;
@@ -297,7 +307,7 @@ void __init omap4_check_revision(void)
if (omap3_has_ ##feat()) \
printk(#feat" ");
-void __init omap3_cpuinfo(void)
+static void __init omap3_cpuinfo(void)
{
u8 rev = GET_OMAP_REVISION();
char cpu_name[16], cpu_rev[16];
diff --git a/arch/arm/mach-omap2/include/mach/id.h b/arch/arm/mach-omap2/include/mach/id.h
new file mode 100644
index 000000000000..02ed3aa56f1e
--- /dev/null
+++ b/arch/arm/mach-omap2/include/mach/id.h
@@ -0,0 +1,22 @@
+/*
+ * OMAP2 CPU identification code
+ *
+ * Copyright (C) 2010 Kan-Ru Chen <kanru@0xlab.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 OMAP2_ARCH_ID_H
+#define OMAP2_ARCH_ID_H
+
+struct omap_die_id {
+ u32 id_0;
+ u32 id_1;
+ u32 id_2;
+ u32 id_3;
+};
+
+void omap_get_die_id(struct omap_die_id *odi);
+
+#endif
diff --git a/arch/arm/mach-omap2/include/mach/omap4-common.h b/arch/arm/mach-omap2/include/mach/omap4-common.h
index 423af3a6dd31..2744dfee1ff4 100644
--- a/arch/arm/mach-omap2/include/mach/omap4-common.h
+++ b/arch/arm/mach-omap2/include/mach/omap4-common.h
@@ -13,6 +13,13 @@
#ifndef OMAP_ARCH_OMAP4_COMMON_H
#define OMAP_ARCH_OMAP4_COMMON_H
+/*
+ * wfi used in low power code. Directly opcode is used instead
+ * of instruction to avoid mulit-omap build break
+ */
+#define do_wfi() \
+ __asm__ __volatile__ (".word 0xe320f003" : : : "memory")
+
#ifdef CONFIG_CACHE_L2X0
extern void __iomem *l2cache_base;
#endif
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 3cfb425ea67e..b9ea70bce563 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -28,12 +28,10 @@
#include <asm/mach/map.h>
-#include <plat/mux.h>
#include <plat/sram.h>
#include <plat/sdrc.h>
#include <plat/gpmc.h>
#include <plat/serial.h>
-#include <plat/vram.h>
#include "clock2xxx.h"
#include "clock3xxx.h"
@@ -45,6 +43,7 @@
#include <plat/clockdomain.h>
#include "clockdomains.h"
+
#include <plat/omap_hwmod.h>
/*
@@ -241,8 +240,6 @@ static void __init _omap2_map_common_io(void)
omap2_check_revision();
omap_sram_init();
- omapfb_reserve_sdram();
- omap_vram_reserve_sdram();
}
#ifdef CONFIG_ARCH_OMAP2420
@@ -316,6 +313,8 @@ static int __init _omap2_init_reprogram_sdrc(void)
void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
struct omap_sdrc_params *sdrc_cs1)
{
+ u8 skip_setup_idle = 0;
+
pwrdm_init(powerdomains_omap);
clkdm_init(clockdomains_omap, clkdm_autodeps);
if (cpu_is_omap242x())
@@ -324,7 +323,6 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
omap2430_hwmod_init();
else if (cpu_is_omap34xx())
omap3xxx_hwmod_init();
- omap2_mux_init();
/* The OPP tables have to be registered before a clk init */
omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
@@ -340,9 +338,13 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
pr_err("Could not init clock framework - unknown CPU\n");
omap_serial_early_init();
+
+#ifndef CONFIG_PM_RUNTIME
+ skip_setup_idle = 1;
+#endif
if (cpu_is_omap24xx() || cpu_is_omap34xx()) /* FIXME: OMAP4 */
- omap_hwmod_late_init();
- omap_pm_if_init();
+ omap_hwmod_late_init(skip_setup_idle);
+
if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
omap2_sdrc_init(sdrc_cs0, sdrc_cs1);
_omap2_init_reprogram_sdrc();
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
index e82da680d908..14ee686b6492 100644
--- a/arch/arm/mach-omap2/iommu2.c
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -44,9 +44,13 @@
#define MMU_IRQ_EMUMISS (1 << 2)
#define MMU_IRQ_TRANSLATIONFAULT (1 << 1)
#define MMU_IRQ_TLBMISS (1 << 0)
-#define MMU_IRQ_MASK \
- (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \
- MMU_IRQ_TRANSLATIONFAULT)
+
+#define __MMU_IRQ_FAULT \
+ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_EMUMISS | MMU_IRQ_TRANSLATIONFAULT)
+#define MMU_IRQ_MASK \
+ (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_TLBMISS)
+#define MMU_IRQ_TWL_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TABLEWALKFAULT)
+#define MMU_IRQ_TLB_MISS_MASK (__MMU_IRQ_FAULT | MMU_IRQ_TLBMISS)
/* MMU_CNTL */
#define MMU_CNTL_SHIFT 1
@@ -61,6 +65,26 @@
((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
+
+static void __iommu_set_twl(struct iommu *obj, bool on)
+{
+ u32 l = iommu_read_reg(obj, MMU_CNTL);
+
+ if (on)
+ iommu_write_reg(obj, MMU_IRQ_TWL_MASK, MMU_IRQENABLE);
+ else
+ iommu_write_reg(obj, MMU_IRQ_TLB_MISS_MASK, MMU_IRQENABLE);
+
+ l &= ~MMU_CNTL_MASK;
+ if (on)
+ l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
+ else
+ l |= (MMU_CNTL_MMU_EN);
+
+ iommu_write_reg(obj, l, MMU_CNTL);
+}
+
+
static int omap2_iommu_enable(struct iommu *obj)
{
u32 l, pa;
@@ -96,13 +120,9 @@ static int omap2_iommu_enable(struct iommu *obj)
l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
iommu_write_reg(obj, l, MMU_SYSCONFIG);
- iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE);
iommu_write_reg(obj, pa, MMU_TTB);
- l = iommu_read_reg(obj, MMU_CNTL);
- l &= ~MMU_CNTL_MASK;
- l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
- iommu_write_reg(obj, l, MMU_CNTL);
+ __iommu_set_twl(obj, true);
return 0;
}
@@ -118,6 +138,11 @@ static void omap2_iommu_disable(struct iommu *obj)
dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
}
+static void omap2_iommu_set_twl(struct iommu *obj, bool on)
+{
+ __iommu_set_twl(obj, false);
+}
+
static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
{
int i;
@@ -147,7 +172,7 @@ static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
printk("\n");
iommu_write_reg(obj, stat, MMU_IRQSTATUS);
- omap2_iommu_disable(obj);
+
return stat;
}
@@ -300,6 +325,7 @@ static const struct iommu_functions omap2_iommu_ops = {
.enable = omap2_iommu_enable,
.disable = omap2_iommu_disable,
+ .set_twl = omap2_iommu_set_twl,
.fault_isr = omap2_iommu_fault_isr,
.tlb_read_cr = omap2_tlb_read_cr,
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index c29337074ad3..87aa4c9597cc 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -20,17 +20,18 @@
#include <mach/irqs.h>
#include <plat/dma.h>
-#include <plat/mux.h>
#include <plat/cpu.h>
#include <plat/mcbsp.h>
+#include "mux.h"
+
static void omap2_mcbsp2_mux_setup(void)
{
- omap_cfg_reg(Y15_24XX_MCBSP2_CLKX);
- omap_cfg_reg(R14_24XX_MCBSP2_FSX);
- omap_cfg_reg(W15_24XX_MCBSP2_DR);
- omap_cfg_reg(V15_24XX_MCBSP2_DX);
- omap_cfg_reg(V14_24XX_GPIO117);
+ omap_mux_init_signal("eac_ac_sclk.mcbsp2_clkx", OMAP_PULL_ENA);
+ omap_mux_init_signal("eac_ac_fs.mcbsp2_fsx", OMAP_PULL_ENA);
+ omap_mux_init_signal("eac_ac_din.mcbsp2_dr", OMAP_PULL_ENA);
+ omap_mux_init_signal("eac_ac_dout.mcbsp2_dx", OMAP_PULL_ENA);
+ omap_mux_init_gpio(117, OMAP_PULL_ENA);
/*
* TODO: Need to add MUX settings for OMAP 2430 SDP
*/
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 8b3d26935a39..ab403b2ed26b 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -37,12 +37,12 @@
#include <asm/system.h>
#include <plat/control.h>
-#include <plat/mux.h>
#include "mux.h"
#define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
#define OMAP_MUX_BASE_SZ 0x5ca
+#define MUXABLE_GPIO_MODE3 BIT(0)
struct omap_mux_entry {
struct omap_mux mux;
@@ -51,6 +51,7 @@ struct omap_mux_entry {
static unsigned long mux_phys;
static void __iomem *mux_base;
+static u8 omap_mux_flags;
u16 omap_mux_read(u16 reg)
{
@@ -76,301 +77,6 @@ void omap_mux_write_array(struct omap_board_mux *board_mux)
}
}
-#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_OMAP_MUX)
-
-static struct omap_mux_cfg arch_mux_cfg;
-
-/* NOTE: See mux.h for the enumeration */
-
-static struct pin_config __initdata_or_module omap24xx_pins[] = {
-/*
- * description mux mux pull pull debug
- * offset mode ena type
- */
-
-/* 24xx I2C */
-MUX_CFG_24XX("M19_24XX_I2C1_SCL", 0x111, 0, 0, 0, 1)
-MUX_CFG_24XX("L15_24XX_I2C1_SDA", 0x112, 0, 0, 0, 1)
-MUX_CFG_24XX("J15_24XX_I2C2_SCL", 0x113, 0, 0, 1, 1)
-MUX_CFG_24XX("H19_24XX_I2C2_SDA", 0x114, 0, 0, 0, 1)
-
-/* Menelaus interrupt */
-MUX_CFG_24XX("W19_24XX_SYS_NIRQ", 0x12c, 0, 1, 1, 1)
-
-/* 24xx clocks */
-MUX_CFG_24XX("W14_24XX_SYS_CLKOUT", 0x137, 0, 1, 1, 1)
-
-/* 24xx GPMC chipselects, wait pin monitoring */
-MUX_CFG_24XX("E2_GPMC_NCS2", 0x08e, 0, 1, 1, 1)
-MUX_CFG_24XX("L2_GPMC_NCS7", 0x093, 0, 1, 1, 1)
-MUX_CFG_24XX("L3_GPMC_WAIT0", 0x09a, 0, 1, 1, 1)
-MUX_CFG_24XX("N7_GPMC_WAIT1", 0x09b, 0, 1, 1, 1)
-MUX_CFG_24XX("M1_GPMC_WAIT2", 0x09c, 0, 1, 1, 1)
-MUX_CFG_24XX("P1_GPMC_WAIT3", 0x09d, 0, 1, 1, 1)
-
-/* 24xx McBSP */
-MUX_CFG_24XX("Y15_24XX_MCBSP2_CLKX", 0x124, 1, 1, 0, 1)
-MUX_CFG_24XX("R14_24XX_MCBSP2_FSX", 0x125, 1, 1, 0, 1)
-MUX_CFG_24XX("W15_24XX_MCBSP2_DR", 0x126, 1, 1, 0, 1)
-MUX_CFG_24XX("V15_24XX_MCBSP2_DX", 0x127, 1, 1, 0, 1)
-
-/* 24xx GPIO */
-MUX_CFG_24XX("M21_242X_GPIO11", 0x0c9, 3, 1, 1, 1)
-MUX_CFG_24XX("P21_242X_GPIO12", 0x0ca, 3, 0, 0, 1)
-MUX_CFG_24XX("AA10_242X_GPIO13", 0x0e5, 3, 0, 0, 1)
-MUX_CFG_24XX("AA6_242X_GPIO14", 0x0e6, 3, 0, 0, 1)
-MUX_CFG_24XX("AA4_242X_GPIO15", 0x0e7, 3, 0, 0, 1)
-MUX_CFG_24XX("Y11_242X_GPIO16", 0x0e8, 3, 0, 0, 1)
-MUX_CFG_24XX("AA12_242X_GPIO17", 0x0e9, 3, 0, 0, 1)
-MUX_CFG_24XX("AA8_242X_GPIO58", 0x0ea, 3, 0, 0, 1)
-MUX_CFG_24XX("Y20_24XX_GPIO60", 0x12c, 3, 0, 0, 1)
-MUX_CFG_24XX("W4__24XX_GPIO74", 0x0f2, 3, 0, 0, 1)
-MUX_CFG_24XX("N15_24XX_GPIO85", 0x103, 3, 0, 0, 1)
-MUX_CFG_24XX("M15_24XX_GPIO92", 0x10a, 3, 0, 0, 1)
-MUX_CFG_24XX("P20_24XX_GPIO93", 0x10b, 3, 0, 0, 1)
-MUX_CFG_24XX("P18_24XX_GPIO95", 0x10d, 3, 0, 0, 1)
-MUX_CFG_24XX("M18_24XX_GPIO96", 0x10e, 3, 0, 0, 1)
-MUX_CFG_24XX("L14_24XX_GPIO97", 0x10f, 3, 0, 0, 1)
-MUX_CFG_24XX("J15_24XX_GPIO99", 0x113, 3, 1, 1, 1)
-MUX_CFG_24XX("V14_24XX_GPIO117", 0x128, 3, 1, 0, 1)
-MUX_CFG_24XX("P14_24XX_GPIO125", 0x140, 3, 1, 1, 1)
-
-/* 242x DBG GPIO */
-MUX_CFG_24XX("V4_242X_GPIO49", 0xd3, 3, 0, 0, 1)
-MUX_CFG_24XX("W2_242X_GPIO50", 0xd4, 3, 0, 0, 1)
-MUX_CFG_24XX("U4_242X_GPIO51", 0xd5, 3, 0, 0, 1)
-MUX_CFG_24XX("V3_242X_GPIO52", 0xd6, 3, 0, 0, 1)
-MUX_CFG_24XX("V2_242X_GPIO53", 0xd7, 3, 0, 0, 1)
-MUX_CFG_24XX("V6_242X_GPIO53", 0xcf, 3, 0, 0, 1)
-MUX_CFG_24XX("T4_242X_GPIO54", 0xd8, 3, 0, 0, 1)
-MUX_CFG_24XX("Y4_242X_GPIO54", 0xd0, 3, 0, 0, 1)
-MUX_CFG_24XX("T3_242X_GPIO55", 0xd9, 3, 0, 0, 1)
-MUX_CFG_24XX("U2_242X_GPIO56", 0xda, 3, 0, 0, 1)
-
-/* 24xx external DMA requests */
-MUX_CFG_24XX("AA10_242X_DMAREQ0", 0x0e5, 2, 0, 0, 1)
-MUX_CFG_24XX("AA6_242X_DMAREQ1", 0x0e6, 2, 0, 0, 1)
-MUX_CFG_24XX("E4_242X_DMAREQ2", 0x074, 2, 0, 0, 1)
-MUX_CFG_24XX("G4_242X_DMAREQ3", 0x073, 2, 0, 0, 1)
-MUX_CFG_24XX("D3_242X_DMAREQ4", 0x072, 2, 0, 0, 1)
-MUX_CFG_24XX("E3_242X_DMAREQ5", 0x071, 2, 0, 0, 1)
-
-/* UART3 */
-MUX_CFG_24XX("K15_24XX_UART3_TX", 0x118, 0, 0, 0, 1)
-MUX_CFG_24XX("K14_24XX_UART3_RX", 0x119, 0, 0, 0, 1)
-
-/* MMC/SDIO */
-MUX_CFG_24XX("G19_24XX_MMC_CLKO", 0x0f3, 0, 0, 0, 1)
-MUX_CFG_24XX("H18_24XX_MMC_CMD", 0x0f4, 0, 0, 0, 1)
-MUX_CFG_24XX("F20_24XX_MMC_DAT0", 0x0f5, 0, 0, 0, 1)
-MUX_CFG_24XX("H14_24XX_MMC_DAT1", 0x0f6, 0, 0, 0, 1)
-MUX_CFG_24XX("E19_24XX_MMC_DAT2", 0x0f7, 0, 0, 0, 1)
-MUX_CFG_24XX("D19_24XX_MMC_DAT3", 0x0f8, 0, 0, 0, 1)
-MUX_CFG_24XX("F19_24XX_MMC_DAT_DIR0", 0x0f9, 0, 0, 0, 1)
-MUX_CFG_24XX("E20_24XX_MMC_DAT_DIR1", 0x0fa, 0, 0, 0, 1)
-MUX_CFG_24XX("F18_24XX_MMC_DAT_DIR2", 0x0fb, 0, 0, 0, 1)
-MUX_CFG_24XX("E18_24XX_MMC_DAT_DIR3", 0x0fc, 0, 0, 0, 1)
-MUX_CFG_24XX("G18_24XX_MMC_CMD_DIR", 0x0fd, 0, 0, 0, 1)
-MUX_CFG_24XX("H15_24XX_MMC_CLKI", 0x0fe, 0, 0, 0, 1)
-
-/* Full speed USB */
-MUX_CFG_24XX("J20_24XX_USB0_PUEN", 0x11d, 0, 0, 0, 1)
-MUX_CFG_24XX("J19_24XX_USB0_VP", 0x11e, 0, 0, 0, 1)
-MUX_CFG_24XX("K20_24XX_USB0_VM", 0x11f, 0, 0, 0, 1)
-MUX_CFG_24XX("J18_24XX_USB0_RCV", 0x120, 0, 0, 0, 1)
-MUX_CFG_24XX("K19_24XX_USB0_TXEN", 0x121, 0, 0, 0, 1)
-MUX_CFG_24XX("J14_24XX_USB0_SE0", 0x122, 0, 0, 0, 1)
-MUX_CFG_24XX("K18_24XX_USB0_DAT", 0x123, 0, 0, 0, 1)
-
-MUX_CFG_24XX("N14_24XX_USB1_SE0", 0x0ed, 2, 0, 0, 1)
-MUX_CFG_24XX("W12_24XX_USB1_SE0", 0x0dd, 3, 0, 0, 1)
-MUX_CFG_24XX("P15_24XX_USB1_DAT", 0x0ee, 2, 0, 0, 1)
-MUX_CFG_24XX("R13_24XX_USB1_DAT", 0x0e0, 3, 0, 0, 1)
-MUX_CFG_24XX("W20_24XX_USB1_TXEN", 0x0ec, 2, 0, 0, 1)
-MUX_CFG_24XX("P13_24XX_USB1_TXEN", 0x0df, 3, 0, 0, 1)
-MUX_CFG_24XX("V19_24XX_USB1_RCV", 0x0eb, 2, 0, 0, 1)
-MUX_CFG_24XX("V12_24XX_USB1_RCV", 0x0de, 3, 0, 0, 1)
-
-MUX_CFG_24XX("AA10_24XX_USB2_SE0", 0x0e5, 2, 0, 0, 1)
-MUX_CFG_24XX("Y11_24XX_USB2_DAT", 0x0e8, 2, 0, 0, 1)
-MUX_CFG_24XX("AA12_24XX_USB2_TXEN", 0x0e9, 2, 0, 0, 1)
-MUX_CFG_24XX("AA6_24XX_USB2_RCV", 0x0e6, 2, 0, 0, 1)
-MUX_CFG_24XX("AA4_24XX_USB2_TLLSE0", 0x0e7, 2, 0, 0, 1)
-
-/* Keypad GPIO*/
-MUX_CFG_24XX("T19_24XX_KBR0", 0x106, 3, 1, 1, 1)
-MUX_CFG_24XX("R19_24XX_KBR1", 0x107, 3, 1, 1, 1)
-MUX_CFG_24XX("V18_24XX_KBR2", 0x139, 3, 1, 1, 1)
-MUX_CFG_24XX("M21_24XX_KBR3", 0xc9, 3, 1, 1, 1)
-MUX_CFG_24XX("E5__24XX_KBR4", 0x138, 3, 1, 1, 1)
-MUX_CFG_24XX("M18_24XX_KBR5", 0x10e, 3, 1, 1, 1)
-MUX_CFG_24XX("R20_24XX_KBC0", 0x108, 3, 0, 0, 1)
-MUX_CFG_24XX("M14_24XX_KBC1", 0x109, 3, 0, 0, 1)
-MUX_CFG_24XX("H19_24XX_KBC2", 0x114, 3, 0, 0, 1)
-MUX_CFG_24XX("V17_24XX_KBC3", 0x135, 3, 0, 0, 1)
-MUX_CFG_24XX("P21_24XX_KBC4", 0xca, 3, 0, 0, 1)
-MUX_CFG_24XX("L14_24XX_KBC5", 0x10f, 3, 0, 0, 1)
-MUX_CFG_24XX("N19_24XX_KBC6", 0x110, 3, 0, 0, 1)
-
-/* 24xx Menelaus Keypad GPIO */
-MUX_CFG_24XX("B3__24XX_KBR5", 0x30, 3, 1, 1, 1)
-MUX_CFG_24XX("AA4_24XX_KBC2", 0xe7, 3, 0, 0, 1)
-MUX_CFG_24XX("B13_24XX_KBC6", 0x110, 3, 0, 0, 1)
-
-/* 2430 USB */
-MUX_CFG_24XX("AD9_2430_USB0_PUEN", 0x133, 4, 0, 0, 1)
-MUX_CFG_24XX("Y11_2430_USB0_VP", 0x134, 4, 0, 0, 1)
-MUX_CFG_24XX("AD7_2430_USB0_VM", 0x135, 4, 0, 0, 1)
-MUX_CFG_24XX("AE7_2430_USB0_RCV", 0x136, 4, 0, 0, 1)
-MUX_CFG_24XX("AD4_2430_USB0_TXEN", 0x137, 4, 0, 0, 1)
-MUX_CFG_24XX("AF9_2430_USB0_SE0", 0x138, 4, 0, 0, 1)
-MUX_CFG_24XX("AE6_2430_USB0_DAT", 0x139, 4, 0, 0, 1)
-MUX_CFG_24XX("AD24_2430_USB1_SE0", 0x107, 2, 0, 0, 1)
-MUX_CFG_24XX("AB24_2430_USB1_RCV", 0x108, 2, 0, 0, 1)
-MUX_CFG_24XX("Y25_2430_USB1_TXEN", 0x109, 2, 0, 0, 1)
-MUX_CFG_24XX("AA26_2430_USB1_DAT", 0x10A, 2, 0, 0, 1)
-
-/* 2430 HS-USB */
-MUX_CFG_24XX("AD9_2430_USB0HS_DATA3", 0x133, 0, 0, 0, 1)
-MUX_CFG_24XX("Y11_2430_USB0HS_DATA4", 0x134, 0, 0, 0, 1)
-MUX_CFG_24XX("AD7_2430_USB0HS_DATA5", 0x135, 0, 0, 0, 1)
-MUX_CFG_24XX("AE7_2430_USB0HS_DATA6", 0x136, 0, 0, 0, 1)
-MUX_CFG_24XX("AD4_2430_USB0HS_DATA2", 0x137, 0, 0, 0, 1)
-MUX_CFG_24XX("AF9_2430_USB0HS_DATA0", 0x138, 0, 0, 0, 1)
-MUX_CFG_24XX("AE6_2430_USB0HS_DATA1", 0x139, 0, 0, 0, 1)
-MUX_CFG_24XX("AE8_2430_USB0HS_CLK", 0x13A, 0, 0, 0, 1)
-MUX_CFG_24XX("AD8_2430_USB0HS_DIR", 0x13B, 0, 0, 0, 1)
-MUX_CFG_24XX("AE5_2430_USB0HS_STP", 0x13c, 0, 1, 1, 1)
-MUX_CFG_24XX("AE9_2430_USB0HS_NXT", 0x13D, 0, 0, 0, 1)
-MUX_CFG_24XX("AC7_2430_USB0HS_DATA7", 0x13E, 0, 0, 0, 1)
-
-/* 2430 McBSP */
-MUX_CFG_24XX("AD6_2430_MCBSP_CLKS", 0x011E, 0, 0, 0, 1)
-
-MUX_CFG_24XX("AB2_2430_MCBSP1_CLKR", 0x011A, 0, 0, 0, 1)
-MUX_CFG_24XX("AD5_2430_MCBSP1_FSR", 0x011B, 0, 0, 0, 1)
-MUX_CFG_24XX("AA1_2430_MCBSP1_DX", 0x011C, 0, 0, 0, 1)
-MUX_CFG_24XX("AF3_2430_MCBSP1_DR", 0x011D, 0, 0, 0, 1)
-MUX_CFG_24XX("AB3_2430_MCBSP1_FSX", 0x011F, 0, 0, 0, 1)
-MUX_CFG_24XX("Y9_2430_MCBSP1_CLKX", 0x0120, 0, 0, 0, 1)
-
-MUX_CFG_24XX("AC10_2430_MCBSP2_FSX", 0x012E, 1, 0, 0, 1)
-MUX_CFG_24XX("AD16_2430_MCBSP2_CLX", 0x012F, 1, 0, 0, 1)
-MUX_CFG_24XX("AE13_2430_MCBSP2_DX", 0x0130, 1, 0, 0, 1)
-MUX_CFG_24XX("AD13_2430_MCBSP2_DR", 0x0131, 1, 0, 0, 1)
-MUX_CFG_24XX("AC10_2430_MCBSP2_FSX_OFF",0x012E, 0, 0, 0, 1)
-MUX_CFG_24XX("AD16_2430_MCBSP2_CLX_OFF",0x012F, 0, 0, 0, 1)
-MUX_CFG_24XX("AE13_2430_MCBSP2_DX_OFF", 0x0130, 0, 0, 0, 1)
-MUX_CFG_24XX("AD13_2430_MCBSP2_DR_OFF", 0x0131, 0, 0, 0, 1)
-
-MUX_CFG_24XX("AC9_2430_MCBSP3_CLKX", 0x0103, 0, 0, 0, 1)
-MUX_CFG_24XX("AE4_2430_MCBSP3_FSX", 0x0104, 0, 0, 0, 1)
-MUX_CFG_24XX("AE2_2430_MCBSP3_DR", 0x0105, 0, 0, 0, 1)
-MUX_CFG_24XX("AF4_2430_MCBSP3_DX", 0x0106, 0, 0, 0, 1)
-
-MUX_CFG_24XX("N3_2430_MCBSP4_CLKX", 0x010B, 1, 0, 0, 1)
-MUX_CFG_24XX("AD23_2430_MCBSP4_DR", 0x010C, 1, 0, 0, 1)
-MUX_CFG_24XX("AB25_2430_MCBSP4_DX", 0x010D, 1, 0, 0, 1)
-MUX_CFG_24XX("AC25_2430_MCBSP4_FSX", 0x010E, 1, 0, 0, 1)
-
-MUX_CFG_24XX("AE16_2430_MCBSP5_CLKX", 0x00ED, 1, 0, 0, 1)
-MUX_CFG_24XX("AF12_2430_MCBSP5_FSX", 0x00ED, 1, 0, 0, 1)
-MUX_CFG_24XX("K7_2430_MCBSP5_DX", 0x00EF, 1, 0, 0, 1)
-MUX_CFG_24XX("M1_2430_MCBSP5_DR", 0x00F0, 1, 0, 0, 1)
-
-/* 2430 MCSPI1 */
-MUX_CFG_24XX("Y18_2430_MCSPI1_CLK", 0x010F, 0, 0, 0, 1)
-MUX_CFG_24XX("AD15_2430_MCSPI1_SIMO", 0x0110, 0, 0, 0, 1)
-MUX_CFG_24XX("AE17_2430_MCSPI1_SOMI", 0x0111, 0, 0, 0, 1)
-MUX_CFG_24XX("U1_2430_MCSPI1_CS0", 0x0112, 0, 0, 0, 1)
-
-/* Touchscreen GPIO */
-MUX_CFG_24XX("AF19_2430_GPIO_85", 0x0113, 3, 0, 0, 1)
-
-};
-
-#define OMAP24XX_PINS_SZ ARRAY_SIZE(omap24xx_pins)
-
-#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
-
-static void __init_or_module omap2_cfg_debug(const struct pin_config *cfg, u16 reg)
-{
- u16 orig;
- u8 warn = 0, debug = 0;
-
- orig = omap_mux_read(cfg->mux_reg - OMAP_MUX_BASE_OFFSET);
-
-#ifdef CONFIG_OMAP_MUX_DEBUG
- debug = cfg->debug;
-#endif
- warn = (orig != reg);
- if (debug || warn)
- printk(KERN_WARNING
- "MUX: setup %s (0x%p): 0x%04x -> 0x%04x\n",
- cfg->name, omap_ctrl_base_get() + cfg->mux_reg,
- orig, reg);
-}
-#else
-#define omap2_cfg_debug(x, y) do {} while (0)
-#endif
-
-static int __init_or_module omap24xx_cfg_reg(const struct pin_config *cfg)
-{
- static DEFINE_SPINLOCK(mux_spin_lock);
- unsigned long flags;
- u8 reg = 0;
-
- spin_lock_irqsave(&mux_spin_lock, flags);
- reg |= cfg->mask & 0x7;
- if (cfg->pull_val)
- reg |= OMAP2_PULL_ENA;
- if (cfg->pu_pd_val)
- reg |= OMAP2_PULL_UP;
- omap2_cfg_debug(cfg, reg);
- omap_mux_write(reg, cfg->mux_reg - OMAP_MUX_BASE_OFFSET);
- spin_unlock_irqrestore(&mux_spin_lock, flags);
-
- return 0;
-}
-
-int __init omap2_mux_init(void)
-{
- u32 mux_pbase;
-
- if (cpu_is_omap2420())
- mux_pbase = OMAP2420_CTRL_BASE + OMAP_MUX_BASE_OFFSET;
- else if (cpu_is_omap2430())
- mux_pbase = OMAP243X_CTRL_BASE + OMAP_MUX_BASE_OFFSET;
- else
- return -ENODEV;
-
- mux_base = ioremap(mux_pbase, OMAP_MUX_BASE_SZ);
- if (!mux_base) {
- printk(KERN_ERR "mux: Could not ioremap\n");
- return -ENODEV;
- }
-
- if (cpu_is_omap24xx()) {
- arch_mux_cfg.pins = omap24xx_pins;
- arch_mux_cfg.size = OMAP24XX_PINS_SZ;
- arch_mux_cfg.cfg_reg = omap24xx_cfg_reg;
-
- return omap_mux_register(&arch_mux_cfg);
- }
-
- return 0;
-}
-
-#else
-int __init omap2_mux_init(void)
-{
- return 0;
-}
-#endif /* CONFIG_OMAP_MUX */
-
-/*----------------------------------------------------------------------------*/
-
-#ifdef CONFIG_ARCH_OMAP3
static LIST_HEAD(muxmodes);
static DEFINE_MUTEX(muxmode_mutex);
@@ -381,6 +87,9 @@ static char *omap_mux_options;
int __init omap_mux_init_gpio(int gpio, int val)
{
struct omap_mux_entry *e;
+ struct omap_mux *gpio_mux;
+ u16 old_mode;
+ u16 mux_mode;
int found = 0;
if (!gpio)
@@ -389,31 +98,33 @@ int __init omap_mux_init_gpio(int gpio, int val)
list_for_each_entry(e, &muxmodes, node) {
struct omap_mux *m = &e->mux;
if (gpio == m->gpio) {
- u16 old_mode;
- u16 mux_mode;
-
- old_mode = omap_mux_read(m->reg_offset);
- mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
- mux_mode |= OMAP_MUX_MODE4;
- printk(KERN_DEBUG "mux: Setting signal "
- "%s.gpio%i 0x%04x -> 0x%04x\n",
- m->muxnames[0], gpio, old_mode, mux_mode);
- omap_mux_write(mux_mode, m->reg_offset);
+ gpio_mux = m;
found++;
}
}
- if (found == 1)
- return 0;
+ if (found == 0) {
+ printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
+ return -ENODEV;
+ }
if (found > 1) {
- printk(KERN_ERR "mux: Multiple gpio paths for gpio%i\n", gpio);
+ printk(KERN_INFO "mux: Multiple gpio paths (%d) for gpio%i\n",
+ found, gpio);
return -EINVAL;
}
- printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
+ old_mode = omap_mux_read(gpio_mux->reg_offset);
+ mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
+ if (omap_mux_flags & MUXABLE_GPIO_MODE3)
+ mux_mode |= OMAP_MUX_MODE3;
+ else
+ mux_mode |= OMAP_MUX_MODE4;
+ printk(KERN_DEBUG "mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n",
+ gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
+ omap_mux_write(mux_mode, gpio_mux->reg_offset);
- return -ENODEV;
+ return 0;
}
int __init omap_mux_init_signal(char *muxname, int val)
@@ -1032,6 +743,9 @@ int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
return -ENODEV;
}
+ if (cpu_is_omap24xx())
+ omap_mux_flags = MUXABLE_GPIO_MODE3;
+
omap_mux_init_package(superset, package_subset, package_balls);
omap_mux_init_list(superset);
omap_mux_init_signals(board_mux);
@@ -1039,5 +753,3 @@ int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
return 0;
}
-#endif /* CONFIG_ARCH_OMAP3 */
-
diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h
index 480abc56e605..a8e040c2c7e9 100644
--- a/arch/arm/mach-omap2/mux.h
+++ b/arch/arm/mach-omap2/mux.h
@@ -7,6 +7,8 @@
* published by the Free Software Foundation.
*/
+#include "mux2420.h"
+#include "mux2430.h"
#include "mux34xx.h"
#define OMAP_MUX_TERMINATOR 0xffff
@@ -56,10 +58,12 @@
/* Flags for omap_mux_init */
#define OMAP_PACKAGE_MASK 0xffff
-#define OMAP_PACKAGE_CBP 4 /* 515-pin 0.40 0.50 */
-#define OMAP_PACKAGE_CUS 3 /* 423-pin 0.65 */
-#define OMAP_PACKAGE_CBB 2 /* 515-pin 0.40 0.50 */
-#define OMAP_PACKAGE_CBC 1 /* 515-pin 0.50 0.65 */
+#define OMAP_PACKAGE_CBP 6 /* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CUS 5 /* 423-pin 0.65 */
+#define OMAP_PACKAGE_CBB 4 /* 515-pin 0.40 0.50 */
+#define OMAP_PACKAGE_CBC 3 /* 515-pin 0.50 0.65 */
+#define OMAP_PACKAGE_ZAC 2 /* 24xx 447-pin POP */
+#define OMAP_PACKAGE_ZAF 1 /* 2420 447-pin SIP */
#define OMAP_MUX_NR_MODES 8 /* Available modes */
@@ -102,7 +106,7 @@ struct omap_board_mux {
u16 value;
};
-#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_ARCH_OMAP3)
+#if defined(CONFIG_OMAP_MUX)
/**
* omap_mux_init_gpio - initialize a signal based on the GPIO number
@@ -171,6 +175,20 @@ void omap_mux_write(u16 val, u16 mux_offset);
void omap_mux_write_array(struct omap_board_mux *board_mux);
/**
+ * omap2420_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap2420_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
+ * omap2430_mux_init() - initialize mux system with board specific set
+ * @board_mux: Board specific mux table
+ * @flags: OMAP package type used for the board
+ */
+int omap2430_mux_init(struct omap_board_mux *board_mux, int flags);
+
+/**
* omap3_mux_init() - initialize mux system with board specific set
* @board_mux: Board specific mux table
* @flags: OMAP package type used for the board
diff --git a/arch/arm/mach-omap2/mux2420.c b/arch/arm/mach-omap2/mux2420.c
new file mode 100644
index 000000000000..fdb04a7eb8aa
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2420.c
@@ -0,0 +1,688 @@
+/*
+ * Copyright (C) 2010 Nokia
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP2420_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP2420_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP2420_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap2420
+ */
+static struct omap_mux __initdata omap2420_muxmodes[] = {
+ _OMAP2420_MUXENTRY(CAM_D0, 54,
+ "cam_d0", "hw_dbg2", "sti_dout", "gpio_54",
+ NULL, NULL, "etk_d2", NULL),
+ _OMAP2420_MUXENTRY(CAM_D1, 53,
+ "cam_d1", "hw_dbg3", "sti_din", "gpio_53",
+ NULL, NULL, "etk_d3", NULL),
+ _OMAP2420_MUXENTRY(CAM_D2, 52,
+ "cam_d2", "hw_dbg4", "mcbsp1_clkx", "gpio_52",
+ NULL, NULL, "etk_d4", NULL),
+ _OMAP2420_MUXENTRY(CAM_D3, 51,
+ "cam_d3", "hw_dbg5", "mcbsp1_dr", "gpio_51",
+ NULL, NULL, "etk_d5", NULL),
+ _OMAP2420_MUXENTRY(CAM_D4, 50,
+ "cam_d4", "hw_dbg6", "mcbsp1_fsr", "gpio_50",
+ NULL, NULL, "etk_d6", NULL),
+ _OMAP2420_MUXENTRY(CAM_D5, 49,
+ "cam_d5", "hw_dbg7", "mcbsp1_clkr", "gpio_49",
+ NULL, NULL, "etk_d7", NULL),
+ _OMAP2420_MUXENTRY(CAM_D6, 0,
+ "cam_d6", "hw_dbg8", NULL, NULL,
+ NULL, NULL, "etk_d8", NULL),
+ _OMAP2420_MUXENTRY(CAM_D7, 0,
+ "cam_d7", "hw_dbg9", NULL, NULL,
+ NULL, NULL, "etk_d9", NULL),
+ _OMAP2420_MUXENTRY(CAM_D8, 54,
+ "cam_d8", "hw_dbg10", NULL, "gpio_54",
+ NULL, NULL, "etk_d10", NULL),
+ _OMAP2420_MUXENTRY(CAM_D9, 53,
+ "cam_d9", "hw_dbg11", NULL, "gpio_53",
+ NULL, NULL, "etk_d11", NULL),
+ _OMAP2420_MUXENTRY(CAM_HS, 55,
+ "cam_hs", "hw_dbg1", "mcbsp1_dx", "gpio_55",
+ NULL, NULL, "etk_d1", NULL),
+ _OMAP2420_MUXENTRY(CAM_LCLK, 57,
+ "cam_lclk", NULL, "mcbsp_clks", "gpio_57",
+ NULL, NULL, "etk_c1", NULL),
+ _OMAP2420_MUXENTRY(CAM_VS, 56,
+ "cam_vs", "hw_dbg0", "mcbsp1_fsx", "gpio_56",
+ NULL, NULL, "etk_d0", NULL),
+ _OMAP2420_MUXENTRY(CAM_XCLK, 0,
+ "cam_xclk", NULL, "sti_clk", NULL,
+ NULL, NULL, "etk_c2", NULL),
+ _OMAP2420_MUXENTRY(DSS_ACBIAS, 48,
+ "dss_acbias", NULL, "mcbsp2_fsx", "gpio_48",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA10, 40,
+ "dss_data10", NULL, NULL, "gpio_40",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA11, 41,
+ "dss_data11", NULL, NULL, "gpio_41",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA12, 42,
+ "dss_data12", NULL, NULL, "gpio_42",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA13, 43,
+ "dss_data13", NULL, NULL, "gpio_43",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA14, 44,
+ "dss_data14", NULL, NULL, "gpio_44",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA15, 45,
+ "dss_data15", NULL, NULL, "gpio_45",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA16, 46,
+ "dss_data16", NULL, NULL, "gpio_46",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA17, 47,
+ "dss_data17", NULL, NULL, "gpio_47",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA8, 38,
+ "dss_data8", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(DSS_DATA9, 39,
+ "dss_data9", NULL, NULL, "gpio_39",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_DIN, 115,
+ "eac_ac_din", "mcbsp2_dr", NULL, "gpio_115",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_DOUT, 116,
+ "eac_ac_dout", "mcbsp2_dx", NULL, "gpio_116",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_FS, 114,
+ "eac_ac_fs", "mcbsp2_fsx", NULL, "gpio_114",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_MCLK, 117,
+ "eac_ac_mclk", NULL, NULL, "gpio_117",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_RST, 118,
+ "eac_ac_rst", "eac_bt_din", NULL, "gpio_118",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_AC_SCLK, 113,
+ "eac_ac_sclk", "mcbsp2_clkx", NULL, "gpio_113",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_DIN, 73,
+ "eac_bt_din", NULL, NULL, "gpio_73",
+ NULL, NULL, "etk_d9", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_DOUT, 74,
+ "eac_bt_dout", NULL, "sti_clk", "gpio_74",
+ NULL, NULL, "etk_d8", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_FS, 72,
+ "eac_bt_fs", NULL, NULL, "gpio_72",
+ NULL, NULL, "etk_d10", NULL),
+ _OMAP2420_MUXENTRY(EAC_BT_SCLK, 71,
+ "eac_bt_sclk", NULL, NULL, "gpio_71",
+ NULL, NULL, "etk_d11", NULL),
+ _OMAP2420_MUXENTRY(GPIO_119, 119,
+ "gpio_119", NULL, "sti_din", "gpio_119",
+ NULL, "sys_boot0", "etk_d12", NULL),
+ _OMAP2420_MUXENTRY(GPIO_120, 120,
+ "gpio_120", NULL, "sti_dout", "gpio_120",
+ "cam_d9", "sys_boot1", "etk_d13", NULL),
+ _OMAP2420_MUXENTRY(GPIO_121, 121,
+ "gpio_121", NULL, NULL, "gpio_121",
+ "jtag_emu2", "sys_boot2", "etk_d14", NULL),
+ _OMAP2420_MUXENTRY(GPIO_122, 122,
+ "gpio_122", NULL, NULL, "gpio_122",
+ "jtag_emu3", "sys_boot3", "etk_d15", NULL),
+ _OMAP2420_MUXENTRY(GPIO_124, 124,
+ "gpio_124", NULL, NULL, "gpio_124",
+ NULL, "sys_boot5", NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_125, 125,
+ "gpio_125", "sys_jtagsel1", "sys_jtagsel2", "gpio_125",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_36, 36,
+ "gpio_36", NULL, NULL, "gpio_36",
+ NULL, "sys_boot4", NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_62, 62,
+ "gpio_62", "uart1_rx", "usb1_dat", "gpio_62",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPIO_6, 6,
+ "gpio_6", "tv_detpulse", NULL, "gpio_6",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A10, 3,
+ "gpmc_a10", NULL, "sys_ndmareq5", "gpio_3",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A1, 12,
+ "gpmc_a1", "dss_data18", NULL, "gpio_12",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A2, 11,
+ "gpmc_a2", "dss_data19", NULL, "gpio_11",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A3, 10,
+ "gpmc_a3", "dss_data20", NULL, "gpio_10",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A4, 9,
+ "gpmc_a4", "dss_data21", NULL, "gpio_9",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A5, 8,
+ "gpmc_a5", "dss_data22", NULL, "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A6, 7,
+ "gpmc_a6", "dss_data23", NULL, "gpio_7",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A7, 6,
+ "gpmc_a7", NULL, "sys_ndmareq2", "gpio_6",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A8, 5,
+ "gpmc_a8", NULL, "sys_ndmareq3", "gpio_5",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_A9, 4,
+ "gpmc_a9", NULL, "sys_ndmareq4", "gpio_4",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_CLK, 21,
+ "gpmc_clk", NULL, NULL, "gpio_21",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D10, 18,
+ "gpmc_d10", "ssi2_rdy_rx", NULL, "gpio_18",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D11, 17,
+ "gpmc_d11", "ssi2_flag_rx", NULL, "gpio_17",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D12, 16,
+ "gpmc_d12", "ssi2_dat_rx", NULL, "gpio_16",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D13, 15,
+ "gpmc_d13", "ssi2_rdy_tx", NULL, "gpio_15",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D14, 14,
+ "gpmc_d14", "ssi2_flag_tx", NULL, "gpio_14",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D15, 13,
+ "gpmc_d15", "ssi2_dat_tx", NULL, "gpio_13",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D8, 20,
+ "gpmc_d8", NULL, NULL, "gpio_20",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_D9, 19,
+ "gpmc_d9", "ssi2_wake", NULL, "gpio_19",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NBE0, 29,
+ "gpmc_nbe0", NULL, NULL, "gpio_29",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NBE1, 30,
+ "gpmc_nbe1", NULL, NULL, "gpio_30",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS1, 22,
+ "gpmc_ncs1", NULL, NULL, "gpio_22",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS2, 23,
+ "gpmc_ncs2", NULL, NULL, "gpio_23",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS3, 24,
+ "gpmc_ncs3", "gpmc_io_dir", NULL, "gpio_24",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS4, 25,
+ "gpmc_ncs4", NULL, NULL, "gpio_25",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS5, 26,
+ "gpmc_ncs5", NULL, NULL, "gpio_26",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS6, 27,
+ "gpmc_ncs6", NULL, NULL, "gpio_27",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NCS7, 28,
+ "gpmc_ncs7", "gpmc_io_dir", "gpio_28", NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_NWP, 31,
+ "gpmc_nwp", NULL, NULL, "gpio_31",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT1, 33,
+ "gpmc_wait1", NULL, NULL, "gpio_33",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT2, 34,
+ "gpmc_wait2", NULL, NULL, "gpio_34",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(GPMC_WAIT3, 35,
+ "gpmc_wait3", NULL, NULL, "gpio_35",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(HDQ_SIO, 101,
+ "hdq_sio", "usb2_tllse0", "sys_altclk", "gpio_101",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(I2C2_SCL, 99,
+ "i2c2_scl", NULL, "gpt9_pwm_evt", "gpio_99",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(I2C2_SDA, 100,
+ "i2c2_sda", NULL, "spi2_ncs1", "gpio_100",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(JTAG_EMU0, 127,
+ "jtag_emu0", NULL, NULL, "gpio_127",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(JTAG_EMU1, 126,
+ "jtag_emu1", NULL, NULL, "gpio_126",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_CLKR, 92,
+ "mcbsp1_clkr", "ssi2_dat_tx", "vlynq_tx1", "gpio_92",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_CLKX, 98,
+ "mcbsp1_clkx", "ssi2_wake", "vlynq_nla", "gpio_98",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_DR, 95,
+ "mcbsp1_dr", "ssi2_dat_rx", "vlynq_rx1", "gpio_95",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_DX, 94,
+ "mcbsp1_dx", "ssi2_rdy_tx", "vlynq_clk", "gpio_94",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_FSR, 93,
+ "mcbsp1_fsr", "ssi2_flag_tx", "vlynq_tx0", "gpio_93",
+ "spi2_ncs1", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP1_FSX, 97,
+ "mcbsp1_fsx", "ssi2_rdy_rx", NULL, "gpio_97",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP2_CLKX, 12,
+ "mcbsp2_clkx", NULL, "dss_data23", "gpio_12",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP2_DR, 11,
+ "mcbsp2_dr", NULL, "dss_data22", "gpio_11",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MCBSP_CLKS, 96,
+ "mcbsp_clks", "ssi2_flag_rx", "vlynq_rx0", "gpio_96",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CLKI, 59,
+ "sdmmc_clki", "ms_clki", NULL, "gpio_59",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CLKO, 0,
+ "sdmmc_clko", "ms_clko", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CMD_DIR, 8,
+ "sdmmc_cmd_dir", NULL, NULL, "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_CMD, 0,
+ "sdmmc_cmd", "ms_bs", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR0, 7,
+ "sdmmc_dat_dir0", "ms_dat0_dir", NULL, "gpio_7",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT0, 0,
+ "sdmmc_dat0", "ms_dat0", NULL, NULL,
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR1, 78,
+ "sdmmc_dat_dir1", "ms_datu_dir", "uart2_rts", "gpio_78",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT1, 75,
+ "sdmmc_dat1", "ms_dat1", NULL, "gpio_75",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR2, 79,
+ "sdmmc_dat_dir2", "ms_datu_dir", "uart2_tx", "gpio_79",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT2, 76,
+ "sdmmc_dat2", "ms_dat2", "uart2_cts", "gpio_76",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT_DIR3, 80,
+ "sdmmc_dat_dir3", "ms_datu_dir", "uart2_rx", "gpio_80",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(MMC_DAT3, 77,
+ "sdmmc_dat3", "ms_dat3", NULL, "gpio_77",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A12, 2,
+ "sdrc_a12", NULL, NULL, "gpio_2",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A13, 1,
+ "sdrc_a13", NULL, NULL, "gpio_1",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_A14, 0,
+ "sdrc_a14", NULL, NULL, "gpio_0",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_CKE1, 38,
+ "sdrc_cke1", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SDRC_NCS1, 37,
+ "sdrc_ncs1", NULL, NULL, "gpio_37",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_CLK, 81,
+ "spi1_clk", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS0, 84,
+ "spi1_ncs0", NULL, NULL, "gpio_84",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS1, 85,
+ "spi1_ncs1", NULL, NULL, "gpio_85",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS2, 86,
+ "spi1_ncs2", NULL, NULL, "gpio_86",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_NCS3, 87,
+ "spi1_ncs3", NULL, NULL, "gpio_87",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_SIMO, 82,
+ "spi1_simo", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI1_SOMI, 83,
+ "spi1_somi", NULL, NULL, "gpio_83",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_CLK, 88,
+ "spi2_clk", NULL, NULL, "gpio_88",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_NCS0, 91,
+ "spi2_ncs0", "gpt12_pwm_evt", NULL, "gpio_91",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_SIMO, 89,
+ "spi2_simo", "gpt10_pwm_evt", NULL, "gpio_89",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SPI2_SOMI, 90,
+ "spi2_somi", "gpt11_pwm_evt", NULL, "gpio_90",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_DAT_RX, 63,
+ "ssi1_dat_rx", "eac_md_sclk", NULL, "gpio_63",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_DAT_TX, 59,
+ "ssi1_dat_tx", "uart1_tx", "usb1_se0", "gpio_59",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_FLAG_RX, 64,
+ "ssi1_flag_rx", "eac_md_din", NULL, "gpio_64",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_FLAG_TX, 25,
+ "ssi1_flag_tx", "uart1_rts", "usb1_rcv", "gpio_25",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_RDY_RX, 65,
+ "ssi1_rdy_rx", "eac_md_dout", NULL, "gpio_65",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_RDY_TX, 61,
+ "ssi1_rdy_tx", "uart1_cts", "usb1_txen", "gpio_61",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SSI1_WAKE, 66,
+ "ssi1_wake", "eac_md_fs", NULL, "gpio_66",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_CLKOUT, 123,
+ "sys_clkout", NULL, NULL, "gpio_123",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_CLKREQ, 52,
+ "sys_clkreq", NULL, NULL, "gpio_52",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(SYS_NIRQ, 60,
+ "sys_nirq", NULL, NULL, "gpio_60",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_CTS, 32,
+ "uart1_cts", NULL, "dss_data18", "gpio_32",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_RTS, 8,
+ "uart1_rts", NULL, "dss_data19", "gpio_8",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_RX, 10,
+ "uart1_rx", NULL, "dss_data21", "gpio_10",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART1_TX, 9,
+ "uart1_tx", NULL, "dss_data20", "gpio_9",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_CTS, 67,
+ "uart2_cts", "usb1_rcv", "gpt9_pwm_evt", "gpio_67",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_RTS, 68,
+ "uart2_rts", "usb1_txen", "gpt10_pwm_evt", "gpio_68",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_RX, 70,
+ "uart2_rx", "usb1_dat", "gpt12_pwm_evt", "gpio_70",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART2_TX, 69,
+ "uart2_tx", "usb1_se0", "gpt11_pwm_evt", "gpio_69",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_CTS_RCTX, 102,
+ "uart3_cts_rctx", "uart3_rx_irrx", NULL, "gpio_102",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_RTS_SD, 103,
+ "uart3_rts_sd", "uart3_tx_irtx", NULL, "gpio_103",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_RX_IRRX, 105,
+ "uart3_rx_irrx", NULL, NULL, "gpio_105",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(UART3_TX_IRTX, 104,
+ "uart3_tx_irtx", "uart3_cts_rctx", NULL, "gpio_104",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_DAT, 112,
+ "usb0_dat", "uart3_rx_irrx", "uart2_rx", "gpio_112",
+ "uart2_tx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_PUEN, 106,
+ "usb0_puen", "mcbsp2_dx", NULL, "gpio_106",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_RCV, 109,
+ "usb0_rcv", "mcbsp2_fsx", NULL, "gpio_109",
+ "uart2_cts", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_SE0, 111,
+ "usb0_se0", "uart3_tx_irtx", "uart2_tx", "gpio_111",
+ "uart2_rx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_TXEN, 110,
+ "usb0_txen", "uart3_cts_rctx", "uart2_cts", "gpio_110",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_VM, 108,
+ "usb0_vm", "mcbsp2_clkx", NULL, "gpio_108",
+ "uart2_rx", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(USB0_VP, 107,
+ "usb0_vp", "mcbsp2_dr", NULL, "gpio_107",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_CLK, 13,
+ "vlynq_clk", "usb2_se0", "sys_ndmareq0", "gpio_13",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_NLA, 58,
+ "vlynq_nla", NULL, NULL, "gpio_58",
+ "cam_d6", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_RX0, 15,
+ "vlynq_rx0", "usb2_tllse0", NULL, "gpio_15",
+ "cam_d7", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_RX1, 14,
+ "vlynq_rx1", "usb2_rcv", "sys_ndmareq1", "gpio_14",
+ "cam_d8", NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_TX0, 17,
+ "vlynq_tx0", "usb2_txen", NULL, "gpio_17",
+ NULL, NULL, NULL, NULL),
+ _OMAP2420_MUXENTRY(VLYNQ_TX1, 16,
+ "vlynq_tx1", "usb2_dat", "sys_clkout2", "gpio_16",
+ NULL, NULL, NULL, NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for 447-pin POP package
+ */
+#ifdef CONFIG_DEBUG_FS
+struct omap_ball __initdata omap2420_pop_ball[] = {
+ _OMAP2420_BALLENTRY(CAM_D0, "y4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D1, "y3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D2, "u7", NULL),
+ _OMAP2420_BALLENTRY(CAM_D3, "ab3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D4, "v2", NULL),
+ _OMAP2420_BALLENTRY(CAM_D5, "ad3", NULL),
+ _OMAP2420_BALLENTRY(CAM_D6, "aa4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D7, "ab4", NULL),
+ _OMAP2420_BALLENTRY(CAM_D8, "ac6", NULL),
+ _OMAP2420_BALLENTRY(CAM_D9, "ac7", NULL),
+ _OMAP2420_BALLENTRY(CAM_HS, "v4", NULL),
+ _OMAP2420_BALLENTRY(CAM_LCLK, "ad6", NULL),
+ _OMAP2420_BALLENTRY(CAM_VS, "p7", NULL),
+ _OMAP2420_BALLENTRY(CAM_XCLK, "w4", NULL),
+ _OMAP2420_BALLENTRY(DSS_ACBIAS, "ae8", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA10, "ac12", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA11, "ae11", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA12, "ae13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA13, "ad13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA14, "ac13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA15, "y12", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA16, "ad14", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA17, "y13", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA8, "ad11", NULL),
+ _OMAP2420_BALLENTRY(DSS_DATA9, "ad12", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_DIN, "ad19", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_DOUT, "af22", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_FS, "ad16", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_MCLK, "y17", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_RST, "ae22", NULL),
+ _OMAP2420_BALLENTRY(EAC_AC_SCLK, "ac18", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_DIN, "u8", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_DOUT, "ad5", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_FS, "w7", NULL),
+ _OMAP2420_BALLENTRY(EAC_BT_SCLK, "ad4", NULL),
+ _OMAP2420_BALLENTRY(GPIO_119, "af6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_120, "af4", NULL),
+ _OMAP2420_BALLENTRY(GPIO_121, "ae6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_122, "w3", NULL),
+ _OMAP2420_BALLENTRY(GPIO_124, "y19", NULL),
+ _OMAP2420_BALLENTRY(GPIO_125, "ae24", NULL),
+ _OMAP2420_BALLENTRY(GPIO_36, "y18", NULL),
+ _OMAP2420_BALLENTRY(GPIO_6, "d6", NULL),
+ _OMAP2420_BALLENTRY(GPIO_62, "ad18", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A1, "m8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A10, "d5", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A2, "w9", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A3, "af10", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A4, "w8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A5, "ae16", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A6, "af9", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A7, "e4", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A8, "j7", NULL),
+ _OMAP2420_BALLENTRY(GPMC_A9, "ae18", NULL),
+ _OMAP2420_BALLENTRY(GPMC_CLK, "p1", "l1"),
+ _OMAP2420_BALLENTRY(GPMC_D10, "t1", "n1"),
+ _OMAP2420_BALLENTRY(GPMC_D11, "u2", "p2"),
+ _OMAP2420_BALLENTRY(GPMC_D12, "u1", "p1"),
+ _OMAP2420_BALLENTRY(GPMC_D13, "p2", "m1"),
+ _OMAP2420_BALLENTRY(GPMC_D14, "h2", "j2"),
+ _OMAP2420_BALLENTRY(GPMC_D15, "h1", "k2"),
+ _OMAP2420_BALLENTRY(GPMC_D8, "v1", "r1"),
+ _OMAP2420_BALLENTRY(GPMC_D9, "y1", "t1"),
+ _OMAP2420_BALLENTRY(GPMC_NBE0, "af12", "aa10"),
+ _OMAP2420_BALLENTRY(GPMC_NBE1, "u3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS1, "af14", "w1"),
+ _OMAP2420_BALLENTRY(GPMC_NCS2, "g4", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS3, "t8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS4, "h8", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS5, "k3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS6, "m7", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NCS7, "p3", NULL),
+ _OMAP2420_BALLENTRY(GPMC_NWP, "ae15", "y5"),
+ _OMAP2420_BALLENTRY(GPMC_WAIT1, "ae20", "y8"),
+ _OMAP2420_BALLENTRY(GPMC_WAIT2, "n2", NULL),
+ _OMAP2420_BALLENTRY(GPMC_WAIT3, "t4", NULL),
+ _OMAP2420_BALLENTRY(HDQ_SIO, "t23", NULL),
+ _OMAP2420_BALLENTRY(I2C2_SCL, "l2", NULL),
+ _OMAP2420_BALLENTRY(I2C2_SDA, "k19", NULL),
+ _OMAP2420_BALLENTRY(JTAG_EMU0, "n24", NULL),
+ _OMAP2420_BALLENTRY(JTAG_EMU1, "ac22", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_CLKR, "y24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_CLKX, "t19", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_DR, "u23", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_DX, "r24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_FSR, "r20", NULL),
+ _OMAP2420_BALLENTRY(MCBSP1_FSX, "r23", NULL),
+ _OMAP2420_BALLENTRY(MCBSP2_CLKX, "t24", NULL),
+ _OMAP2420_BALLENTRY(MCBSP2_DR, "p20", NULL),
+ _OMAP2420_BALLENTRY(MCBSP_CLKS, "p23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CLKI, "c23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CLKO, "h23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CMD, "j23", NULL),
+ _OMAP2420_BALLENTRY(MMC_CMD_DIR, "j24", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT0, "h17", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR0, "f23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT1, "g19", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR1, "d23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT2, "h20", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR2, "g23", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT3, "d24", NULL),
+ _OMAP2420_BALLENTRY(MMC_DAT_DIR3, "e23", NULL),
+ _OMAP2420_BALLENTRY(SDRC_A12, "w26", "r21"),
+ _OMAP2420_BALLENTRY(SDRC_A13, "w25", "aa15"),
+ _OMAP2420_BALLENTRY(SDRC_A14, "aa26", "y12"),
+ _OMAP2420_BALLENTRY(SDRC_CKE1, "ae25", "y13"),
+ _OMAP2420_BALLENTRY(SDRC_NCS1, "y25", "t20"),
+ _OMAP2420_BALLENTRY(SPI1_CLK, "y23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS0, "w24", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS1, "w23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS2, "v23", NULL),
+ _OMAP2420_BALLENTRY(SPI1_NCS3, "u20", NULL),
+ _OMAP2420_BALLENTRY(SPI1_SIMO, "h10", NULL),
+ _OMAP2420_BALLENTRY(SPI1_SOMI, "v19", NULL),
+ _OMAP2420_BALLENTRY(SPI2_CLK, "v24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_NCS0, "aa24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_SIMO, "u24", NULL),
+ _OMAP2420_BALLENTRY(SPI2_SOMI, "v25", NULL),
+ _OMAP2420_BALLENTRY(SSI1_DAT_RX, "w15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_DAT_TX, "w13", NULL),
+ _OMAP2420_BALLENTRY(SSI1_FLAG_RX, "af11", NULL),
+ _OMAP2420_BALLENTRY(SSI1_FLAG_TX, "ac15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_RDY_RX, "ac16", NULL),
+ _OMAP2420_BALLENTRY(SSI1_RDY_TX, "af15", NULL),
+ _OMAP2420_BALLENTRY(SSI1_WAKE, "ad15", NULL),
+ _OMAP2420_BALLENTRY(SYS_CLKOUT, "ae19", NULL),
+ _OMAP2420_BALLENTRY(SYS_CLKREQ, "ad20", NULL),
+ _OMAP2420_BALLENTRY(SYS_NIRQ, "y20", NULL),
+ _OMAP2420_BALLENTRY(UART1_CTS, "g20", NULL),
+ _OMAP2420_BALLENTRY(UART1_RTS, "k20", NULL),
+ _OMAP2420_BALLENTRY(UART1_RX, "t20", NULL),
+ _OMAP2420_BALLENTRY(UART1_TX, "h12", NULL),
+ _OMAP2420_BALLENTRY(UART2_CTS, "ac24", NULL),
+ _OMAP2420_BALLENTRY(UART2_RTS, "w20", NULL),
+ _OMAP2420_BALLENTRY(UART2_RX, "ad24", NULL),
+ _OMAP2420_BALLENTRY(UART2_TX, "ab24", NULL),
+ _OMAP2420_BALLENTRY(UART3_CTS_RCTX, "k24", NULL),
+ _OMAP2420_BALLENTRY(UART3_RTS_SD, "m20", NULL),
+ _OMAP2420_BALLENTRY(UART3_RX_IRRX, "h24", NULL),
+ _OMAP2420_BALLENTRY(UART3_TX_IRTX, "g24", NULL),
+ _OMAP2420_BALLENTRY(USB0_DAT, "j25", NULL),
+ _OMAP2420_BALLENTRY(USB0_PUEN, "l23", NULL),
+ _OMAP2420_BALLENTRY(USB0_RCV, "k23", NULL),
+ _OMAP2420_BALLENTRY(USB0_SE0, "l24", NULL),
+ _OMAP2420_BALLENTRY(USB0_TXEN, "m24", NULL),
+ _OMAP2420_BALLENTRY(USB0_VM, "n23", NULL),
+ _OMAP2420_BALLENTRY(USB0_VP, "m23", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_CLK, "w12", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_NLA, "ae10", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_RX0, "ad7", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_RX1, "w10", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_TX0, "y15", NULL),
+ _OMAP2420_BALLENTRY(VLYNQ_TX1, "w14", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap2420_pop_ball NULL
+#endif
+
+int __init omap2420_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_ball *package_balls = NULL;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_ZAC:
+ package_balls = omap2420_pop_ball;
+ break;
+ case OMAP_PACKAGE_ZAF:
+ /* REVISIT: Please add data */
+ default:
+ pr_warning("mux: No ball data available for omap2420 package\n");
+ }
+
+ return omap_mux_init(OMAP2420_CONTROL_PADCONF_MUX_PBASE,
+ OMAP2420_CONTROL_PADCONF_MUX_SIZE,
+ omap2420_muxmodes, NULL, board_subset,
+ package_balls);
+}
diff --git a/arch/arm/mach-omap2/mux2420.h b/arch/arm/mach-omap2/mux2420.h
new file mode 100644
index 000000000000..0f555aa847b5
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2420.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP2420_CONTROL_PADCONF_MUX_PBASE 0x48000030LU
+
+#define OMAP2420_MUX(mode0, mux_value) \
+{ \
+ .reg_offset = (OMAP2420_CONTROL_PADCONF_##mode0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/*
+ * OMAP2420 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM. Add 0x48000030 to these values to get the
+ * absolute addresses. The name in the macro is the mode-0 name of
+ * the pin. NOTE: These registers are 8-bits wide.
+ */
+#define OMAP2420_CONTROL_PADCONF_SDRC_A14_OFFSET 0x000
+#define OMAP2420_CONTROL_PADCONF_SDRC_A13_OFFSET 0x001
+#define OMAP2420_CONTROL_PADCONF_SDRC_A12_OFFSET 0x002
+#define OMAP2420_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x003
+#define OMAP2420_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x004
+#define OMAP2420_CONTROL_PADCONF_SDRC_A11_OFFSET 0x005
+#define OMAP2420_CONTROL_PADCONF_SDRC_A10_OFFSET 0x006
+#define OMAP2420_CONTROL_PADCONF_SDRC_A9_OFFSET 0x007
+#define OMAP2420_CONTROL_PADCONF_SDRC_A8_OFFSET 0x008
+#define OMAP2420_CONTROL_PADCONF_SDRC_A7_OFFSET 0x009
+#define OMAP2420_CONTROL_PADCONF_SDRC_A6_OFFSET 0x00a
+#define OMAP2420_CONTROL_PADCONF_SDRC_A5_OFFSET 0x00b
+#define OMAP2420_CONTROL_PADCONF_SDRC_A4_OFFSET 0x00c
+#define OMAP2420_CONTROL_PADCONF_SDRC_A3_OFFSET 0x00d
+#define OMAP2420_CONTROL_PADCONF_SDRC_A2_OFFSET 0x00e
+#define OMAP2420_CONTROL_PADCONF_SDRC_A1_OFFSET 0x00f
+#define OMAP2420_CONTROL_PADCONF_SDRC_A0_OFFSET 0x010
+#define OMAP2420_CONTROL_PADCONF_SDRC_D31_OFFSET 0x021
+#define OMAP2420_CONTROL_PADCONF_SDRC_D30_OFFSET 0x022
+#define OMAP2420_CONTROL_PADCONF_SDRC_D29_OFFSET 0x023
+#define OMAP2420_CONTROL_PADCONF_SDRC_D28_OFFSET 0x024
+#define OMAP2420_CONTROL_PADCONF_SDRC_D27_OFFSET 0x025
+#define OMAP2420_CONTROL_PADCONF_SDRC_D26_OFFSET 0x026
+#define OMAP2420_CONTROL_PADCONF_SDRC_D25_OFFSET 0x027
+#define OMAP2420_CONTROL_PADCONF_SDRC_D24_OFFSET 0x028
+#define OMAP2420_CONTROL_PADCONF_SDRC_D23_OFFSET 0x029
+#define OMAP2420_CONTROL_PADCONF_SDRC_D22_OFFSET 0x02a
+#define OMAP2420_CONTROL_PADCONF_SDRC_D21_OFFSET 0x02b
+#define OMAP2420_CONTROL_PADCONF_SDRC_D20_OFFSET 0x02c
+#define OMAP2420_CONTROL_PADCONF_SDRC_D19_OFFSET 0x02d
+#define OMAP2420_CONTROL_PADCONF_SDRC_D18_OFFSET 0x02e
+#define OMAP2420_CONTROL_PADCONF_SDRC_D17_OFFSET 0x02f
+#define OMAP2420_CONTROL_PADCONF_SDRC_D16_OFFSET 0x030
+#define OMAP2420_CONTROL_PADCONF_SDRC_D15_OFFSET 0x031
+#define OMAP2420_CONTROL_PADCONF_SDRC_D14_OFFSET 0x032
+#define OMAP2420_CONTROL_PADCONF_SDRC_D13_OFFSET 0x033
+#define OMAP2420_CONTROL_PADCONF_SDRC_D12_OFFSET 0x034
+#define OMAP2420_CONTROL_PADCONF_SDRC_D11_OFFSET 0x035
+#define OMAP2420_CONTROL_PADCONF_SDRC_D10_OFFSET 0x036
+#define OMAP2420_CONTROL_PADCONF_SDRC_D9_OFFSET 0x037
+#define OMAP2420_CONTROL_PADCONF_SDRC_D8_OFFSET 0x038
+#define OMAP2420_CONTROL_PADCONF_SDRC_D7_OFFSET 0x039
+#define OMAP2420_CONTROL_PADCONF_SDRC_D6_OFFSET 0x03a
+#define OMAP2420_CONTROL_PADCONF_SDRC_D5_OFFSET 0x03b
+#define OMAP2420_CONTROL_PADCONF_SDRC_D4_OFFSET 0x03c
+#define OMAP2420_CONTROL_PADCONF_SDRC_D3_OFFSET 0x03d
+#define OMAP2420_CONTROL_PADCONF_SDRC_D2_OFFSET 0x03e
+#define OMAP2420_CONTROL_PADCONF_SDRC_D1_OFFSET 0x03f
+#define OMAP2420_CONTROL_PADCONF_SDRC_D0_OFFSET 0x040
+#define OMAP2420_CONTROL_PADCONF_GPMC_A10_OFFSET 0x041
+#define OMAP2420_CONTROL_PADCONF_GPMC_A9_OFFSET 0x042
+#define OMAP2420_CONTROL_PADCONF_GPMC_A8_OFFSET 0x043
+#define OMAP2420_CONTROL_PADCONF_GPMC_A7_OFFSET 0x044
+#define OMAP2420_CONTROL_PADCONF_GPMC_A6_OFFSET 0x045
+#define OMAP2420_CONTROL_PADCONF_GPMC_A5_OFFSET 0x046
+#define OMAP2420_CONTROL_PADCONF_GPMC_A4_OFFSET 0x047
+#define OMAP2420_CONTROL_PADCONF_GPMC_A3_OFFSET 0x048
+#define OMAP2420_CONTROL_PADCONF_GPMC_A2_OFFSET 0x049
+#define OMAP2420_CONTROL_PADCONF_GPMC_A1_OFFSET 0x04a
+#define OMAP2420_CONTROL_PADCONF_GPMC_D15_OFFSET 0x04b
+#define OMAP2420_CONTROL_PADCONF_GPMC_D14_OFFSET 0x04c
+#define OMAP2420_CONTROL_PADCONF_GPMC_D13_OFFSET 0x04d
+#define OMAP2420_CONTROL_PADCONF_GPMC_D12_OFFSET 0x04e
+#define OMAP2420_CONTROL_PADCONF_GPMC_D11_OFFSET 0x04f
+#define OMAP2420_CONTROL_PADCONF_GPMC_D10_OFFSET 0x050
+#define OMAP2420_CONTROL_PADCONF_GPMC_D9_OFFSET 0x051
+#define OMAP2420_CONTROL_PADCONF_GPMC_D8_OFFSET 0x052
+#define OMAP2420_CONTROL_PADCONF_GPMC_D7_OFFSET 0x053
+#define OMAP2420_CONTROL_PADCONF_GPMC_D6_OFFSET 0x054
+#define OMAP2420_CONTROL_PADCONF_GPMC_D5_OFFSET 0x055
+#define OMAP2420_CONTROL_PADCONF_GPMC_D4_OFFSET 0x056
+#define OMAP2420_CONTROL_PADCONF_GPMC_D3_OFFSET 0x057
+#define OMAP2420_CONTROL_PADCONF_GPMC_D2_OFFSET 0x058
+#define OMAP2420_CONTROL_PADCONF_GPMC_D1_OFFSET 0x059
+#define OMAP2420_CONTROL_PADCONF_GPMC_D0_OFFSET 0x05a
+#define OMAP2420_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x05b
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x05c
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x05d
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x05e
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x05f
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x060
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x061
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x062
+#define OMAP2420_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x063
+#define OMAP2420_CONTROL_PADCONF_GPMC_NALE_ALE_OFFSET 0x064
+#define OMAP2420_CONTROL_PADCONF_GPMC_NOE_OFFSET 0x065
+#define OMAP2420_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x066
+#define OMAP2420_CONTROL_PADCONF_GPMC_NBE0_OFFSET 0x067
+#define OMAP2420_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x068
+#define OMAP2420_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x069
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x06a
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x06b
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x06c
+#define OMAP2420_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x06d
+#define OMAP2420_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x06e
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x06f
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x070
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x071
+#define OMAP2420_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x072
+#define OMAP2420_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x073
+#define OMAP2420_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x074
+#define OMAP2420_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x075
+#define OMAP2420_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x076
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x077
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x078
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x079
+#define OMAP2420_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x07a
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x07f
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x080
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x081
+#define OMAP2420_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x082
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x083
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x084
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x085
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x086
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x087
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x088
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x089
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x08a
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x08b
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x08c
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x08d
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x08e
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x08f
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x090
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x091
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x092
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x093
+#define OMAP2420_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x094
+#define OMAP2420_CONTROL_PADCONF_UART1_CTS_OFFSET 0x095
+#define OMAP2420_CONTROL_PADCONF_UART1_RTS_OFFSET 0x096
+#define OMAP2420_CONTROL_PADCONF_UART1_TX_OFFSET 0x097
+#define OMAP2420_CONTROL_PADCONF_UART1_RX_OFFSET 0x098
+#define OMAP2420_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x099
+#define OMAP2420_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x09a
+#define OMAP2420_CONTROL_PADCONF_DSS_PCL_OFFSET 0x09b
+#define OMAP2420_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x09c
+#define OMAP2420_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x09d
+#define OMAP2420_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x09e
+#define OMAP2420_CONTROL_PADCONF_CAM_D9_OFFSET 0x09f
+#define OMAP2420_CONTROL_PADCONF_CAM_D8_OFFSET 0x0a0
+#define OMAP2420_CONTROL_PADCONF_CAM_D7_OFFSET 0x0a1
+#define OMAP2420_CONTROL_PADCONF_CAM_D6_OFFSET 0x0a2
+#define OMAP2420_CONTROL_PADCONF_CAM_D5_OFFSET 0x0a3
+#define OMAP2420_CONTROL_PADCONF_CAM_D4_OFFSET 0x0a4
+#define OMAP2420_CONTROL_PADCONF_CAM_D3_OFFSET 0x0a5
+#define OMAP2420_CONTROL_PADCONF_CAM_D2_OFFSET 0x0a6
+#define OMAP2420_CONTROL_PADCONF_CAM_D1_OFFSET 0x0a7
+#define OMAP2420_CONTROL_PADCONF_CAM_D0_OFFSET 0x0a8
+#define OMAP2420_CONTROL_PADCONF_CAM_HS_OFFSET 0x0a9
+#define OMAP2420_CONTROL_PADCONF_CAM_VS_OFFSET 0x0aa
+#define OMAP2420_CONTROL_PADCONF_CAM_LCLK_OFFSET 0x0ab
+#define OMAP2420_CONTROL_PADCONF_CAM_XCLK_OFFSET 0x0ac
+#define OMAP2420_CONTROL_PADCONF_SSI1_DAT_TX_OFFSET 0x0ad
+#define OMAP2420_CONTROL_PADCONF_SSI1_FLAG_TX_OFFSET 0x0ae
+#define OMAP2420_CONTROL_PADCONF_SSI1_RDY_TX_OFFSET 0x0af
+#define OMAP2420_CONTROL_PADCONF_GPIO_62_OFFSET 0x0b0
+#define OMAP2420_CONTROL_PADCONF_SSI1_DAT_RX_OFFSET 0x0b1
+#define OMAP2420_CONTROL_PADCONF_SSI1_FLAG_RX_OFFSET 0x0b2
+#define OMAP2420_CONTROL_PADCONF_SSI1_RDY_RX_OFFSET 0x0b3
+#define OMAP2420_CONTROL_PADCONF_SSI1_WAKE_OFFSET 0x0b4
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_CLK_OFFSET 0x0b5
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_RX1_OFFSET 0x0b6
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_RX0_OFFSET 0x0b7
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_TX1_OFFSET 0x0b8
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_TX0_OFFSET 0x0b9
+#define OMAP2420_CONTROL_PADCONF_VLYNQ_NLA_OFFSET 0x0ba
+#define OMAP2420_CONTROL_PADCONF_UART2_CTS_OFFSET 0x0bb
+#define OMAP2420_CONTROL_PADCONF_UART2_RTS_OFFSET 0x0bc
+#define OMAP2420_CONTROL_PADCONF_UART2_TX_OFFSET 0x0bd
+#define OMAP2420_CONTROL_PADCONF_UART2_RX_OFFSET 0x0be
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_SCLK_OFFSET 0x0bf
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_FS_OFFSET 0x0c0
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_DIN_OFFSET 0x0c1
+#define OMAP2420_CONTROL_PADCONF_EAC_BT_DOUT_OFFSET 0x0c2
+#define OMAP2420_CONTROL_PADCONF_MMC_CLKO_OFFSET 0x0c3
+#define OMAP2420_CONTROL_PADCONF_MMC_CMD_OFFSET 0x0c4
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT0_OFFSET 0x0c5
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT1_OFFSET 0x0c6
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT2_OFFSET 0x0c7
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT3_OFFSET 0x0c8
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR0_OFFSET 0x0c9
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR1_OFFSET 0x0ca
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR2_OFFSET 0x0cb
+#define OMAP2420_CONTROL_PADCONF_MMC_DAT_DIR3_OFFSET 0x0cc
+#define OMAP2420_CONTROL_PADCONF_MMC_CMD_DIR_OFFSET 0x0cd
+#define OMAP2420_CONTROL_PADCONF_MMC_CLKI_OFFSET 0x0ce
+#define OMAP2420_CONTROL_PADCONF_SPI1_CLK_OFFSET 0x0cf
+#define OMAP2420_CONTROL_PADCONF_SPI1_SIMO_OFFSET 0x0d0
+#define OMAP2420_CONTROL_PADCONF_SPI1_SOMI_OFFSET 0x0d1
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS0_OFFSET 0x0d2
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS1_OFFSET 0x0d3
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS2_OFFSET 0x0d4
+#define OMAP2420_CONTROL_PADCONF_SPI1_NCS3_OFFSET 0x0d5
+#define OMAP2420_CONTROL_PADCONF_SPI2_CLK_OFFSET 0x0d6
+#define OMAP2420_CONTROL_PADCONF_SPI2_SIMO_OFFSET 0x0d7
+#define OMAP2420_CONTROL_PADCONF_SPI2_SOMI_OFFSET 0x0d8
+#define OMAP2420_CONTROL_PADCONF_SPI2_NCS0_OFFSET 0x0d9
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x0da
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x0db
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x0dc
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x0dd
+#define OMAP2420_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x0de
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x0df
+#define OMAP2420_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x0e0
+#define OMAP2420_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x0e1
+#define OMAP2420_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x0e2
+#define OMAP2420_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x0e3
+#define OMAP2420_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x0e4
+#define OMAP2420_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x0e5
+#define OMAP2420_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x0e6
+#define OMAP2420_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x0e7
+#define OMAP2420_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x0e8
+#define OMAP2420_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x0e9
+#define OMAP2420_CONTROL_PADCONF_TV_CVBS_OFFSET 0x0ea
+#define OMAP2420_CONTROL_PADCONF_TV_VREF_OFFSET 0x0eb
+#define OMAP2420_CONTROL_PADCONF_TV_RREF_OFFSET 0x0ec
+#define OMAP2420_CONTROL_PADCONF_USB0_PUEN_OFFSET 0x0ed
+#define OMAP2420_CONTROL_PADCONF_USB0_VP_OFFSET 0x0ee
+#define OMAP2420_CONTROL_PADCONF_USB0_VM_OFFSET 0x0ef
+#define OMAP2420_CONTROL_PADCONF_USB0_RCV_OFFSET 0x0f0
+#define OMAP2420_CONTROL_PADCONF_USB0_TXEN_OFFSET 0x0f1
+#define OMAP2420_CONTROL_PADCONF_USB0_SE0_OFFSET 0x0f2
+#define OMAP2420_CONTROL_PADCONF_USB0_DAT_OFFSET 0x0f3
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_SCLK_OFFSET 0x0f4
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_FS_OFFSET 0x0f5
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_DIN_OFFSET 0x0f6
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_DOUT_OFFSET 0x0f7
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_MCLK_OFFSET 0x0f8
+#define OMAP2420_CONTROL_PADCONF_EAC_AC_RST_OFFSET 0x0f9
+#define OMAP2420_CONTROL_PADCONF_SYS_NRESPWRON_OFFSET 0x0fa
+#define OMAP2420_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x0fb
+#define OMAP2420_CONTROL_PADCONF_SYS_NIRQ_OFFSET 0x0fc
+#define OMAP2420_CONTROL_PADCONF_SYS_NV_OFFSET 0x0fd
+#define OMAP2420_CONTROL_PADCONF_GPIO_119_OFFSET 0x0fe
+#define OMAP2420_CONTROL_PADCONF_GPIO_120_OFFSET 0x0ff
+#define OMAP2420_CONTROL_PADCONF_GPIO_121_OFFSET 0x100
+#define OMAP2420_CONTROL_PADCONF_GPIO_122_OFFSET 0x101
+#define OMAP2420_CONTROL_PADCONF_SYS_32K_OFFSET 0x102
+#define OMAP2420_CONTROL_PADCONF_SYS_XTALIN_OFFSET 0x103
+#define OMAP2420_CONTROL_PADCONF_SYS_XTALOUT_OFFSET 0x104
+#define OMAP2420_CONTROL_PADCONF_GPIO_36_OFFSET 0x105
+#define OMAP2420_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x106
+#define OMAP2420_CONTROL_PADCONF_SYS_CLKOUT_OFFSET 0x107
+#define OMAP2420_CONTROL_PADCONF_GPIO_6_OFFSET 0x108
+#define OMAP2420_CONTROL_PADCONF_GPIO_124_OFFSET 0x109
+#define OMAP2420_CONTROL_PADCONF_GPIO_125_OFFSET 0x10a
+#define OMAP2420_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x10b
+#define OMAP2420_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x10c
+#define OMAP2420_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x10d
+#define OMAP2420_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x10e
+#define OMAP2420_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0x10f
+#define OMAP2420_CONTROL_PADCONF_JTAG_TMS_OFFSET 0x110
+#define OMAP2420_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x111
+#define OMAP2420_CONTROL_PADCONF_JTAG_TDO_OFFSET 0x112
+
+#define OMAP2420_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP2420_CONTROL_PADCONF_JTAG_TDO_OFFSET + 0x1)
diff --git a/arch/arm/mach-omap2/mux2430.c b/arch/arm/mach-omap2/mux2430.c
new file mode 100644
index 000000000000..7dcaaa8af32a
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2430.c
@@ -0,0 +1,791 @@
+/*
+ * Copyright (C) 2010 Nokia
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include "mux.h"
+
+#ifdef CONFIG_OMAP_MUX
+
+#define _OMAP2430_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+ .muxnames = { m0, m1, m2, m3, m4, m5, m6, m7 }, \
+}
+
+#else
+
+#define _OMAP2430_MUXENTRY(M0, g, m0, m1, m2, m3, m4, m5, m6, m7) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .gpio = (g), \
+}
+
+#endif
+
+#define _OMAP2430_BALLENTRY(M0, bb, bt) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##M0##_OFFSET), \
+ .balls = { bb, bt }, \
+}
+
+/*
+ * Superset of all mux modes for omap2430
+ */
+static struct omap_mux __initdata omap2430_muxmodes[] = {
+ _OMAP2430_MUXENTRY(CAM_D0, 133,
+ "cam_d0", "hw_dbg0", "sti_dout", "gpio_133",
+ NULL, NULL, "etk_d2", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D10, 146,
+ "cam_d10", NULL, NULL, "gpio_146",
+ NULL, NULL, "etk_d12", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D11, 145,
+ "cam_d11", NULL, NULL, "gpio_145",
+ NULL, NULL, "etk_d13", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D1, 132,
+ "cam_d1", "hw_dbg1", "sti_din", "gpio_132",
+ NULL, NULL, "etk_d3", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D2, 129,
+ "cam_d2", "hw_dbg2", "mcbsp1_clkx", "gpio_129",
+ NULL, NULL, "etk_d4", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D3, 128,
+ "cam_d3", "hw_dbg3", "mcbsp1_dr", "gpio_128",
+ NULL, NULL, "etk_d5", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D4, 143,
+ "cam_d4", "hw_dbg4", "mcbsp1_fsr", "gpio_143",
+ NULL, NULL, "etk_d6", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D5, 112,
+ "cam_d5", "hw_dbg5", "mcbsp1_clkr", "gpio_112",
+ NULL, NULL, "etk_d7", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D6, 137,
+ "cam_d6", "hw_dbg6", NULL, "gpio_137",
+ NULL, NULL, "etk_d8", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D7, 136,
+ "cam_d7", "hw_dbg7", NULL, "gpio_136",
+ NULL, NULL, "etk_d9", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D8, 135,
+ "cam_d8", "hw_dbg8", NULL, "gpio_135",
+ NULL, NULL, "etk_d10", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_D9, 134,
+ "cam_d9", "hw_dbg9", NULL, "gpio_134",
+ NULL, NULL, "etk_d11", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_HS, 11,
+ "cam_hs", "hw_dbg10", "mcbsp1_dx", "gpio_11",
+ NULL, NULL, "etk_d1", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_LCLK, 0,
+ "cam_lclk", NULL, "mcbsp_clks", NULL,
+ NULL, NULL, "etk_c1", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_VS, 12,
+ "cam_vs", "hw_dbg11", "mcbsp1_fsx", "gpio_12",
+ NULL, NULL, "etk_d0", "safe_mode"),
+ _OMAP2430_MUXENTRY(CAM_XCLK, 0,
+ "cam_xclk", NULL, "sti_clk", NULL,
+ NULL, NULL, "etk_c2", NULL),
+ _OMAP2430_MUXENTRY(DSS_ACBIAS, 48,
+ "dss_acbias", NULL, "mcbsp2_fsx", "gpio_48",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA0, 40,
+ "dss_data0", "uart1_cts", NULL, "gpio_40",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA10, 128,
+ "dss_data10", "sdi_data1n", NULL, "gpio_128",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA11, 129,
+ "dss_data11", "sdi_data1p", NULL, "gpio_129",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA12, 130,
+ "dss_data12", "sdi_data2n", NULL, "gpio_130",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA13, 131,
+ "dss_data13", "sdi_data2p", NULL, "gpio_131",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA14, 132,
+ "dss_data14", "sdi_data3n", NULL, "gpio_132",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA15, 133,
+ "dss_data15", "sdi_data3p", NULL, "gpio_133",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA16, 46,
+ "dss_data16", NULL, NULL, "gpio_46",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA17, 47,
+ "dss_data17", NULL, NULL, "gpio_47",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA1, 41,
+ "dss_data1", "uart1_rts", NULL, "gpio_41",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA2, 42,
+ "dss_data2", "uart1_tx", NULL, "gpio_42",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA3, 43,
+ "dss_data3", "uart1_rx", NULL, "gpio_43",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA4, 44,
+ "dss_data4", "uart3_rx_irrx", NULL, "gpio_44",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA5, 45,
+ "dss_data5", "uart3_tx_irtx", NULL, "gpio_45",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA6, 144,
+ "dss_data6", NULL, NULL, "gpio_144",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA7, 147,
+ "dss_data7", NULL, NULL, "gpio_147",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA8, 38,
+ "dss_data8", NULL, NULL, "gpio_38",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_DATA9, 39,
+ "dss_data9", NULL, NULL, "gpio_39",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(DSS_HSYNC, 110,
+ "dss_hsync", NULL, NULL, "gpio_110",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_113, 113,
+ "gpio_113", "mcbsp2_clkx", NULL, "gpio_113",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_114, 114,
+ "gpio_114", "mcbsp2_fsx", NULL, "gpio_114",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_115, 115,
+ "gpio_115", "mcbsp2_dr", NULL, "gpio_115",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_116, 116,
+ "gpio_116", "mcbsp2_dx", NULL, "gpio_116",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_128, 128,
+ "gpio_128", NULL, "sti_din", "gpio_128",
+ NULL, "sys_boot0", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_129, 129,
+ "gpio_129", NULL, "sti_dout", "gpio_129",
+ NULL, "sys_boot1", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_130, 130,
+ "gpio_130", NULL, NULL, "gpio_130",
+ "jtag_emu2", "sys_boot2", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_131, 131,
+ "gpio_131", NULL, NULL, "gpio_131",
+ "jtag_emu3", "sys_boot3", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_132, 132,
+ "gpio_132", NULL, NULL, "gpio_132",
+ NULL, "sys_boot4", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_133, 133,
+ "gpio_133", NULL, NULL, "gpio_133",
+ NULL, "sys_boot5", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_134, 134,
+ "gpio_134", "ccp_datn", NULL, "gpio_134",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_135, 135,
+ "gpio_135", "ccp_datp", NULL, "gpio_135",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_136, 136,
+ "gpio_136", "ccp_clkn", NULL, "gpio_136",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_137, 137,
+ "gpio_137", "ccp_clkp", NULL, "gpio_137",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_138, 138,
+ "gpio_138", "spi3_clk", NULL, "gpio_138",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_139, 139,
+ "gpio_139", "spi3_cs0", "sys_ndmareq3", "gpio_139",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_140, 140,
+ "gpio_140", "spi3_simo", "sys_ndmareq4", "gpio_140",
+ NULL, NULL, "etk_d14", "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_141, 141,
+ "gpio_141", "spi3_somi", NULL, "gpio_141",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_142, 142,
+ "gpio_142", "spi3_cs1", "sys_ndmareq2", "gpio_142",
+ NULL, NULL, "etk_d15", "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_148, 148,
+ "gpio_148", "mcbsp5_fsx", NULL, "gpio_148",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_149, 149,
+ "gpio_149", "mcbsp5_dx", NULL, "gpio_149",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_150, 150,
+ "gpio_150", "mcbsp5_dr", NULL, "gpio_150",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_151, 151,
+ "gpio_151", "sys_pwrok", NULL, "gpio_151",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_152, 152,
+ "gpio_152", "uart1_cts", "sys_ndmareq1", "gpio_152",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_153, 153,
+ "gpio_153", "uart1_rx", "sys_ndmareq0", "gpio_153",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_154, 154,
+ "gpio_154", "mcbsp5_clkx", NULL, "gpio_154",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_63, 63,
+ "gpio_63", "mcbsp4_clkx", NULL, "gpio_63",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_78, 78,
+ "gpio_78", NULL, "uart2_rts", "gpio_78",
+ "uart3_rts_sd", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_79, 79,
+ "gpio_79", "secure_indicator", "uart2_tx", "gpio_79",
+ "uart3_tx_irtx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_7, 7,
+ "gpio_7", NULL, "uart2_cts", "gpio_7",
+ "uart3_cts_rctx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPIO_80, 80,
+ "gpio_80", NULL, "uart2_rx", "gpio_80",
+ "uart3_rx_irrx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A10, 3,
+ "gpmc_a10", NULL, "sys_ndmareq0", "gpio_3",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A1, 31,
+ "gpmc_a1", NULL, NULL, "gpio_31",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A2, 30,
+ "gpmc_a2", NULL, NULL, "gpio_30",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A3, 29,
+ "gpmc_a3", NULL, NULL, "gpio_29",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A4, 49,
+ "gpmc_a4", NULL, NULL, "gpio_49",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A5, 53,
+ "gpmc_a5", NULL, NULL, "gpio_53",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A6, 52,
+ "gpmc_a6", NULL, NULL, "gpio_52",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A7, 6,
+ "gpmc_a7", NULL, NULL, "gpio_6",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A8, 5,
+ "gpmc_a8", NULL, NULL, "gpio_5",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_A9, 4,
+ "gpmc_a9", NULL, "sys_ndmareq1", "gpio_4",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_CLK, 21,
+ "gpmc_clk", NULL, NULL, "gpio_21",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D10, 18,
+ "gpmc_d10", NULL, NULL, "gpio_18",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D11, 57,
+ "gpmc_d11", NULL, NULL, "gpio_57",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D12, 77,
+ "gpmc_d12", NULL, NULL, "gpio_77",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D13, 76,
+ "gpmc_d13", NULL, NULL, "gpio_76",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D14, 55,
+ "gpmc_d14", NULL, NULL, "gpio_55",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D15, 54,
+ "gpmc_d15", NULL, NULL, "gpio_54",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D8, 20,
+ "gpmc_d8", NULL, NULL, "gpio_20",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_D9, 19,
+ "gpmc_d9", NULL, NULL, "gpio_19",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS1, 22,
+ "gpmc_ncs1", NULL, NULL, "gpio_22",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS2, 23,
+ "gpmc_ncs2", NULL, NULL, "gpio_23",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS3, 24,
+ "gpmc_ncs3", "gpmc_io_dir", NULL, "gpio_24",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS4, 25,
+ "gpmc_ncs4", NULL, NULL, "gpio_25",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS5, 26,
+ "gpmc_ncs5", NULL, NULL, "gpio_26",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS6, 27,
+ "gpmc_ncs6", NULL, NULL, "gpio_27",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_NCS7, 28,
+ "gpmc_ncs7", "gpmc_io_dir", NULL, "gpio_28",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT1, 33,
+ "gpmc_wait1", NULL, NULL, "gpio_33",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT2, 34,
+ "gpmc_wait2", NULL, NULL, "gpio_34",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(GPMC_WAIT3, 35,
+ "gpmc_wait3", NULL, NULL, "gpio_35",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(HDQ_SIO, 101,
+ "hdq_sio", "usb2_tllse0", "sys_altclk", "gpio_101",
+ "uart3_rx_irrx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C1_SCL, 50,
+ "i2c1_scl", NULL, NULL, "gpio_50",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C1_SDA, 51,
+ "i2c1_sda", NULL, NULL, "gpio_51",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C2_SCL, 99,
+ "i2c2_scl", NULL, NULL, "gpio_99",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(I2C2_SDA, 100,
+ "i2c2_sda", NULL, NULL, "gpio_100",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(JTAG_EMU0, 127,
+ "jtag_emu0", "secure_indicator", NULL, "gpio_127",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(JTAG_EMU1, 126,
+ "jtag_emu1", NULL, NULL, "gpio_126",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_CLKR, 92,
+ "mcbsp1_clkr", "ssi2_dat_tx", NULL, "gpio_92",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_CLKX, 98,
+ "mcbsp1_clkx", "ssi2_wake", NULL, "gpio_98",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_DR, 95,
+ "mcbsp1_dr", "ssi2_dat_rx", NULL, "gpio_95",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_DX, 94,
+ "mcbsp1_dx", "ssi2_rdy_tx", NULL, "gpio_94",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_FSR, 93,
+ "mcbsp1_fsr", "ssi2_flag_tx", NULL, "gpio_93",
+ "spi2_cs1", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP1_FSX, 97,
+ "mcbsp1_fsx", "ssi2_rdy_rx", NULL, "gpio_97",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP2_CLKX, 147,
+ "mcbsp2_clkx", "sdi_clkp", "dss_data23", "gpio_147",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP2_DR, 144,
+ "mcbsp2_dr", "sdi_clkn", "dss_data22", "gpio_144",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_CLKX, 71,
+ "mcbsp3_clkx", NULL, NULL, "gpio_71",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_DR, 73,
+ "mcbsp3_dr", NULL, NULL, "gpio_73",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_DX, 74,
+ "mcbsp3_dx", NULL, "sti_clk", "gpio_74",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP3_FSX, 72,
+ "mcbsp3_fsx", NULL, NULL, "gpio_72",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(MCBSP_CLKS, 96,
+ "mcbsp_clks", "ssi2_flag_rx", NULL, "gpio_96",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_CLKO, 0,
+ "sdmmc1_clko", "ms_clko", NULL, NULL,
+ NULL, "hw_dbg9", "hw_dbg3", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_CMD, 0,
+ "sdmmc1_cmd", "ms_bs", NULL, NULL,
+ NULL, "hw_dbg8", "hw_dbg2", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT0, 0,
+ "sdmmc1_dat0", "ms_dat0", NULL, NULL,
+ NULL, "hw_dbg7", "hw_dbg1", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT1, 75,
+ "sdmmc1_dat1", "ms_dat1", NULL, "gpio_75",
+ NULL, "hw_dbg6", "hw_dbg0", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT2, 0,
+ "sdmmc1_dat2", "ms_dat2", NULL, NULL,
+ NULL, "hw_dbg5", "hw_dbg10", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC1_DAT3, 0,
+ "sdmmc1_dat3", "ms_dat3", NULL, NULL,
+ NULL, "hw_dbg4", "hw_dbg11", "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_CLKO, 13,
+ "sdmmc2_clko", NULL, NULL, "gpio_13",
+ NULL, "spi3_clk", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_CMD, 15,
+ "sdmmc2_cmd", "usb2_rcv", NULL, "gpio_15",
+ NULL, "spi3_simo", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT0, 16,
+ "sdmmc2_dat0", "usb2_tllse0", NULL, "gpio_16",
+ NULL, "spi3_somi", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT1, 58,
+ "sdmmc2_dat1", "usb2_txen", NULL, "gpio_58",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT2, 17,
+ "sdmmc2_dat2", "usb2_dat", NULL, "gpio_17",
+ NULL, "spi3_cs1", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDMMC2_DAT3, 14,
+ "sdmmc2_dat3", "usb2_se0", NULL, "gpio_14",
+ NULL, "spi3_cs0", NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A12, 2,
+ "sdrc_a12", NULL, NULL, "gpio_2",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A13, 1,
+ "sdrc_a13", NULL, NULL, "gpio_1",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_A14, 0,
+ "sdrc_a14", NULL, NULL, "gpio_0",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_CKE1, 36,
+ "sdrc_cke1", NULL, NULL, "gpio_36",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SDRC_NCS1, 37,
+ "sdrc_ncs1", NULL, NULL, "gpio_37",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CLK, 81,
+ "spi1_clk", NULL, NULL, "gpio_81",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS0, 84,
+ "spi1_cs0", NULL, NULL, "gpio_84",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS1, 85,
+ "spi1_cs1", NULL, NULL, "gpio_85",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS2, 86,
+ "spi1_cs2", NULL, NULL, "gpio_86",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_CS3, 87,
+ "spi1_cs3", "spi2_cs1", NULL, "gpio_87",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_SIMO, 82,
+ "spi1_simo", NULL, NULL, "gpio_82",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI1_SOMI, 83,
+ "spi1_somi", NULL, NULL, "gpio_83",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_CLK, 88,
+ "spi2_clk", "gpt9_pwm_evt", NULL, "gpio_88",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_CS0, 91,
+ "spi2_cs0", "gpt12_pwm_evt", NULL, "gpio_91",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_SIMO, 89,
+ "spi2_simo", "gpt10_pwm_evt", NULL, "gpio_89",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SPI2_SOMI, 90,
+ "spi2_somi", "gpt11_pwm_evt", NULL, "gpio_90",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_DAT_RX, 62,
+ "ssi1_dat_rx", "uart1_rx", "usb1_dat", "gpio_62",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_DAT_TX, 59,
+ "ssi1_dat_tx", "uart1_tx", "usb1_se0", "gpio_59",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_FLAG_RX, 64,
+ "ssi1_flag_rx", "mcbsp4_dr", NULL, "gpio_64",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_FLAG_TX, 60,
+ "ssi1_flag_tx", "uart1_rts", "usb1_rcv", "gpio_60",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_RDY_RX, 65,
+ "ssi1_rdy_rx", "mcbsp4_dx", NULL, "gpio_65",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_RDY_TX, 61,
+ "ssi1_rdy_tx", "uart1_cts", "usb1_txen", "gpio_61",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SSI1_WAKE, 66,
+ "ssi1_wake", "mcbsp4_fsx", NULL, "gpio_66",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_CLKOUT, 111,
+ "sys_clkout", NULL, NULL, "gpio_111",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_DRM_MSECURE, 118,
+ "sys_drm_msecure", NULL, "sys_ndmareq6", "gpio_118",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_NIRQ0, 56,
+ "sys_nirq0", NULL, NULL, "gpio_56",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(SYS_NIRQ1, 125,
+ "sys_nirq1", NULL, "sys_ndmareq5", "gpio_125",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_CTS, 32,
+ "uart1_cts", "sdi_vsync", "dss_data18", "gpio_32",
+ "mcbsp5_clkx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_RTS, 8,
+ "uart1_rts", "sdi_hsync", "dss_data19", "gpio_8",
+ "mcbsp5_fsx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_RX, 10,
+ "uart1_rx", "sdi_stp", "dss_data21", "gpio_10",
+ "mcbsp5_dr", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART1_TX, 9,
+ "uart1_tx", "sdi_den", "dss_data20", "gpio_9",
+ "mcbsp5_dx", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_CTS, 67,
+ "uart2_cts", "usb1_rcv", "gpt9_pwm_evt", "gpio_67",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_RTS, 68,
+ "uart2_rts", "usb1_txen", "gpt10_pwm_evt", "gpio_68",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_RX, 70,
+ "uart2_rx", "usb1_dat", "gpt12_pwm_evt", "gpio_70",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART2_TX, 69,
+ "uart2_tx", "usb1_se0", "gpt11_pwm_evt", "gpio_69",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_CTS_RCTX, 102,
+ "uart3_cts_rctx", "uart3_rx_irrx", NULL, "gpio_102",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_RTS_SD, 103,
+ "uart3_rts_sd", "uart3_tx_irtx", NULL, "gpio_103",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_RX_IRRX, 105,
+ "uart3_rx_irrx", NULL, NULL, "gpio_105",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(UART3_TX_IRTX, 104,
+ "uart3_tx_irtx", "uart3_cts_rctx", NULL, "gpio_104",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_CLK, 120,
+ "usb0hs_clk", NULL, NULL, "gpio_120",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA0, 0,
+ "usb0hs_data0", "uart3_tx_irtx", NULL, NULL,
+ "usb0_txen", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA1, 0,
+ "usb0hs_data1", "uart3_rx_irrx", NULL, NULL,
+ "usb0_dat", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA2, 0,
+ "usb0hs_data2", "uart3_rts_sd", NULL, NULL,
+ "usb0_se0", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA3, 106,
+ "usb0hs_data3", NULL, "uart3_cts_rctx", "gpio_106",
+ "usb0_puen", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA4, 107,
+ "usb0hs_data4", "mcbsp2_dr", NULL, "gpio_107",
+ "usb0_vp", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA5, 108,
+ "usb0hs_data5", "mcbsp2_dx", NULL, "gpio_108",
+ "usb0_vm", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA6, 109,
+ "usb0hs_data6", "mcbsp2_fsx", NULL, "gpio_109",
+ "usb0_rcv", NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DATA7, 124,
+ "usb0hs_data7", "mcbsp2_clkx", NULL, "gpio_124",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_DIR, 121,
+ "usb0hs_dir", NULL, NULL, "gpio_121",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_NXT, 123,
+ "usb0hs_nxt", NULL, NULL, "gpio_123",
+ NULL, NULL, NULL, "safe_mode"),
+ _OMAP2430_MUXENTRY(USB0HS_STP, 122,
+ "usb0hs_stp", NULL, NULL, "gpio_122",
+ NULL, NULL, NULL, "safe_mode"),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+
+/*
+ * Balls for POP package
+ * 447-pin s-PBGA Package, 0.00mm Ball Pitch (Bottom)
+ */
+#ifdef CONFIG_DEBUG_FS
+struct omap_ball __initdata omap2430_pop_ball[] = {
+ _OMAP2430_BALLENTRY(CAM_D0, "t8", NULL),
+ _OMAP2430_BALLENTRY(CAM_D1, "t4", NULL),
+ _OMAP2430_BALLENTRY(CAM_D10, "r4", NULL),
+ _OMAP2430_BALLENTRY(CAM_D11, "w3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D2, "r2", NULL),
+ _OMAP2430_BALLENTRY(CAM_D3, "u3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D4, "u2", NULL),
+ _OMAP2430_BALLENTRY(CAM_D5, "v1", NULL),
+ _OMAP2430_BALLENTRY(CAM_D6, "t3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D7, "r3", NULL),
+ _OMAP2430_BALLENTRY(CAM_D8, "u7", NULL),
+ _OMAP2430_BALLENTRY(CAM_D9, "t7", NULL),
+ _OMAP2430_BALLENTRY(CAM_HS, "p2", NULL),
+ _OMAP2430_BALLENTRY(CAM_LCLK, "r7", NULL),
+ _OMAP2430_BALLENTRY(CAM_VS, "n2", NULL),
+ _OMAP2430_BALLENTRY(CAM_XCLK, "p3", NULL),
+ _OMAP2430_BALLENTRY(DSS_ACBIAS, "y3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA0, "v8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA1, "w1", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA10, "k25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA11, "j25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA12, "k24", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA13, "j24", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA14, "h25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA15, "g25", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA16, "ac3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA17, "y7", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA2, "u8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA3, "u4", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA4, "v3", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA5, "aa4", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA6, "w8", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA7, "y1", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA8, "aa2", NULL),
+ _OMAP2430_BALLENTRY(DSS_DATA9, "ab4", NULL),
+ _OMAP2430_BALLENTRY(DSS_HSYNC, "v2", NULL),
+ _OMAP2430_BALLENTRY(GPIO_113, "ad16", NULL),
+ _OMAP2430_BALLENTRY(GPIO_114, "ac10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_115, "ad13", NULL),
+ _OMAP2430_BALLENTRY(GPIO_116, "ae15", NULL),
+ _OMAP2430_BALLENTRY(GPIO_128, "p1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_129, "r1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_130, "p7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_131, "l8", NULL),
+ _OMAP2430_BALLENTRY(GPIO_132, "w24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_133, "aa24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_134, "ae12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_135, "ae11", NULL),
+ _OMAP2430_BALLENTRY(GPIO_136, "ad12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_137, "ad11", NULL),
+ _OMAP2430_BALLENTRY(GPIO_138, "y12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_139, "ad17", NULL),
+ _OMAP2430_BALLENTRY(GPIO_140, "l7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_141, "ac24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_142, "m3", NULL),
+ _OMAP2430_BALLENTRY(GPIO_148, "af12", NULL),
+ _OMAP2430_BALLENTRY(GPIO_149, "k7", NULL),
+ _OMAP2430_BALLENTRY(GPIO_150, "m1", NULL),
+ _OMAP2430_BALLENTRY(GPIO_151, "ad14", NULL),
+ _OMAP2430_BALLENTRY(GPIO_152, "ad18", NULL),
+ _OMAP2430_BALLENTRY(GPIO_153, "u24", NULL),
+ _OMAP2430_BALLENTRY(GPIO_154, "ae16", NULL),
+ _OMAP2430_BALLENTRY(GPIO_63, "n3", NULL),
+ _OMAP2430_BALLENTRY(GPIO_7, "ac23", NULL),
+ _OMAP2430_BALLENTRY(GPIO_78, "ad10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_79, "ae10", NULL),
+ _OMAP2430_BALLENTRY(GPIO_80, "ae13", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A1, "a9", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A10, "g12", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A2, "b8", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A3, "g10", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A4, "g11", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A5, "a10", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A6, "g13", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A7, "a6", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A8, "h1", NULL),
+ _OMAP2430_BALLENTRY(GPMC_A9, "c8", NULL),
+ _OMAP2430_BALLENTRY(GPMC_CLK, "n1", "l1"),
+ _OMAP2430_BALLENTRY(GPMC_D10, "d1", "n1"),
+ _OMAP2430_BALLENTRY(GPMC_D11, "d2", "p2"),
+ _OMAP2430_BALLENTRY(GPMC_D12, "e1", "p1"),
+ _OMAP2430_BALLENTRY(GPMC_D13, "e3", "m1"),
+ _OMAP2430_BALLENTRY(GPMC_D14, "c7", "j2"),
+ _OMAP2430_BALLENTRY(GPMC_D15, "f3", "k2"),
+ _OMAP2430_BALLENTRY(GPMC_D8, "e2", "r1"),
+ _OMAP2430_BALLENTRY(GPMC_D9, "ab1", "t1"),
+ _OMAP2430_BALLENTRY(GPMC_NCS1, "ac1", "w1"),
+ _OMAP2430_BALLENTRY(GPMC_NCS2, "c6", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS3, "b9", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS4, "b4", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS5, "a4", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS6, "f1", NULL),
+ _OMAP2430_BALLENTRY(GPMC_NCS7, "a7", NULL),
+ _OMAP2430_BALLENTRY(GPMC_WAIT1, "j1", "y8"),
+ _OMAP2430_BALLENTRY(GPMC_WAIT2, "b7", NULL),
+ _OMAP2430_BALLENTRY(GPMC_WAIT3, "g14", NULL),
+ _OMAP2430_BALLENTRY(HDQ_SIO, "h20", NULL),
+ _OMAP2430_BALLENTRY(I2C1_SCL, "y17", NULL),
+ _OMAP2430_BALLENTRY(I2C1_SDA, "ac19", NULL),
+ _OMAP2430_BALLENTRY(I2C2_SCL, "n7", NULL),
+ _OMAP2430_BALLENTRY(I2C2_SDA, "m4", NULL),
+ _OMAP2430_BALLENTRY(JTAG_EMU0, "e25", NULL),
+ _OMAP2430_BALLENTRY(JTAG_EMU1, "e24", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_CLKR, "ab2", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_CLKX, "y9", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_DR, "af3", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_DX, "aa1", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_FSR, "ad5", NULL),
+ _OMAP2430_BALLENTRY(MCBSP1_FSX, "ab3", NULL),
+ _OMAP2430_BALLENTRY(MCBSP2_CLKX, "j26", NULL),
+ _OMAP2430_BALLENTRY(MCBSP2_DR, "k26", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_CLKX, "ac9", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_DR, "ae2", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_DX, "af4", NULL),
+ _OMAP2430_BALLENTRY(MCBSP3_FSX, "ae4", NULL),
+ _OMAP2430_BALLENTRY(MCBSP_CLKS, "ad6", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_CLKO, "n23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_CMD, "l23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT0, "m24", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT1, "p23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT2, "t20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC1_DAT3, "r20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_CLKO, "v26", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_CMD, "w20", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT0, "v23", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT1, "y24", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT2, "v25", NULL),
+ _OMAP2430_BALLENTRY(SDMMC2_DAT3, "v24", NULL),
+ _OMAP2430_BALLENTRY(SDRC_A12, "w26", "r21"),
+ _OMAP2430_BALLENTRY(SDRC_A13, "af20", "aa15"),
+ _OMAP2430_BALLENTRY(SDRC_A14, "af16", "y12"),
+ _OMAP2430_BALLENTRY(SDRC_CKE1, "af15", "y13"),
+ _OMAP2430_BALLENTRY(SDRC_NCS1, "aa25", "t20"),
+ _OMAP2430_BALLENTRY(SPI1_CLK, "y18", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS0, "u1", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS1, "af19", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS2, "ae19", NULL),
+ _OMAP2430_BALLENTRY(SPI1_CS3, "h24", NULL),
+ _OMAP2430_BALLENTRY(SPI1_SIMO, "ad15", NULL),
+ _OMAP2430_BALLENTRY(SPI1_SOMI, "ae17", NULL),
+ _OMAP2430_BALLENTRY(SPI2_CLK, "y20", NULL),
+ _OMAP2430_BALLENTRY(SPI2_CS0, "y19", NULL),
+ _OMAP2430_BALLENTRY(SPI2_SIMO, "ac20", NULL),
+ _OMAP2430_BALLENTRY(SPI2_SOMI, "ad19", NULL),
+ _OMAP2430_BALLENTRY(SSI1_DAT_RX, "aa26", NULL),
+ _OMAP2430_BALLENTRY(SSI1_DAT_TX, "ad24", NULL),
+ _OMAP2430_BALLENTRY(SSI1_FLAG_RX, "ad23", NULL),
+ _OMAP2430_BALLENTRY(SSI1_FLAG_TX, "ab24", NULL),
+ _OMAP2430_BALLENTRY(SSI1_RDY_RX, "ab25", NULL),
+ _OMAP2430_BALLENTRY(SSI1_RDY_TX, "y25", NULL),
+ _OMAP2430_BALLENTRY(SSI1_WAKE, "ac25", NULL),
+ _OMAP2430_BALLENTRY(SYS_CLKOUT, "r25", NULL),
+ _OMAP2430_BALLENTRY(SYS_DRM_MSECURE, "ae3", NULL),
+ _OMAP2430_BALLENTRY(SYS_NIRQ0, "w25", NULL),
+ _OMAP2430_BALLENTRY(SYS_NIRQ1, "ad21", NULL),
+ _OMAP2430_BALLENTRY(UART1_CTS, "p24", NULL),
+ _OMAP2430_BALLENTRY(UART1_RTS, "p25", NULL),
+ _OMAP2430_BALLENTRY(UART1_RX, "n24", NULL),
+ _OMAP2430_BALLENTRY(UART1_TX, "r24", NULL),
+ _OMAP2430_BALLENTRY(UART2_CTS, "u25", NULL),
+ _OMAP2430_BALLENTRY(UART2_RTS, "t23", NULL),
+ _OMAP2430_BALLENTRY(UART2_RX, "t24", NULL),
+ _OMAP2430_BALLENTRY(UART2_TX, "u20", NULL),
+ _OMAP2430_BALLENTRY(UART3_CTS_RCTX, "m2", NULL),
+ _OMAP2430_BALLENTRY(UART3_RTS_SD, "k2", NULL),
+ _OMAP2430_BALLENTRY(UART3_RX_IRRX, "l3", NULL),
+ _OMAP2430_BALLENTRY(UART3_TX_IRTX, "l2", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_CLK, "ae8", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA0, "ad4", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA1, "ae6", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA2, "af9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA3, "ad9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA4, "y11", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA5, "ad7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA6, "ae7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DATA7, "ac7", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_DIR, "ad8", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_NXT, "ae9", NULL),
+ _OMAP2430_BALLENTRY(USB0HS_STP, "ae5", NULL),
+ { .reg_offset = OMAP_MUX_TERMINATOR },
+};
+#else
+#define omap2430_pop_ball NULL
+#endif
+
+int __init omap2430_mux_init(struct omap_board_mux *board_subset, int flags)
+{
+ struct omap_ball *package_balls = NULL;
+
+ switch (flags & OMAP_PACKAGE_MASK) {
+ case OMAP_PACKAGE_ZAC:
+ package_balls = omap2430_pop_ball;
+ break;
+ default:
+ pr_warning("mux: No ball data available for omap2420 package\n");
+ }
+
+ return omap_mux_init(OMAP2430_CONTROL_PADCONF_MUX_PBASE,
+ OMAP2430_CONTROL_PADCONF_MUX_SIZE,
+ omap2430_muxmodes, NULL, board_subset,
+ package_balls);
+}
diff --git a/arch/arm/mach-omap2/mux2430.h b/arch/arm/mach-omap2/mux2430.h
new file mode 100644
index 000000000000..adbea0d03e08
--- /dev/null
+++ b/arch/arm/mach-omap2/mux2430.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2009 Nokia
+ * Copyright (C) 2009 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define OMAP2430_CONTROL_PADCONF_MUX_PBASE 0x49002030LU
+
+#define OMAP2430_MUX(mode0, mux_value) \
+{ \
+ .reg_offset = (OMAP2430_CONTROL_PADCONF_##mode0##_OFFSET), \
+ .value = (mux_value), \
+}
+
+/*
+ * OMAP2430 CONTROL_PADCONF* register offsets for pin-muxing
+ *
+ * Extracted from the TRM. Add 0x49002030 to these values to get the
+ * absolute addresses. The name in the macro is the mode-0 name of
+ * the pin. NOTE: These registers are 8-bits wide.
+ *
+ * Note that these defines use SDMMC instead of MMC for compability
+ * with signal names used in 3630.
+ */
+#define OMAP2430_CONTROL_PADCONF_GPMC_CLK_OFFSET 0x000
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS0_OFFSET 0x001
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS1_OFFSET 0x002
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS2_OFFSET 0x003
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS3_OFFSET 0x004
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS4_OFFSET 0x005
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS5_OFFSET 0x006
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS6_OFFSET 0x007
+#define OMAP2430_CONTROL_PADCONF_GPMC_NCS7_OFFSET 0x008
+#define OMAP2430_CONTROL_PADCONF_GPMC_NADV_ALE_OFFSET 0x009
+#define OMAP2430_CONTROL_PADCONF_GPMC_NOE_NRE_OFFSET 0x00a
+#define OMAP2430_CONTROL_PADCONF_GPMC_NWE_OFFSET 0x00b
+#define OMAP2430_CONTROL_PADCONF_GPMC_NBE0_CLE_OFFSET 0x00c
+#define OMAP2430_CONTROL_PADCONF_GPMC_NBE1_OFFSET 0x00d
+#define OMAP2430_CONTROL_PADCONF_GPMC_NWP_OFFSET 0x00e
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT0_OFFSET 0x00f
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT1_OFFSET 0x010
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT2_OFFSET 0x011
+#define OMAP2430_CONTROL_PADCONF_GPMC_WAIT3_OFFSET 0x012
+#define OMAP2430_CONTROL_PADCONF_SDRC_CLK_OFFSET 0x013
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCLK_OFFSET 0x014
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCS0_OFFSET 0x015
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCS1_OFFSET 0x016
+#define OMAP2430_CONTROL_PADCONF_SDRC_CKE0_OFFSET 0x017
+#define OMAP2430_CONTROL_PADCONF_SDRC_CKE1_OFFSET 0x018
+#define OMAP2430_CONTROL_PADCONF_SDRC_NRAS_OFFSET 0x019
+#define OMAP2430_CONTROL_PADCONF_SDRC_NCAS_OFFSET 0x01a
+#define OMAP2430_CONTROL_PADCONF_SDRC_NWE_OFFSET 0x01b
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM0_OFFSET 0x01c
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM1_OFFSET 0x01d
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM2_OFFSET 0x01e
+#define OMAP2430_CONTROL_PADCONF_SDRC_DM3_OFFSET 0x01f
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS0_OFFSET 0x020
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS1_OFFSET 0x021
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS2_OFFSET 0x022
+#define OMAP2430_CONTROL_PADCONF_SDRC_DQS3_OFFSET 0x023
+#define OMAP2430_CONTROL_PADCONF_SDRC_A14_OFFSET 0x024
+#define OMAP2430_CONTROL_PADCONF_SDRC_A13_OFFSET 0x025
+#define OMAP2430_CONTROL_PADCONF_SDRC_A12_OFFSET 0x026
+#define OMAP2430_CONTROL_PADCONF_SDRC_BA1_OFFSET 0x027
+#define OMAP2430_CONTROL_PADCONF_SDRC_BA0_OFFSET 0x028
+#define OMAP2430_CONTROL_PADCONF_SDRC_A11_OFFSET 0x029
+#define OMAP2430_CONTROL_PADCONF_SDRC_A10_OFFSET 0x02a
+#define OMAP2430_CONTROL_PADCONF_SDRC_A9_OFFSET 0x02b
+#define OMAP2430_CONTROL_PADCONF_SDRC_A8_OFFSET 0x02c
+#define OMAP2430_CONTROL_PADCONF_SDRC_A7_OFFSET 0x02d
+#define OMAP2430_CONTROL_PADCONF_SDRC_A6_OFFSET 0x02e
+#define OMAP2430_CONTROL_PADCONF_SDRC_A5_OFFSET 0x02f
+#define OMAP2430_CONTROL_PADCONF_SDRC_A4_OFFSET 0x030
+#define OMAP2430_CONTROL_PADCONF_SDRC_A3_OFFSET 0x031
+#define OMAP2430_CONTROL_PADCONF_SDRC_A2_OFFSET 0x032
+#define OMAP2430_CONTROL_PADCONF_SDRC_A1_OFFSET 0x033
+#define OMAP2430_CONTROL_PADCONF_SDRC_A0_OFFSET 0x034
+#define OMAP2430_CONTROL_PADCONF_SDRC_D31_OFFSET 0x035
+#define OMAP2430_CONTROL_PADCONF_SDRC_D30_OFFSET 0x036
+#define OMAP2430_CONTROL_PADCONF_SDRC_D29_OFFSET 0x037
+#define OMAP2430_CONTROL_PADCONF_SDRC_D28_OFFSET 0x038
+#define OMAP2430_CONTROL_PADCONF_SDRC_D27_OFFSET 0x039
+#define OMAP2430_CONTROL_PADCONF_SDRC_D26_OFFSET 0x03a
+#define OMAP2430_CONTROL_PADCONF_SDRC_D25_OFFSET 0x03b
+#define OMAP2430_CONTROL_PADCONF_SDRC_D24_OFFSET 0x03c
+#define OMAP2430_CONTROL_PADCONF_SDRC_D23_OFFSET 0x03d
+#define OMAP2430_CONTROL_PADCONF_SDRC_D22_OFFSET 0x03e
+#define OMAP2430_CONTROL_PADCONF_SDRC_D21_OFFSET 0x03f
+#define OMAP2430_CONTROL_PADCONF_SDRC_D20_OFFSET 0x040
+#define OMAP2430_CONTROL_PADCONF_SDRC_D19_OFFSET 0x041
+#define OMAP2430_CONTROL_PADCONF_SDRC_D18_OFFSET 0x042
+#define OMAP2430_CONTROL_PADCONF_SDRC_D17_OFFSET 0x043
+#define OMAP2430_CONTROL_PADCONF_SDRC_D16_OFFSET 0x044
+#define OMAP2430_CONTROL_PADCONF_SDRC_D15_OFFSET 0x045
+#define OMAP2430_CONTROL_PADCONF_SDRC_D14_OFFSET 0x046
+#define OMAP2430_CONTROL_PADCONF_SDRC_D13_OFFSET 0x047
+#define OMAP2430_CONTROL_PADCONF_SDRC_D12_OFFSET 0x048
+#define OMAP2430_CONTROL_PADCONF_SDRC_D11_OFFSET 0x049
+#define OMAP2430_CONTROL_PADCONF_SDRC_D10_OFFSET 0x04a
+#define OMAP2430_CONTROL_PADCONF_SDRC_D9_OFFSET 0x04b
+#define OMAP2430_CONTROL_PADCONF_SDRC_D8_OFFSET 0x04c
+#define OMAP2430_CONTROL_PADCONF_SDRC_D7_OFFSET 0x04d
+#define OMAP2430_CONTROL_PADCONF_SDRC_D6_OFFSET 0x04e
+#define OMAP2430_CONTROL_PADCONF_SDRC_D5_OFFSET 0x04f
+#define OMAP2430_CONTROL_PADCONF_SDRC_D4_OFFSET 0x050
+#define OMAP2430_CONTROL_PADCONF_SDRC_D3_OFFSET 0x051
+#define OMAP2430_CONTROL_PADCONF_SDRC_D2_OFFSET 0x052
+#define OMAP2430_CONTROL_PADCONF_SDRC_D1_OFFSET 0x053
+#define OMAP2430_CONTROL_PADCONF_SDRC_D0_OFFSET 0x054
+#define OMAP2430_CONTROL_PADCONF_GPMC_A10_OFFSET 0x055
+#define OMAP2430_CONTROL_PADCONF_GPMC_A9_OFFSET 0x056
+#define OMAP2430_CONTROL_PADCONF_GPMC_A8_OFFSET 0x057
+#define OMAP2430_CONTROL_PADCONF_GPMC_A7_OFFSET 0x058
+#define OMAP2430_CONTROL_PADCONF_GPMC_A6_OFFSET 0x059
+#define OMAP2430_CONTROL_PADCONF_GPMC_A5_OFFSET 0x05a
+#define OMAP2430_CONTROL_PADCONF_GPMC_A4_OFFSET 0x05b
+#define OMAP2430_CONTROL_PADCONF_GPMC_A3_OFFSET 0x05c
+#define OMAP2430_CONTROL_PADCONF_GPMC_A2_OFFSET 0x05d
+#define OMAP2430_CONTROL_PADCONF_GPMC_A1_OFFSET 0x05e
+#define OMAP2430_CONTROL_PADCONF_GPMC_D15_OFFSET 0x05f
+#define OMAP2430_CONTROL_PADCONF_GPMC_D14_OFFSET 0x060
+#define OMAP2430_CONTROL_PADCONF_GPMC_D13_OFFSET 0x061
+#define OMAP2430_CONTROL_PADCONF_GPMC_D12_OFFSET 0x062
+#define OMAP2430_CONTROL_PADCONF_GPMC_D11_OFFSET 0x063
+#define OMAP2430_CONTROL_PADCONF_GPMC_D10_OFFSET 0x064
+#define OMAP2430_CONTROL_PADCONF_GPMC_D9_OFFSET 0x065
+#define OMAP2430_CONTROL_PADCONF_GPMC_D8_OFFSET 0x066
+#define OMAP2430_CONTROL_PADCONF_GPMC_D7_OFFSET 0x067
+#define OMAP2430_CONTROL_PADCONF_GPMC_D6_OFFSET 0x068
+#define OMAP2430_CONTROL_PADCONF_GPMC_D5_OFFSET 0x069
+#define OMAP2430_CONTROL_PADCONF_GPMC_D4_OFFSET 0x06a
+#define OMAP2430_CONTROL_PADCONF_GPMC_D3_OFFSET 0x06b
+#define OMAP2430_CONTROL_PADCONF_GPMC_D2_OFFSET 0x06c
+#define OMAP2430_CONTROL_PADCONF_GPMC_D1_OFFSET 0x06d
+#define OMAP2430_CONTROL_PADCONF_GPMC_D0_OFFSET 0x06e
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA0_OFFSET 0x06f
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA1_OFFSET 0x070
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA2_OFFSET 0x071
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA3_OFFSET 0x072
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA4_OFFSET 0x073
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA5_OFFSET 0x074
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA6_OFFSET 0x075
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA7_OFFSET 0x076
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA8_OFFSET 0x077
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA9_OFFSET 0x078
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA10_OFFSET 0x079
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA11_OFFSET 0x07a
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA12_OFFSET 0x07b
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA13_OFFSET 0x07c
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA14_OFFSET 0x07d
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA15_OFFSET 0x07e
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA16_OFFSET 0x07f
+#define OMAP2430_CONTROL_PADCONF_DSS_DATA17_OFFSET 0x080
+#define OMAP2430_CONTROL_PADCONF_UART1_CTS_OFFSET 0x081
+#define OMAP2430_CONTROL_PADCONF_UART1_RTS_OFFSET 0x082
+#define OMAP2430_CONTROL_PADCONF_UART1_TX_OFFSET 0x083
+#define OMAP2430_CONTROL_PADCONF_UART1_RX_OFFSET 0x084
+#define OMAP2430_CONTROL_PADCONF_MCBSP2_DR_OFFSET 0x085
+#define OMAP2430_CONTROL_PADCONF_MCBSP2_CLKX_OFFSET 0x086
+#define OMAP2430_CONTROL_PADCONF_DSS_PCLK_OFFSET 0x087
+#define OMAP2430_CONTROL_PADCONF_DSS_VSYNC_OFFSET 0x088
+#define OMAP2430_CONTROL_PADCONF_DSS_HSYNC_OFFSET 0x089
+#define OMAP2430_CONTROL_PADCONF_DSS_ACBIAS_OFFSET 0x08a
+#define OMAP2430_CONTROL_PADCONF_SYS_NRESPWRON_OFFSET 0x08b
+#define OMAP2430_CONTROL_PADCONF_SYS_NRESWARM_OFFSET 0x08c
+#define OMAP2430_CONTROL_PADCONF_SYS_NIRQ0_OFFSET 0x08d
+#define OMAP2430_CONTROL_PADCONF_SYS_NIRQ1_OFFSET 0x08e
+#define OMAP2430_CONTROL_PADCONF_SYS_VMODE_OFFSET 0x08f
+#define OMAP2430_CONTROL_PADCONF_GPIO_128_OFFSET 0x090
+#define OMAP2430_CONTROL_PADCONF_GPIO_129_OFFSET 0x091
+#define OMAP2430_CONTROL_PADCONF_GPIO_130_OFFSET 0x092
+#define OMAP2430_CONTROL_PADCONF_GPIO_131_OFFSET 0x093
+#define OMAP2430_CONTROL_PADCONF_SYS_32K_OFFSET 0x094
+#define OMAP2430_CONTROL_PADCONF_SYS_XTALIN_OFFSET 0x095
+#define OMAP2430_CONTROL_PADCONF_SYS_XTALOUT_OFFSET 0x096
+#define OMAP2430_CONTROL_PADCONF_GPIO_132_OFFSET 0x097
+#define OMAP2430_CONTROL_PADCONF_SYS_CLKREQ_OFFSET 0x098
+#define OMAP2430_CONTROL_PADCONF_SYS_CLKOUT_OFFSET 0x099
+#define OMAP2430_CONTROL_PADCONF_GPIO_151_OFFSET 0x09a
+#define OMAP2430_CONTROL_PADCONF_GPIO_133_OFFSET 0x09b
+#define OMAP2430_CONTROL_PADCONF_JTAG_EMU1_OFFSET 0x09c
+#define OMAP2430_CONTROL_PADCONF_JTAG_EMU0_OFFSET 0x09d
+#define OMAP2430_CONTROL_PADCONF_JTAG_NTRST_OFFSET 0x09e
+#define OMAP2430_CONTROL_PADCONF_JTAG_TCK_OFFSET 0x09f
+#define OMAP2430_CONTROL_PADCONF_JTAG_RTCK_OFFSET 0x0a0
+#define OMAP2430_CONTROL_PADCONF_JTAG_TMS_OFFSET 0x0a1
+#define OMAP2430_CONTROL_PADCONF_JTAG_TDI_OFFSET 0x0a2
+#define OMAP2430_CONTROL_PADCONF_JTAG_TDO_OFFSET 0x0a3
+#define OMAP2430_CONTROL_PADCONF_CAM_D9_OFFSET 0x0a4
+#define OMAP2430_CONTROL_PADCONF_CAM_D8_OFFSET 0x0a5
+#define OMAP2430_CONTROL_PADCONF_CAM_D7_OFFSET 0x0a6
+#define OMAP2430_CONTROL_PADCONF_CAM_D6_OFFSET 0x0a7
+#define OMAP2430_CONTROL_PADCONF_CAM_D5_OFFSET 0x0a8
+#define OMAP2430_CONTROL_PADCONF_CAM_D4_OFFSET 0x0a9
+#define OMAP2430_CONTROL_PADCONF_CAM_D3_OFFSET 0x0aa
+#define OMAP2430_CONTROL_PADCONF_CAM_D2_OFFSET 0x0ab
+#define OMAP2430_CONTROL_PADCONF_CAM_D1_OFFSET 0x0ac
+#define OMAP2430_CONTROL_PADCONF_CAM_D0_OFFSET 0x0ad
+#define OMAP2430_CONTROL_PADCONF_CAM_HS_OFFSET 0x0ae
+#define OMAP2430_CONTROL_PADCONF_CAM_VS_OFFSET 0x0af
+#define OMAP2430_CONTROL_PADCONF_CAM_LCLK_OFFSET 0x0b0
+#define OMAP2430_CONTROL_PADCONF_CAM_XCLK_OFFSET 0x0b1
+#define OMAP2430_CONTROL_PADCONF_CAM_D11_OFFSET 0x0b2
+#define OMAP2430_CONTROL_PADCONF_CAM_D10_OFFSET 0x0b3
+#define OMAP2430_CONTROL_PADCONF_GPIO_134_OFFSET 0x0b4
+#define OMAP2430_CONTROL_PADCONF_GPIO_135_OFFSET 0x0b5
+#define OMAP2430_CONTROL_PADCONF_GPIO_136_OFFSET 0x0b6
+#define OMAP2430_CONTROL_PADCONF_GPIO_137_OFFSET 0x0b7
+#define OMAP2430_CONTROL_PADCONF_GPIO_138_OFFSET 0x0b8
+#define OMAP2430_CONTROL_PADCONF_GPIO_139_OFFSET 0x0b9
+#define OMAP2430_CONTROL_PADCONF_GPIO_140_OFFSET 0x0ba
+#define OMAP2430_CONTROL_PADCONF_GPIO_141_OFFSET 0x0bb
+#define OMAP2430_CONTROL_PADCONF_GPIO_142_OFFSET 0x0bc
+#define OMAP2430_CONTROL_PADCONF_GPIO_154_OFFSET 0x0bd
+#define OMAP2430_CONTROL_PADCONF_GPIO_148_OFFSET 0x0be
+#define OMAP2430_CONTROL_PADCONF_GPIO_149_OFFSET 0x0bf
+#define OMAP2430_CONTROL_PADCONF_GPIO_150_OFFSET 0x0c0
+#define OMAP2430_CONTROL_PADCONF_GPIO_152_OFFSET 0x0c1
+#define OMAP2430_CONTROL_PADCONF_GPIO_153_OFFSET 0x0c2
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_CLKO_OFFSET 0x0c3
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_CMD_OFFSET 0x0c4
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT0_OFFSET 0x0c5
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT1_OFFSET 0x0c6
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT2_OFFSET 0x0c7
+#define OMAP2430_CONTROL_PADCONF_SDMMC1_DAT3_OFFSET 0x0c8
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_CLKO_OFFSET 0x0c9
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT3_OFFSET 0x0ca
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_CMD_OFFSET 0x0cb
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT0_OFFSET 0x0cc
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT2_OFFSET 0x0cd
+#define OMAP2430_CONTROL_PADCONF_SDMMC2_DAT1_OFFSET 0x0ce
+#define OMAP2430_CONTROL_PADCONF_UART2_CTS_OFFSET 0x0cf
+#define OMAP2430_CONTROL_PADCONF_UART2_RTS_OFFSET 0x0d0
+#define OMAP2430_CONTROL_PADCONF_UART2_TX_OFFSET 0x0d1
+#define OMAP2430_CONTROL_PADCONF_UART2_RX_OFFSET 0x0d2
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_CLKX_OFFSET 0x0d3
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_FSX_OFFSET 0x0d4
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_DR_OFFSET 0x0d5
+#define OMAP2430_CONTROL_PADCONF_MCBSP3_DX_OFFSET 0x0d6
+#define OMAP2430_CONTROL_PADCONF_SSI1_DAT_TX_OFFSET 0x0d7
+#define OMAP2430_CONTROL_PADCONF_SSI1_FLAG_TX_OFFSET 0x0d8
+#define OMAP2430_CONTROL_PADCONF_SSI1_RDY_TX_OFFSET 0x0d9
+#define OMAP2430_CONTROL_PADCONF_SSI1_DAT_RX_OFFSET 0x0da
+#define OMAP2430_CONTROL_PADCONF_GPIO_63_OFFSET 0x0db
+#define OMAP2430_CONTROL_PADCONF_SSI1_FLAG_RX_OFFSET 0x0dc
+#define OMAP2430_CONTROL_PADCONF_SSI1_RDY_RX_OFFSET 0x0dd
+#define OMAP2430_CONTROL_PADCONF_SSI1_WAKE_OFFSET 0x0de
+#define OMAP2430_CONTROL_PADCONF_SPI1_CLK_OFFSET 0x0df
+#define OMAP2430_CONTROL_PADCONF_SPI1_SIMO_OFFSET 0x0e0
+#define OMAP2430_CONTROL_PADCONF_SPI1_SOMI_OFFSET 0x0e1
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS0_OFFSET 0x0e2
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS1_OFFSET 0x0e3
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS2_OFFSET 0x0e4
+#define OMAP2430_CONTROL_PADCONF_SPI1_CS3_OFFSET 0x0e5
+#define OMAP2430_CONTROL_PADCONF_SPI2_CLK_OFFSET 0x0e6
+#define OMAP2430_CONTROL_PADCONF_SPI2_SIMO_OFFSET 0x0e7
+#define OMAP2430_CONTROL_PADCONF_SPI2_SOMI_OFFSET 0x0e8
+#define OMAP2430_CONTROL_PADCONF_SPI2_CS0_OFFSET 0x0e9
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_CLKR_OFFSET 0x0ea
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_FSR_OFFSET 0x0eb
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_DX_OFFSET 0x0ec
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_DR_OFFSET 0x0ed
+#define OMAP2430_CONTROL_PADCONF_MCBSP_CLKS_OFFSET 0x0ee
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_FSX_OFFSET 0x0ef
+#define OMAP2430_CONTROL_PADCONF_MCBSP1_CLKX_OFFSET 0x0f0
+#define OMAP2430_CONTROL_PADCONF_I2C1_SCL_OFFSET 0x0f1
+#define OMAP2430_CONTROL_PADCONF_I2C1_SDA_OFFSET 0x0f2
+#define OMAP2430_CONTROL_PADCONF_I2C2_SCL_OFFSET 0x0f3
+#define OMAP2430_CONTROL_PADCONF_I2C2_SDA_OFFSET 0x0f4
+#define OMAP2430_CONTROL_PADCONF_HDQ_SIO_OFFSET 0x0f5
+#define OMAP2430_CONTROL_PADCONF_UART3_CTS_RCTX_OFFSET 0x0f6
+#define OMAP2430_CONTROL_PADCONF_UART3_RTS_SD_OFFSET 0x0f7
+#define OMAP2430_CONTROL_PADCONF_UART3_TX_IRTX_OFFSET 0x0f8
+#define OMAP2430_CONTROL_PADCONF_UART3_RX_IRRX_OFFSET 0x0f9
+#define OMAP2430_CONTROL_PADCONF_GPIO_7_OFFSET 0x0fa
+#define OMAP2430_CONTROL_PADCONF_GPIO_78_OFFSET 0x0fb
+#define OMAP2430_CONTROL_PADCONF_GPIO_79_OFFSET 0x0fc
+#define OMAP2430_CONTROL_PADCONF_GPIO_80_OFFSET 0x0fd
+#define OMAP2430_CONTROL_PADCONF_GPIO_113_OFFSET 0x0fe
+#define OMAP2430_CONTROL_PADCONF_GPIO_114_OFFSET 0x0ff
+#define OMAP2430_CONTROL_PADCONF_GPIO_115_OFFSET 0x100
+#define OMAP2430_CONTROL_PADCONF_GPIO_116_OFFSET 0x101
+#define OMAP2430_CONTROL_PADCONF_SYS_DRM_MSECURE_OFFSET 0x102
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA3_OFFSET 0x103
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA4_OFFSET 0x104
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA5_OFFSET 0x105
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA6_OFFSET 0x106
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA2_OFFSET 0x107
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA0_OFFSET 0x108
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA1_OFFSET 0x109
+#define OMAP2430_CONTROL_PADCONF_USB0HS_CLK_OFFSET 0x10a
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DIR_OFFSET 0x10b
+#define OMAP2430_CONTROL_PADCONF_USB0HS_STP_OFFSET 0x10c
+#define OMAP2430_CONTROL_PADCONF_USB0HS_NXT_OFFSET 0x10d
+#define OMAP2430_CONTROL_PADCONF_USB0HS_DATA7_OFFSET 0x10e
+#define OMAP2430_CONTROL_PADCONF_TV_OUT_OFFSET 0x10f
+#define OMAP2430_CONTROL_PADCONF_TV_VREF_OFFSET 0x110
+#define OMAP2430_CONTROL_PADCONF_TV_RSET_OFFSET 0x111
+#define OMAP2430_CONTROL_PADCONF_TV_VFB_OFFSET 0x112
+#define OMAP2430_CONTROL_PADCONF_TV_DACOUT_OFFSET 0x113
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD0_OFFSET 0x114
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD1_OFFSET 0x115
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD2_OFFSET 0x116
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD3_OFFSET 0x117
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD4_OFFSET 0x118
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD5_OFFSET 0x119
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD6_OFFSET 0x11a
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD7_OFFSET 0x11b
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD8_OFFSET 0x11c
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD9_OFFSET 0x11d
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD10_OFFSET 0x11e
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD11_OFFSET 0x11f
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD12_OFFSET 0x120
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD13_OFFSET 0x121
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD14_OFFSET 0x122
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD15_OFFSET 0x123
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD16_OFFSET 0x124
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD17_OFFSET 0x125
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD18_OFFSET 0x126
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD19_OFFSET 0x127
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD20_OFFSET 0x128
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD21_OFFSET 0x129
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD22_OFFSET 0x12a
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD23_OFFSET 0x12b
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD24_OFFSET 0x12c
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD25_OFFSET 0x12d
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD26_OFFSET 0x12e
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD27_OFFSET 0x12f
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD28_OFFSET 0x130
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD29_OFFSET 0x131
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD30_OFFSET 0x132
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD31_OFFSET 0x133
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD32_OFFSET 0x134
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD33_OFFSET 0x135
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD34_OFFSET 0x136
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD35_OFFSET 0x137
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD36_OFFSET 0x138
+#define OMAP2430_CONTROL_PADCONF_AD2DMCAD37_OFFSET 0x139
+#define OMAP2430_CONTROL_PADCONF_AD2DMWRITE_OFFSET 0x13a
+#define OMAP2430_CONTROL_PADCONF_D2DCLK26MI_OFFSET 0x13b
+#define OMAP2430_CONTROL_PADCONF_D2DNRESPWRON1_OFFSET 0x13c
+#define OMAP2430_CONTROL_PADCONF_D2DNRESWARM_OFFSET 0x13d
+#define OMAP2430_CONTROL_PADCONF_D2DARM9NIRQ_OFFSET 0x13e
+#define OMAP2430_CONTROL_PADCONF_D2DUMA2P6FIQ_OFFSET 0x13f
+#define OMAP2430_CONTROL_PADCONF_D2DSPINT_OFFSET 0x140
+#define OMAP2430_CONTROL_PADCONF_D2DFRINT_OFFSET 0x141
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ0_OFFSET 0x142
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ1_OFFSET 0x143
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ2_OFFSET 0x144
+#define OMAP2430_CONTROL_PADCONF_D2DDMAREQ3_OFFSET 0x145
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTRST_OFFSET 0x146
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTDI_OFFSET 0x147
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTDO_OFFSET 0x148
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTMS_OFFSET 0x149
+#define OMAP2430_CONTROL_PADCONF_D2DN3GTCK_OFFSET 0x14a
+#define OMAP2430_CONTROL_PADCONF_D2DN3GRTCK_OFFSET 0x14b
+#define OMAP2430_CONTROL_PADCONF_D2DMSTDBY_OFFSET 0x14c
+#define OMAP2430_CONTROL_PADCONF_AD2DSREAD_OFFSET 0x14d
+#define OMAP2430_CONTROL_PADCONF_D2DSWAKEUP_OFFSET 0x14e
+#define OMAP2430_CONTROL_PADCONF_D2DIDLEREQ_OFFSET 0x14f
+#define OMAP2430_CONTROL_PADCONF_D2DIDLEACK_OFFSET 0x150
+#define OMAP2430_CONTROL_PADCONF_D2DSPARE0_OFFSET 0x151
+#define OMAP2430_CONTROL_PADCONF_AD2DSWRITE_OFFSET 0x152
+#define OMAP2430_CONTROL_PADCONF_AD2DMREAD_OFFSET 0x153
+
+#define OMAP2430_CONTROL_PADCONF_MUX_SIZE \
+ (OMAP2430_CONTROL_PADCONF_AD2DMREAD_OFFSET + 0x1)
diff --git a/arch/arm/mach-omap2/mux34xx.c b/arch/arm/mach-omap2/mux34xx.c
index 2ff4dce95ee8..f64d7eea3451 100644
--- a/arch/arm/mach-omap2/mux34xx.c
+++ b/arch/arm/mach-omap2/mux34xx.c
@@ -2032,19 +2032,19 @@ int __init omap3_mux_init(struct omap_board_mux *board_subset, int flags)
struct omap_ball *package_balls;
switch (flags & OMAP_PACKAGE_MASK) {
- case (OMAP_PACKAGE_CBC):
+ case OMAP_PACKAGE_CBC:
package_subset = omap3_cbc_subset;
package_balls = omap3_cbc_ball;
break;
- case (OMAP_PACKAGE_CBB):
+ case OMAP_PACKAGE_CBB:
package_subset = omap3_cbb_subset;
package_balls = omap3_cbb_ball;
break;
- case (OMAP_PACKAGE_CUS):
+ case OMAP_PACKAGE_CUS:
package_subset = omap3_cus_subset;
package_balls = omap3_cus_ball;
break;
- case (OMAP_PACKAGE_CBP):
+ case OMAP_PACKAGE_CBP:
package_subset = omap36xx_cbp_subset;
package_balls = omap36xx_cbp_ball;
break;
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index ef0e7a00dd6c..6ae937a06cc1 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -47,19 +47,3 @@ hold: ldr r12,=0x103
b secondary_startup
END(omap_secondary_startup)
-
-ENTRY(omap_modify_auxcoreboot0)
- stmfd sp!, {r1-r12, lr}
- ldr r12, =0x104
- dsb
- smc #0
- ldmfd sp!, {r1-r12, pc}
-END(omap_modify_auxcoreboot0)
-
-ENTRY(omap_auxcoreboot_addr)
- stmfd sp!, {r2-r12, lr}
- ldr r12, =0x105
- dsb
- smc #0
- ldmfd sp!, {r2-r12, pc}
-END(omap_auxcoreboot_addr)
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c
new file mode 100644
index 000000000000..6cee456ca542
--- /dev/null
+++ b/arch/arm/mach-omap2/omap-hotplug.c
@@ -0,0 +1,79 @@
+/*
+ * OMAP4 SMP cpu-hotplug support
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Author:
+ * Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * Platform file needed for the OMAP4 SMP. This file is based on arm
+ * realview smp platform.
+ * Copyright (c) 2002 ARM Limited.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <asm/cacheflush.h>
+#include <mach/omap4-common.h>
+
+static DECLARE_COMPLETION(cpu_killed);
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+ unsigned int this_cpu = hard_smp_processor_id();
+
+ if (cpu != this_cpu) {
+ pr_crit("platform_cpu_die running on %u, should be %u\n",
+ this_cpu, cpu);
+ BUG();
+ }
+ pr_notice("CPU%u: shutdown\n", cpu);
+ complete(&cpu_killed);
+ flush_cache_all();
+ dsb();
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0)
+ printk(KERN_CRIT "Secure clear status failed\n");
+
+ for (;;) {
+ /*
+ * Execute WFI
+ */
+ do_wfi();
+
+ if (omap_read_auxcoreboot0() == cpu) {
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ }
+ pr_debug("CPU%u: spurious wakeup call\n", cpu);
+ }
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c
index eb9bee73e0cb..f5a1aad1a5c0 100644
--- a/arch/arm/mach-omap2/omap-iommu.c
+++ b/arch/arm/mach-omap2/omap-iommu.c
@@ -59,7 +59,7 @@ static struct platform_device *omap3_iommu_pdev[NR_OMAP3_IOMMU_DEVICES];
static struct iommu_device omap4_devices[] = {
{
.base = OMAP4_MMU1_BASE,
- .irq = INT_44XX_DUCATI_MMU_IRQ,
+ .irq = OMAP44XX_IRQ_DUCATI_MMU,
.pdata = {
.name = "ducati",
.nr_tlb_entries = 32,
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 1cf52313759e..af3c20c8d3f9 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -73,9 +73,10 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
* the AuxCoreBoot1 register is updated with cpu state
* A barrier is added to ensure that write buffer is drained
*/
- omap_modify_auxcoreboot0(0x200, 0x0);
+ omap_modify_auxcoreboot0(0x200, 0xfffffdff);
flush_cache_all();
smp_wmb();
+ smp_cross_call(cpumask_of(cpu));
/*
* Now the secondary core is starting up let it run its
diff --git a/arch/arm/mach-omap2/omap44xx-smc.S b/arch/arm/mach-omap2/omap44xx-smc.S
index f61c7771ca47..1980dc31a1a2 100644
--- a/arch/arm/mach-omap2/omap44xx-smc.S
+++ b/arch/arm/mach-omap2/omap44xx-smc.S
@@ -30,3 +30,28 @@ ENTRY(omap_smc1)
smc #0
ldmfd sp!, {r2-r12, pc}
END(omap_smc1)
+
+ENTRY(omap_modify_auxcoreboot0)
+ stmfd sp!, {r1-r12, lr}
+ ldr r12, =0x104
+ dsb
+ smc #0
+ ldmfd sp!, {r1-r12, pc}
+END(omap_modify_auxcoreboot0)
+
+ENTRY(omap_auxcoreboot_addr)
+ stmfd sp!, {r2-r12, lr}
+ ldr r12, =0x105
+ dsb
+ smc #0
+ ldmfd sp!, {r2-r12, pc}
+END(omap_auxcoreboot_addr)
+
+ENTRY(omap_read_auxcoreboot0)
+ stmfd sp!, {r2-r12, lr}
+ ldr r12, =0x103
+ dsb
+ smc #0
+ mov r0, r0, lsr #9
+ ldmfd sp!, {r2-r12, pc}
+END(omap_read_auxcoreboot0)
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index b7a4133267d8..cb911d7d1a3c 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -1,7 +1,7 @@
/*
* omap_hwmod implementation for OMAP2/3/4
*
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
*
* Paul Walmsley, Benoît Cousson, Kevin Hilman
*
@@ -423,7 +423,7 @@ static int _init_main_clk(struct omap_hwmod *oh)
}
/**
- * _init_interface_clk - get a struct clk * for the the hwmod's interface clks
+ * _init_interface_clks - get a struct clk * for the the hwmod's interface clks
* @oh: struct omap_hwmod *
*
* Called from _init_clocks(). Populates the @oh OCP slave interface
@@ -764,6 +764,7 @@ static struct omap_hwmod *_lookup(const char *name)
/**
* _init_clocks - clk_get() all clocks associated with this hwmod
* @oh: struct omap_hwmod *
+ * @data: not used; pass NULL
*
* Called by omap_hwmod_late_init() (after omap2_clk_init()).
* Resolves all clock names embedded in the hwmod. Must be called
@@ -771,7 +772,7 @@ static struct omap_hwmod *_lookup(const char *name)
* has not yet been registered or if the clocks have already been
* initialized, 0 on success, or a non-zero error on failure.
*/
-static int _init_clocks(struct omap_hwmod *oh)
+static int _init_clocks(struct omap_hwmod *oh, void *data)
{
int ret = 0;
@@ -886,7 +887,7 @@ static int _reset(struct omap_hwmod *oh)
}
/**
- * _enable - enable an omap_hwmod
+ * _omap_hwmod_enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
*
* Enables an omap_hwmod @oh such that the MPU can access the hwmod's
@@ -894,7 +895,7 @@ static int _reset(struct omap_hwmod *oh)
* Returns -EINVAL if the hwmod is in the wrong state or passes along
* the return value of _wait_target_ready().
*/
-static int _enable(struct omap_hwmod *oh)
+int _omap_hwmod_enable(struct omap_hwmod *oh)
{
int r;
@@ -939,7 +940,7 @@ static int _enable(struct omap_hwmod *oh)
* no further work. Returns -EINVAL if the hwmod is in the wrong
* state or returns 0.
*/
-static int _idle(struct omap_hwmod *oh)
+int _omap_hwmod_idle(struct omap_hwmod *oh)
{
if (oh->_state != _HWMOD_STATE_ENABLED) {
WARN(1, "omap_hwmod: %s: idle state can only be entered from "
@@ -996,19 +997,25 @@ static int _shutdown(struct omap_hwmod *oh)
/**
* _setup - do initial configuration of omap_hwmod
* @oh: struct omap_hwmod *
+ * @skip_setup_idle_p: do not idle hwmods at the end of the fn if 1
*
* Writes the CLOCKACTIVITY bits @clockact to the hwmod @oh
- * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex
- * held. Returns -EINVAL if the hwmod is in the wrong state or returns
- * 0.
+ * OCP_SYSCONFIG register. Must be called with omap_hwmod_mutex held.
+ * @skip_setup_idle is intended to be used on a system that will not
+ * call omap_hwmod_enable() to enable devices (e.g., a system without
+ * PM runtime). Returns -EINVAL if the hwmod is in the wrong state or
+ * returns 0.
*/
-static int _setup(struct omap_hwmod *oh)
+static int _setup(struct omap_hwmod *oh, void *data)
{
int i, r;
+ u8 skip_setup_idle;
- if (!oh)
+ if (!oh || !data)
return -EINVAL;
+ skip_setup_idle = *(u8 *)data;
+
/* Set iclk autoidle mode */
if (oh->slaves_cnt > 0) {
for (i = 0; i < oh->slaves_cnt; i++) {
@@ -1029,7 +1036,7 @@ static int _setup(struct omap_hwmod *oh)
oh->_state = _HWMOD_STATE_INITIALIZED;
- r = _enable(oh);
+ r = _omap_hwmod_enable(oh);
if (r) {
pr_warning("omap_hwmod: %s: cannot be enabled (%d)\n",
oh->name, oh->_state);
@@ -1041,7 +1048,7 @@ static int _setup(struct omap_hwmod *oh)
* XXX Do the OCP_SYSCONFIG bits need to be
* reprogrammed after a reset? If not, then this can
* be removed. If they do, then probably the
- * _enable() function should be split to avoid the
+ * _omap_hwmod_enable() function should be split to avoid the
* rewrite of the OCP_SYSCONFIG register.
*/
if (oh->class->sysc) {
@@ -1050,8 +1057,8 @@ static int _setup(struct omap_hwmod *oh)
}
}
- if (!(oh->flags & HWMOD_INIT_NO_IDLE))
- _idle(oh);
+ if (!(oh->flags & HWMOD_INIT_NO_IDLE) && !skip_setup_idle)
+ _omap_hwmod_idle(oh);
return 0;
}
@@ -1062,14 +1069,29 @@ static int _setup(struct omap_hwmod *oh)
u32 omap_hwmod_readl(struct omap_hwmod *oh, u16 reg_offs)
{
- return __raw_readl(oh->_rt_va + reg_offs);
+ return __raw_readl(oh->_mpu_rt_va + reg_offs);
}
void omap_hwmod_writel(u32 v, struct omap_hwmod *oh, u16 reg_offs)
{
- __raw_writel(v, oh->_rt_va + reg_offs);
+ __raw_writel(v, oh->_mpu_rt_va + reg_offs);
}
+/**
+ * omap_hwmod_set_slave_idlemode - set the hwmod's OCP slave idlemode
+ * @oh: struct omap_hwmod *
+ * @idlemode: SIDLEMODE field bits (shifted to bit 0)
+ *
+ * Sets the IP block's OCP slave idlemode in hardware, and updates our
+ * local copy. Intended to be used by drivers that have some erratum
+ * that requires direct manipulation of the SIDLEMODE bits. Returns
+ * -EINVAL if @oh is null, or passes along the return value from
+ * _set_slave_idlemode().
+ *
+ * XXX Does this function have any current users? If not, we should
+ * remove it; it is better to let the rest of the hwmod code handle this.
+ * Any users of this function should be scrutinized carefully.
+ */
int omap_hwmod_set_slave_idlemode(struct omap_hwmod *oh, u8 idlemode)
{
u32 v;
@@ -1124,7 +1146,7 @@ int omap_hwmod_register(struct omap_hwmod *oh)
ms_id = _find_mpu_port_index(oh);
if (!IS_ERR_VALUE(ms_id)) {
oh->_mpu_port_index = ms_id;
- oh->_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
+ oh->_mpu_rt_va = _find_mpu_rt_base(oh, oh->_mpu_port_index);
} else {
oh->_int_flags |= _HWMOD_NO_MPU_PORT;
}
@@ -1164,6 +1186,7 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
/**
* omap_hwmod_for_each - call function for each registered omap_hwmod
* @fn: pointer to a callback function
+ * @data: void * data to pass to callback function
*
* Call @fn for each registered omap_hwmod, passing @data to each
* function. @fn must return 0 for success or any other value for
@@ -1172,7 +1195,8 @@ struct omap_hwmod *omap_hwmod_lookup(const char *name)
* caller of omap_hwmod_for_each(). @fn is called with
* omap_hwmod_for_each() held.
*/
-int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+ void *data)
{
struct omap_hwmod *temp_oh;
int ret;
@@ -1182,7 +1206,7 @@ int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh))
mutex_lock(&omap_hwmod_mutex);
list_for_each_entry(temp_oh, &omap_hwmod_list, node) {
- ret = (*fn)(temp_oh);
+ ret = (*fn)(temp_oh, data);
if (ret)
break;
}
@@ -1229,24 +1253,28 @@ int omap_hwmod_init(struct omap_hwmod **ohs)
/**
* omap_hwmod_late_init - do some post-clock framework initialization
+ * @skip_setup_idle: if 1, do not idle hwmods in _setup()
*
* Must be called after omap2_clk_init(). Resolves the struct clk names
* to struct clk pointers for each registered omap_hwmod. Also calls
* _setup() on each hwmod. Returns 0.
*/
-int omap_hwmod_late_init(void)
+int omap_hwmod_late_init(u8 skip_setup_idle)
{
int r;
/* XXX check return value */
- r = omap_hwmod_for_each(_init_clocks);
+ r = omap_hwmod_for_each(_init_clocks, NULL);
WARN(r, "omap_hwmod: omap_hwmod_late_init(): _init_clocks failed\n");
mpu_oh = omap_hwmod_lookup(MPU_INITIATOR_NAME);
WARN(!mpu_oh, "omap_hwmod: could not find MPU initiator hwmod %s\n",
MPU_INITIATOR_NAME);
- omap_hwmod_for_each(_setup);
+ if (skip_setup_idle)
+ pr_debug("omap_hwmod: will leave hwmods enabled during setup\n");
+
+ omap_hwmod_for_each(_setup, &skip_setup_idle);
return 0;
}
@@ -1270,7 +1298,7 @@ int omap_hwmod_unregister(struct omap_hwmod *oh)
pr_debug("omap_hwmod: %s: unregistering\n", oh->name);
mutex_lock(&omap_hwmod_mutex);
- iounmap(oh->_rt_va);
+ iounmap(oh->_mpu_rt_va);
list_del(&oh->node);
mutex_unlock(&omap_hwmod_mutex);
@@ -1292,12 +1320,13 @@ int omap_hwmod_enable(struct omap_hwmod *oh)
return -EINVAL;
mutex_lock(&omap_hwmod_mutex);
- r = _enable(oh);
+ r = _omap_hwmod_enable(oh);
mutex_unlock(&omap_hwmod_mutex);
return r;
}
+
/**
* omap_hwmod_idle - idle an omap_hwmod
* @oh: struct omap_hwmod *
@@ -1311,7 +1340,7 @@ int omap_hwmod_idle(struct omap_hwmod *oh)
return -EINVAL;
mutex_lock(&omap_hwmod_mutex);
- _idle(oh);
+ _omap_hwmod_idle(oh);
mutex_unlock(&omap_hwmod_mutex);
return 0;
@@ -1413,7 +1442,7 @@ int omap_hwmod_reset(struct omap_hwmod *oh)
mutex_lock(&omap_hwmod_mutex);
r = _reset(oh);
if (!r)
- r = _enable(oh);
+ r = _omap_hwmod_enable(oh);
mutex_unlock(&omap_hwmod_mutex);
return r;
@@ -1530,6 +1559,29 @@ struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh)
}
/**
+ * omap_hwmod_get_mpu_rt_va - return the module's base address (for the MPU)
+ * @oh: struct omap_hwmod *
+ *
+ * Returns the virtual address corresponding to the beginning of the
+ * module's register target, in the address range that is intended to
+ * be used by the MPU. Returns the virtual address upon success or NULL
+ * upon error.
+ */
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
+{
+ if (!oh)
+ return NULL;
+
+ if (oh->_int_flags & _HWMOD_NO_MPU_PORT)
+ return NULL;
+
+ if (oh->_state == _HWMOD_STATE_UNKNOWN)
+ return NULL;
+
+ return oh->_mpu_rt_va;
+}
+
+/**
* omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
* @oh: struct omap_hwmod *
* @init_oh: struct omap_hwmod * (initiator)
diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
index e5530c51f77d..3cc768e8bc04 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c
@@ -30,42 +30,44 @@
*/
static struct omap_hwmod omap2420_mpu_hwmod;
-static struct omap_hwmod omap2420_l3_hwmod;
+static struct omap_hwmod omap2420_iva_hwmod;
+static struct omap_hwmod omap2420_l3_main_hwmod;
static struct omap_hwmod omap2420_l4_core_hwmod;
/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2420_l3__l4_core = {
- .master = &omap2420_l3_hwmod,
+static struct omap_hwmod_ocp_if omap2420_l3_main__l4_core = {
+ .master = &omap2420_l3_main_hwmod,
.slave = &omap2420_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2420_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap2420_mpu__l3_main = {
.master = &omap2420_mpu_hwmod,
- .slave = &omap2420_l3_hwmod,
+ .slave = &omap2420_l3_main_hwmod,
.user = OCP_USER_MPU,
};
/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_slaves[] = {
- &omap2420_mpu__l3,
+static struct omap_hwmod_ocp_if *omap2420_l3_main_slaves[] = {
+ &omap2420_mpu__l3_main,
};
/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2420_l3_masters[] = {
- &omap2420_l3__l4_core,
+static struct omap_hwmod_ocp_if *omap2420_l3_main_masters[] = {
+ &omap2420_l3_main__l4_core,
};
/* L3 */
-static struct omap_hwmod omap2420_l3_hwmod = {
- .name = "l3_hwmod",
+static struct omap_hwmod omap2420_l3_main_hwmod = {
+ .name = "l3_main",
.class = &l3_hwmod_class,
- .masters = omap2420_l3_masters,
- .masters_cnt = ARRAY_SIZE(omap2420_l3_masters),
- .slaves = omap2420_l3_slaves,
- .slaves_cnt = ARRAY_SIZE(omap2420_l3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+ .masters = omap2420_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_l3_main_masters),
+ .slaves = omap2420_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2420_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
};
static struct omap_hwmod omap2420_l4_wkup_hwmod;
@@ -79,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = {
- &omap2420_l3__l4_core,
+ &omap2420_l3_main__l4_core,
};
/* Master interfaces on the L4_CORE interconnect */
@@ -89,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = {
/* L4 CORE */
static struct omap_hwmod omap2420_l4_core_hwmod = {
- .name = "l4_core_hwmod",
+ .name = "l4_core",
.class = &l4_hwmod_class,
.masters = omap2420_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap2420_l4_core_masters),
.slaves = omap2420_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
};
/* Slave interfaces on the L4_WKUP interconnect */
@@ -109,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2420_l4_wkup_masters[] = {
/* L4 WKUP */
static struct omap_hwmod omap2420_l4_wkup_hwmod = {
- .name = "l4_wkup_hwmod",
+ .name = "l4_wkup",
.class = &l4_hwmod_class,
.masters = omap2420_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap2420_l4_wkup_masters),
.slaves = omap2420_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap2420_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
+ .flags = HWMOD_NO_IDLEST,
};
/* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap2420_mpu_masters[] = {
- &omap2420_mpu__l3,
+ &omap2420_mpu__l3_main,
};
/* MPU */
@@ -133,11 +137,40 @@ static struct omap_hwmod omap2420_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420),
};
+/*
+ * IVA1 interface data
+ */
+
+/* IVA <- L3 interface */
+static struct omap_hwmod_ocp_if omap2420_l3__iva = {
+ .master = &omap2420_l3_main_hwmod,
+ .slave = &omap2420_iva_hwmod,
+ .clk = "iva1_ifck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2420_iva_masters[] = {
+ &omap2420_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2420_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap2420_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap2420_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420)
+};
+
static __initdata struct omap_hwmod *omap2420_hwmods[] = {
- &omap2420_l3_hwmod,
+ &omap2420_l3_main_hwmod,
&omap2420_l4_core_hwmod,
&omap2420_l4_wkup_hwmod,
&omap2420_mpu_hwmod,
+ &omap2420_iva_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
index 0852d954da40..4526628ed287 100644
--- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c
@@ -30,47 +30,47 @@
*/
static struct omap_hwmod omap2430_mpu_hwmod;
-static struct omap_hwmod omap2430_l3_hwmod;
+static struct omap_hwmod omap2430_iva_hwmod;
+static struct omap_hwmod omap2430_l3_main_hwmod;
static struct omap_hwmod omap2430_l4_core_hwmod;
/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap2430_l3__l4_core = {
- .master = &omap2430_l3_hwmod,
+static struct omap_hwmod_ocp_if omap2430_l3_main__l4_core = {
+ .master = &omap2430_l3_main_hwmod,
.slave = &omap2430_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap2430_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap2430_mpu__l3_main = {
.master = &omap2430_mpu_hwmod,
- .slave = &omap2430_l3_hwmod,
+ .slave = &omap2430_l3_main_hwmod,
.user = OCP_USER_MPU,
};
/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_slaves[] = {
- &omap2430_mpu__l3,
+static struct omap_hwmod_ocp_if *omap2430_l3_main_slaves[] = {
+ &omap2430_mpu__l3_main,
};
/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap2430_l3_masters[] = {
- &omap2430_l3__l4_core,
+static struct omap_hwmod_ocp_if *omap2430_l3_main_masters[] = {
+ &omap2430_l3_main__l4_core,
};
/* L3 */
-static struct omap_hwmod omap2430_l3_hwmod = {
- .name = "l3_hwmod",
+static struct omap_hwmod omap2430_l3_main_hwmod = {
+ .name = "l3_main",
.class = &l3_hwmod_class,
- .masters = omap2430_l3_masters,
- .masters_cnt = ARRAY_SIZE(omap2430_l3_masters),
- .slaves = omap2430_l3_slaves,
- .slaves_cnt = ARRAY_SIZE(omap2430_l3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ .masters = omap2430_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_l3_main_masters),
+ .slaves = omap2430_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap2430_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
};
static struct omap_hwmod omap2430_l4_wkup_hwmod;
-static struct omap_hwmod omap2430_mmc1_hwmod;
-static struct omap_hwmod omap2430_mmc2_hwmod;
/* L4_CORE -> L4_WKUP interface */
static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
@@ -81,7 +81,7 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap2430_l4_core_slaves[] = {
- &omap2430_l3__l4_core,
+ &omap2430_l3_main__l4_core,
};
/* Master interfaces on the L4_CORE interconnect */
@@ -91,13 +91,14 @@ static struct omap_hwmod_ocp_if *omap2430_l4_core_masters[] = {
/* L4 CORE */
static struct omap_hwmod omap2430_l4_core_hwmod = {
- .name = "l4_core_hwmod",
+ .name = "l4_core",
.class = &l4_hwmod_class,
.masters = omap2430_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap2430_l4_core_masters),
.slaves = omap2430_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
};
/* Slave interfaces on the L4_WKUP interconnect */
@@ -111,18 +112,19 @@ static struct omap_hwmod_ocp_if *omap2430_l4_wkup_masters[] = {
/* L4 WKUP */
static struct omap_hwmod omap2430_l4_wkup_hwmod = {
- .name = "l4_wkup_hwmod",
+ .name = "l4_wkup",
.class = &l4_hwmod_class,
.masters = omap2430_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap2430_l4_wkup_masters),
.slaves = omap2430_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap2430_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
+ .flags = HWMOD_NO_IDLEST,
};
/* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap2430_mpu_masters[] = {
- &omap2430_mpu__l3,
+ &omap2430_mpu__l3_main,
};
/* MPU */
@@ -135,11 +137,40 @@ static struct omap_hwmod omap2430_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430),
};
+/*
+ * IVA2_1 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap2430_l3__iva = {
+ .master = &omap2430_l3_main_hwmod,
+ .slave = &omap2430_iva_hwmod,
+ .clk = "dsp_fck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap2430_iva_masters[] = {
+ &omap2430_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap2430_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap2430_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap2430_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430)
+};
+
static __initdata struct omap_hwmod *omap2430_hwmods[] = {
- &omap2430_l3_hwmod,
+ &omap2430_l3_main_hwmod,
&omap2430_l4_core_hwmod,
&omap2430_l4_wkup_hwmod,
&omap2430_mpu_hwmod,
+ &omap2430_iva_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 39b0c0eaa37d..5d8eb58ba5e3 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -32,51 +32,53 @@
*/
static struct omap_hwmod omap3xxx_mpu_hwmod;
-static struct omap_hwmod omap3xxx_l3_hwmod;
+static struct omap_hwmod omap3xxx_iva_hwmod;
+static struct omap_hwmod omap3xxx_l3_main_hwmod;
static struct omap_hwmod omap3xxx_l4_core_hwmod;
static struct omap_hwmod omap3xxx_l4_per_hwmod;
/* L3 -> L4_CORE interface */
-static struct omap_hwmod_ocp_if omap3xxx_l3__l4_core = {
- .master = &omap3xxx_l3_hwmod,
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
+ .master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_l4_core_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* L3 -> L4_PER interface */
-static struct omap_hwmod_ocp_if omap3xxx_l3__l4_per = {
- .master = &omap3xxx_l3_hwmod,
+static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_per = {
+ .master = &omap3xxx_l3_main_hwmod,
.slave = &omap3xxx_l4_per_hwmod,
.user = OCP_USER_MPU | OCP_USER_SDMA,
};
/* MPU -> L3 interface */
-static struct omap_hwmod_ocp_if omap3xxx_mpu__l3 = {
+static struct omap_hwmod_ocp_if omap3xxx_mpu__l3_main = {
.master = &omap3xxx_mpu_hwmod,
- .slave = &omap3xxx_l3_hwmod,
+ .slave = &omap3xxx_l3_main_hwmod,
.user = OCP_USER_MPU,
};
/* Slave interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l3_slaves[] = {
- &omap3xxx_mpu__l3,
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_slaves[] = {
+ &omap3xxx_mpu__l3_main,
};
/* Master interfaces on the L3 interconnect */
-static struct omap_hwmod_ocp_if *omap3xxx_l3_masters[] = {
- &omap3xxx_l3__l4_core,
- &omap3xxx_l3__l4_per,
+static struct omap_hwmod_ocp_if *omap3xxx_l3_main_masters[] = {
+ &omap3xxx_l3_main__l4_core,
+ &omap3xxx_l3_main__l4_per,
};
/* L3 */
-static struct omap_hwmod omap3xxx_l3_hwmod = {
- .name = "l3_hwmod",
+static struct omap_hwmod omap3xxx_l3_main_hwmod = {
+ .name = "l3_main",
.class = &l3_hwmod_class,
- .masters = omap3xxx_l3_masters,
- .masters_cnt = ARRAY_SIZE(omap3xxx_l3_masters),
- .slaves = omap3xxx_l3_slaves,
- .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ .masters = omap3xxx_l3_main_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_l3_main_masters),
+ .slaves = omap3xxx_l3_main_slaves,
+ .slaves_cnt = ARRAY_SIZE(omap3xxx_l3_main_slaves),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
};
static struct omap_hwmod omap3xxx_l4_wkup_hwmod;
@@ -90,7 +92,7 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = {
/* Slave interfaces on the L4_CORE interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
- &omap3xxx_l3__l4_core,
+ &omap3xxx_l3_main__l4_core,
};
/* Master interfaces on the L4_CORE interconnect */
@@ -100,18 +102,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = {
/* L4 CORE */
static struct omap_hwmod omap3xxx_l4_core_hwmod = {
- .name = "l4_core_hwmod",
+ .name = "l4_core",
.class = &l4_hwmod_class,
.masters = omap3xxx_l4_core_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_core_masters),
.slaves = omap3xxx_l4_core_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_core_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
};
/* Slave interfaces on the L4_PER interconnect */
static struct omap_hwmod_ocp_if *omap3xxx_l4_per_slaves[] = {
- &omap3xxx_l3__l4_per,
+ &omap3xxx_l3_main__l4_per,
};
/* Master interfaces on the L4_PER interconnect */
@@ -120,13 +123,14 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_per_masters[] = {
/* L4 PER */
static struct omap_hwmod omap3xxx_l4_per_hwmod = {
- .name = "l4_per_hwmod",
+ .name = "l4_per",
.class = &l4_hwmod_class,
.masters = omap3xxx_l4_per_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_per_masters),
.slaves = omap3xxx_l4_per_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_per_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
};
/* Slave interfaces on the L4_WKUP interconnect */
@@ -140,18 +144,19 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_wkup_masters[] = {
/* L4 WKUP */
static struct omap_hwmod omap3xxx_l4_wkup_hwmod = {
- .name = "l4_wkup_hwmod",
+ .name = "l4_wkup",
.class = &l4_hwmod_class,
.masters = omap3xxx_l4_wkup_masters,
.masters_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_masters),
.slaves = omap3xxx_l4_wkup_slaves,
.slaves_cnt = ARRAY_SIZE(omap3xxx_l4_wkup_slaves),
- .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
+ .flags = HWMOD_NO_IDLEST,
};
/* Master interfaces on the MPU device */
static struct omap_hwmod_ocp_if *omap3xxx_mpu_masters[] = {
- &omap3xxx_mpu__l3,
+ &omap3xxx_mpu__l3_main,
};
/* MPU */
@@ -164,12 +169,41 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430),
};
+/*
+ * IVA2_2 interface data
+ */
+
+/* IVA2 <- L3 interface */
+static struct omap_hwmod_ocp_if omap3xxx_l3__iva = {
+ .master = &omap3xxx_l3_main_hwmod,
+ .slave = &omap3xxx_iva_hwmod,
+ .clk = "iva2_ck",
+ .user = OCP_USER_MPU | OCP_USER_SDMA,
+};
+
+static struct omap_hwmod_ocp_if *omap3xxx_iva_masters[] = {
+ &omap3xxx_l3__iva,
+};
+
+/*
+ * IVA2 (IVA2)
+ */
+
+static struct omap_hwmod omap3xxx_iva_hwmod = {
+ .name = "iva",
+ .class = &iva_hwmod_class,
+ .masters = omap3xxx_iva_masters,
+ .masters_cnt = ARRAY_SIZE(omap3xxx_iva_masters),
+ .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430)
+};
+
static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
- &omap3xxx_l3_hwmod,
+ &omap3xxx_l3_main_hwmod,
&omap3xxx_l4_core_hwmod,
&omap3xxx_l4_per_hwmod,
&omap3xxx_l4_wkup_hwmod,
&omap3xxx_mpu_hwmod,
+ &omap3xxx_iva_hwmod,
NULL,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.c b/arch/arm/mach-omap2/omap_hwmod_common_data.c
index 1e80b914fa1a..08a134243ecb 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.c
@@ -66,3 +66,6 @@ struct omap_hwmod_class mpu_hwmod_class = {
.name = "mpu"
};
+struct omap_hwmod_class iva_hwmod_class = {
+ .name = "iva"
+};
diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h
index 3645a28c7c27..c34e98bf1242 100644
--- a/arch/arm/mach-omap2/omap_hwmod_common_data.h
+++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h
@@ -20,5 +20,6 @@
extern struct omap_hwmod_class l3_hwmod_class;
extern struct omap_hwmod_class l4_hwmod_class;
extern struct omap_hwmod_class mpu_hwmod_class;
+extern struct omap_hwmod_class iva_hwmod_class;
#endif
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
new file mode 100644
index 000000000000..68f9f2e95891
--- /dev/null
+++ b/arch/arm/mach-omap2/pm.c
@@ -0,0 +1,84 @@
+/*
+ * pm.c - Common OMAP2+ power management-related code
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Copyright (C) 2010 Nokia Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/err.h>
+
+#include <plat/omap-pm.h>
+#include <plat/omap_device.h>
+#include <plat/common.h>
+
+static struct omap_device_pm_latency *pm_lats;
+
+static struct device *mpu_dev;
+static struct device *dsp_dev;
+static struct device *l3_dev;
+
+struct device *omap2_get_mpuss_device(void)
+{
+ WARN_ON_ONCE(!mpu_dev);
+ return mpu_dev;
+}
+
+struct device *omap2_get_dsp_device(void)
+{
+ WARN_ON_ONCE(!dsp_dev);
+ return dsp_dev;
+}
+
+struct device *omap2_get_l3_device(void)
+{
+ WARN_ON_ONCE(!l3_dev);
+ return l3_dev;
+}
+
+/* static int _init_omap_device(struct omap_hwmod *oh, void *user) */
+static int _init_omap_device(char *name, struct device **new_dev)
+{
+ struct omap_hwmod *oh;
+ struct omap_device *od;
+
+ oh = omap_hwmod_lookup(name);
+ if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ od = omap_device_build(oh->name, 0, oh, NULL, 0, pm_lats, 0, false);
+ if (WARN(IS_ERR(od), "%s: could not build omap_device for %s\n",
+ __func__, name))
+ return -ENODEV;
+
+ *new_dev = &od->pdev.dev;
+
+ return 0;
+}
+
+/*
+ * Build omap_devices for processors and bus.
+ */
+static void omap2_init_processor_devices(void)
+{
+ _init_omap_device("mpu", &mpu_dev);
+ _init_omap_device("iva", &dsp_dev);
+ _init_omap_device("l3_main", &l3_dev);
+}
+
+static int __init omap2_common_pm_init(void)
+{
+ omap2_init_processor_devices();
+ omap_pm_if_init();
+
+ return 0;
+}
+device_initcall(omap2_common_pm_init);
+
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index e321281ab6e1..6aeedeacdad8 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -39,7 +39,6 @@
#include <plat/clock.h>
#include <plat/sram.h>
#include <plat/control.h>
-#include <plat/mux.h>
#include <plat/dma.h>
#include <plat/board.h>
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index b88737fd6cfe..fb4994ad622e 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -385,8 +385,9 @@ void omap_sram_idle(void)
/* Enable IO-PAD and IO-CHAIN wakeups */
per_next_state = pwrdm_read_next_pwrst(per_pwrdm);
core_next_state = pwrdm_read_next_pwrst(core_pwrdm);
- if (per_next_state < PWRDM_POWER_ON ||
- core_next_state < PWRDM_POWER_ON) {
+ if (omap3_has_io_wakeup() && \
+ (per_next_state < PWRDM_POWER_ON ||
+ core_next_state < PWRDM_POWER_ON)) {
prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
omap3_enable_io_chain();
}
@@ -479,7 +480,7 @@ void omap_sram_idle(void)
}
/* Disable IO-PAD and IO-CHAIN wakeup */
- if (core_next_state < PWRDM_POWER_ON) {
+ if (omap3_has_io_wakeup() && core_next_state < PWRDM_POWER_ON) {
prm_clear_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, PM_WKEN);
omap3_disable_io_chain();
}
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
new file mode 100644
index 000000000000..54544b4fc76b
--- /dev/null
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -0,0 +1,135 @@
+/*
+ * OMAP4 Power Management Routines
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Rajendra Nayak <rnayak@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.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <plat/powerdomain.h>
+#include <mach/omap4-common.h>
+
+struct power_state {
+ struct powerdomain *pwrdm;
+ u32 next_state;
+#ifdef CONFIG_SUSPEND
+ u32 saved_state;
+#endif
+ struct list_head node;
+};
+
+static LIST_HEAD(pwrst_list);
+
+#ifdef CONFIG_SUSPEND
+static int omap4_pm_prepare(void)
+{
+ disable_hlt();
+ return 0;
+}
+
+static int omap4_pm_suspend(void)
+{
+ do_wfi();
+ return 0;
+}
+
+static int omap4_pm_enter(suspend_state_t suspend_state)
+{
+ int ret = 0;
+
+ switch (suspend_state) {
+ case PM_SUSPEND_STANDBY:
+ case PM_SUSPEND_MEM:
+ ret = omap4_pm_suspend();
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void omap4_pm_finish(void)
+{
+ enable_hlt();
+ return;
+}
+
+static int omap4_pm_begin(suspend_state_t state)
+{
+ return 0;
+}
+
+static void omap4_pm_end(void)
+{
+ return;
+}
+
+static struct platform_suspend_ops omap_pm_ops = {
+ .begin = omap4_pm_begin,
+ .end = omap4_pm_end,
+ .prepare = omap4_pm_prepare,
+ .enter = omap4_pm_enter,
+ .finish = omap4_pm_finish,
+ .valid = suspend_valid_only_mem,
+};
+#endif /* CONFIG_SUSPEND */
+
+static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
+{
+ struct power_state *pwrst;
+
+ if (!pwrdm->pwrsts)
+ return 0;
+
+ pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
+ if (!pwrst)
+ return -ENOMEM;
+ pwrst->pwrdm = pwrdm;
+ pwrst->next_state = PWRDM_POWER_ON;
+ list_add(&pwrst->node, &pwrst_list);
+
+ return pwrdm_set_next_pwrst(pwrst->pwrdm, pwrst->next_state);
+}
+
+/**
+ * omap4_pm_init - Init routine for OMAP4 PM
+ *
+ * Initializes all powerdomain and clockdomain target states
+ * and all PRCM settings.
+ */
+static int __init omap4_pm_init(void)
+{
+ int ret;
+
+ if (!cpu_is_omap44xx())
+ return -ENODEV;
+
+ pr_err("Power Management for TI OMAP4.\n");
+
+#ifdef CONFIG_PM
+ ret = pwrdm_for_each(pwrdms_setup, NULL);
+ if (ret) {
+ pr_err("Failed to setup powerdomains\n");
+ goto err2;
+ }
+#endif
+
+#ifdef CONFIG_SUSPEND
+ suspend_set_ops(&omap_pm_ops);
+#endif /* CONFIG_SUSPEND */
+
+err2:
+ return ret;
+}
+late_initcall(omap4_pm_init);
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 3771254dfa81..566e991ede81 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -37,6 +37,9 @@
#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
#define UART_OMAP_WER 0x17 /* Wake-up enable register */
+#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
+#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
+
/*
* NOTE: By default the serial timeout is disabled as it causes lost characters
* over the serial ports. This means that the UART clocks will stay on until
@@ -64,6 +67,7 @@ struct omap_uart_state {
struct list_head node;
struct platform_device pdev;
+ u32 errata;
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
int context_valid;
@@ -74,6 +78,7 @@ struct omap_uart_state {
u16 sysc;
u16 scr;
u16 wer;
+ u16 mcr;
#endif
};
@@ -180,6 +185,42 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart)
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
+/*
+ * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
+ * The access to uart register after MDR1 Access
+ * causes UART to corrupt data.
+ *
+ * Need a delay =
+ * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
+ * give 10 times as much
+ */
+static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
+ u8 fcr_val)
+{
+ struct plat_serial8250_port *p = uart->p;
+ u8 timeout = 255;
+
+ serial_write_reg(p, UART_OMAP_MDR1, mdr1_val);
+ udelay(2);
+ serial_write_reg(p, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
+ UART_FCR_CLEAR_RCVR);
+ /*
+ * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
+ * TX_FIFO_E bit is 1.
+ */
+ while (UART_LSR_THRE != (serial_read_reg(p, UART_LSR) &
+ (UART_LSR_THRE | UART_LSR_DR))) {
+ timeout--;
+ if (!timeout) {
+ /* Should *never* happen. we warn and carry on */
+ dev_crit(&uart->pdev.dev, "Errata i202: timedout %x\n",
+ serial_read_reg(p, UART_LSR));
+ break;
+ }
+ udelay(1);
+ }
+}
+
static void omap_uart_save_context(struct omap_uart_state *uart)
{
u16 lcr = 0;
@@ -197,6 +238,9 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
uart->scr = serial_read_reg(p, UART_OMAP_SCR);
uart->wer = serial_read_reg(p, UART_OMAP_WER);
+ serial_write_reg(p, UART_LCR, 0x80);
+ uart->mcr = serial_read_reg(p, UART_MCR);
+ serial_write_reg(p, UART_LCR, lcr);
uart->context_valid = 1;
}
@@ -214,7 +258,10 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
uart->context_valid = 0;
- serial_write_reg(p, UART_OMAP_MDR1, 0x7);
+ if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
+ omap_uart_mdr1_errataset(uart, 0x07, 0xA0);
+ else
+ serial_write_reg(p, UART_OMAP_MDR1, 0x7);
serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
efr = serial_read_reg(p, UART_EFR);
serial_write_reg(p, UART_EFR, UART_EFR_ECB);
@@ -225,14 +272,18 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
serial_write_reg(p, UART_DLM, uart->dlh);
serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
serial_write_reg(p, UART_IER, uart->ier);
- serial_write_reg(p, UART_FCR, 0xA1);
+ serial_write_reg(p, UART_LCR, 0x80);
+ serial_write_reg(p, UART_MCR, uart->mcr);
serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
serial_write_reg(p, UART_EFR, efr);
serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
serial_write_reg(p, UART_OMAP_SCR, uart->scr);
serial_write_reg(p, UART_OMAP_WER, uart->wer);
serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
- serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
+ if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
+ omap_uart_mdr1_errataset(uart, 0x00, 0xA1);
+ else
+ serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
}
#else
static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
@@ -489,8 +540,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
}
uart->wk_mask = wk_mask;
} else {
- uart->wk_en = 0;
- uart->wk_st = 0;
+ uart->wk_en = NULL;
+ uart->wk_st = NULL;
uart->wk_mask = 0;
uart->padconf = 0;
}
@@ -552,7 +603,8 @@ static ssize_t sleep_timeout_store(struct device *dev,
return n;
}
-DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store);
+static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
+ sleep_timeout_store);
#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
#else
static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
@@ -749,14 +801,20 @@ void __init omap_serial_init_port(int port)
* omap3xxx: Never read empty UART fifo on UARTs
* with IP rev >=0x52
*/
- if (cpu_is_omap44xx()) {
- uart->p->serial_in = serial_in_override;
- uart->p->serial_out = serial_out_override;
- } else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
- >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) {
+ if (cpu_is_omap44xx())
+ uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
+ else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
+ >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
+ uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
+
+ if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
uart->p->serial_in = serial_in_override;
uart->p->serial_out = serial_out_override;
}
+
+ /* Enable the MDR1 errata for OMAP3 */
+ if (cpu_is_omap34xx())
+ uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
}
/**
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
index d72d1ac30333..b11bf385d360 100644
--- a/arch/arm/mach-omap2/usb-ehci.c
+++ b/arch/arm/mach-omap2/usb-ehci.c
@@ -23,7 +23,6 @@
#include <linux/dma-mapping.h>
#include <asm/io.h>
-#include <plat/mux.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-omap2/usb-fs.c b/arch/arm/mach-omap2/usb-fs.c
new file mode 100644
index 000000000000..a216d88b04b5
--- /dev/null
+++ b/arch/arm/mach-omap2/usb-fs.c
@@ -0,0 +1,359 @@
+/*
+ * Platform level USB initialization for FS USB OTG controller on omap1 and 24xx
+ *
+ * Copyright (C) 2004 Texas Instruments, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License 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/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/irq.h>
+
+#include <plat/control.h>
+#include <plat/usb.h>
+#include <plat/board.h>
+
+#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
+#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
+#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
+#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
+#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
+
+#include "mux.h"
+
+#if defined(CONFIG_ARCH_OMAP2)
+
+#ifdef CONFIG_USB_GADGET_OMAP
+
+static struct resource udc_resources[] = {
+ /* order is significant! */
+ { /* registers */
+ .start = UDC_BASE,
+ .end = UDC_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, { /* general IRQ */
+ .start = INT_USB_IRQ_GEN,
+ .flags = IORESOURCE_IRQ,
+ }, { /* PIO IRQ */
+ .start = INT_USB_IRQ_NISO,
+ .flags = IORESOURCE_IRQ,
+ }, { /* SOF IRQ */
+ .start = INT_USB_IRQ_ISO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device udc_device = {
+ .name = "omap_udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+};
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+ pdata->udc_device = &udc_device;
+}
+
+#else
+
+static inline void udc_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+
+/* The dmamask must be set for OHCI to work */
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct resource ohci_resources[] = {
+ {
+ .start = OMAP_OHCI_BASE,
+ .end = OMAP_OHCI_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = INT_USB_IRQ_HGEN,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ohci_device = {
+ .name = "ohci",
+ .id = -1,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+};
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+ pdata->ohci_device = &ohci_device;
+}
+
+#else
+
+static inline void ohci_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
+
+static struct resource otg_resources[] = {
+ /* order is significant! */
+ {
+ .start = OTG_BASE,
+ .end = OTG_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = INT_USB_IRQ_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device otg_device = {
+ .name = "omap_otg",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(otg_resources),
+ .resource = otg_resources,
+};
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+ pdata->otg_device = &otg_device;
+}
+
+#else
+
+static inline void otg_device_init(struct omap_usb_config *pdata)
+{
+}
+
+#endif
+
+static void omap2_usb_devconf_clear(u8 port, u32 mask)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r &= ~USBTXWRMODEI(port, mask);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb_devconf_set(u8 port, u32 mask)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r |= USBTXWRMODEI(port, mask);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb2_disable_5pinbitll(void)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI);
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static void omap2_usb2_enable_5pinunitll(void)
+{
+ u32 r;
+
+ r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI;
+ omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
+}
+
+static u32 __init omap2_usb0_init(unsigned nwires, unsigned is_device)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb_devconf_clear(0, USB_BIDIR_TLL);
+
+ if (nwires == 0)
+ return 0;
+
+ if (is_device)
+ omap_mux_init_signal("usb0_puen", 0);
+
+ omap_mux_init_signal("usb0_dat", 0);
+ omap_mux_init_signal("usb0_txen", 0);
+ omap_mux_init_signal("usb0_se0", 0);
+ if (nwires != 3)
+ omap_mux_init_signal("usb0_rcv", 0);
+
+ switch (nwires) {
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(0, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(0, USB_BIDIR);
+ break;
+ case 6:
+ syscon1 = 3;
+ omap_mux_init_signal("usb0_vp", 0);
+ omap_mux_init_signal("usb0_vm", 0);
+ omap2_usb_devconf_set(0, USB_UNIDIR);
+ break;
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 0, nwires);
+ }
+
+ return syscon1 << 16;
+}
+
+static u32 __init omap2_usb1_init(unsigned nwires)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb_devconf_clear(1, USB_BIDIR_TLL);
+
+ if (nwires == 0)
+ return 0;
+
+ /* NOTE: board-specific code must set up pin muxing for usb1,
+ * since each signal could come out on either of two balls.
+ */
+
+ switch (nwires) {
+ case 2:
+ /* NOTE: board-specific code must override this setting if
+ * this TLL link is not using DP/DM
+ */
+ syscon1 = 1;
+ omap2_usb_devconf_set(1, USB_BIDIR_TLL);
+ break;
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(1, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(1, USB_BIDIR);
+ break;
+ case 6:
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 1, nwires);
+ }
+
+ return syscon1 << 20;
+}
+
+static u32 __init omap2_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ u32 syscon1 = 0;
+
+ omap2_usb2_disable_5pinbitll();
+ alt_pingroup = 0;
+
+ /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
+ if (alt_pingroup || nwires == 0)
+ return 0;
+
+ omap_mux_init_signal("usb2_dat", 0);
+ omap_mux_init_signal("usb2_se0", 0);
+ if (nwires > 2)
+ omap_mux_init_signal("usb2_txen", 0);
+ if (nwires > 3)
+ omap_mux_init_signal("usb2_rcv", 0);
+
+ switch (nwires) {
+ case 2:
+ /* NOTE: board-specific code must override this setting if
+ * this TLL link is not using DP/DM
+ */
+ syscon1 = 1;
+ omap2_usb_devconf_set(2, USB_BIDIR_TLL);
+ break;
+ case 3:
+ syscon1 = 2;
+ omap2_usb_devconf_set(2, USB_BIDIR);
+ break;
+ case 4:
+ syscon1 = 1;
+ omap2_usb_devconf_set(2, USB_BIDIR);
+ break;
+ case 5:
+ /* NOTE: board-specific code must mux this setting depending
+ * on TLL link using DP/DM. Something must also
+ * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
+ * 2420: hdq_sio.usb2_tllse0 or vlynq_rx0.usb2_tllse0
+ * 2430: hdq_sio.usb2_tllse0 or sdmmc2_dat0.usb2_tllse0
+ */
+
+ syscon1 = 3;
+ omap2_usb2_enable_5pinunitll();
+ break;
+ case 6:
+ default:
+ printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
+ 2, nwires);
+ }
+
+ return syscon1 << 24;
+}
+
+void __init omap2_usbfs_init(struct omap_usb_config *pdata)
+{
+ struct clk *ick;
+
+ if (!cpu_is_omap24xx())
+ return;
+
+ ick = clk_get(NULL, "usb_l4_ick");
+ if (IS_ERR(ick))
+ return;
+
+ clk_enable(ick);
+ pdata->usb0_init = omap2_usb0_init;
+ pdata->usb1_init = omap2_usb1_init;
+ pdata->usb2_init = omap2_usb2_init;
+ udc_device_init(pdata);
+ ohci_device_init(pdata);
+ otg_device_init(pdata);
+ omap_otg_init(pdata);
+ clk_disable(ick);
+ clk_put(ick);
+}
+
+#endif
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index 96f6787e00b2..33a5cde1c227 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -28,7 +28,6 @@
#include <mach/hardware.h>
#include <mach/irqs.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#ifdef CONFIG_USB_MUSB_SOC
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index 10a2013c1104..64a0112b70a5 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -17,8 +17,8 @@
#include <linux/usb/musb.h>
#include <plat/gpmc.h>
-#include <plat/mux.h>
+#include "mux.h"
static u8 async_cs, sync_cs;
static unsigned refclk_psec;
@@ -325,17 +325,17 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
else {
/* assume OMAP 2420 ES2.0 and later */
if (dmachan & (1 << 0))
- omap_cfg_reg(AA10_242X_DMAREQ0);
+ omap_mux_init_signal("sys_ndmareq0", 0);
if (dmachan & (1 << 1))
- omap_cfg_reg(AA6_242X_DMAREQ1);
+ omap_mux_init_signal("sys_ndmareq1", 0);
if (dmachan & (1 << 2))
- omap_cfg_reg(E4_242X_DMAREQ2);
+ omap_mux_init_signal("sys_ndmareq2", 0);
if (dmachan & (1 << 3))
- omap_cfg_reg(G4_242X_DMAREQ3);
+ omap_mux_init_signal("sys_ndmareq3", 0);
if (dmachan & (1 << 4))
- omap_cfg_reg(D3_242X_DMAREQ4);
+ omap_mux_init_signal("sys_ndmareq4", 0);
if (dmachan & (1 << 5))
- omap_cfg_reg(E3_242X_DMAREQ5);
+ omap_mux_init_signal("sys_ndmareq5", 0);
}
/* so far so good ... register the device */
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
index 161fc2d61207..0f3130599770 100644
--- a/arch/arm/mach-pxa/cm-x2xx-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -35,7 +35,7 @@ static int cmx2xx_it8152_irq_gpio;
* This is really ugly and we need a better way of specifying
* DMA-capable regions of memory.
*/
-void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size,
+void __init cmx2xx_pci_adjust_zones(unsigned long *zone_size,
unsigned long *zhole_size)
{
unsigned int sz = SZ_64M >> PAGE_SHIFT;
@@ -46,7 +46,7 @@ void __init cmx2xx_pci_adjust_zones(int node, unsigned long *zone_size,
/*
* Only adjust if > 64M on current system
*/
- if (node || (zone_size[0] <= sz))
+ if (zone_size[0] <= sz)
return;
zone_size[1] = zone_size[0] - sz;
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 3d1dcb9ac08f..95234fb4fcf8 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -715,7 +715,6 @@ static void __init fixup_corgi(struct machine_desc *desc,
sharpsl_save_param();
mi->nr_banks=1;
mi->bank[0].start = 0xa0000000;
- mi->bank[0].node = 0;
if (machine_is_corgi())
mi->bank[0].size = (32*1024*1024);
else
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index 96ed13081639..a0ab3082a000 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -34,7 +34,6 @@ void __init eseries_fixup(struct machine_desc *desc,
{
mi->nr_banks=1;
mi->bank[0].start = 0xa0000000;
- mi->bank[0].node = 0;
if (machine_is_e800())
mi->bank[0].size = (128*1024*1024);
else
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 890fb90a672f..c6305c5b8a72 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -26,8 +26,7 @@ extern unsigned int get_clk_frequency_khz(int info);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
- mi->bank[__nr].size = (__size), \
- mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+ mi->bank[__nr].size = (__size)
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
diff --git a/arch/arm/mach-pxa/include/mach/memory.h b/arch/arm/mach-pxa/include/mach/memory.h
index f626730ee42e..264b79a3f2aa 100644
--- a/arch/arm/mach-pxa/include/mach/memory.h
+++ b/arch/arm/mach-pxa/include/mach/memory.h
@@ -30,11 +30,10 @@
#define NODE_MEM_SIZE_BITS 26
#if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
-void cmx2xx_pci_adjust_zones(int node, unsigned long *size,
- unsigned long *holes);
+void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes);
-#define arch_adjust_zones(node, size, holes) \
- cmx2xx_pci_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+ cmx2xx_pci_adjust_zones(size, holes)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_64M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_64M)
diff --git a/arch/arm/mach-pxa/palmt5.c b/arch/arm/mach-pxa/palmt5.c
index 5305a3993e69..6f0b3619a226 100644
--- a/arch/arm/mach-pxa/palmt5.c
+++ b/arch/arm/mach-pxa/palmt5.c
@@ -21,6 +21,7 @@
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/lmb.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
@@ -396,6 +397,11 @@ static void __init palmt5_udc_init(void)
}
}
+static void __init palmt5_reserve(void)
+{
+ lmb_reserve(0xa0200000, 0x1000);
+}
+
static void __init palmt5_init(void)
{
pxa2xx_mfp_config(ARRAY_AND_SIZE(palmt5_pin_config));
@@ -421,6 +427,7 @@ MACHINE_START(PALMT5, "Palm Tungsten|T5")
.io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc,
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .reserve = palmt5_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = palmt5_init
diff --git a/arch/arm/mach-pxa/palmtreo.c b/arch/arm/mach-pxa/palmtreo.c
index d8b4469607a1..e712b861e9b8 100644
--- a/arch/arm/mach-pxa/palmtreo.c
+++ b/arch/arm/mach-pxa/palmtreo.c
@@ -20,6 +20,7 @@
#include <linux/irq.h>
#include <linux/gpio_keys.h>
#include <linux/input.h>
+#include <linux/lmb.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
#include <linux/gpio.h>
@@ -633,6 +634,12 @@ static void __init treo_lcd_power_init(void)
treo_lcd_screen.pxafb_lcd_power = treo_lcd_power;
}
+static void __init treo_reserve(void)
+{
+ lmb_reserve(0xa0000000, 0x1000);
+ lmb_reserve(0xa2000000, 0x1000);
+}
+
static void __init treo_init(void)
{
pxa_set_ffuart_info(NULL);
@@ -668,6 +675,7 @@ MACHINE_START(TREO680, "Palm Treo 680")
.io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .reserve = treo_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = treo680_init,
@@ -691,6 +699,7 @@ MACHINE_START(CENTRO, "Palm Centro 685")
.io_pg_offst = io_p2v(0x40000000),
.boot_params = 0xa0000100,
.map_io = pxa_map_io,
+ .reserve = treo_reserve,
.init_irq = pxa27x_init_irq,
.timer = &pxa_timer,
.init_machine = centro_init,
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index f4abdaafdac4..bc2758b54446 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -463,7 +463,6 @@ static void __init fixup_poodle(struct machine_desc *desc,
sharpsl_save_param();
mi->nr_banks=1;
mi->bank[0].start = 0xa0000000;
- mi->bank[0].node = 0;
mi->bank[0].size = (32*1024*1024);
}
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index c1048a35f187..51756c723557 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -847,7 +847,6 @@ static void __init fixup_spitz(struct machine_desc *desc,
sharpsl_save_param();
mi->nr_banks = 1;
mi->bank[0].start = 0xa0000000;
- mi->bank[0].node = 0;
mi->bank[0].size = (64*1024*1024);
}
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 7512b822c6ca..83cc3a18c2e9 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -948,7 +948,6 @@ static void __init fixup_tosa(struct machine_desc *desc,
sharpsl_save_param();
mi->nr_banks=1;
mi->bank[0].start = 0xa0000000;
- mi->bank[0].node = 0;
mi->bank[0].size = (64*1024*1024);
}
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c
index 595be19f8ad5..4b3d2fd15b4e 100644
--- a/arch/arm/mach-realview/core.c
+++ b/arch/arm/mach-realview/core.c
@@ -61,12 +61,11 @@ void __iomem *gic_cpu_base_addr;
/*
* Adjust the zones if there are restrictions for DMA access.
*/
-void __init realview_adjust_zones(int node, unsigned long *size,
- unsigned long *hole)
+void __init realview_adjust_zones(unsigned long *size, unsigned long *hole)
{
unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
- if (!machine_is_realview_pbx() || node || (size[0] <= dma_size))
+ if (!machine_is_realview_pbx() || size[0] <= dma_size)
return;
size[ZONE_NORMAL] = size[0] - dma_size;
@@ -232,6 +231,21 @@ static unsigned int realview_mmc_status(struct device *dev)
struct amba_device *adev = container_of(dev, struct amba_device, dev);
u32 mask;
+ if (machine_is_realview_pb1176()) {
+ static bool inserted = false;
+
+ /*
+ * The PB1176 does not have the status register,
+ * assume it is inserted at startup, then invert
+ * for each call so card insertion/removal will
+ * be detected anyway. This will not be called if
+ * GPIO on PL061 is active, which is the proper
+ * way to do this on the PB1176.
+ */
+ inserted = !inserted;
+ return inserted ? 0 : 1;
+ }
+
if (adev->res.start == REALVIEW_MMCI0_BASE)
mask = 1;
else
@@ -313,6 +327,12 @@ static struct clk_lookup lookups[] = {
}, { /* UART3 */
.dev_id = "fpga:uart3",
.clk = &ref24_clk,
+ }, { /* UART3 is on the dev chip in PB1176 */
+ .dev_id = "dev:uart3",
+ .clk = &ref24_clk,
+ }, { /* UART4 only exists in PB1176 */
+ .dev_id = "fpga:uart4",
+ .clk = &ref24_clk,
}, { /* KMI0 */
.dev_id = "fpga:kmi0",
.clk = &ref24_clk,
@@ -322,7 +342,7 @@ static struct clk_lookup lookups[] = {
}, { /* MMC0 */
.dev_id = "fpga:mmc0",
.clk = &ref24_clk,
- }, { /* EB:CLCD */
+ }, { /* CLCD is in the PB1176 and EB DevChip */
.dev_id = "dev:clcd",
.clk = &oscvco_clk,
}, { /* PB:CLCD */
diff --git a/arch/arm/mach-realview/include/mach/board-pb1176.h b/arch/arm/mach-realview/include/mach/board-pb1176.h
index 2f5ccb298858..002ab5d8c11c 100644
--- a/arch/arm/mach-realview/include/mach/board-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/board-pb1176.h
@@ -26,6 +26,7 @@
/*
* Peripheral addresses
*/
+#define REALVIEW_PB1176_UART4_BASE 0x10009000 /* UART 4 */
#define REALVIEW_PB1176_SCTL_BASE 0x10100000 /* System controller */
#define REALVIEW_PB1176_SMC_BASE 0x10111000 /* SMC */
#define REALVIEW_PB1176_DMC_BASE 0x10109000 /* DMC configuration */
diff --git a/arch/arm/mach-realview/include/mach/memory.h b/arch/arm/mach-realview/include/mach/memory.h
index 2417bbcf97fd..5dafc157b276 100644
--- a/arch/arm/mach-realview/include/mach/memory.h
+++ b/arch/arm/mach-realview/include/mach/memory.h
@@ -30,10 +30,9 @@
#endif
#if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
-extern void realview_adjust_zones(int node, unsigned long *size,
- unsigned long *hole);
-#define arch_adjust_zones(node, size, hole) \
- realview_adjust_zones(node, size, hole)
+extern void realview_adjust_zones(unsigned long *size, unsigned long *hole);
+#define arch_adjust_zones(size, hole) \
+ realview_adjust_zones(size, hole)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_256M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_256M)
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 099a1f125cf8..9f02350cff3b 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -144,8 +144,6 @@ static struct pl061_platform_data gpio2_plat_data = {
#define MPMC_DMA { 0, 0 }
#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
#define PB1176_CLCD_DMA { 0, 0 }
-#define DMAC_IRQ { IRQ_PB1176_DMAC, NO_IRQ }
-#define DMAC_DMA { 0, 0 }
#define SCTL_IRQ { NO_IRQ, NO_IRQ }
#define SCTL_DMA { 0, 0 }
#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ }
@@ -166,6 +164,8 @@ static struct pl061_platform_data gpio2_plat_data = {
#define PB1176_UART2_DMA { 11, 10 }
#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ }
#define PB1176_UART3_DMA { 0x86, 0x87 }
+#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ }
+#define PB1176_UART4_DMA { 0, 0 }
#define PB1176_SSP_IRQ { IRQ_PB1176_SSP, NO_IRQ }
#define PB1176_SSP_DMA { 9, 8 }
@@ -174,7 +174,7 @@ AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", PB1176_UART3, NULL);
+AMBA_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL);
/* DevChip Primecells */
AMBA_DEVICE(smc, "dev:smc", PB1176_SMC, NULL);
@@ -188,18 +188,16 @@ AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
AMBA_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL);
AMBA_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL);
AMBA_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL);
+AMBA_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL);
AMBA_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, NULL);
-
-/* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd, "issp:clcd", PB1176_CLCD, &clcd_plat_data);
-//AMBA_DEVICE(dmac, "issp:dmac", PB1176_DMAC, NULL);
+AMBA_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data);
static struct amba_device *amba_devs[] __initdata = {
-// &dmac_device,
&uart0_device,
&uart1_device,
&uart2_device,
&uart3_device,
+ &uart4_device,
&smc_device,
&clcd_device,
&sctl_device,
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 779b45b3f80f..9feb8c35d942 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/lmb.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/sysdev.h>
@@ -304,6 +305,13 @@ static void __init h1940_map_io(void)
s3c_pm_init();
}
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init h1940_reserve(void)
+{
+ lmb_reserve(0x30003000, 0x1000);
+ lmb_reserve(0x30081000, 0x1000);
+}
+
static void __init h1940_init_irq(void)
{
s3c24xx_init_irq();
@@ -346,6 +354,7 @@ MACHINE_START(H1940, "IPAQ-H1940")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = h1940_map_io,
+ .reserve = h1940_reserve,
.init_irq = h1940_init_irq,
.init_machine = h1940_init,
.timer = &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2412/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index ba93a356a839..054c9f92232a 100644
--- a/arch/arm/mach-s3c2412/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -119,7 +119,6 @@ static void __init smdk2413_fixup(struct machine_desc *desc,
mi->nr_banks=1;
mi->bank[0].start = 0x30000000;
mi->bank[0].size = SZ_64M;
- mi->bank[0].node = 0;
}
}
diff --git a/arch/arm/mach-s3c2412/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index 3ca9265b6997..f291ac25d312 100644
--- a/arch/arm/mach-s3c2412/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -137,7 +137,6 @@ static void __init vstms_fixup(struct machine_desc *desc,
mi->nr_banks=1;
mi->bank[0].start = 0x30000000;
mi->bank[0].size = SZ_64M;
- mi->bank[0].node = 0;
}
}
diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c
index 8603b577a24b..5ea4f39c526b 100644
--- a/arch/arm/mach-s3c2440/mach-rx1950.c
+++ b/arch/arm/mach-s3c2440/mach-rx1950.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/lmb.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/init.h>
@@ -570,12 +571,20 @@ static void __init rx1950_init_machine(void)
platform_add_devices(rx1950_devices, ARRAY_SIZE(rx1950_devices));
}
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx1950_reserve(void)
+{
+ lmb_reserve(0x30003000, 0x1000);
+ lmb_reserve(0x30081000, 0x1000);
+}
+
MACHINE_START(RX1950, "HP iPAQ RX1950")
/* Maintainers: Vasily Khoruzhick */
.phys_io = S3C2410_PA_UART,
.io_pg_offst = (((u32) S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = rx1950_map_io,
+ .reserve = rx1950_reserve,
.init_irq = s3c24xx_init_irq,
.init_machine = rx1950_init_machine,
.timer = &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index d2946de3f365..b8e34e630443 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/list.h>
+#include <linux/lmb.h>
#include <linux/timer.h>
#include <linux/init.h>
#include <linux/tty.h>
@@ -191,6 +192,13 @@ static void __init rx3715_map_io(void)
s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
}
+/* H1940 and RX3715 need to reserve this for suspend */
+static void __init rx3715_reserve(void)
+{
+ lmb_reserve(0x30003000, 0x1000);
+ lmb_reserve(0x30081000, 0x1000);
+}
+
static void __init rx3715_init_irq(void)
{
s3c24xx_init_irq();
@@ -214,6 +222,7 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
.io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
.boot_params = S3C2410_SDRAM_PA + 0x100,
.map_io = rx3715_map_io,
+ .reserve = rx3715_reserve,
.init_irq = rx3715_init_irq,
.init_machine = rx3715_init_machine,
.timer = &s3c24xx_timer,
diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig
index f5a59727949f..12f063b12569 100644
--- a/arch/arm/mach-s3c64xx/Kconfig
+++ b/arch/arm/mach-s3c64xx/Kconfig
@@ -57,6 +57,11 @@ config S3C64XX_SETUP_I2C1
help
Common setup code for i2c bus 1.
+config S3C64XX_SETUP_IDE
+ bool
+ help
+ Common setup code for S3C64XX IDE.
+
config S3C64XX_SETUP_FB_24BPP
bool
help
@@ -95,6 +100,7 @@ config MACH_SMDK6410
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_I2C1
+ select SAMSUNG_DEV_IDE
select S3C_DEV_FB
select SAMSUNG_DEV_TS
select S3C_DEV_USB_HOST
@@ -103,6 +109,7 @@ config MACH_SMDK6410
select HAVE_S3C2410_WATCHDOG
select S3C64XX_SETUP_SDHCI
select S3C64XX_SETUP_I2C1
+ select S3C64XX_SETUP_IDE
select S3C64XX_SETUP_FB_24BPP
help
Machine support for the Samsung SMDK6410
diff --git a/arch/arm/mach-s3c64xx/Makefile b/arch/arm/mach-s3c64xx/Makefile
index 9d1006938f5c..aa5c36772b1a 100644
--- a/arch/arm/mach-s3c64xx/Makefile
+++ b/arch/arm/mach-s3c64xx/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_S3C64XX_DMA) += dma.o
obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0.o
obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S3C64XX_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c
index fbd85a9b7bbf..7772f92d2905 100644
--- a/arch/arm/mach-s3c64xx/clock.c
+++ b/arch/arm/mach-s3c64xx/clock.c
@@ -310,6 +310,12 @@ static struct clk init_clocks[] = {
.id = -1,
.parent = &clk_p,
.ctrlbit = S3C_CLKCON_PCLK_AC97,
+ }, {
+ .name = "cfcon",
+ .id = -1,
+ .parent = &clk_h,
+ .enable = s3c64xx_hclk_ctrl,
+ .ctrlbit = S3C_CLKCON_HCLK_IHOST,
}
};
diff --git a/arch/arm/mach-s3c64xx/include/mach/map.h b/arch/arm/mach-s3c64xx/include/mach/map.h
index e1eab3c94aea..1caaa5f25f8d 100644
--- a/arch/arm/mach-s3c64xx/include/mach/map.h
+++ b/arch/arm/mach-s3c64xx/include/mach/map.h
@@ -86,6 +86,9 @@
#define S3C64XX_SZ_GPIO SZ_4K
#define S3C64XX_PA_SDRAM (0x50000000)
+
+#define S3C64XX_PA_CFCON (0x70300000)
+
#define S3C64XX_PA_VIC0 (0x71200000)
#define S3C64XX_PA_VIC1 (0x71300000)
@@ -120,5 +123,6 @@
#define S3C_PA_WDT S3C64XX_PA_WATCHDOG
#define SAMSUNG_PA_ADC S3C64XX_PA_ADC
+#define SAMSUNG_PA_CFCON S3C64XX_PA_CFCON
#endif /* __ASM_ARCH_6400_MAP_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
index 0114eb0c1fe7..05332b998ec0 100644
--- a/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c64xx/include/mach/regs-clock.h
@@ -34,6 +34,7 @@
#define S3C_SCLK_GATE S3C_CLKREG(0x38)
#define S3C_MEM0_GATE S3C_CLKREG(0x3C)
#define S3C6410_CLK_SRC2 S3C_CLKREG(0x10C)
+#define S3C_MEM_SYS_CFG S3C_CLKREG(0x120)
/* CLKDIV0 */
#define S3C6400_CLKDIV0_PCLK_MASK (0xf << 12)
@@ -154,4 +155,8 @@
#define S3C6400_CLKSRC_EPLL_MOUT_SHIFT (2)
#define S3C6400_CLKSRC_MFC (1 << 4)
+/* MEM_SYS_CFG */
+#define MEM_SYS_CFG_INDEP_CF 0x4000
+#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
+
#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c
index d9a03555f88b..0d7d93fbc43b 100644
--- a/arch/arm/mach-s3c64xx/mach-smdk6410.c
+++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c
@@ -56,6 +56,7 @@
#include <mach/regs-gpio.h>
#include <mach/regs-sys.h>
#include <mach/regs-srom.h>
+#include <plat/ata.h>
#include <plat/iic.h>
#include <plat/fb.h>
#include <plat/gpio-cfg.h>
@@ -242,6 +243,10 @@ static struct platform_device smdk6410_b_pwr_5v = {
};
#endif
+static struct s3c_ide_platdata smdk6410_ide_pdata __initdata = {
+ .setup_gpio = s3c64xx_ide_setup_gpio,
+};
+
static struct map_desc smdk6410_iodesc[] = {};
static struct platform_device *smdk6410_devices[] __initdata = {
@@ -265,6 +270,7 @@ static struct platform_device *smdk6410_devices[] __initdata = {
&smdk6410_smsc911x,
&s3c_device_adc,
+ &s3c_device_cfcon,
&s3c_device_ts,
&s3c_device_wdt,
};
@@ -665,6 +671,8 @@ static void __init smdk6410_machine_init(void)
i2c_register_board_info(0, i2c_devs0, ARRAY_SIZE(i2c_devs0));
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
+ s3c_ide_set_platdata(&smdk6410_ide_pdata);
+
platform_add_devices(smdk6410_devices, ARRAY_SIZE(smdk6410_devices));
}
diff --git a/arch/arm/mach-s3c64xx/s3c6410.c b/arch/arm/mach-s3c64xx/s3c6410.c
index 014401c39f36..312aa6b115e8 100644
--- a/arch/arm/mach-s3c64xx/s3c6410.c
+++ b/arch/arm/mach-s3c64xx/s3c6410.c
@@ -37,8 +37,9 @@
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/sdhci.h>
+#include <plat/ata-core.h>
+#include <plat/adc-core.h>
#include <plat/iic-core.h>
-#include <plat/adc.h>
#include <plat/onenand-core.h>
#include <mach/s3c6400.h>
#include <mach/s3c6410.h>
@@ -54,10 +55,11 @@ void __init s3c6410_map_io(void)
s3c_i2c0_setname("s3c2440-i2c");
s3c_i2c1_setname("s3c2440-i2c");
- s3c_device_adc.name = "s3c64xx-adc";
+ s3c_adc_setname("s3c64xx-adc");
s3c_device_nand.name = "s3c6400-nand";
s3c_onenand_setname("s3c6410-onenand");
s3c64xx_onenand1_setname("s3c6410-onenand");
+ s3c_cfcon_setname("s3c64xx-pata");
}
void __init s3c6410_init_clocks(int xtal)
diff --git a/arch/arm/mach-s3c64xx/setup-ide.c b/arch/arm/mach-s3c64xx/setup-ide.c
new file mode 100644
index 000000000000..c12c315f33bc
--- /dev/null
+++ b/arch/arm/mach-s3c64xx/setup-ide.c
@@ -0,0 +1,46 @@
+/* linux/arch/arm/mach-s3c64xx/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * S3C64XX setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+
+void s3c64xx_ide_setup_gpio(void)
+{
+ u32 reg;
+ u32 gpio = 0;
+
+ reg = readl(S3C_MEM_SYS_CFG) & (~0x3f);
+
+ /* Independent CF interface, CF chip select configuration */
+ writel(reg | MEM_SYS_CFG_INDEP_CF |
+ MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S3C_MEM_SYS_CFG);
+
+ s3c_gpio_cfgpin(S3C64XX_GPB(4), S3C_GPIO_SFN(4));
+
+ /* Set XhiDATA[15:0] pins as CF Data[15:0] */
+ for (gpio = S3C64XX_GPK(0); gpio <= S3C64XX_GPK(15); gpio++)
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(5));
+
+ /* Set XhiADDR[2:0] pins as CF ADDR[2:0] */
+ for (gpio = S3C64XX_GPL(0); gpio <= S3C64XX_GPL(2); gpio++)
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+
+ /* Set Xhi ctrl pins as CF ctrl pins(IORDY, IOWR, IORD, CE[0:1]) */
+ s3c_gpio_cfgpin(S3C64XX_GPM(5), S3C_GPIO_SFN(1));
+ for (gpio = S3C64XX_GPM(0); gpio <= S3C64XX_GPM(4); gpio++)
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(6));
+}
diff --git a/arch/arm/mach-s5p6440/cpu.c b/arch/arm/mach-s5p6440/cpu.c
index b2fe6a58155a..526f33adb31d 100644
--- a/arch/arm/mach-s5p6440/cpu.c
+++ b/arch/arm/mach-s5p6440/cpu.c
@@ -37,6 +37,7 @@
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/s5p6440.h>
+#include <plat/adc-core.h>
static void s5p6440_idle(void)
{
@@ -61,7 +62,7 @@ static void s5p6440_idle(void)
void __init s5p6440_map_io(void)
{
/* initialize any device information early */
- s3c_device_adc.name = "s3c64xx-adc";
+ s3c_adc_setname("s3c64xx-adc");
}
void __init s5p6440_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index b2a11dfa3399..a7ba205f3c1c 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -25,6 +25,11 @@ config S5PC100_SETUP_I2C1
help
Common setup code for i2c bus 1.
+config S5PC100_SETUP_IDE
+ bool
+ help
+ Common setup code for S5PC100 IDE GPIO configurations
+
config S5PC100_SETUP_SDHCI
bool
select S5PC100_SETUP_SDHCI_GPIO
@@ -39,13 +44,19 @@ config S5PC100_SETUP_SDHCI_GPIO
config MACH_SMDKC100
bool "SMDKC100"
select CPU_S5PC100
+ select SAMSUNG_DEV_ADC
select S3C_DEV_FB
select S3C_DEV_I2C1
+ select SAMSUNG_DEV_IDE
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC1
select S3C_DEV_HSMMC2
+ select SAMSUNG_DEV_TS
+ select S3C_DEV_WDT
+ select HAVE_S3C2410_WATCHDOG
select S5PC100_SETUP_FB_24BPP
select S5PC100_SETUP_I2C1
+ select S5PC100_SETUP_IDE
select S5PC100_SETUP_SDHCI
help
Machine support for the Samsung SMDKC100
diff --git a/arch/arm/mach-s5pc100/Makefile b/arch/arm/mach-s5pc100/Makefile
index 543f3de5131e..ab3ebe2f5d2a 100644
--- a/arch/arm/mach-s5pc100/Makefile
+++ b/arch/arm/mach-s5pc100/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_CPU_S5PC100) += dma.o
obj-$(CONFIG_S5PC100_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
+obj-$(CONFIG_S5PC100_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S5PC100_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PC100_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5pc100/cpu.c b/arch/arm/mach-s5pc100/cpu.c
index 7b5bdbc9a5df..799d22f41fcd 100644
--- a/arch/arm/mach-s5pc100/cpu.c
+++ b/arch/arm/mach-s5pc100/cpu.c
@@ -38,8 +38,10 @@
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/clock.h>
+#include <plat/ata-core.h>
#include <plat/iic-core.h>
#include <plat/sdhci.h>
+#include <plat/adc-core.h>
#include <plat/onenand-core.h>
#include <plat/s5pc100.h>
@@ -87,11 +89,14 @@ void __init s5pc100_map_io(void)
s5pc100_default_sdhci1();
s5pc100_default_sdhci2();
+ s3c_adc_setname("s3c64xx-adc");
+
/* the i2c devices are directly compatible with s3c2440 */
s3c_i2c0_setname("s3c2440-i2c");
s3c_i2c1_setname("s3c2440-i2c");
s3c_onenand_setname("s5pc100-onenand");
+ s3c_cfcon_setname("s5pc100-pata");
}
void __init s5pc100_init_clocks(int xtal)
diff --git a/arch/arm/mach-s5pc100/include/mach/irqs.h b/arch/arm/mach-s5pc100/include/mach/irqs.h
index 28aa551dc3a8..bfcc0b9d7ad7 100644
--- a/arch/arm/mach-s5pc100/include/mach/irqs.h
+++ b/arch/arm/mach-s5pc100/include/mach/irqs.h
@@ -38,7 +38,7 @@
#define IRQ_IEMIEC S5P_IRQ_VIC1(6)
#define IRQ_ONENAND S5P_IRQ_VIC1(7)
#define IRQ_NFC S5P_IRQ_VIC1(8)
-#define IRQ_CFC S5P_IRQ_VIC1(9)
+#define IRQ_CFCON S5P_IRQ_VIC1(9)
#define IRQ_UART0 S5P_IRQ_VIC1(10)
#define IRQ_UART1 S5P_IRQ_VIC1(11)
#define IRQ_UART2 S5P_IRQ_VIC1(12)
diff --git a/arch/arm/mach-s5pc100/include/mach/map.h b/arch/arm/mach-s5pc100/include/mach/map.h
index cadae4305688..66b626081430 100644
--- a/arch/arm/mach-s5pc100/include/mach/map.h
+++ b/arch/arm/mach-s5pc100/include/mach/map.h
@@ -61,6 +61,8 @@
#define S5PC100_PA_ONENAND (0xE7100000)
+#define S5PC100_PA_CFCON (0xE7800000)
+
/* DMA */
#define S5PC100_PA_MDMA (0xE8100000)
#define S5PC100_PA_PDMA0 (0xE9000000)
@@ -72,6 +74,8 @@
#define S5PC100_PA_SYSTIMER (0xEA100000)
+#define S5PC100_PA_WATCHDOG (0xEA200000)
+
#define S5PC100_PA_UART (0xEC000000)
#define S5P_PA_UART0 (S5PC100_PA_UART + 0x0)
@@ -104,6 +108,8 @@
#define S5PC100_PA_PCM0 0xF2400000
#define S5PC100_PA_PCM1 0xF2500000
+#define S5PC100_PA_TSADC (0xF3000000)
+
/* KEYPAD */
#define S5PC100_PA_KEYPAD (0xF3100000)
@@ -130,9 +136,12 @@
#define S3C_PA_HSMMC1 S5PC100_PA_HSMMC(1)
#define S3C_PA_HSMMC2 S5PC100_PA_HSMMC(2)
#define S3C_PA_KEYPAD S5PC100_PA_KEYPAD
-#define S3C_PA_TSADC S5PC100_PA_TSADC
+#define S3C_PA_WDT S5PC100_PA_WATCHDOG
#define S3C_PA_ONENAND S5PC100_PA_ONENAND
#define S3C_PA_ONENAND_BUF S5PC100_PA_ONENAND_BUF
#define S3C_SZ_ONENAND_BUF S5PC100_SZ_ONENAND_BUF
+#define SAMSUNG_PA_ADC S5PC100_PA_TSADC
+#define SAMSUNG_PA_CFCON S5PC100_PA_CFCON
+
#endif /* __ASM_ARCH_C100_MAP_H */
diff --git a/arch/arm/mach-s5pc100/include/mach/regs-clock.h b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
index 5d27d286d504..bc92da2e0ba2 100644
--- a/arch/arm/mach-s5pc100/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pc100/include/mach/regs-clock.h
@@ -71,7 +71,10 @@
#define S5P_CLKDIV1_PCLKD1_SHIFT (16)
#define S5PC100_SWRESET S5PC100_REG_OTHERS(0x000)
+#define S5PC100_MEM_SYS_CFG S5PC100_REG_OTHERS(0x200)
#define S5PC100_SWRESET_RESETVAL 0xc100
+#define MEM_SYS_CFG_EBI_FIX_PRI_CFCON 0x30
+
#endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c
index af22f8202a07..bf1b9271f34f 100644
--- a/arch/arm/mach-s5pc100/mach-smdkc100.c
+++ b/arch/arm/mach-s5pc100/mach-smdkc100.c
@@ -42,6 +42,9 @@
#include <plat/s5pc100.h>
#include <plat/fb.h>
#include <plat/iic.h>
+#include <plat/ata.h>
+#include <plat/adc.h>
+#include <plat/ts.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define S5PC100_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -149,18 +152,32 @@ static struct s3c_fb_platdata smdkc100_lcd_pdata __initdata = {
.setup_gpio = s5pc100_fb_gpio_setup_24bpp,
};
+static struct s3c_ide_platdata smdkc100_ide_pdata __initdata = {
+ .setup_gpio = s5pc100_ide_setup_gpio,
+};
+
static struct platform_device *smdkc100_devices[] __initdata = {
+ &s3c_device_adc,
+ &s3c_device_cfcon,
&s3c_device_i2c0,
&s3c_device_i2c1,
&s3c_device_fb,
&s3c_device_hsmmc0,
&s3c_device_hsmmc1,
&s3c_device_hsmmc2,
+ &s3c_device_ts,
+ &s3c_device_wdt,
&smdkc100_lcd_powerdev,
&s5pc100_device_iis0,
&s5pc100_device_ac97,
};
+static struct s3c2410_ts_mach_info s3c_ts_platform __initdata = {
+ .delay = 10000,
+ .presc = 49,
+ .oversampling_shift = 2,
+};
+
static void __init smdkc100_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
@@ -170,6 +187,8 @@ static void __init smdkc100_map_io(void)
static void __init smdkc100_machine_init(void)
{
+ s3c24xx_ts_set_platdata(&s3c_ts_platform);
+
/* I2C */
s3c_i2c0_set_platdata(NULL);
s3c_i2c1_set_platdata(NULL);
@@ -177,6 +196,7 @@ static void __init smdkc100_machine_init(void)
i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1));
s3c_fb_set_platdata(&smdkc100_lcd_pdata);
+ s3c_ide_set_platdata(&smdkc100_ide_pdata);
/* LCD init */
gpio_request(S5PC100_GPD(0), "GPD");
diff --git a/arch/arm/mach-s5pc100/setup-ide.c b/arch/arm/mach-s5pc100/setup-ide.c
new file mode 100644
index 000000000000..83575671fb59
--- /dev/null
+++ b/arch/arm/mach-s5pc100/setup-ide.c
@@ -0,0 +1,70 @@
+/* linux/arch/arm/mach-s5pc100/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PC100 setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/gpio-cfg.h>
+
+void s5pc100_ide_setup_gpio(void)
+{
+ u32 reg;
+ u32 gpio = 0;
+
+ /* Independent CF interface, CF chip select configuration */
+ reg = readl(S5PC100_MEM_SYS_CFG) & (~0x3f);
+ writel(reg | MEM_SYS_CFG_EBI_FIX_PRI_CFCON, S5PC100_MEM_SYS_CFG);
+
+ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST, CF_DMACK */
+ for (gpio = S5PC100_GPJ0(0); gpio <= S5PC100_GPJ0(7); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ /*CF_Data[0 - 7] */
+ for (gpio = S5PC100_GPJ2(0); gpio <= S5PC100_GPJ2(7); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ /* CF_Data[8 - 15] */
+ for (gpio = S5PC100_GPJ3(0); gpio <= S5PC100_GPJ3(7); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+ for (gpio = S5PC100_GPJ4(0); gpio <= S5PC100_GPJ4(3); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ /* EBI_OE, EBI_WE */
+ for (gpio = S5PC100_GPK0(6); gpio <= S5PC100_GPK0(7); gpio++)
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
+
+ /* CF_OE, CF_WE */
+ for (gpio = S5PC100_GPK1(6); gpio <= S5PC100_GPK1(7); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ /* CF_CD */
+ s3c_gpio_cfgpin(S5PC100_GPK3(5), S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(S5PC100_GPK3(5), S3C_GPIO_PULL_NONE);
+}
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 0761eac9aaea..e65825f47f0f 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -27,6 +27,11 @@ config S5PV210_SETUP_I2C2
help
Common setup code for i2c bus 2.
+config S5PV210_SETUP_IDE
+ bool
+ help
+ Common setup code for S5PV210 IDE GPIO configurations
+
config S5PV210_SETUP_FB_24BPP
bool
help
@@ -43,14 +48,15 @@ config S5PV210_SETUP_SDHCI_GPIO
help
Common setup code for SDHCI gpio.
-# machine support
+menu "S5PC110 Machines"
config MACH_AQUILA
- bool "Samsung Aquila"
+ bool "Aquila"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select S5PV210_SETUP_FB_24BPP
select S3C_DEV_FB
+ select S5PC110_DEV_ONENAND
help
Machine support for the Samsung Aquila target based on S5PC110 SoC
@@ -58,34 +64,47 @@ config MACH_GONI
bool "GONI"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
+ select S5PV210_SETUP_FB_24BPP
+ select S3C_DEV_FB
+ select S5PC110_DEV_ONENAND
help
Machine support for Samsung GONI board
S5PC110(MCP) is one of package option of S5PV210
+config MACH_SMDKC110
+ bool "SMDKC110"
+ select CPU_S5PV210
+ select ARCH_SPARSEMEM_ENABLE
+ select SAMSUNG_DEV_IDE
+ select S3C_DEV_WDT
+ select HAVE_S3C2410_WATCHDOG
+ select S5PV210_SETUP_IDE
+ help
+ Machine support for Samsung SMDKC110
+ S5PC110(MCP) is one of package option of S5PV210
+
+endmenu
+
config S5PC110_DEV_ONENAND
bool
help
Compile in platform device definition for OneNAND1 controller
+menu "S5PV210 Machines"
+
config MACH_SMDKV210
bool "SMDKV210"
select CPU_S5PV210
select ARCH_SPARSEMEM_ENABLE
select SAMSUNG_DEV_ADC
+ select SAMSUNG_DEV_IDE
select SAMSUNG_DEV_TS
select S3C_DEV_WDT
select HAVE_S3C2410_WATCHDOG
+ select S5PV210_SETUP_IDE
help
Machine support for Samsung SMDKV210
-config MACH_SMDKC110
- bool "SMDKC110"
- select CPU_S5PV210
- select ARCH_SPARSEMEM_ENABLE
- select S3C_DEV_WDT
- select HAVE_S3C2410_WATCHDOG
- help
- Machine support for Samsung SMDKC110
- S5PC110(MCP) is one of package option of S5PV210
+endmenu
endif
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index 30be9a6a4620..af557856b12e 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -31,5 +31,6 @@ obj-$(CONFIG_S5PC110_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S5PV210_SETUP_FB_24BPP) += setup-fb-24bpp.o
obj-$(CONFIG_S5PV210_SETUP_I2C1) += setup-i2c1.o
obj-$(CONFIG_S5PV210_SETUP_I2C2) += setup-i2c2.o
+obj-$(CONFIG_S5PV210_SETUP_IDE) += setup-ide.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI) += setup-sdhci.o
obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO) += setup-sdhci-gpio.o
diff --git a/arch/arm/mach-s5pv210/cpu.c b/arch/arm/mach-s5pv210/cpu.c
index 411a4a9cbfc7..0556cfe19dce 100644
--- a/arch/arm/mach-s5pv210/cpu.c
+++ b/arch/arm/mach-s5pv210/cpu.c
@@ -32,6 +32,8 @@
#include <plat/devs.h>
#include <plat/clock.h>
#include <plat/s5pv210.h>
+#include <plat/ata-core.h>
+#include <plat/adc-core.h>
#include <plat/iic-core.h>
#include <plat/sdhci.h>
@@ -76,10 +78,6 @@ static void s5pv210_idle(void)
void __init s5pv210_map_io(void)
{
-#ifdef CONFIG_S3C_DEV_ADC
- s3c_device_adc.name = "s3c64xx-adc";
-#endif
-
iotable_init(s5pv210_iodesc, ARRAY_SIZE(s5pv210_iodesc));
/* initialise device information early */
@@ -87,6 +85,9 @@ void __init s5pv210_map_io(void)
s5pv210_default_sdhci1();
s5pv210_default_sdhci2();
+ s3c_adc_setname("s3c64xx-adc");
+ s3c_cfcon_setname("s5pv210-pata");
+
/* the i2c devices are directly compatible with s3c2440 */
s3c_i2c0_setname("s3c2440-i2c");
s3c_i2c1_setname("s3c2440-i2c");
diff --git a/arch/arm/mach-s5pv210/gpiolib.c b/arch/arm/mach-s5pv210/gpiolib.c
index 9ea8972e023d..0d459112d039 100644
--- a/arch/arm/mach-s5pv210/gpiolib.c
+++ b/arch/arm/mach-s5pv210/gpiolib.c
@@ -207,6 +207,20 @@ static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
.label = "MP03",
},
}, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP04(0),
+ .ngpio = S5PV210_GPIO_MP04_NR,
+ .label = "MP04",
+ },
+ }, {
+ .config = &gpio_cfg_noint,
+ .chip = {
+ .base = S5PV210_MP05(0),
+ .ngpio = S5PV210_GPIO_MP05_NR,
+ .label = "MP05",
+ },
+ }, {
.base = (S5P_VA_GPIO + 0xC00),
.config = &gpio_cfg_noint,
.chip = {
diff --git a/arch/arm/mach-s5pv210/include/mach/gpio.h b/arch/arm/mach-s5pv210/include/mach/gpio.h
index d6461ba2b71d..1f4b595534c2 100644
--- a/arch/arm/mach-s5pv210/include/mach/gpio.h
+++ b/arch/arm/mach-s5pv210/include/mach/gpio.h
@@ -52,6 +52,8 @@
#define S5PV210_GPIO_MP01_NR (8)
#define S5PV210_GPIO_MP02_NR (4)
#define S5PV210_GPIO_MP03_NR (8)
+#define S5PV210_GPIO_MP04_NR (8)
+#define S5PV210_GPIO_MP05_NR (8)
/* GPIO bank numbers */
@@ -94,6 +96,8 @@ enum s5p_gpio_number {
S5PV210_GPIO_MP01_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_J4),
S5PV210_GPIO_MP02_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP01),
S5PV210_GPIO_MP03_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP02),
+ S5PV210_GPIO_MP04_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP03),
+ S5PV210_GPIO_MP05_START = S5PV210_GPIO_NEXT(S5PV210_GPIO_MP04),
};
/* S5PV210 GPIO number definitions */
@@ -127,13 +131,15 @@ enum s5p_gpio_number {
#define S5PV210_MP01(_nr) (S5PV210_GPIO_MP01_START + (_nr))
#define S5PV210_MP02(_nr) (S5PV210_GPIO_MP02_START + (_nr))
#define S5PV210_MP03(_nr) (S5PV210_GPIO_MP03_START + (_nr))
+#define S5PV210_MP04(_nr) (S5PV210_GPIO_MP04_START + (_nr))
+#define S5PV210_MP05(_nr) (S5PV210_GPIO_MP05_START + (_nr))
/* the end of the S5PV210 specific gpios */
-#define S5PV210_GPIO_END (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + 1)
+#define S5PV210_GPIO_END (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + 1)
#define S3C_GPIO_END S5PV210_GPIO_END
-/* define the number of gpios we need to the one after the MP03() range */
-#define ARCH_NR_GPIOS (S5PV210_MP03(S5PV210_GPIO_MP03_NR) + \
+/* define the number of gpios we need to the one after the MP05() range */
+#define ARCH_NR_GPIOS (S5PV210_MP05(S5PV210_GPIO_MP05_NR) + \
CONFIG_SAMSUNG_GPIO_EXTRA + 1)
#include <asm-generic/gpio.h>
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 96895378ea27..e1d3c453db81 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -45,7 +45,7 @@
#define IRQ_IEMIEC S5P_IRQ_VIC1(6)
#define IRQ_ONENAND S5P_IRQ_VIC1(7)
#define IRQ_NFC S5P_IRQ_VIC1(8)
-#define IRQ_CFC S5P_IRQ_VIC1(9)
+#define IRQ_CFCON S5P_IRQ_VIC1(9)
#define IRQ_UART0 S5P_IRQ_VIC1(10)
#define IRQ_UART1 S5P_IRQ_VIC1(11)
#define IRQ_UART2 S5P_IRQ_VIC1(12)
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 34eb168ec950..3846a0be2fa6 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -54,6 +54,8 @@
#define S5PV210_PA_SROMC (0xE8000000)
+#define S5PV210_PA_CFCON (0xE8200000)
+
#define S5PV210_PA_MDMA 0xFA200000
#define S5PV210_PA_PDMA0 0xE0900000
#define S5PV210_PA_PDMA1 0xE0A00000
@@ -104,5 +106,6 @@
#define S3C_PA_WDT S5PV210_PA_WATCHDOG
#define SAMSUNG_PA_ADC S5PV210_PA_ADC
+#define SAMSUNG_PA_CFCON S5PV210_PA_CFCON
#endif /* __ASM_ARCH_MAP_H */
diff --git a/arch/arm/mach-s5pv210/include/mach/memory.h b/arch/arm/mach-s5pv210/include/mach/memory.h
index 379117e27600..d503e0c4ce4f 100644
--- a/arch/arm/mach-s5pv210/include/mach/memory.h
+++ b/arch/arm/mach-s5pv210/include/mach/memory.h
@@ -16,8 +16,13 @@
#define PHYS_OFFSET UL(0x20000000)
#define CONSISTENT_DMA_SIZE (SZ_8M + SZ_4M + SZ_2M)
-/* Maximum of 256MiB in one bank */
-#define MAX_PHYSMEM_BITS 32
+/*
+ * Sparsemem support
+ * Physical memory can be located from 0x20000000 to 0x7fffffff,
+ * so MAX_PHYSMEM_BITS is 31.
+ */
+
+#define MAX_PHYSMEM_BITS 31
#define SECTION_SIZE_BITS 28
#endif /* __ASM_ARCH_MEMORY_H */
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c
index 10bc76ec4025..099261867e73 100644
--- a/arch/arm/mach-s5pv210/mach-aquila.c
+++ b/arch/arm/mach-s5pv210/mach-aquila.c
@@ -13,6 +13,12 @@
#include <linux/init.h>
#include <linux/serial_core.h>
#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/mfd/max8998.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -23,6 +29,7 @@
#include <mach/regs-clock.h>
#include <mach/regs-fb.h>
+#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
@@ -39,38 +46,44 @@
#define S5PV210_ULCON_DEFAULT S3C2410_LCON_CS8
-#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
- S5PV210_UFCON_TXTRIG4 | \
- S5PV210_UFCON_RXTRIG4)
+#define S5PV210_UFCON_DEFAULT S3C2410_UFCON_FIFOMODE
-static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
+static struct s3c2410_uartcfg aquila_uartcfgs[] __initdata = {
[0] = {
.hwport = 0,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ /*
+ * Actually UART0 can support 256 bytes fifo, but aquila board
+ * supports 128 bytes fifo because of initial chip bug
+ */
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG128 | S5PV210_UFCON_RXTRIG128,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG64 | S5PV210_UFCON_RXTRIG64,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
},
};
@@ -116,19 +129,338 @@ static struct s3c_fb_platdata aquila_lcd_pdata __initdata = {
.setup_gpio = s5pv210_fb_gpio_setup_24bpp,
};
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_init_data aquila_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data aquila_ldo3_data = {
+ .constraints = {
+ .name = "VUSB/MIPI_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo4_data = {
+ .constraints = {
+ .name = "VDAC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo5_data = {
+ .constraints = {
+ .name = "VTF_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo6_data = {
+ .constraints = {
+ .name = "VCC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo7_data = {
+ .constraints = {
+ .name = "VCC_3.0V",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo8_data = {
+ .constraints = {
+ .name = "VUSB/VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo9_data = {
+ .constraints = {
+ .name = "VCC/VCAM_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo10_data = {
+ .constraints = {
+ .name = "VPLL_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo11_data = {
+ .constraints = {
+ .name = "CAM_IO_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo12_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo13_data = {
+ .constraints = {
+ .name = "CAM_A_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo14_data = {
+ .constraints = {
+ .name = "CAM_CIF_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo15_data = {
+ .constraints = {
+ .name = "CAM_AF_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo16_data = {
+ .constraints = {
+ .name = "VMIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data aquila_ldo17_data = {
+ .constraints = {
+ .name = "CAM_8M_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer[] = {
+ { .supply = "vddarm", },
+};
+
+static struct regulator_consumer_supply buck2_consumer[] = {
+ { .supply = "vddint", },
+};
+
+static struct regulator_init_data aquila_buck1_data = {
+ .constraints = {
+ .name = "VARM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck1_consumer),
+ .consumer_supplies = buck1_consumer,
+};
+
+static struct regulator_init_data aquila_buck2_data = {
+ .constraints = {
+ .name = "VINT_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_consumer),
+ .consumer_supplies = buck2_consumer,
+};
+
+static struct regulator_init_data aquila_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data aquila_buck4_data = {
+ .constraints = {
+ .name = "CAM_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct max8998_regulator_data aquila_regulators[] = {
+ { MAX8998_LDO2, &aquila_ldo2_data },
+ { MAX8998_LDO3, &aquila_ldo3_data },
+ { MAX8998_LDO4, &aquila_ldo4_data },
+ { MAX8998_LDO5, &aquila_ldo5_data },
+ { MAX8998_LDO6, &aquila_ldo6_data },
+ { MAX8998_LDO7, &aquila_ldo7_data },
+ { MAX8998_LDO8, &aquila_ldo8_data },
+ { MAX8998_LDO9, &aquila_ldo9_data },
+ { MAX8998_LDO10, &aquila_ldo10_data },
+ { MAX8998_LDO11, &aquila_ldo11_data },
+ { MAX8998_LDO12, &aquila_ldo12_data },
+ { MAX8998_LDO13, &aquila_ldo13_data },
+ { MAX8998_LDO14, &aquila_ldo14_data },
+ { MAX8998_LDO15, &aquila_ldo15_data },
+ { MAX8998_LDO16, &aquila_ldo16_data },
+ { MAX8998_LDO17, &aquila_ldo17_data },
+ { MAX8998_BUCK1, &aquila_buck1_data },
+ { MAX8998_BUCK2, &aquila_buck2_data },
+ { MAX8998_BUCK3, &aquila_buck3_data },
+ { MAX8998_BUCK4, &aquila_buck4_data },
+};
+
+static struct max8998_platform_data aquila_max8998_pdata = {
+ .num_regulators = ARRAY_SIZE(aquila_regulators),
+ .regulators = aquila_regulators,
+};
+#endif
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4 4
+static struct i2c_gpio_platform_data aquila_i2c_gpio_pmic_data = {
+ .sda_pin = S5PV210_GPJ4(0), /* XMSMCSN */
+ .scl_pin = S5PV210_GPJ4(3), /* XMSMIRQN */
+};
+
+static struct platform_device aquila_i2c_gpio_pmic = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_PMIC_BUS_4,
+ .dev = {
+ .platform_data = &aquila_i2c_gpio_pmic_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+ {
+ /* 0xCC when SRAD = 0 */
+ I2C_BOARD_INFO("max8998", 0xCC >> 1),
+ .platform_data = &aquila_max8998_pdata,
+ },
+#endif
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button aquila_gpio_keys_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = S5PV210_GPH2(6),
+ .desc = "gpio-keys: KEY_POWER",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data aquila_gpio_keys_data = {
+ .buttons = aquila_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(aquila_gpio_keys_table),
+};
+
+static struct platform_device aquila_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &aquila_gpio_keys_data,
+ },
+};
+
+static void __init aquila_pmic_init(void)
+{
+ /* AP_PMIC_IRQ: EINT7 */
+ s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+ /* nPower: EINT22 */
+ s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
static struct platform_device *aquila_devices[] __initdata = {
+ &aquila_i2c_gpio_pmic,
+ &aquila_device_gpiokeys,
&s3c_device_fb,
+ &s5pc110_device_onenand,
};
static void __init aquila_map_io(void)
{
s5p_init_io(NULL, 0, S5P_VA_CHIPID);
s3c24xx_init_clocks(24000000);
- s3c24xx_init_uarts(smdkv210_uartcfgs, ARRAY_SIZE(smdkv210_uartcfgs));
+ s3c24xx_init_uarts(aquila_uartcfgs, ARRAY_SIZE(aquila_uartcfgs));
}
static void __init aquila_machine_init(void)
{
+ /* PMIC */
+ aquila_pmic_init();
+ i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+ ARRAY_SIZE(i2c_gpio_pmic_devs));
+
/* FB */
s3c_fb_set_platdata(&aquila_lcd_pdata);
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index 4863b13824e4..7b18505e5171 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -12,6 +12,13 @@
#include <linux/types.h>
#include <linux/init.h>
#include <linux/serial_core.h>
+#include <linux/fb.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/mfd/max8998.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -20,11 +27,14 @@
#include <mach/map.h>
#include <mach/regs-clock.h>
+#include <mach/regs-fb.h>
+#include <plat/gpio-cfg.h>
#include <plat/regs-serial.h>
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/fb.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -36,9 +46,7 @@
#define S5PV210_ULCON_DEFAULT S3C2410_LCON_CS8
-#define S5PV210_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | \
- S5PV210_UFCON_TXTRIG4 | \
- S5PV210_UFCON_RXTRIG4)
+#define S5PV210_UFCON_DEFAULT S3C2410_UFCON_FIFOMODE
static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
[0] = {
@@ -46,32 +54,378 @@ static struct s3c2410_uartcfg goni_uartcfgs[] __initdata = {
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG256 | S5PV210_UFCON_RXTRIG256,
},
[1] = {
.hwport = 1,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG64 | S5PV210_UFCON_RXTRIG64,
},
[2] = {
.hwport = 2,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
},
[3] = {
.hwport = 3,
.flags = 0,
.ucon = S5PV210_UCON_DEFAULT,
.ulcon = S5PV210_ULCON_DEFAULT,
- .ufcon = S5PV210_UFCON_DEFAULT,
+ .ufcon = S5PV210_UFCON_DEFAULT |
+ S5PV210_UFCON_TXTRIG16 | S5PV210_UFCON_RXTRIG16,
},
};
+/* Frame Buffer */
+static struct s3c_fb_pd_win goni_fb_win0 = {
+ .win_mode = {
+ .pixclock = 1000000000000ULL / ((16+16+2+480)*(28+3+2+800)*55),
+ .left_margin = 16,
+ .right_margin = 16,
+ .upper_margin = 3,
+ .lower_margin = 28,
+ .hsync_len = 2,
+ .vsync_len = 2,
+ .xres = 480,
+ .yres = 800,
+ .refresh = 55,
+ },
+ .max_bpp = 32,
+ .default_bpp = 16,
+};
+
+static struct s3c_fb_platdata goni_lcd_pdata __initdata = {
+ .win[0] = &goni_fb_win0,
+ .vidcon0 = VIDCON0_VIDOUT_RGB | VIDCON0_PNRMODE_RGB |
+ VIDCON0_CLKSEL_LCD,
+ .vidcon1 = VIDCON1_INV_VCLK | VIDCON1_INV_VDEN
+ | VIDCON1_INV_HSYNC | VIDCON1_INV_VSYNC,
+ .setup_gpio = s5pv210_fb_gpio_setup_24bpp,
+};
+
+/* MAX8998 regulators */
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+
+static struct regulator_init_data goni_ldo2_data = {
+ .constraints = {
+ .name = "VALIVE_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data goni_ldo3_data = {
+ .constraints = {
+ .name = "VUSB/MIPI_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo4_data = {
+ .constraints = {
+ .name = "VDAC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo5_data = {
+ .constraints = {
+ .name = "VTF_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo6_data = {
+ .constraints = {
+ .name = "VCC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo7_data = {
+ .constraints = {
+ .name = "VLCD_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo8_data = {
+ .constraints = {
+ .name = "VUSB/VADC_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo9_data = {
+ .constraints = {
+ .name = "VCC/VCAM_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo10_data = {
+ .constraints = {
+ .name = "VPLL_1.1V",
+ .min_uV = 1100000,
+ .max_uV = 1100000,
+ .apply_uV = 1,
+ .boot_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo11_data = {
+ .constraints = {
+ .name = "CAM_IO_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo12_data = {
+ .constraints = {
+ .name = "CAM_ISP_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo13_data = {
+ .constraints = {
+ .name = "CAM_A_2.8V",
+ .min_uV = 2800000,
+ .max_uV = 2800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo14_data = {
+ .constraints = {
+ .name = "CAM_CIF_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo15_data = {
+ .constraints = {
+ .name = "CAM_AF_3.3V",
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo16_data = {
+ .constraints = {
+ .name = "VMIPI_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct regulator_init_data goni_ldo17_data = {
+ .constraints = {
+ .name = "VCC_3.0V_LCD",
+ .min_uV = 3000000,
+ .max_uV = 3000000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+/* BUCK */
+static struct regulator_consumer_supply buck1_consumer[] = {
+ { .supply = "vddarm", },
+};
+
+static struct regulator_consumer_supply buck2_consumer[] = {
+ { .supply = "vddint", },
+};
+
+static struct regulator_init_data goni_buck1_data = {
+ .constraints = {
+ .name = "VARM_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck1_consumer),
+ .consumer_supplies = buck1_consumer,
+};
+
+static struct regulator_init_data goni_buck2_data = {
+ .constraints = {
+ .name = "VINT_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_consumer),
+ .consumer_supplies = buck2_consumer,
+};
+
+static struct regulator_init_data goni_buck3_data = {
+ .constraints = {
+ .name = "VCC_1.8V",
+ .min_uV = 1800000,
+ .max_uV = 1800000,
+ .apply_uV = 1,
+ .state_mem = {
+ .enabled = 1,
+ },
+ },
+};
+
+static struct regulator_init_data goni_buck4_data = {
+ .constraints = {
+ .name = "CAM_CORE_1.2V",
+ .min_uV = 1200000,
+ .max_uV = 1200000,
+ .apply_uV = 1,
+ .always_on = 1,
+ },
+};
+
+static struct max8998_regulator_data goni_regulators[] = {
+ { MAX8998_LDO2, &goni_ldo2_data },
+ { MAX8998_LDO3, &goni_ldo3_data },
+ { MAX8998_LDO4, &goni_ldo4_data },
+ { MAX8998_LDO5, &goni_ldo5_data },
+ { MAX8998_LDO6, &goni_ldo6_data },
+ { MAX8998_LDO7, &goni_ldo7_data },
+ { MAX8998_LDO8, &goni_ldo8_data },
+ { MAX8998_LDO9, &goni_ldo9_data },
+ { MAX8998_LDO10, &goni_ldo10_data },
+ { MAX8998_LDO11, &goni_ldo11_data },
+ { MAX8998_LDO12, &goni_ldo12_data },
+ { MAX8998_LDO13, &goni_ldo13_data },
+ { MAX8998_LDO14, &goni_ldo14_data },
+ { MAX8998_LDO15, &goni_ldo15_data },
+ { MAX8998_LDO16, &goni_ldo16_data },
+ { MAX8998_LDO17, &goni_ldo17_data },
+ { MAX8998_BUCK1, &goni_buck1_data },
+ { MAX8998_BUCK2, &goni_buck2_data },
+ { MAX8998_BUCK3, &goni_buck3_data },
+ { MAX8998_BUCK4, &goni_buck4_data },
+};
+
+static struct max8998_platform_data goni_max8998_pdata = {
+ .num_regulators = ARRAY_SIZE(goni_regulators),
+ .regulators = goni_regulators,
+};
+#endif
+
+/* GPIO I2C PMIC */
+#define AP_I2C_GPIO_PMIC_BUS_4 4
+static struct i2c_gpio_platform_data goni_i2c_gpio_pmic_data = {
+ .sda_pin = S5PV210_GPJ4(0), /* XMSMCSN */
+ .scl_pin = S5PV210_GPJ4(3), /* XMSMIRQN */
+};
+
+static struct platform_device goni_i2c_gpio_pmic = {
+ .name = "i2c-gpio",
+ .id = AP_I2C_GPIO_PMIC_BUS_4,
+ .dev = {
+ .platform_data = &goni_i2c_gpio_pmic_data,
+ },
+};
+
+static struct i2c_board_info i2c_gpio_pmic_devs[] __initdata = {
+#if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
+ {
+ /* 0xCC when SRAD = 0 */
+ I2C_BOARD_INFO("max8998", 0xCC >> 1),
+ .platform_data = &goni_max8998_pdata,
+ },
+#endif
+};
+
+/* PMIC Power button */
+static struct gpio_keys_button goni_gpio_keys_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = S5PV210_GPH2(6),
+ .desc = "gpio-keys: KEY_POWER",
+ .type = EV_KEY,
+ .active_low = 1,
+ .wakeup = 1,
+ .debounce_interval = 1,
+ },
+};
+
+static struct gpio_keys_platform_data goni_gpio_keys_data = {
+ .buttons = goni_gpio_keys_table,
+ .nbuttons = ARRAY_SIZE(goni_gpio_keys_table),
+};
+
+static struct platform_device goni_device_gpiokeys = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &goni_gpio_keys_data,
+ },
+};
+
+static void __init goni_pmic_init(void)
+{
+ /* AP_PMIC_IRQ: EINT7 */
+ s3c_gpio_cfgpin(S5PV210_GPH0(7), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH0(7), S3C_GPIO_PULL_UP);
+
+ /* nPower: EINT22 */
+ s3c_gpio_cfgpin(S5PV210_GPH2(6), S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(S5PV210_GPH2(6), S3C_GPIO_PULL_UP);
+}
+
+
static struct platform_device *goni_devices[] __initdata = {
+ &s3c_device_fb,
+ &s5pc110_device_onenand,
+ &goni_i2c_gpio_pmic,
+ &goni_device_gpiokeys,
};
static void __init goni_map_io(void)
@@ -83,6 +437,13 @@ static void __init goni_map_io(void)
static void __init goni_machine_init(void)
{
+ /* PMIC */
+ goni_pmic_init();
+ i2c_register_board_info(AP_I2C_GPIO_PMIC_BUS_4, i2c_gpio_pmic_devs,
+ ARRAY_SIZE(i2c_gpio_pmic_devs));
+ /* FB */
+ s3c_fb_set_platdata(&goni_lcd_pdata);
+
platform_add_devices(goni_devices, ARRAY_SIZE(goni_devices));
}
diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c
index 4c8903c6d104..723e6078b97a 100644
--- a/arch/arm/mach-s5pv210/mach-smdkc110.c
+++ b/arch/arm/mach-s5pv210/mach-smdkc110.c
@@ -25,6 +25,7 @@
#include <plat/s5pv210.h>
#include <plat/devs.h>
#include <plat/cpu.h>
+#include <plat/ata.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -71,9 +72,14 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+static struct s3c_ide_platdata smdkv210_ide_pdata __initdata = {
+ .setup_gpio = s5pv210_ide_setup_gpio,
+};
+
static struct platform_device *smdkc110_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
+ &s3c_device_cfcon,
&s3c_device_wdt,
};
@@ -86,6 +92,8 @@ static void __init smdkc110_map_io(void)
static void __init smdkc110_machine_init(void)
{
+ s3c_ide_set_platdata(&smdkv210_ide_pdata);
+
platform_add_devices(smdkc110_devices, ARRAY_SIZE(smdkc110_devices));
}
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index 0d4627948040..cc902c1e8f98 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -27,6 +27,7 @@
#include <plat/cpu.h>
#include <plat/adc.h>
#include <plat/ts.h>
+#include <plat/ata.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
#define S5PV210_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
@@ -73,10 +74,15 @@ static struct s3c2410_uartcfg smdkv210_uartcfgs[] __initdata = {
},
};
+static struct s3c_ide_platdata smdkv210_ide_pdata __initdata = {
+ .setup_gpio = s5pv210_ide_setup_gpio,
+};
+
static struct platform_device *smdkv210_devices[] __initdata = {
&s5pv210_device_iis0,
&s5pv210_device_ac97,
&s3c_device_adc,
+ &s3c_device_cfcon,
&s3c_device_ts,
&s3c_device_wdt,
};
@@ -97,6 +103,8 @@ static void __init smdkv210_map_io(void)
static void __init smdkv210_machine_init(void)
{
s3c24xx_ts_set_platdata(&s3c_ts_platform);
+ s3c_ide_set_platdata(&smdkv210_ide_pdata);
+
platform_add_devices(smdkv210_devices, ARRAY_SIZE(smdkv210_devices));
}
diff --git a/arch/arm/mach-s5pv210/setup-ide.c b/arch/arm/mach-s5pv210/setup-ide.c
new file mode 100644
index 000000000000..b558b1cc8d60
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-ide.c
@@ -0,0 +1,50 @@
+/* linux/arch/arm/mach-s5pv210/setup-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * S5PV210 setup information for IDE
+ *
+ * This program is free software; you can 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/gpio.h>
+
+#include <plat/gpio-cfg.h>
+
+void s5pv210_ide_setup_gpio(void)
+{
+ unsigned int gpio = 0;
+
+ for (gpio = S5PV210_GPJ0(0); gpio <= S5PV210_GPJ0(7); gpio++) {
+ /* CF_Add[0 - 2], CF_IORDY, CF_INTRQ, CF_DMARQ, CF_DMARST,
+ CF_DMACK */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = S5PV210_GPJ2(0); gpio <= S5PV210_GPJ2(7); gpio++) {
+ /*CF_Data[0 - 7] */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = S5PV210_GPJ3(0); gpio <= S5PV210_GPJ3(7); gpio++) {
+ /* CF_Data[8 - 15] */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+
+ for (gpio = S5PV210_GPJ4(0); gpio <= S5PV210_GPJ4(3); gpio++) {
+ /* CF_CS0, CF_CS1, CF_IORD, CF_IOWR */
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(4));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ s5p_gpio_set_drvstr(gpio, S5P_GPIO_DRVSTR_LV4);
+ }
+}
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
index ec03f187c52b..b7a9a601c2d1 100644
--- a/arch/arm/mach-sa1100/generic.h
+++ b/arch/arm/mach-sa1100/generic.h
@@ -13,8 +13,7 @@ extern void __init sa1100_init_gpio(void);
#define SET_BANK(__nr,__start,__size) \
mi->bank[__nr].start = (__start), \
- mi->bank[__nr].size = (__size), \
- mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+ mi->bank[__nr].size = (__size)
extern void (*sa1100fb_backlight_power)(int on);
extern void (*sa1100fb_lcd_power)(int on);
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
index d5277f9bee77..128a1dfa96b9 100644
--- a/arch/arm/mach-sa1100/include/mach/memory.h
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -17,10 +17,10 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_SA1111
-void sa1111_adjust_zones(int node, unsigned long *size, unsigned long *holes);
+void sa1111_adjust_zones(unsigned long *size, unsigned long *holes);
-#define arch_adjust_zones(node, size, holes) \
- sa1111_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+ sa1111_adjust_zones(size, holes)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_1M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_1M)
diff --git a/arch/arm/mach-shark/include/mach/memory.h b/arch/arm/mach-shark/include/mach/memory.h
index 3053e5b7f168..d9c4812f1c31 100644
--- a/arch/arm/mach-shark/include/mach/memory.h
+++ b/arch/arm/mach-shark/include/mach/memory.h
@@ -19,9 +19,8 @@
#ifndef __ASSEMBLY__
-static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsigned long *zhole_size)
+static inline void __arch_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size)
{
- if (node != 0) return;
/* Only the first 4 MB (=1024 Pages) are usable for DMA */
/* See dev / -> .properties in OpenFirmware. */
zone_size[1] = zone_size[0] - 1024;
@@ -30,8 +29,8 @@ static inline void __arch_adjust_zones(int node, unsigned long *zone_size, unsig
zhole_size[0] = 0;
}
-#define arch_adjust_zones(node, size, holes) \
- __arch_adjust_zones(node, size, holes)
+#define arch_adjust_zones(size, holes) \
+ __arch_adjust_zones(size, holes)
#define ISA_DMA_THRESHOLD (PHYS_OFFSET + SZ_4M - 1)
#define MAX_DMA_ADDRESS (PAGE_OFFSET + SZ_4M)
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index f2b88c5fe142..1de8d171c6e9 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -7,6 +7,7 @@ config ARCH_SH7367
select CPU_V6
select HAVE_CLK
select COMMON_CLKDEV
+ select SH_CLK_CPG
select GENERIC_CLOCKEVENTS
config ARCH_SH7377
@@ -14,6 +15,7 @@ config ARCH_SH7377
select CPU_V7
select HAVE_CLK
select COMMON_CLKDEV
+ select SH_CLK_CPG
select GENERIC_CLOCKEVENTS
config ARCH_SH7372
@@ -21,6 +23,7 @@ config ARCH_SH7372
select CPU_V7
select HAVE_CLK
select COMMON_CLKDEV
+ select SH_CLK_CPG
select GENERIC_CLOCKEVENTS
comment "SH-Mobile Board Type"
@@ -39,6 +42,7 @@ config MACH_AP4EVB
bool "AP4EVB board"
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
+ select SH_LCD_MIPI_DSI
comment "SH-Mobile System Configuration"
@@ -76,6 +80,15 @@ config SH_TIMER_CMT
help
This enables build of the CMT timer driver.
+config SH_TIMER_TMU
+ bool "TMU timer driver"
+ default y
+ help
+ This enables build of the TMU timer driver.
+
endmenu
+config SH_CLK_CPG
+ bool
+
endif
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 6d385d371c33..5e16b4c69222 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -3,12 +3,12 @@
#
# Common objects
-obj-y := timer.o console.o
+obj-y := timer.o console.o clock.o
# CPU objects
obj-$(CONFIG_ARCH_SH7367) += setup-sh7367.o clock-sh7367.o intc-sh7367.o
-obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7367.o intc-sh7377.o
-obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7367.o intc-sh7372.o
+obj-$(CONFIG_ARCH_SH7377) += setup-sh7377.o clock-sh7377.o intc-sh7377.o
+obj-$(CONFIG_ARCH_SH7372) += setup-sh7372.o clock-sh7372.o intc-sh7372.o
# Pinmux setup
pfc-$(CONFIG_ARCH_SH7367) := pfc-sh7367.o
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index 1c2ec96ce261..5d24d4ec93a7 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -17,25 +17,44 @@
* 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/clk.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
+#include <linux/mmc/host.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mmcif.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
#include <linux/io.h>
#include <linux/smsc911x.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_clk.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
+#include <linux/usb/r8a66597.h>
+
+#include <sound/sh_fsi.h>
+
+#include <video/sh_mobile_lcdc.h>
+#include <video/sh_mipi_dsi.h>
+
#include <mach/common.h>
+#include <mach/irqs.h>
#include <mach/sh7372.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/time.h>
/*
* Address Interface BusWidth note
@@ -80,12 +99,50 @@
*/
/*
- * KEYSC
+ * LCD / IRQ / KEYSC / IrDA
+ *
+ * IRQ = IRQ26 (TS), IRQ27 (VIO), IRQ28 (TouchScreen)
+ * LCD = 2nd LCDC
+ *
+ * | SW43 |
+ * SW3 | ON | OFF |
+ * -------------+-----------------------+---------------+
+ * ON | KEY / IrDA | LCD |
+ * OFF | KEY / IrDA / IRQ | IRQ |
+ */
+
+/*
+ * USB
+ *
+ * J7 : 1-2 MAX3355E VBUS
+ * 2-3 DC 5.0V
+ *
+ * S39: bit2: off
+ */
+
+/*
+ * FSI/FSMI
*
- * SW43 KEYSC
- * -------------------------
- * ON enable
- * OFF disable
+ * SW41 : ON : SH-Mobile AP4 Audio Mode
+ * : OFF : Bluetooth Audio Mode
+ */
+
+/*
+ * MMC0/SDHI1 (CN7)
+ *
+ * J22 : select card voltage
+ * 1-2 pin : 1.8v
+ * 2-3 pin : 3.3v
+ *
+ * SW1 | SW33
+ * | bit1 | bit2 | bit3 | bit4
+ * ------------+------+------+------+-------
+ * MMC0 OFF | OFF | ON | ON | X
+ * SDHI1 OFF | ON | X | OFF | ON
+ *
+ * voltage lebel
+ * CN7 : 1.8v
+ * CN12: 3.3v
*/
/* MTD */
@@ -148,7 +205,7 @@ static struct resource smc911x_resources[] = {
.end = 0x16000000 - 1,
.flags = IORESOURCE_MEM,
}, {
- .start = 6,
+ .start = evt2irq(0x02c0) /* IRQ6A */,
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
},
};
@@ -191,7 +248,7 @@ static struct resource keysc_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 79,
+ .start = evt2irq(0x0be0), /* KEYSC_KEY */
.flags = IORESOURCE_IRQ,
},
};
@@ -206,7 +263,52 @@ static struct platform_device keysc_device = {
},
};
+/* SH_MMCIF */
+static struct resource sh_mmcif_resources[] = {
+ [0] = {
+ .name = "SH_MMCIF",
+ .start = 0xE6BD0000,
+ .end = 0xE6BD00FF,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ /* MMC ERR */
+ .start = evt2irq(0x1ac0),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* MMC NOR */
+ .start = evt2irq(0x1ae0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_mmcif_plat_data sh_mmcif_plat = {
+ .sup_pclk = 0,
+ .ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
+ .caps = MMC_CAP_4_BIT_DATA |
+ MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NEEDS_POLL,
+};
+
+static struct platform_device sh_mmcif_device = {
+ .name = "sh_mmcif",
+ .id = 0,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sh_mmcif_plat,
+ },
+ .num_resources = ARRAY_SIZE(sh_mmcif_resources),
+ .resource = sh_mmcif_resources,
+};
+
/* SDHI0 */
+static struct sh_mobile_sdhi_info sdhi0_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
+};
+
static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
@@ -215,7 +317,7 @@ static struct resource sdhi0_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 96,
+ .start = evt2irq(0x0e00) /* SDHI0 */,
.flags = IORESOURCE_IRQ,
},
};
@@ -225,6 +327,206 @@ static struct platform_device sdhi0_device = {
.num_resources = ARRAY_SIZE(sdhi0_resources),
.resource = sdhi0_resources,
.id = 0,
+ .dev = {
+ .platform_data = &sdhi0_info,
+ },
+};
+
+/* SDHI1 */
+static struct sh_mobile_sdhi_info sdhi1_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
+ .tmio_ocr_mask = MMC_VDD_165_195,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6860000,
+ .end = 0xe68601ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e80),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &sdhi1_info,
+ },
+};
+
+/* USB1 */
+static void usb1_host_port_power(int port, int power)
+{
+ if (!power) /* only power-on supported for now */
+ return;
+
+ /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
+ __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
+}
+
+static struct r8a66597_platdata usb1_host_data = {
+ .on_chip = 1,
+ .port_power = usb1_host_port_power,
+};
+
+static struct resource usb1_host_resources[] = {
+ [0] = {
+ .name = "USBHS",
+ .start = 0xE68B0000,
+ .end = 0xE68B00E6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb1_host_device = {
+ .name = "r8a66597_hcd",
+ .id = 1,
+ .dev = {
+ .dma_mask = NULL, /* not use dma */
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usb1_host_data,
+ },
+ .num_resources = ARRAY_SIZE(usb1_host_resources),
+ .resource = usb1_host_resources,
+};
+
+static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
+ .clock_source = LCDC_CLK_PERIPHERAL, /* One of interface clocks */
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .bpp = 16,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .lcd_cfg = {
+ .name = "R63302(QHD)",
+ .xres = 544,
+ .yres = 961,
+ .left_margin = 72,
+ .right_margin = 600,
+ .hsync_len = 16,
+ .upper_margin = 8,
+ .lower_margin = 8,
+ .vsync_len = 2,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+ },
+ .lcd_size_cfg = {
+ .width = 44,
+ .height = 79,
+ },
+ }
+};
+
+static struct resource lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC",
+ .start = 0xfe940000, /* P4-only space */
+ .end = 0xfe943fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x580),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(lcdc_resources),
+ .resource = lcdc_resources,
+ .dev = {
+ .platform_data = &sh_mobile_lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static struct resource mipidsi0_resources[] = {
+ [0] = {
+ .start = 0xffc60000,
+ .end = 0xffc68fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct sh_mipi_dsi_info mipidsi0_info = {
+ .data_format = MIPI_RGB888,
+ .lcd_chan = &sh_mobile_lcdc_info.ch[0],
+};
+
+static struct platform_device mipidsi0_device = {
+ .name = "sh-mipi-dsi",
+ .num_resources = ARRAY_SIZE(mipidsi0_resources),
+ .resource = mipidsi0_resources,
+ .id = 0,
+ .dev = {
+ .platform_data = &mipidsi0_info,
+ },
+};
+
+/* FSI */
+#define IRQ_FSI evt2irq(0x1840)
+#define FSIACKCR 0xE6150018
+static void fsiackcr_init(struct clk *clk)
+{
+ u32 status = __raw_readl(clk->enable_reg);
+
+ /* use external clock */
+ status &= ~0x000000ff;
+ status |= 0x00000080;
+ __raw_writel(status, clk->enable_reg);
+}
+
+static struct clk_ops fsiackcr_clk_ops = {
+ .init = fsiackcr_init,
+};
+
+static struct clk fsiackcr_clk = {
+ .ops = &fsiackcr_clk_ops,
+ .enable_reg = (void __iomem *)FSIACKCR,
+ .rate = 0, /* unknown */
+};
+
+static struct sh_fsi_platform_info fsi_info = {
+ .porta_flags = SH_FSI_BRS_INV |
+ SH_FSI_OUT_SLAVE_MODE |
+ SH_FSI_IN_SLAVE_MODE |
+ SH_FSI_OFMT(PCM) |
+ SH_FSI_IFMT(PCM),
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xFE3C0000,
+ .end = 0xFE3C0400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_FSI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
};
static struct platform_device *ap4evb_devices[] __initdata = {
@@ -232,6 +534,38 @@ static struct platform_device *ap4evb_devices[] __initdata = {
&smc911x_device,
&keysc_device,
&sdhi0_device,
+ &sdhi1_device,
+ &usb1_host_device,
+ &lcdc_device,
+ &mipidsi0_device,
+ &fsi_device,
+ &sh_mmcif_device
+};
+
+/* TouchScreen (Needs SW3 set to OFF) */
+#define IRQ28 evt2irq(0x3380) /* IRQ28A */
+static struct tsc2007_platform_data tsc2007_info = {
+ .model = 2007,
+ .x_plate_ohms = 180,
+};
+
+/* I2C */
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4643", 0x13),
+ },
+};
+
+static struct i2c_board_info i2c1_devices[] = {
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ },
+ {
+ I2C_BOARD_INFO("tsc2007", 0x48),
+ .type = "tsc2007",
+ .platform_data = &tsc2007_info,
+ .irq = IRQ28,
+ },
};
static struct map_desc ap4evb_io_desc[] __initdata = {
@@ -250,14 +584,71 @@ static void __init ap4evb_map_io(void)
{
iotable_init(ap4evb_io_desc, ARRAY_SIZE(ap4evb_io_desc));
- /* setup early devices, clocks and console here as well */
+ /* setup early devices and console here as well */
sh7372_add_early_devices();
- sh7367_clock_init(); /* use g3 clocks for now */
shmobile_setup_console();
}
+/* This function will disappear when we switch to (runtime) PM */
+static int __init ap4evb_init_display_clk(void)
+{
+ struct clk *lcdc_clk;
+ struct clk *dsitx_clk;
+ int ret;
+
+ lcdc_clk = clk_get(&lcdc_device.dev, "sh_mobile_lcdc_fb.0");
+ if (IS_ERR(lcdc_clk))
+ return PTR_ERR(lcdc_clk);
+
+ dsitx_clk = clk_get(&mipidsi0_device.dev, "sh-mipi-dsi.0");
+ if (IS_ERR(dsitx_clk)) {
+ ret = PTR_ERR(dsitx_clk);
+ goto eclkdsitxget;
+ }
+
+ ret = clk_enable(lcdc_clk);
+ if (ret < 0)
+ goto eclklcdcon;
+
+ ret = clk_enable(dsitx_clk);
+ if (ret < 0)
+ goto eclkdsitxon;
+
+ return 0;
+
+eclkdsitxon:
+ clk_disable(lcdc_clk);
+eclklcdcon:
+ clk_put(dsitx_clk);
+eclkdsitxget:
+ clk_put(lcdc_clk);
+
+ return ret;
+}
+
+device_initcall(ap4evb_init_display_clk);
+
+/*
+ * FIXME !!
+ *
+ * gpio_no_direction is quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_no_direction(u32 addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+#define GPIO_PORT9CR 0xE6051009
+#define GPIO_PORT10CR 0xE605100A
+
static void __init ap4evb_init(void)
{
+ struct clk *clk;
+
sh7372_pinmux_init();
/* enable SCIFA0 */
@@ -318,16 +709,102 @@ static void __init ap4evb_init(void)
gpio_request(GPIO_FN_SDHID0_1, NULL);
gpio_request(GPIO_FN_SDHID0_0, NULL);
+ /* enable TouchScreen */
+ gpio_request(GPIO_FN_IRQ28_123, NULL);
+ set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
+
+ /* MMCIF */
+ gpio_request(GPIO_FN_MMCD0_0, NULL);
+ gpio_request(GPIO_FN_MMCD0_1, NULL);
+ gpio_request(GPIO_FN_MMCD0_2, NULL);
+ gpio_request(GPIO_FN_MMCD0_3, NULL);
+ gpio_request(GPIO_FN_MMCD0_4, NULL);
+ gpio_request(GPIO_FN_MMCD0_5, NULL);
+ gpio_request(GPIO_FN_MMCD0_6, NULL);
+ gpio_request(GPIO_FN_MMCD0_7, NULL);
+ gpio_request(GPIO_FN_MMCCMD0, NULL);
+ gpio_request(GPIO_FN_MMCCLK0, NULL);
+
+ /* USB enable */
+ gpio_request(GPIO_FN_VBUS0_1, NULL);
+ gpio_request(GPIO_FN_IDIN_1_18, NULL);
+ gpio_request(GPIO_FN_PWEN_1_115, NULL);
+ gpio_request(GPIO_FN_OVCN_1_114, NULL);
+ gpio_request(GPIO_FN_EXTLP_1, NULL);
+ gpio_request(GPIO_FN_OVCN2_1, NULL);
+
+ /* setup USB phy */
+ __raw_writew(0x8a0a, 0xE6058130); /* USBCR2 */
+
+ /* enable FSI2 */
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+ gpio_request(GPIO_PORT161, NULL);
+ gpio_direction_output(GPIO_PORT161, 0); /* slave */
+
+ gpio_request(GPIO_PORT9, NULL);
+ gpio_request(GPIO_PORT10, NULL);
+ gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+
+ /* set SPU2 clock to 119.6 MHz */
+ clk = clk_get(NULL, "spu_clk");
+ if (!IS_ERR(clk)) {
+ clk_set_rate(clk, clk_round_rate(clk, 119600000));
+ clk_put(clk);
+ }
+
+ /* change parent of FSI A */
+ clk = clk_get(NULL, "fsia_clk");
+ if (!IS_ERR(clk)) {
+ clk_register(&fsiackcr_clk);
+ clk_set_parent(clk, &fsiackcr_clk);
+ clk_put(clk);
+ }
+
+ /*
+ * set irq priority, to avoid sound chopping
+ * when NFS rootfs is used
+ * FSI(3) > SMSC911X(2)
+ */
+ intc_set_priority(IRQ_FSI, 3);
+
+ i2c_register_board_info(0, i2c0_devices,
+ ARRAY_SIZE(i2c0_devices));
+
+ i2c_register_board_info(1, i2c1_devices,
+ ARRAY_SIZE(i2c1_devices));
+
+ /* SDHI1 */
+ gpio_request(GPIO_FN_SDHICMD1, NULL);
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHID1_3, NULL);
+ gpio_request(GPIO_FN_SDHID1_2, NULL);
+ gpio_request(GPIO_FN_SDHID1_1, NULL);
+ gpio_request(GPIO_FN_SDHID1_0, NULL);
+
sh7372_add_standard_devices();
platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
}
+static void __init ap4evb_timer_init(void)
+{
+ sh7372_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer ap4evb_timer = {
+ .init = ap4evb_timer_init,
+};
+
MACHINE_START(AP4EVB, "ap4evb")
.phys_io = 0xe6000000,
.io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = ap4evb_map_io,
.init_irq = sh7372_init_irq,
.init_machine = ap4evb_init,
- .timer = &shmobile_timer,
+ .timer = &ap4evb_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g3evm.c b/arch/arm/mach-shmobile/board-g3evm.c
index 9247503296c4..95ccb949d5d9 100644
--- a/arch/arm/mach-shmobile/board-g3evm.c
+++ b/arch/arm/mach-shmobile/board-g3evm.c
@@ -37,6 +37,15 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+/*
+ * IrDA
+ *
+ * S67: 5bit : ON power
+ * : 6bit : ON remote control
+ * OFF IrDA
+ */
static struct mtd_partition nor_flash_partitions[] = {
{
@@ -91,7 +100,7 @@ static struct platform_device nor_flash_device = {
};
/* USBHS */
-void usb_host_port_power(int port, int power)
+static void usb_host_port_power(int port, int power)
{
if (!power) /* only power-on supported for now */
return;
@@ -113,7 +122,7 @@ static struct resource usb_host_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 65,
+ .start = evt2irq(0xa20), /* USBHS_USHI0 */
.flags = IORESOURCE_IRQ,
},
};
@@ -153,7 +162,7 @@ static struct resource keysc_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 79,
+ .start = evt2irq(0xbe0), /* KEYSC_KEY */
.flags = IORESOURCE_IRQ,
},
};
@@ -209,11 +218,30 @@ static struct platform_device nand_flash_device = {
},
};
+static struct resource irda_resources[] = {
+ [0] = {
+ .start = 0xE6D00000,
+ .end = 0xE6D01FD4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x480), /* IRDA */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device irda_device = {
+ .name = "sh_irda",
+ .resource = irda_resources,
+ .num_resources = ARRAY_SIZE(irda_resources),
+};
+
static struct platform_device *g3evm_devices[] __initdata = {
&nor_flash_device,
&usb_host_device,
&keysc_device,
&nand_flash_device,
+ &irda_device,
};
static struct map_desc g3evm_io_desc[] __initdata = {
@@ -232,9 +260,8 @@ static void __init g3evm_map_io(void)
{
iotable_init(g3evm_io_desc, ARRAY_SIZE(g3evm_io_desc));
- /* setup early devices, clocks and console here as well */
+ /* setup early devices and console here as well */
sh7367_add_early_devices();
- sh7367_clock_init();
shmobile_setup_console();
}
@@ -271,9 +298,6 @@ static void __init g3evm_init(void)
gpio_request(GPIO_FN_EXTLP, NULL);
gpio_request(GPIO_FN_IDIN, NULL);
- /* enable clock in SYMSTPCR2 */
- __raw_writel(__raw_readl(0xe6158048) & ~(1 << 22), 0xe6158048);
-
/* setup USB phy */
__raw_writew(0x0300, 0xe605810a); /* USBCR1 */
__raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
@@ -318,16 +342,32 @@ static void __init g3evm_init(void)
/* FOE, FCDE, FSC on dedicated pins */
__raw_writel(__raw_readl(0xe6158048) & ~(1 << 15), 0xe6158048);
+ /* IrDA */
+ gpio_request(GPIO_FN_IRDA_OUT, NULL);
+ gpio_request(GPIO_FN_IRDA_IN, NULL);
+ gpio_request(GPIO_FN_IRDA_FIRSEL, NULL);
+ set_irq_type(evt2irq(0x480), IRQ_TYPE_LEVEL_LOW);
+
sh7367_add_standard_devices();
platform_add_devices(g3evm_devices, ARRAY_SIZE(g3evm_devices));
}
+static void __init g3evm_timer_init(void)
+{
+ sh7367_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer g3evm_timer = {
+ .init = g3evm_timer_init,
+};
+
MACHINE_START(G3EVM, "g3evm")
.phys_io = 0xe6000000,
.io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = g3evm_map_io,
.init_irq = sh7367_init_irq,
.init_machine = g3evm_init,
- .timer = &shmobile_timer,
+ .timer = &g3evm_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index 10673a90be52..2c3ff6f7f34c 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -30,12 +30,39 @@
#include <linux/io.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
+#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/gpio.h>
#include <mach/sh7377.h>
#include <mach/common.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+
+/*
+ * SDHI
+ *
+ * SDHI0 : card detection is possible
+ * SDHI1 : card detection is impossible
+ *
+ * [G4-MAIN-BOARD]
+ * JP74 : short # DBG_2V8A for SDHI0
+ * JP75 : NC # DBG_3V3A for SDHI0
+ * JP76 : NC # DBG_3V3A_SD for SDHI0
+ * JP77 : NC # 3V3A_SDIO for SDHI1
+ * JP78 : short # DBG_2V8A for SDHI1
+ * JP79 : NC # DBG_3V3A for SDHI1
+ * JP80 : NC # DBG_3V3A_SD for SDHI1
+ *
+ * [G4-CORE-BOARD]
+ * S32 : all off # to dissever from G3-CORE_DBG board
+ * S33 : all off # to dissever from G3-CORE_DBG board
+ *
+ * [G3-CORE_DBG-BOARD]
+ * S1 : all off # to dissever from G3-CORE_DBG board
+ * S3 : all off # to dissever from G3-CORE_DBG board
+ * S4 : all off # to dissever from G3-CORE_DBG board
+ */
static struct mtd_partition nor_flash_partitions[] = {
{
@@ -90,7 +117,7 @@ static struct platform_device nor_flash_device = {
};
/* USBHS */
-void usb_host_port_power(int port, int power)
+static void usb_host_port_power(int port, int power)
{
if (!power) /* only power-on supported for now */
return;
@@ -112,8 +139,7 @@ static struct resource usb_host_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 65,
- .end = 65,
+ .start = evt2irq(0x0a20), /* USBHS_USHI0 */
.flags = IORESOURCE_IRQ,
},
};
@@ -154,7 +180,7 @@ static struct resource keysc_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 79,
+ .start = evt2irq(0x0be0), /* KEYSC_KEY */
.flags = IORESOURCE_IRQ,
},
};
@@ -169,10 +195,53 @@ static struct platform_device keysc_device = {
},
};
+/* SDHI */
+static struct resource sdhi0_resources[] = {
+ [0] = {
+ .name = "SDHI0",
+ .start = 0xe6d50000,
+ .end = 0xe6d501ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e00), /* SDHI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi0_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi0_resources),
+ .resource = sdhi0_resources,
+ .id = 0,
+};
+
+static struct resource sdhi1_resources[] = {
+ [0] = {
+ .name = "SDHI1",
+ .start = 0xe6d60000,
+ .end = 0xe6d601ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x0e80), /* SDHI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi1_device = {
+ .name = "sh_mobile_sdhi",
+ .num_resources = ARRAY_SIZE(sdhi1_resources),
+ .resource = sdhi1_resources,
+ .id = 1,
+};
+
static struct platform_device *g4evm_devices[] __initdata = {
&nor_flash_device,
&usb_host_device,
&keysc_device,
+ &sdhi0_device,
+ &sdhi1_device,
};
static struct map_desc g4evm_io_desc[] __initdata = {
@@ -191,12 +260,41 @@ static void __init g4evm_map_io(void)
{
iotable_init(g4evm_io_desc, ARRAY_SIZE(g4evm_io_desc));
- /* setup early devices, clocks and console here as well */
+ /* setup early devices and console here as well */
sh7377_add_early_devices();
- sh7367_clock_init(); /* use g3 clocks for now */
shmobile_setup_console();
}
+#define GPIO_SDHID0_D0 0xe60520fc
+#define GPIO_SDHID0_D1 0xe60520fd
+#define GPIO_SDHID0_D2 0xe60520fe
+#define GPIO_SDHID0_D3 0xe60520ff
+#define GPIO_SDHICMD0 0xe6052100
+
+#define GPIO_SDHID1_D0 0xe6052103
+#define GPIO_SDHID1_D1 0xe6052104
+#define GPIO_SDHID1_D2 0xe6052105
+#define GPIO_SDHID1_D3 0xe6052106
+#define GPIO_SDHICMD1 0xe6052107
+
+/*
+ * FIXME !!
+ *
+ * gpio_pull_up is quick_hack.
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static void __init gpio_pull_up(u32 addr)
+{
+ u8 data = __raw_readb(addr);
+
+ data &= 0x0F;
+ data |= 0xC0;
+ __raw_writeb(data, addr);
+}
+
static void __init g4evm_init(void)
{
sh7377_pinmux_init();
@@ -229,9 +327,6 @@ static void __init g4evm_init(void)
gpio_request(GPIO_FN_EXTLP, NULL);
gpio_request(GPIO_FN_IDIN, NULL);
- /* enable clock in SMSTPCR3 */
- __raw_writel(__raw_readl(0xe615013c) & ~(1 << 22), 0xe615013c);
-
/* setup USB phy */
__raw_writew(0x0200, 0xe605810a); /* USBCR1 */
__raw_writew(0x00e0, 0xe60581c0); /* CPFCH */
@@ -253,16 +348,54 @@ static void __init g4evm_init(void)
gpio_request(GPIO_FN_PORT71_KEYIN5_PU, NULL);
gpio_request(GPIO_FN_PORT72_KEYIN6_PU, NULL);
+ /* SDHI0 */
+ gpio_request(GPIO_FN_SDHICLK0, NULL);
+ gpio_request(GPIO_FN_SDHICD0, NULL);
+ gpio_request(GPIO_FN_SDHID0_0, NULL);
+ gpio_request(GPIO_FN_SDHID0_1, NULL);
+ gpio_request(GPIO_FN_SDHID0_2, NULL);
+ gpio_request(GPIO_FN_SDHID0_3, NULL);
+ gpio_request(GPIO_FN_SDHICMD0, NULL);
+ gpio_request(GPIO_FN_SDHIWP0, NULL);
+ gpio_pull_up(GPIO_SDHID0_D0);
+ gpio_pull_up(GPIO_SDHID0_D1);
+ gpio_pull_up(GPIO_SDHID0_D2);
+ gpio_pull_up(GPIO_SDHID0_D3);
+ gpio_pull_up(GPIO_SDHICMD0);
+
+ /* SDHI1 */
+ gpio_request(GPIO_FN_SDHICLK1, NULL);
+ gpio_request(GPIO_FN_SDHID1_0, NULL);
+ gpio_request(GPIO_FN_SDHID1_1, NULL);
+ gpio_request(GPIO_FN_SDHID1_2, NULL);
+ gpio_request(GPIO_FN_SDHID1_3, NULL);
+ gpio_request(GPIO_FN_SDHICMD1, NULL);
+ gpio_pull_up(GPIO_SDHID1_D0);
+ gpio_pull_up(GPIO_SDHID1_D1);
+ gpio_pull_up(GPIO_SDHID1_D2);
+ gpio_pull_up(GPIO_SDHID1_D3);
+ gpio_pull_up(GPIO_SDHICMD1);
+
sh7377_add_standard_devices();
platform_add_devices(g4evm_devices, ARRAY_SIZE(g4evm_devices));
}
+static void __init g4evm_timer_init(void)
+{
+ sh7377_clock_init();
+ shmobile_timer.init();
+}
+
+static struct sys_timer g4evm_timer = {
+ .init = g4evm_timer_init,
+};
+
MACHINE_START(G4EVM, "g4evm")
.phys_io = 0xe6000000,
.io_pg_offst = ((0xe6000000) >> 18) & 0xfffc,
.map_io = g4evm_map_io,
.init_irq = sh7377_init_irq,
.init_machine = g4evm_init,
- .timer = &shmobile_timer,
+ .timer = &g4evm_timer,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index bb940c6e4e6c..b6454c9f2abb 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -1,5 +1,5 @@
/*
- * Preliminary clock framework support for sh7367
+ * SH7367 clock framework support
*
* Copyright (C) 2010 Magnus Damm
*
@@ -17,87 +17,342 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/init.h>
-#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+
+/* SH7367 registers */
+#define RTFRQCR 0xe6150000
+#define SYFRQCR 0xe6150004
+#define CMFRQCR 0xe61500E0
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define SCLKACR 0xe6150010
+#define SCLKBCR 0xe6150014
+#define SUBUSBCKCR 0xe6158080
+#define SPUCKCR 0xe6150084
+#define MSUCKCR 0xe6150088
+#define MVI3CKCR 0xe6150090
+#define VOUCKCR 0xe6150094
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define PLLC1CR 0xe6150028
+#define PLLC2CR 0xe615002C
+#define RTMSTPCR0 0xe6158030
+#define RTMSTPCR2 0xe6158038
+#define SYMSTPCR0 0xe6158040
+#define SYMSTPCR2 0xe6158048
+#define CMMSTPCR0 0xe615804c
-struct clk {
- const char *name;
- unsigned long rate;
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
};
-#include <asm/clkdev.h>
+/*
+ * 26MHz default rate for the EXTALB1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7367_extalb1_clk = {
+ .rate = 26666666,
+};
-int __clk_get(struct clk *clk)
-{
- return 1;
-}
-EXPORT_SYMBOL(__clk_get);
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7367_extal2_clk = {
+ .rate = 48000000,
+};
-void __clk_put(struct clk *clk)
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
{
+ return clk->parent->rate / 2;
}
-EXPORT_SYMBOL(__clk_put);
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extalb1 by two */
+static struct clk extalb1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7367_extalb1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7367_extal2_clk,
+};
-int clk_enable(struct clk *clk)
+/* PLLC1 */
+static unsigned long pllc1_recalc(struct clk *clk)
{
- return 0;
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC1CR) & (1 << 14))
+ mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
}
-EXPORT_SYMBOL(clk_enable);
-void clk_disable(struct clk *clk)
+static struct clk_ops pllc1_clk_ops = {
+ .recalc = pllc1_recalc,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc1_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalb1_div2_clk,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+static unsigned long pllc2_recalc(struct clk *clk)
{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
}
-EXPORT_SYMBOL(clk_disable);
-unsigned long clk_get_rate(struct clk *clk)
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+};
+
+static struct clk pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalb1_div2_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh7367_extalb1_clk,
+ &sh7367_extal2_clk,
+ &extalb1_div2_clk,
+ &extal2_div2_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &pllc2_clk,
+};
+
+static void div4_kick(struct clk *clk)
{
- return clk ? clk->rate : 0;
+ unsigned long value;
+
+ /* set KICK bit in SYFRQCR to update hardware setting */
+ value = __raw_readl(SYFRQCR);
+ value |= (1 << 31);
+ __raw_writel(value, SYFRQCR);
}
-EXPORT_SYMBOL(clk_get_rate);
-/* a static peripheral clock for now - enough to get sh-sci working */
-static struct clk peripheral_clk = {
- .name = "peripheral_clk",
- .rate = 48000000,
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 0, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
};
-/* a static rclk for now - enough to get sh_cmt working */
-static struct clk r_clk = {
- .name = "r_clk",
- .rate = 32768,
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_G, DIV4_S, DIV4_B,
+ DIV4_ZX, DIV4_ZT, DIV4_Z, DIV4_ZD, DIV4_HP,
+ DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_G] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_S] = DIV4(RTFRQCR, 12, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZX] = DIV4(SYFRQCR, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
+ [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZD] = DIV4(SYFRQCR, 8, 0x6fff, 0),
+ [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
+ [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
};
-/* a static usb0 for now - enough to get r8a66597 working */
-static struct clk usb0_clk = {
- .name = "usb0",
+enum { DIV6_SUB, DIV6_SIUA, DIV6_SIUB, DIV6_MSU, DIV6_SPU,
+ DIV6_MVI3, DIV6_MF1, DIV6_MF2,
+ DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_VOU,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7367_extal2_clk, SUBUSBCKCR, 0),
+ [DIV6_SIUA] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKACR, 0),
+ [DIV6_SIUB] = SH_CLK_DIV6(&pllc1_div2_clk, SCLKBCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
+ [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
+ [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
};
-/* a static keysc0 clk for now - enough to get sh_keysc working */
-static struct clk keysc0_clk = {
- .name = "keysc0",
+enum { RTMSTP001,
+ RTMSTP231, RTMSTP230, RTMSTP229, RTMSTP228, RTMSTP226,
+ RTMSTP216, RTMSTP206, RTMSTP205, RTMSTP201,
+ SYMSTP023, SYMSTP007, SYMSTP006, SYMSTP004,
+ SYMSTP003, SYMSTP002, SYMSTP001, SYMSTP000,
+ SYMSTP231, SYMSTP229, SYMSTP225, SYMSTP223, SYMSTP222,
+ SYMSTP215, SYMSTP214, SYMSTP213, SYMSTP211,
+ CMMSTP003,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [RTMSTP001] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR0, 1, 0), /* IIC2 */
+ [RTMSTP231] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 31, 0), /* VEU3 */
+ [RTMSTP230] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 30, 0), /* VEU2 */
+ [RTMSTP229] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 29, 0), /* VEU1 */
+ [RTMSTP228] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 28, 0), /* VEU0 */
+ [RTMSTP226] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 26, 0), /* VEU2H */
+ [RTMSTP216] = MSTP(&div6_clks[DIV6_SUB], RTMSTPCR2, 16, 0), /* IIC0 */
+ [RTMSTP206] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 6, 0), /* JPU */
+ [RTMSTP205] = MSTP(&div6_clks[DIV6_VOU], RTMSTPCR2, 5, 0), /* VOU */
+ [RTMSTP201] = MSTP(&div4_clks[DIV4_B], RTMSTPCR2, 1, 0), /* VPU */
+ [SYMSTP023] = MSTP(&div6_clks[DIV6_SPU], SYMSTPCR0, 23, 0), /* SPU1 */
+ [SYMSTP007] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 7, 0), /* SCIFA5 */
+ [SYMSTP006] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 6, 0), /* SCIFB */
+ [SYMSTP004] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 4, 0), /* SCIFA0 */
+ [SYMSTP003] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 3, 0), /* SCIFA1 */
+ [SYMSTP002] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 2, 0), /* SCIFA2 */
+ [SYMSTP001] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 1, 0), /* SCIFA3 */
+ [SYMSTP000] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR0, 0, 0), /* SCIFA4 */
+ [SYMSTP231] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 31, 0), /* SIU */
+ [SYMSTP229] = MSTP(&r_clk, SYMSTPCR2, 29, 0), /* CMT10 */
+ [SYMSTP225] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 25, 0), /* IRDA */
+ [SYMSTP223] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 23, 0), /* IIC1 */
+ [SYMSTP222] = MSTP(&div6_clks[DIV6_SUB], SYMSTPCR2, 22, 0), /* USBHS */
+ [SYMSTP215] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 15, 0), /* FLCTL */
+ [SYMSTP214] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 14, 0), /* SDHI0 */
+ [SYMSTP213] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 13, 0), /* SDHI1 */
+ [SYMSTP211] = MSTP(&div4_clks[DIV4_HP], SYMSTPCR2, 11, 0), /* SDHI2 */
+ [CMMSTP003] = MSTP(&r_clk, CMMSTPCR0, 3, 0), /* KEYSC */
};
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
static struct clk_lookup lookups[] = {
- {
- .clk = &peripheral_clk,
- }, {
- .clk = &r_clk,
- }, {
- .clk = &usb0_clk,
- }, {
- .clk = &keysc0_clk,
- }
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extalb1", &sh7367_extalb1_clk),
+ CLKDEV_CON_ID("extal2", &sh7367_extal2_clk),
+ CLKDEV_CON_ID("extalb1_div2_clk", &extalb1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("g_clk", &div4_clks[DIV4_G]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
+ CLKDEV_CON_ID("zd_clk", &div4_clks[DIV4_ZD]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("siua_clk", &div6_clks[DIV6_SIUA]),
+ CLKDEV_CON_ID("siub_clk", &div6_clks[DIV6_SIUB]),
+ CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
+ CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
+ CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[RTMSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[RTMSTP231]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[RTMSTP230]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[RTMSTP229]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[RTMSTP228]), /* VEU0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[RTMSTP226]), /* VEU2H */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[RTMSTP216]), /* IIC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[RTMSTP206]), /* JPU */
+ CLKDEV_DEV_ID("sh-vou", &mstp_clks[RTMSTP205]), /* VOU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[RTMSTP201]), /* VPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[SYMSTP023]), /* SPU1 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[SYMSTP007]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[SYMSTP006]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[SYMSTP004]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[SYMSTP003]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[SYMSTP002]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[SYMSTP001]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[SYMSTP000]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh_siu", &mstp_clks[SYMSTP231]), /* SIU */
+ CLKDEV_CON_ID("cmt1", &mstp_clks[SYMSTP229]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_irda", &mstp_clks[SYMSTP225]), /* IRDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[SYMSTP223]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[SYMSTP222]), /* USBHS */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[SYMSTP222]), /* USBHS */
+ CLKDEV_DEV_ID("sh_flctl", &mstp_clks[SYMSTP215]), /* FLCTL */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[SYMSTP214]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[SYMSTP213]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[SYMSTP211]), /* SDHI2 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[CMMSTP003]), /* KEYSC */
};
void __init sh7367_clock_init(void)
{
- int i;
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
- for (i = 0; i < ARRAY_SIZE(lookups); i++) {
- lookups[i].con_id = lookups[i].clk->name;
- clkdev_add(&lookups[i]);
- }
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7367 clocks\n");
}
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
new file mode 100644
index 000000000000..241caea32260
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -0,0 +1,399 @@
+/*
+ * SH7372 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+
+/* SH7372 registers */
+#define FRQCRA 0xe6150000
+#define FRQCRB 0xe6150004
+#define FRQCRC 0xe61500e0
+#define FRQCRD 0xe61500e4
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000c
+#define VCLKCR3 0xe615001c
+#define FMSICKCR 0xe6150010
+#define FMSOCKCR 0xe6150014
+#define FSIACKCR 0xe6150018
+#define FSIBCKCR 0xe6150090
+#define SUBCKCR 0xe6150080
+#define SPUCKCR 0xe6150084
+#define VOUCKCR 0xe6150088
+#define HDMICKCR 0xe6150094
+#define DSITCKCR 0xe6150060
+#define DSI0PCKCR 0xe6150064
+#define DSI1PCKCR 0xe6150098
+#define PLLC01CR 0xe6150028
+#define PLLC2CR 0xe615002c
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013c
+#define SMSTPCR4 0xe6150140
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTAL1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7372_extal1_clk = {
+ .rate = 26666666,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7372_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extal1 by two */
+static struct clk extal1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7372_extal1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7372_extal2_clk,
+};
+
+/* Divide extal2 by four */
+static struct clk extal2_div4_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &extal2_div2_clk,
+};
+
+/* PLLC0 and PLLC1 */
+static unsigned long pllc01_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC01CR) & (1 << 14))
+ mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc01_clk_ops = {
+ .recalc = pllc01_recalc,
+};
+
+static struct clk pllc0_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extal1_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRC,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc01_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extal1_div2_clk,
+ .enable_reg = (void __iomem *)FRQCRA,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+static unsigned long pllc2_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+};
+
+static struct clk pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extal1_div2_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh7372_extal1_clk,
+ &sh7372_extal2_clk,
+ &extal1_div2_clk,
+ &extal2_div2_clk,
+ &extal2_div4_clk,
+ &pllc0_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &pllc2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in FRQCRB to update hardware setting */
+ value = __raw_readl(FRQCRB);
+ value |= (1 << 31);
+ __raw_writel(value, FRQCRB);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
+ DIV4_ZTR, DIV4_ZT, DIV4_ZX, DIV4_HP,
+ DIV4_ISPB, DIV4_S, DIV4_ZB, DIV4_ZB3, DIV4_CP,
+ DIV4_DDRP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(FRQCRA, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(FRQCRA, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(FRQCRA, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_CSIR] = DIV4(FRQCRA, 0, 0x6fff, 0),
+ [DIV4_ZTR] = DIV4(FRQCRB, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(FRQCRB, 16, 0x6fff, 0),
+ [DIV4_ZX] = DIV4(FRQCRB, 12, 0x6fff, 0),
+ [DIV4_HP] = DIV4(FRQCRB, 4, 0x6fff, 0),
+ [DIV4_ISPB] = DIV4(FRQCRC, 20, 0x6fff, 0),
+ [DIV4_S] = DIV4(FRQCRC, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(FRQCRC, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(FRQCRC, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(FRQCRC, 0, 0x6fff, 0),
+ [DIV4_DDRP] = DIV4(FRQCRD, 0, 0x677c, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
+ DIV6_FSIA, DIV6_FSIB, DIV6_SUB, DIV6_SPU,
+ DIV6_VOU, DIV6_HDMI, DIV6_DSIT, DIV6_DSI0P, DIV6_DSI1P,
+ DIV6_NR };
+
+static struct clk div6_clks[DIV6_NR] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
+ [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
+ [DIV6_FSIA] = SH_CLK_DIV6(&pllc1_div2_clk, FSIACKCR, 0),
+ [DIV6_FSIB] = SH_CLK_DIV6(&pllc1_div2_clk, FSIBCKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7372_extal2_clk, SUBCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_VOU] = SH_CLK_DIV6(&pllc1_div2_clk, VOUCKCR, 0),
+ [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSI0P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI0PCKCR, 0),
+ [DIV6_DSI1P] = SH_CLK_DIV6(&pllc1_div2_clk, DSI1PCKCR, 0),
+};
+
+enum { MSTP001,
+ MSTP131, MSTP130,
+ MSTP129, MSTP128,
+ MSTP118, MSTP117, MSTP116,
+ MSTP106, MSTP101, MSTP100,
+ MSTP223,
+ MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
+ MSTP415, MSTP410, MSTP411, MSTP406, MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
+ [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
+ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
+ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
+ [MSTP118] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
+ [MSTP117] = MSTP(&div6_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
+ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
+ [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
+ [MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
+ [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, CLK_ENABLE_ON_INIT), /* FSIA */
+ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
+ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
+ [MSTP415] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
+ [MSTP411] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 11, 0), /* IIC3 */
+ [MSTP410] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 10, 0), /* IIC4 */
+ [MSTP406] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR4, 6, 0), /* USB1 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extal1", &sh7372_extal1_clk),
+ CLKDEV_CON_ID("extal2", &sh7372_extal2_clk),
+ CLKDEV_CON_ID("extal1_div2_clk", &extal1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
+ CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
+ CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
+ CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("zx_clk", &div4_clks[DIV4_ZX]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("ispb_clk", &div4_clks[DIV4_ISPB]),
+ CLKDEV_CON_ID("s_clk", &div4_clks[DIV4_S]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+ CLKDEV_CON_ID("ddrp_clk", &div4_clks[DIV4_DDRP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
+ CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
+ CLKDEV_CON_ID("fsia_clk", &div6_clks[DIV6_FSIA]),
+ CLKDEV_CON_ID("fsib_clk", &div6_clks[DIV6_FSIB]),
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("vou_clk", &div6_clks[DIV6_VOU]),
+ CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
+ CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
+ CLKDEV_CON_ID("dsi0p_clk", &div6_clks[DIV6_DSI0P]),
+ CLKDEV_CON_ID("dsi1p_clk", &div6_clks[DIV6_DSI1P]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
+ CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
+ CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_fsi", &mstp_clks[MSTP328]), /* FSI */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP323]), /* USB0 */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP323]), /* USB0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]), /* SDHI2 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* IIC3 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
+ CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+};
+
+void __init sh7372_clock_init(void)
+{
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7372 clocks\n");
+
+}
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
new file mode 100644
index 000000000000..e007c28cf0a8
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -0,0 +1,369 @@
+/*
+ * SH7377 clock framework support
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * 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
+ *
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <mach/common.h>
+#include <asm/clkdev.h>
+
+/* SH7377 registers */
+#define RTFRQCR 0xe6150000
+#define SYFRQCR 0xe6150004
+#define CMFRQCR 0xe61500E0
+#define VCLKCR1 0xe6150008
+#define VCLKCR2 0xe615000C
+#define VCLKCR3 0xe615001C
+#define FMSICKCR 0xe6150010
+#define FMSOCKCR 0xe6150014
+#define FSICKCR 0xe6150018
+#define PLLC1CR 0xe6150028
+#define PLLC2CR 0xe615002C
+#define SUBUSBCKCR 0xe6150080
+#define SPUCKCR 0xe6150084
+#define MSUCKCR 0xe6150088
+#define MVI3CKCR 0xe6150090
+#define HDMICKCR 0xe6150094
+#define MFCK1CR 0xe6150098
+#define MFCK2CR 0xe615009C
+#define DSITCKCR 0xe6150060
+#define DSIPCKCR 0xe6150064
+#define SMSTPCR0 0xe6150130
+#define SMSTPCR1 0xe6150134
+#define SMSTPCR2 0xe6150138
+#define SMSTPCR3 0xe615013C
+#define SMSTPCR4 0xe6150140
+
+/* Fixed 32 KHz root clock from EXTALR pin */
+static struct clk r_clk = {
+ .rate = 32768,
+};
+
+/*
+ * 26MHz default rate for the EXTALC1 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7377_extalc1_clk = {
+ .rate = 26666666,
+};
+
+/*
+ * 48MHz default rate for the EXTAL2 root input clock.
+ * If needed, reset this with clk_set_rate() from the platform code.
+ */
+struct clk sh7377_extal2_clk = {
+ .rate = 48000000,
+};
+
+/* A fixed divide-by-2 block */
+static unsigned long div2_recalc(struct clk *clk)
+{
+ return clk->parent->rate / 2;
+}
+
+static struct clk_ops div2_clk_ops = {
+ .recalc = div2_recalc,
+};
+
+/* Divide extalc1 by two */
+static struct clk extalc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7377_extalc1_clk,
+};
+
+/* Divide extal2 by two */
+static struct clk extal2_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &sh7377_extal2_clk,
+};
+
+/* Divide extal2 by four */
+static struct clk extal2_div4_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &extal2_div2_clk,
+};
+
+/* PLLC1 */
+static unsigned long pllc1_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC1CR) & (1 << 14))
+ mult = (((__raw_readl(RTFRQCR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc1_clk_ops = {
+ .recalc = pllc1_recalc,
+};
+
+static struct clk pllc1_clk = {
+ .ops = &pllc1_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalc1_div2_clk,
+};
+
+/* Divide PLLC1 by two */
+static struct clk pllc1_div2_clk = {
+ .ops = &div2_clk_ops,
+ .parent = &pllc1_clk,
+};
+
+/* PLLC2 */
+static unsigned long pllc2_recalc(struct clk *clk)
+{
+ unsigned long mult = 1;
+
+ if (__raw_readl(PLLC2CR) & (1 << 31))
+ mult = (((__raw_readl(PLLC2CR) >> 24) & 0x3f) + 1) * 2;
+
+ return clk->parent->rate * mult;
+}
+
+static struct clk_ops pllc2_clk_ops = {
+ .recalc = pllc2_recalc,
+};
+
+static struct clk pllc2_clk = {
+ .ops = &pllc2_clk_ops,
+ .flags = CLK_ENABLE_ON_INIT,
+ .parent = &extalc1_div2_clk,
+};
+
+static struct clk *main_clks[] = {
+ &r_clk,
+ &sh7377_extalc1_clk,
+ &sh7377_extal2_clk,
+ &extalc1_div2_clk,
+ &extal2_div2_clk,
+ &extal2_div4_clk,
+ &pllc1_clk,
+ &pllc1_div2_clk,
+ &pllc2_clk,
+};
+
+static void div4_kick(struct clk *clk)
+{
+ unsigned long value;
+
+ /* set KICK bit in SYFRQCR to update hardware setting */
+ value = __raw_readl(SYFRQCR);
+ value |= (1 << 31);
+ __raw_writel(value, SYFRQCR);
+}
+
+static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18,
+ 24, 32, 36, 48, 0, 72, 96, 0 };
+
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = divisors,
+ .nr_divisors = ARRAY_SIZE(divisors),
+};
+
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
+ .kick = div4_kick,
+};
+
+enum { DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_CSIR,
+ DIV4_ZTR, DIV4_ZT, DIV4_Z, DIV4_HP,
+ DIV4_ZS, DIV4_ZB, DIV4_ZB3, DIV4_CP, DIV4_NR };
+
+#define DIV4(_reg, _bit, _mask, _flags) \
+ SH_CLK_DIV4(&pllc1_clk, _reg, _bit, _mask, _flags)
+
+static struct clk div4_clks[DIV4_NR] = {
+ [DIV4_I] = DIV4(RTFRQCR, 20, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_ZG] = DIV4(RTFRQCR, 16, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_B] = DIV4(RTFRQCR, 8, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_M1] = DIV4(RTFRQCR, 4, 0x6fff, CLK_ENABLE_ON_INIT),
+ [DIV4_CSIR] = DIV4(RTFRQCR, 0, 0x6fff, 0),
+ [DIV4_ZTR] = DIV4(SYFRQCR, 20, 0x6fff, 0),
+ [DIV4_ZT] = DIV4(SYFRQCR, 16, 0x6fff, 0),
+ [DIV4_Z] = DIV4(SYFRQCR, 12, 0x6fff, 0),
+ [DIV4_HP] = DIV4(SYFRQCR, 4, 0x6fff, 0),
+ [DIV4_ZS] = DIV4(CMFRQCR, 12, 0x6fff, 0),
+ [DIV4_ZB] = DIV4(CMFRQCR, 8, 0x6fff, 0),
+ [DIV4_ZB3] = DIV4(CMFRQCR, 4, 0x6fff, 0),
+ [DIV4_CP] = DIV4(CMFRQCR, 0, 0x6fff, 0),
+};
+
+enum { DIV6_VCK1, DIV6_VCK2, DIV6_VCK3, DIV6_FMSI, DIV6_FMSO,
+ DIV6_FSI, DIV6_SUB, DIV6_SPU, DIV6_MSU, DIV6_MVI3, DIV6_HDMI,
+ DIV6_MF1, DIV6_MF2, DIV6_DSIT, DIV6_DSIP,
+ DIV6_NR };
+
+static struct clk div6_clks[] = {
+ [DIV6_VCK1] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR1, 0),
+ [DIV6_VCK2] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR2, 0),
+ [DIV6_VCK3] = SH_CLK_DIV6(&pllc1_div2_clk, VCLKCR3, 0),
+ [DIV6_FMSI] = SH_CLK_DIV6(&pllc1_div2_clk, FMSICKCR, 0),
+ [DIV6_FMSO] = SH_CLK_DIV6(&pllc1_div2_clk, FMSOCKCR, 0),
+ [DIV6_FSI] = SH_CLK_DIV6(&pllc1_div2_clk, FSICKCR, 0),
+ [DIV6_SUB] = SH_CLK_DIV6(&sh7377_extal2_clk, SUBUSBCKCR, 0),
+ [DIV6_SPU] = SH_CLK_DIV6(&pllc1_div2_clk, SPUCKCR, 0),
+ [DIV6_MSU] = SH_CLK_DIV6(&pllc1_div2_clk, MSUCKCR, 0),
+ [DIV6_MVI3] = SH_CLK_DIV6(&pllc1_div2_clk, MVI3CKCR, 0),
+ [DIV6_HDMI] = SH_CLK_DIV6(&pllc1_div2_clk, HDMICKCR, 0),
+ [DIV6_MF1] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK1CR, 0),
+ [DIV6_MF2] = SH_CLK_DIV6(&pllc1_div2_clk, MFCK2CR, 0),
+ [DIV6_DSIT] = SH_CLK_DIV6(&pllc1_div2_clk, DSITCKCR, 0),
+ [DIV6_DSIP] = SH_CLK_DIV6(&pllc1_div2_clk, DSIPCKCR, 0),
+};
+
+enum { MSTP001,
+ MSTP131, MSTP130, MSTP129, MSTP128, MSTP116, MSTP106, MSTP101,
+ MSTP223, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
+ MSTP331, MSTP329, MSTP325, MSTP323, MSTP322,
+ MSTP315, MSTP314, MSTP313,
+ MSTP403,
+ MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+ SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[] = {
+ [MSTP001] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR0, 1, 0), /* IIC2 */
+ [MSTP131] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 31, 0), /* VEU3 */
+ [MSTP130] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 30, 0), /* VEU2 */
+ [MSTP129] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 29, 0), /* VEU1 */
+ [MSTP128] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 28, 0), /* VEU0 */
+ [MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+ [MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
+ [MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
+ [MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+ [MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
+ [MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
+ [MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
+ [MSTP203] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 3, 0), /* SCIFA1 */
+ [MSTP202] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 2, 0), /* SCIFA2 */
+ [MSTP201] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 1, 0), /* SCIFA3 */
+ [MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
+ [MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
+ [MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IRDA */
+ [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
+ [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL */
+ [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
+ [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
+ [MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+};
+
+#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
+#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk }
+
+static struct clk_lookup lookups[] = {
+ /* main clocks */
+ CLKDEV_CON_ID("r_clk", &r_clk),
+ CLKDEV_CON_ID("extalc1", &sh7377_extalc1_clk),
+ CLKDEV_CON_ID("extal2", &sh7377_extal2_clk),
+ CLKDEV_CON_ID("extalc1_div2_clk", &extalc1_div2_clk),
+ CLKDEV_CON_ID("extal2_div2_clk", &extal2_div2_clk),
+ CLKDEV_CON_ID("extal2_div4_clk", &extal2_div4_clk),
+ CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
+ CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
+ CLKDEV_CON_ID("pllc2_clk", &pllc2_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
+ CLKDEV_CON_ID("zg_clk", &div4_clks[DIV4_ZG]),
+ CLKDEV_CON_ID("b_clk", &div4_clks[DIV4_B]),
+ CLKDEV_CON_ID("m1_clk", &div4_clks[DIV4_M1]),
+ CLKDEV_CON_ID("csir_clk", &div4_clks[DIV4_CSIR]),
+ CLKDEV_CON_ID("ztr_clk", &div4_clks[DIV4_ZTR]),
+ CLKDEV_CON_ID("zt_clk", &div4_clks[DIV4_ZT]),
+ CLKDEV_CON_ID("z_clk", &div4_clks[DIV4_Z]),
+ CLKDEV_CON_ID("hp_clk", &div4_clks[DIV4_HP]),
+ CLKDEV_CON_ID("zs_clk", &div4_clks[DIV4_ZS]),
+ CLKDEV_CON_ID("zb_clk", &div4_clks[DIV4_ZB]),
+ CLKDEV_CON_ID("zb3_clk", &div4_clks[DIV4_ZB3]),
+ CLKDEV_CON_ID("cp_clk", &div4_clks[DIV4_CP]),
+
+ /* DIV6 clocks */
+ CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
+ CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
+ CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+ CLKDEV_CON_ID("fmsi_clk", &div6_clks[DIV6_FMSI]),
+ CLKDEV_CON_ID("fmso_clk", &div6_clks[DIV6_FMSO]),
+ CLKDEV_CON_ID("fsi_clk", &div6_clks[DIV6_FSI]),
+ CLKDEV_CON_ID("sub_clk", &div6_clks[DIV6_SUB]),
+ CLKDEV_CON_ID("spu_clk", &div6_clks[DIV6_SPU]),
+ CLKDEV_CON_ID("msu_clk", &div6_clks[DIV6_MSU]),
+ CLKDEV_CON_ID("mvi3_clk", &div6_clks[DIV6_MVI3]),
+ CLKDEV_CON_ID("hdmi_clk", &div6_clks[DIV6_HDMI]),
+ CLKDEV_CON_ID("mf1_clk", &div6_clks[DIV6_MF1]),
+ CLKDEV_CON_ID("mf2_clk", &div6_clks[DIV6_MF2]),
+ CLKDEV_CON_ID("dsit_clk", &div6_clks[DIV6_DSIT]),
+ CLKDEV_CON_ID("dsip_clk", &div6_clks[DIV6_DSIP]),
+
+ /* MSTP32 clocks */
+ CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.4", &mstp_clks[MSTP131]), /* VEU3 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.3", &mstp_clks[MSTP130]), /* VEU2 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.2", &mstp_clks[MSTP129]), /* VEU1 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.1", &mstp_clks[MSTP128]), /* VEU0 */
+ CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
+ CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
+ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP206]), /* SCIFB */
+ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
+ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */
+ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP202]), /* SCIFA2 */
+ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]), /* SCIFA3 */
+ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
+ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
+ CLKDEV_CON_ID("cmt1", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_irda", &mstp_clks[MSTP325]), /* IRDA */
+ CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
+ CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USBHS */
+ CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USBHS */
+ CLKDEV_DEV_ID("sh_flctl", &mstp_clks[MSTP315]), /* FLCTL */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
+ CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+};
+
+void __init sh7377_clock_init(void)
+{
+ int k, ret = 0;
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+ ret = clk_register(main_clks[k]);
+
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
+
+ if (!ret)
+ ret = sh_clk_div6_register(div6_clks, DIV6_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ if (!ret)
+ clk_init();
+ else
+ panic("failed to setup sh7377 clocks\n");
+}
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c
new file mode 100644
index 000000000000..b7c705a213a2
--- /dev/null
+++ b/arch/arm/mach-shmobile/clock.c
@@ -0,0 +1,44 @@
+/*
+ * SH-Mobile Timer
+ *
+ * Copyright (C) 2010 Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sh_clk.h>
+
+int __init clk_init(void)
+{
+ /* Kick the child clocks.. */
+ recalculate_root_clocks();
+
+ /* Enable the necessary init clocks */
+ clk_enable_init_clocks();
+
+ return 0;
+}
+
+int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+EXPORT_SYMBOL(__clk_get);
+
+void __clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(__clk_put);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 57903605cc51..efeef778a875 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -3,21 +3,31 @@
extern struct sys_timer shmobile_timer;
extern void shmobile_setup_console(void);
+struct clk;
+extern int clk_init(void);
extern void sh7367_init_irq(void);
extern void sh7367_add_early_devices(void);
extern void sh7367_add_standard_devices(void);
extern void sh7367_clock_init(void);
extern void sh7367_pinmux_init(void);
+extern struct clk sh7367_extalb1_clk;
+extern struct clk sh7367_extal2_clk;
extern void sh7377_init_irq(void);
extern void sh7377_add_early_devices(void);
extern void sh7377_add_standard_devices(void);
+extern void sh7377_clock_init(void);
extern void sh7377_pinmux_init(void);
+extern struct clk sh7377_extalc1_clk;
+extern struct clk sh7377_extal2_clk;
extern void sh7372_init_irq(void);
extern void sh7372_add_early_devices(void);
extern void sh7372_add_standard_devices(void);
+extern void sh7372_clock_init(void);
extern void sh7372_pinmux_init(void);
+extern struct clk sh7372_extal1_clk;
+extern struct clk sh7372_extal2_clk;
#endif /* __ARCH_MACH_COMMON_H */
diff --git a/arch/arm/mach-shmobile/include/mach/irqs.h b/arch/arm/mach-shmobile/include/mach/irqs.h
index 5179b72e1ee3..e881797648a9 100644
--- a/arch/arm/mach-shmobile/include/mach/irqs.h
+++ b/arch/arm/mach-shmobile/include/mach/irqs.h
@@ -4,7 +4,13 @@
#define NR_IRQS 512
#define NR_IRQS_LEGACY 8
+/* INTCA */
#define evt2irq(evt) (((evt) >> 5) - 16)
#define irq2evt(irq) (((irq) + 16) << 5)
+/* INTCS */
+#define INTCS_VECT_BASE 0x2200
+#define INTCS_VECT(n, vect) INTC_VECT((n), INTCS_VECT_BASE + (vect))
+#define intcs_evt2irq(evt) evt2irq(INTCS_VECT_BASE + (evt))
+
#endif /* __ASM_MACH_IRQS_H */
diff --git a/arch/arm/mach-shmobile/include/mach/memory.h b/arch/arm/mach-shmobile/include/mach/memory.h
index e188183f4dce..377584e57e03 100644
--- a/arch/arm/mach-shmobile/include/mach/memory.h
+++ b/arch/arm/mach-shmobile/include/mach/memory.h
@@ -4,4 +4,7 @@
#define PHYS_OFFSET UL(CONFIG_MEMORY_START)
#define MEM_SIZE UL(CONFIG_MEMORY_SIZE)
+/* DMA memory at 0xf6000000 - 0xffdfffff */
+#define CONSISTENT_DMA_SIZE (158 << 20)
+
#endif /* __ASM_MACH_MEMORY_H */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index dc34f00c56b8..c2d2d811059c 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -431,4 +431,28 @@ enum {
GPIO_FN_SDENC_DV_CLKI,
};
+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_SCIF0_TX,
+ SHDMA_SLAVE_SCIF0_RX,
+ SHDMA_SLAVE_SCIF1_TX,
+ SHDMA_SLAVE_SCIF1_RX,
+ SHDMA_SLAVE_SCIF2_TX,
+ SHDMA_SLAVE_SCIF2_RX,
+ SHDMA_SLAVE_SCIF3_TX,
+ SHDMA_SLAVE_SCIF3_RX,
+ SHDMA_SLAVE_SCIF4_TX,
+ SHDMA_SLAVE_SCIF4_RX,
+ SHDMA_SLAVE_SCIF5_TX,
+ SHDMA_SLAVE_SCIF5_RX,
+ SHDMA_SLAVE_SCIF6_TX,
+ SHDMA_SLAVE_SCIF6_RX,
+ SHDMA_SLAVE_SDHI0_RX,
+ SHDMA_SLAVE_SDHI0_TX,
+ SHDMA_SLAVE_SDHI1_RX,
+ SHDMA_SLAVE_SDHI1_TX,
+ SHDMA_SLAVE_SDHI2_RX,
+ SHDMA_SLAVE_SDHI2_TX,
+};
+
#endif /* __ASM_SH7372_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h
index fb3c4f1ab252..4aecf6e3a859 100644
--- a/arch/arm/mach-shmobile/include/mach/vmalloc.h
+++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h
@@ -1,6 +1,7 @@
#ifndef __ASM_MACH_VMALLOC_H
#define __ASM_MACH_VMALLOC_H
-#define VMALLOC_END (PAGE_OFFSET + 0x24000000)
+/* Vmalloc at ... - 0xe5ffffff */
+#define VMALLOC_END 0xe6000000
#endif /* __ASM_MACH_VMALLOC_H */
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
index 5ff70cadfc32..1a20c489b20d 100644
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -75,7 +75,7 @@ enum {
ETM11, ARM11, USBHS, FLCTL, IIC1
};
-static struct intc_vect intca_vectors[] = {
+static struct intc_vect intca_vectors[] __initdata = {
INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
@@ -162,7 +162,7 @@ static struct intc_group intca_groups[] __initdata = {
INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
};
-static struct intc_mask_reg intca_mask_registers[] = {
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
{ 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
{ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
{ 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
@@ -211,7 +211,7 @@ static struct intc_mask_reg intca_mask_registers[] = {
MISTY, CMT3, RWDT1, RWDT0 } },
};
-static struct intc_prio_reg intca_prio_registers[] = {
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
{ 0xe6900010, 0, 32, 4, /* INTPRI00A */
{ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
{ 0xe6900014, 0, 32, 4, /* INTPRI10A */
@@ -263,8 +263,178 @@ static struct intc_desc intca_desc __initdata = {
intca_sense_registers, intca_ack_registers),
};
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+ VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3,
+ VIO3_VOU,
+ RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
+ VIO1_CEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2,
+ VPU,
+ SGX530,
+ _2DDMAC_2DDM0, _2DDMAC_2DDM1, _2DDMAC_2DDM2, _2DDMAC_2DDM3,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUB, IPMMU_IPMMUS,
+ RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+ MSIOF,
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT,
+ TSIF,
+ IPMMUI,
+ MVI3,
+ ICB,
+ PEP,
+ ASA,
+ BEM,
+ VE2HO,
+ HQE,
+ JPEG,
+ LCDC,
+
+ /* interrupt groups INTCS */
+ _2DDMAC, RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ INTCS_VECT(VIO2_VEU0, 0x700), INTCS_VECT(VIO2_VEU1, 0x720),
+ INTCS_VECT(VIO2_VEU2, 0x740), INTCS_VECT(VIO2_VEU3, 0x760),
+ INTCS_VECT(VIO3_VOU, 0x780),
+ INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
+ INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
+ INTCS_VECT(VIO1_CEU, 0x880), INTCS_VECT(VIO1_BEU0, 0x8a0),
+ INTCS_VECT(VIO1_BEU1, 0x8c0), INTCS_VECT(VIO1_BEU2, 0x8e0),
+ INTCS_VECT(VPU, 0x980),
+ INTCS_VECT(SGX530, 0x9e0),
+ INTCS_VECT(_2DDMAC_2DDM0, 0xa00), INTCS_VECT(_2DDMAC_2DDM1, 0xa20),
+ INTCS_VECT(_2DDMAC_2DDM2, 0xa40), INTCS_VECT(_2DDMAC_2DDM3, 0xa60),
+ INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
+ INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
+ INTCS_VECT(IPMMU_IPMMUB, 0xb20), INTCS_VECT(IPMMU_IPMMUS, 0xb60),
+ INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
+ INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+ INTCS_VECT(MSIOF, 0xd20),
+ INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
+ INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
+ INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
+ INTCS_VECT(TMU_TUNI2, 0xec0),
+ INTCS_VECT(CMT, 0xf00),
+ INTCS_VECT(TSIF, 0xf20),
+ INTCS_VECT(IPMMUI, 0xf60),
+ INTCS_VECT(MVI3, 0x420),
+ INTCS_VECT(ICB, 0x480),
+ INTCS_VECT(PEP, 0x4a0),
+ INTCS_VECT(ASA, 0x4c0),
+ INTCS_VECT(BEM, 0x4e0),
+ INTCS_VECT(VE2HO, 0x520),
+ INTCS_VECT(HQE, 0x540),
+ INTCS_VECT(JPEG, 0x560),
+ INTCS_VECT(LCDC, 0x580),
+
+ INTC_VECT(INTCS, 0xf80),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(_2DDMAC, _2DDMAC_2DDM0, _2DDMAC_2DDM1,
+ _2DDMAC_2DDM2, _2DDMAC_2DDM3),
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
+ RTDMAC_1_DEI2, RTDMAC_1_DEI3),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
+ INTC_GROUP(VEU, VIO2_VEU0, VIO2_VEU1, VIO2_VEU2, VIO2_VEU3),
+ INTC_GROUP(BEU, VIO1_BEU0, VIO1_BEU1, VIO1_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ INTC_GROUP(IPMMU, IPMMU_IPMMUS, IPMMU_IPMMUB),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { VIO1_BEU2, VIO1_BEU1, VIO1_BEU0, VIO1_CEU,
+ VIO2_VEU3, VIO2_VEU2, VIO2_VEU1, VIO2_VEU0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { VIO3_VOU, 0, VE2HO, VPU,
+ 0, 0, 0, 0 } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { _2DDMAC_2DDM3, _2DDMAC_2DDM2, _2DDMAC_2DDM1, _2DDMAC_2DDM0,
+ BEM, ASA, PEP, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, MVI3, 0,
+ JPEG, HQE, 0, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
+ RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ SGX530, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, 0, 0, CMT,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
+ { IPMMU_IPMMUS, 0, IPMMU_IPMMUB, 0,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, 0, IPMMUI, TSIF } },
+ { 0xffd20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { 0, MVI3, _2DDMAC, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPEG, LCDC, 0, 0 } },
+ { 0xffd20008, 0, 16, 4, /* IPRCS */ { BBIF2, 0, 0, 0 } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, VIO1_CEU, 0, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
+ TMU_TUNI2, 0 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, VIO3_VOU, VEU, BEU } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF, IIC0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, SGX530, 0, 0 } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { BEM, ASA, IPMMUI, PEP } },
+ { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, VE2HO, HQE } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd2ffff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7367-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)get_irq_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
void __init sh7367_init_irq(void)
{
- /* INTCA */
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ set_irq_data(evt2irq(0xf80), (void *)intevtsa);
+ set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
}
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index 3ce9d9bd5899..e3551b56cd03 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -319,17 +319,17 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
{ 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
{ 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
CMT14, CMT15 } },
- { 0xe694003c, 0, 16, 4, /* IPRPA3 */ { 0, 0,
+ { 0xe695003c, 0, 16, 4, /* IPRPA3 */ { 0, 0,
MMC_MMC_ERR, MMC_MMC_NOR } },
- { 0xe6940040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
+ { 0xe6950040, 0, 16, 4, /* IPRQA3 */ { IIC4_ALI4, IIC4_TACKI4,
IIC4_WAITI4, IIC4_DTEI4 } },
- { 0xe6940044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
+ { 0xe6950044, 0, 16, 4, /* IPRRA3 */ { IIC3_ALI3, IIC3_TACKI3,
IIC3_WAITI3, IIC3_DTEI3 } },
- { 0xe6940048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
+ { 0xe6950048, 0, 16, 4, /* IPRSA3 */ { 0/*ERI*/, 0/*RXI*/,
0/*TXI*/, 0/*TEI*/} },
- { 0xe694004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
+ { 0xe695004c, 0, 16, 4, /* IPRTA3 */ { USB0_USB0I1, USB0_USB0I0,
USB1_USB1I1, USB1_USB1I0 } },
- { 0xe6940050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
+ { 0xe6950050, 0, 16, 4, /* IPRUA3 */ { USBHSDMAC1_USHDMI, 0, 0, 0 } },
};
static struct intc_sense_reg intca_sense_registers[] __initdata = {
@@ -363,7 +363,227 @@ static struct intc_desc intca_desc __initdata = {
intca_sense_registers, intca_ack_registers),
};
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+ VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
+ RTDMAC_1_DEI0, RTDMAC_1_DEI1, RTDMAC_1_DEI2, RTDMAC_1_DEI3,
+ CEU, BEU_BEU0, BEU_BEU1, BEU_BEU2,
+ VPU,
+ TSIF1,
+ _3DG_SGX530,
+ _2DDMAC,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR,
+ MSIOF,
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT0,
+ TSIF0,
+ LMB,
+ CTI,
+ ICB,
+ JPU_JPEG,
+ LCDC,
+ LCRC,
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
+ ISP,
+ LCDC1,
+ CSIRX,
+ DSITX_DSITX0,
+ DSITX_DSITX1,
+ TMU1_TUNI0, TMU1_TUNI1, TMU1_TUNI2,
+ CMT4,
+ DSITX1_DSITX1_0,
+ DSITX1_DSITX1_1,
+ CPORTS2R,
+ JPU6E,
+
+ /* interrupt groups INTCS */
+ RTDMAC_1, RTDMAC_2, VEU, BEU, IIC0, IPMMU, IIC2,
+ RTDMAC2_1, RTDMAC2_2, TMU1, DSITX,
+};
+
+static struct intc_vect intcs_vectors[] = {
+ INTCS_VECT(VEU_VEU0, 0x700), INTCS_VECT(VEU_VEU1, 0x720),
+ INTCS_VECT(VEU_VEU2, 0x740), INTCS_VECT(VEU_VEU3, 0x760),
+ INTCS_VECT(RTDMAC_1_DEI0, 0x800), INTCS_VECT(RTDMAC_1_DEI1, 0x820),
+ INTCS_VECT(RTDMAC_1_DEI2, 0x840), INTCS_VECT(RTDMAC_1_DEI3, 0x860),
+ INTCS_VECT(CEU, 0x880), INTCS_VECT(BEU_BEU0, 0x8a0),
+ INTCS_VECT(BEU_BEU1, 0x8c0), INTCS_VECT(BEU_BEU2, 0x8e0),
+ INTCS_VECT(VPU, 0x980),
+ INTCS_VECT(TSIF1, 0x9a0),
+ INTCS_VECT(_3DG_SGX530, 0x9e0),
+ INTCS_VECT(_2DDMAC, 0xa00),
+ INTCS_VECT(IIC2_ALI2, 0xa80), INTCS_VECT(IIC2_TACKI2, 0xaa0),
+ INTCS_VECT(IIC2_WAITI2, 0xac0), INTCS_VECT(IIC2_DTEI2, 0xae0),
+ INTCS_VECT(IPMMU_IPMMUR, 0xb00), INTCS_VECT(IPMMU_IPMMUR2, 0xb20),
+ INTCS_VECT(RTDMAC_2_DEI4, 0xb80), INTCS_VECT(RTDMAC_2_DEI5, 0xba0),
+ INTCS_VECT(RTDMAC_2_DADERR, 0xbc0),
+ INTCS_VECT(IIC0_ALI0, 0xe00), INTCS_VECT(IIC0_TACKI0, 0xe20),
+ INTCS_VECT(IIC0_WAITI0, 0xe40), INTCS_VECT(IIC0_DTEI0, 0xe60),
+ INTCS_VECT(TMU_TUNI0, 0xe80), INTCS_VECT(TMU_TUNI1, 0xea0),
+ INTCS_VECT(TMU_TUNI2, 0xec0),
+ INTCS_VECT(CMT0, 0xf00),
+ INTCS_VECT(TSIF0, 0xf20),
+ INTCS_VECT(LMB, 0xf60),
+ INTCS_VECT(CTI, 0x400),
+ INTCS_VECT(ICB, 0x480),
+ INTCS_VECT(JPU_JPEG, 0x560),
+ INTCS_VECT(LCDC, 0x580),
+ INTCS_VECT(LCRC, 0x5a0),
+ INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
+ INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
+ INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13a0),
+ INTCS_VECT(RTDMAC2_2_DADERR, 0x13c0),
+ INTCS_VECT(ISP, 0x1720),
+ INTCS_VECT(LCDC1, 0x1780),
+ INTCS_VECT(CSIRX, 0x17a0),
+ INTCS_VECT(DSITX_DSITX0, 0x17c0),
+ INTCS_VECT(DSITX_DSITX1, 0x17e0),
+ INTCS_VECT(TMU1_TUNI0, 0x1900), INTCS_VECT(TMU1_TUNI1, 0x1920),
+ INTCS_VECT(TMU1_TUNI2, 0x1940),
+ INTCS_VECT(CMT4, 0x1980),
+ INTCS_VECT(DSITX1_DSITX1_0, 0x19a0),
+ INTCS_VECT(DSITX1_DSITX1_1, 0x19c0),
+ INTCS_VECT(CPORTS2R, 0x1a20),
+ INTCS_VECT(JPU6E, 0x1a80),
+
+ INTC_VECT(INTCS, 0xf80),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC_1, RTDMAC_1_DEI0, RTDMAC_1_DEI1,
+ RTDMAC_1_DEI2, RTDMAC_1_DEI3),
+ INTC_GROUP(RTDMAC_2, RTDMAC_2_DEI4, RTDMAC_2_DEI5, RTDMAC_2_DADERR),
+ INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
+ INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+ INTC_GROUP(RTDMAC2_1, RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
+ RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
+ INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4,
+ RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
+ INTC_GROUP(TMU1, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0),
+ INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] = {
+ { 0xffd20184, 0xffd201c4, 8, /* IMR1SA / IMCR1SA */
+ { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
+ VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
+ { 0xffd20188, 0xffd201c8, 8, /* IMR2SA / IMCR2SA */
+ { 0, 0, 0, VPU,
+ 0, 0, 0, 0 } },
+ { 0xffd2018c, 0xffd201cc, 8, /* IMR3SA / IMCR3SA */
+ { 0, 0, 0, _2DDMAC,
+ 0, 0, 0, ICB } },
+ { 0xffd20190, 0xffd201d0, 8, /* IMR4SA / IMCR4SA */
+ { 0, 0, 0, CTI,
+ JPU_JPEG, 0, LCRC, LCDC } },
+ { 0xffd20194, 0xffd201d4, 8, /* IMR5SA / IMCR5SA */
+ { 0, RTDMAC_2_DADERR, RTDMAC_2_DEI5, RTDMAC_2_DEI4,
+ RTDMAC_1_DEI3, RTDMAC_1_DEI2, RTDMAC_1_DEI1, RTDMAC_1_DEI0 } },
+ { 0xffd20198, 0xffd201d8, 8, /* IMR6SA / IMCR6SA */
+ { 0, 0, MSIOF, 0,
+ _3DG_SGX530, 0, 0, 0 } },
+ { 0xffd2019c, 0xffd201dc, 8, /* IMR7SA / IMCR7SA */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ { 0xffd201a4, 0xffd201e4, 8, /* IMR9SA / IMCR9SA */
+ { 0, 0, 0, CMT0,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xffd201a8, 0xffd201e8, 8, /* IMR10SA / IMCR10SA */
+ { 0, 0, IPMMU_IPMMUR2, IPMMU_IPMMUR,
+ 0, 0, 0, 0 } },
+ { 0xffd201ac, 0xffd201ec, 8, /* IMR11SA / IMCR11SA */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xffd50180, 0xffd501c0, 8, /* IMR0SA3 / IMCR0SA3 */
+ { 0, RTDMAC2_2_DADERR, RTDMAC2_2_DEI5, RTDMAC2_2_DEI4,
+ RTDMAC2_1_DEI3, RTDMAC2_1_DEI2, RTDMAC2_1_DEI1, RTDMAC2_1_DEI0 } },
+ { 0xffd50190, 0xffd501d0, 8, /* IMR4SA3 / IMCR4SA3 */
+ { 0, ISP, 0, 0,
+ LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
+ { 0xffd50198, 0xffd501d8, 8, /* IMR6SA3 / IMCR6SA3 */
+ { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
+ CMT4, DSITX1_DSITX1_0, DSITX1_DSITX1_1, 0 } },
+ { 0xffd5019c, 0xffd501dc, 8, /* IMR7SA3 / IMCR7SA3 */
+ { 0, CPORTS2R, 0, 0,
+ JPU6E, 0, 0, 0 } },
+ { 0xffd20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } },
+};
+
+/* Priority is needed for INTCA to receive the INTCS interrupt */
+static struct intc_prio_reg intcs_prio_registers[] = {
+ { 0xffd20000, 0, 16, 4, /* IPRAS */ { CTI, 0, _2DDMAC, ICB } },
+ { 0xffd20004, 0, 16, 4, /* IPRBS */ { JPU_JPEG, LCDC, 0, LCRC } },
+ { 0xffd20010, 0, 16, 4, /* IPRES */ { RTDMAC_1, CEU, 0, VPU } },
+ { 0xffd20014, 0, 16, 4, /* IPRFS */ { 0, RTDMAC_2, 0, CMT0 } },
+ { 0xffd20018, 0, 16, 4, /* IPRGS */ { TMU_TUNI0, TMU_TUNI1,
+ TMU_TUNI2, TSIF1 } },
+ { 0xffd2001c, 0, 16, 4, /* IPRHS */ { 0, 0, VEU, BEU } },
+ { 0xffd20020, 0, 16, 4, /* IPRIS */ { 0, MSIOF, TSIF0, IIC0 } },
+ { 0xffd20024, 0, 16, 4, /* IPRJS */ { 0, _3DG_SGX530, 0, 0 } },
+ { 0xffd20028, 0, 16, 4, /* IPRKS */ { 0, 0, LMB, 0 } },
+ { 0xffd2002c, 0, 16, 4, /* IPRLS */ { IPMMU, 0, 0, 0 } },
+ { 0xffd20030, 0, 16, 4, /* IPRMS */ { IIC2, 0, 0, 0 } },
+ { 0xffd50000, 0, 16, 4, /* IPRAS3 */ { RTDMAC2_1, 0, 0, 0 } },
+ { 0xffd50004, 0, 16, 4, /* IPRBS3 */ { RTDMAC2_2, 0, 0, 0 } },
+ { 0xffd50020, 0, 16, 4, /* IPRIS3 */ { 0, ISP, 0, 0 } },
+ { 0xffd50024, 0, 16, 4, /* IPRJS3 */ { LCDC1, CSIRX, DSITX, 0 } },
+ { 0xffd50030, 0, 16, 4, /* IPRMS3 */ { TMU1, 0, 0, 0 } },
+ { 0xffd50034, 0, 16, 4, /* IPRNS3 */ { CMT4, DSITX1_DSITX1_0,
+ DSITX1_DSITX1_1, 0 } },
+ { 0xffd50038, 0, 16, 4, /* IPROS3 */ { 0, CPORTS2R, 0, 0 } },
+ { 0xffd5003c, 0, 16, 4, /* IPRPS3 */ { JPU6E, 0, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd201ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0xffd50000,
+ .end = 0xffd501ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7372-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups, intcs_mask_registers,
+ intcs_prio_registers, NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)get_irq_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
void __init sh7372_init_irq(void)
{
+ void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
+
register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ set_irq_data(evt2irq(0xf80), (void *)intevtsa);
+ set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
index 5c781e2d1897..2cdeb8ccd821 100644
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -90,7 +90,7 @@ enum {
ICUSB, ICUDMC
};
-static struct intc_vect intca_vectors[] = {
+static struct intc_vect intca_vectors[] __initdata = {
INTC_VECT(IRQ0A, 0x0200), INTC_VECT(IRQ1A, 0x0220),
INTC_VECT(IRQ2A, 0x0240), INTC_VECT(IRQ3A, 0x0260),
INTC_VECT(IRQ4A, 0x0280), INTC_VECT(IRQ5A, 0x02a0),
@@ -202,7 +202,7 @@ static struct intc_group intca_groups[] __initdata = {
INTC_GROUP(ICUDMC, ICUDMC_ICUDMC1, ICUDMC_ICUDMC2),
};
-static struct intc_mask_reg intca_mask_registers[] = {
+static struct intc_mask_reg intca_mask_registers[] __initdata = {
{ 0xe6900040, 0xe6900060, 8, /* INTMSK00A / INTMSKCLR00A */
{ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
{ 0xe6900044, 0xe6900064, 8, /* INTMSK10A / INTMSKCLR10A */
@@ -272,7 +272,7 @@ static struct intc_mask_reg intca_mask_registers[] = {
SCIFA6, 0, 0, 0 } },
};
-static struct intc_prio_reg intca_prio_registers[] = {
+static struct intc_prio_reg intca_prio_registers[] __initdata = {
{ 0xe6900010, 0, 32, 4, /* INTPRI00A */
{ IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A } },
{ 0xe6900014, 0, 32, 4, /* INTPRI10A */
@@ -346,7 +346,301 @@ static struct intc_desc intca_desc __initdata = {
intca_sense_registers, intca_ack_registers),
};
+/* this macro ignore entry which is also in INTCA */
+#define __IGNORE(a...)
+#define __IGNORE0(a...) 0
+
+enum {
+ UNUSED_INTCS = 0,
+
+ INTCS,
+
+ /* interrupt sources INTCS */
+ VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3,
+ RTDMAC1_1_DEI0, RTDMAC1_1_DEI1, RTDMAC1_1_DEI2, RTDMAC1_1_DEI3,
+ CEU,
+ BEU_BEU0, BEU_BEU1, BEU_BEU2,
+ __IGNORE(MFI)
+ __IGNORE(BBIF2)
+ VPU,
+ TSIF1,
+ __IGNORE(SGX540)
+ _2DDMAC,
+ IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2,
+ IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR,
+ __IGNORE(KEYSC)
+ __IGNORE(TTI20)
+ __IGNORE(MSIOF)
+ IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0,
+ TMU_TUNI0, TMU_TUNI1, TMU_TUNI2,
+ CMT0,
+ TSIF0,
+ __IGNORE(CMT2)
+ LMB,
+ __IGNORE(MSUG)
+ __IGNORE(MSU_MSU, MSU_MSU2)
+ __IGNORE(CTI)
+ MVI3,
+ __IGNORE(RWDT0)
+ __IGNORE(RWDT1)
+ ICB,
+ PEP,
+ ASA,
+ __IGNORE(_2DG)
+ HQE,
+ JPU,
+ LCDC0,
+ __IGNORE(LCRC)
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR,
+ FRC,
+ LCDC1,
+ CSIRX,
+ DSITX_DSITX0, DSITX_DSITX1,
+ __IGNORE(SPU2_SPU0, SPU2_SPU1)
+ __IGNORE(FSI)
+ __IGNORE(FMSI)
+ __IGNORE(SCUV)
+ TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12,
+ TSIF2,
+ CMT4,
+ __IGNORE(MFIS2)
+ CPORTS2R,
+
+ /* interrupt groups INTCS */
+ RTDMAC1_1, RTDMAC1_2, VEU, BEU, IIC0, __IGNORE(MSU) IPMMU,
+ IIC2, RTDMAC2_1, RTDMAC2_2, DSITX, __IGNORE(SPU2) TMU1,
+};
+
+#define INTCS_INTVECT 0x0F80
+static struct intc_vect intcs_vectors[] __initdata = {
+ INTCS_VECT(VEU_VEU0, 0x0700), INTCS_VECT(VEU_VEU1, 0x0720),
+ INTCS_VECT(VEU_VEU2, 0x0740), INTCS_VECT(VEU_VEU3, 0x0760),
+ INTCS_VECT(RTDMAC1_1_DEI0, 0x0800), INTCS_VECT(RTDMAC1_1_DEI1, 0x0820),
+ INTCS_VECT(RTDMAC1_1_DEI2, 0x0840), INTCS_VECT(RTDMAC1_1_DEI3, 0x0860),
+ INTCS_VECT(CEU, 0x0880),
+ INTCS_VECT(BEU_BEU0, 0x08A0),
+ INTCS_VECT(BEU_BEU1, 0x08C0),
+ INTCS_VECT(BEU_BEU2, 0x08E0),
+ __IGNORE(INTCS_VECT(MFI, 0x0900))
+ __IGNORE(INTCS_VECT(BBIF2, 0x0960))
+ INTCS_VECT(VPU, 0x0980),
+ INTCS_VECT(TSIF1, 0x09A0),
+ __IGNORE(INTCS_VECT(SGX540, 0x09E0))
+ INTCS_VECT(_2DDMAC, 0x0A00),
+ INTCS_VECT(IIC2_ALI2, 0x0A80), INTCS_VECT(IIC2_TACKI2, 0x0AA0),
+ INTCS_VECT(IIC2_WAITI2, 0x0AC0), INTCS_VECT(IIC2_DTEI2, 0x0AE0),
+ INTCS_VECT(IPMMU_IPMMUR, 0x0B00), INTCS_VECT(IPMMU_IPMMUR2, 0x0B20),
+ INTCS_VECT(RTDMAC1_2_DEI4, 0x0B80),
+ INTCS_VECT(RTDMAC1_2_DEI5, 0x0BA0),
+ INTCS_VECT(RTDMAC1_2_DADERR, 0x0BC0),
+ __IGNORE(INTCS_VECT(KEYSC 0x0BE0))
+ __IGNORE(INTCS_VECT(TTI20, 0x0C80))
+ __IGNORE(INTCS_VECT(MSIOF, 0x0D20))
+ INTCS_VECT(IIC0_ALI0, 0x0E00), INTCS_VECT(IIC0_TACKI0, 0x0E20),
+ INTCS_VECT(IIC0_WAITI0, 0x0E40), INTCS_VECT(IIC0_DTEI0, 0x0E60),
+ INTCS_VECT(TMU_TUNI0, 0x0E80),
+ INTCS_VECT(TMU_TUNI1, 0x0EA0),
+ INTCS_VECT(TMU_TUNI2, 0x0EC0),
+ INTCS_VECT(CMT0, 0x0F00),
+ INTCS_VECT(TSIF0, 0x0F20),
+ __IGNORE(INTCS_VECT(CMT2, 0x0F40))
+ INTCS_VECT(LMB, 0x0F60),
+ __IGNORE(INTCS_VECT(MSUG, 0x0F80))
+ __IGNORE(INTCS_VECT(MSU_MSU, 0x0FA0))
+ __IGNORE(INTCS_VECT(MSU_MSU2, 0x0FC0))
+ __IGNORE(INTCS_VECT(CTI, 0x0400))
+ INTCS_VECT(MVI3, 0x0420),
+ __IGNORE(INTCS_VECT(RWDT0, 0x0440))
+ __IGNORE(INTCS_VECT(RWDT1, 0x0460))
+ INTCS_VECT(ICB, 0x0480),
+ INTCS_VECT(PEP, 0x04A0),
+ INTCS_VECT(ASA, 0x04C0),
+ __IGNORE(INTCS_VECT(_2DG, 0x04E0))
+ INTCS_VECT(HQE, 0x0540),
+ INTCS_VECT(JPU, 0x0560),
+ INTCS_VECT(LCDC0, 0x0580),
+ __IGNORE(INTCS_VECT(LCRC, 0x05A0))
+ INTCS_VECT(RTDMAC2_1_DEI0, 0x1300), INTCS_VECT(RTDMAC2_1_DEI1, 0x1320),
+ INTCS_VECT(RTDMAC2_1_DEI2, 0x1340), INTCS_VECT(RTDMAC2_1_DEI3, 0x1360),
+ INTCS_VECT(RTDMAC2_2_DEI4, 0x1380), INTCS_VECT(RTDMAC2_2_DEI5, 0x13A0),
+ INTCS_VECT(RTDMAC2_2_DADERR, 0x13C0),
+ INTCS_VECT(FRC, 0x1700),
+ INTCS_VECT(LCDC1, 0x1780),
+ INTCS_VECT(CSIRX, 0x17A0),
+ INTCS_VECT(DSITX_DSITX0, 0x17C0), INTCS_VECT(DSITX_DSITX1, 0x17E0),
+ __IGNORE(INTCS_VECT(SPU2_SPU0, 0x1800))
+ __IGNORE(INTCS_VECT(SPU2_SPU1, 0x1820))
+ __IGNORE(INTCS_VECT(FSI, 0x1840))
+ __IGNORE(INTCS_VECT(FMSI, 0x1860))
+ __IGNORE(INTCS_VECT(SCUV, 0x1880))
+ INTCS_VECT(TMU1_TUNI10, 0x1900), INTCS_VECT(TMU1_TUNI11, 0x1920),
+ INTCS_VECT(TMU1_TUNI12, 0x1940),
+ INTCS_VECT(TSIF2, 0x1960),
+ INTCS_VECT(CMT4, 0x1980),
+ __IGNORE(INTCS_VECT(MFIS2, 0x1A00))
+ INTCS_VECT(CPORTS2R, 0x1A20),
+
+ INTC_VECT(INTCS, INTCS_INTVECT),
+};
+
+static struct intc_group intcs_groups[] __initdata = {
+ INTC_GROUP(RTDMAC1_1,
+ RTDMAC1_1_DEI0, RTDMAC1_1_DEI1,
+ RTDMAC1_1_DEI2, RTDMAC1_1_DEI3),
+ INTC_GROUP(RTDMAC1_2,
+ RTDMAC1_2_DEI4, RTDMAC1_2_DEI5, RTDMAC1_2_DADERR),
+ INTC_GROUP(VEU, VEU_VEU0, VEU_VEU1, VEU_VEU2, VEU_VEU3),
+ INTC_GROUP(BEU, BEU_BEU0, BEU_BEU1, BEU_BEU2),
+ INTC_GROUP(IIC0, IIC0_ALI0, IIC0_TACKI0, IIC0_WAITI0, IIC0_DTEI0),
+ __IGNORE(INTC_GROUP(MSU, MSU_MSU, MSU_MSU2))
+ INTC_GROUP(IPMMU, IPMMU_IPMMUR, IPMMU_IPMMUR2),
+ INTC_GROUP(IIC2, IIC2_ALI2, IIC2_TACKI2, IIC2_WAITI2, IIC2_DTEI2),
+ INTC_GROUP(RTDMAC2_1,
+ RTDMAC2_1_DEI0, RTDMAC2_1_DEI1,
+ RTDMAC2_1_DEI2, RTDMAC2_1_DEI3),
+ INTC_GROUP(RTDMAC2_2, RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR),
+ INTC_GROUP(DSITX, DSITX_DSITX0, DSITX_DSITX1),
+ __IGNORE(INTC_GROUP(SPU2, SPU2_SPU0, SPU2_SPU1))
+ INTC_GROUP(TMU1, TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12),
+};
+
+static struct intc_mask_reg intcs_mask_registers[] __initdata = {
+ { 0xE6940184, 0xE69401C4, 8, /* IMR1AS / IMCR1AS */
+ { BEU_BEU2, BEU_BEU1, BEU_BEU0, CEU,
+ VEU_VEU3, VEU_VEU2, VEU_VEU1, VEU_VEU0 } },
+ { 0xE6940188, 0xE69401C8, 8, /* IMR2AS / IMCR2AS */
+ { 0, 0, 0, VPU,
+ __IGNORE0(BBIF2), 0, 0, __IGNORE0(MFI) } },
+ { 0xE694018C, 0xE69401CC, 8, /* IMR3AS / IMCR3AS */
+ { 0, 0, 0, _2DDMAC,
+ __IGNORE0(_2DG), ASA, PEP, ICB } },
+ { 0xE6940190, 0xE69401D0, 8, /* IMR4AS / IMCR4AS */
+ { 0, 0, MVI3, __IGNORE0(CTI),
+ JPU, HQE, __IGNORE0(LCRC), LCDC0 } },
+ { 0xE6940194, 0xE69401D4, 8, /* IMR5AS / IMCR5AS */
+ { __IGNORE0(KEYSC), RTDMAC1_2_DADERR, RTDMAC1_2_DEI5, RTDMAC1_2_DEI4,
+ RTDMAC1_1_DEI3, RTDMAC1_1_DEI2, RTDMAC1_1_DEI1, RTDMAC1_1_DEI0 } },
+ __IGNORE({ 0xE6940198, 0xE69401D8, 8, /* IMR6AS / IMCR6AS */
+ { 0, 0, MSIOF, 0,
+ SGX540, 0, TTI20, 0 } })
+ { 0xE694019C, 0xE69401DC, 8, /* IMR7AS / IMCR7AS */
+ { 0, TMU_TUNI2, TMU_TUNI1, TMU_TUNI0,
+ 0, 0, 0, 0 } },
+ __IGNORE({ 0xE69401A0, 0xE69401E0, 8, /* IMR8AS / IMCR8AS */
+ { 0, 0, 0, 0,
+ 0, MSU_MSU, MSU_MSU2, MSUG } })
+ { 0xE69401A4, 0xE69401E4, 8, /* IMR9AS / IMCR9AS */
+ { __IGNORE0(RWDT1), __IGNORE0(RWDT0), __IGNORE0(CMT2), CMT0,
+ IIC2_DTEI2, IIC2_WAITI2, IIC2_TACKI2, IIC2_ALI2 } },
+ { 0xE69401A8, 0xE69401E8, 8, /* IMR10AS / IMCR10AS */
+ { 0, 0, IPMMU_IPMMUR, IPMMU_IPMMUR2,
+ 0, 0, 0, 0 } },
+ { 0xE69401AC, 0xE69401EC, 8, /* IMR11AS / IMCR11AS */
+ { IIC0_DTEI0, IIC0_WAITI0, IIC0_TACKI0, IIC0_ALI0,
+ 0, TSIF1, LMB, TSIF0 } },
+ { 0xE6950180, 0xE69501C0, 8, /* IMR0AS3 / IMCR0AS3 */
+ { RTDMAC2_1_DEI0, RTDMAC2_1_DEI1, RTDMAC2_1_DEI2, RTDMAC2_1_DEI3,
+ RTDMAC2_2_DEI4, RTDMAC2_2_DEI5, RTDMAC2_2_DADERR, 0 } },
+ { 0xE6950190, 0xE69501D0, 8, /* IMR4AS3 / IMCR4AS3 */
+ { FRC, 0, 0, 0,
+ LCDC1, CSIRX, DSITX_DSITX0, DSITX_DSITX1 } },
+ __IGNORE({ 0xE6950194, 0xE69501D4, 8, /* IMR5AS3 / IMCR5AS3 */
+ {SPU2_SPU0, SPU2_SPU1, FSI, FMSI,
+ SCUV, 0, 0, 0 } })
+ { 0xE6950198, 0xE69501D8, 8, /* IMR6AS3 / IMCR6AS3 */
+ { TMU1_TUNI10, TMU1_TUNI11, TMU1_TUNI12, TSIF2,
+ CMT4, 0, 0, 0 } },
+ { 0xE695019C, 0xE69501DC, 8, /* IMR7AS3 / IMCR7AS3 */
+ { __IGNORE0(MFIS2), CPORTS2R, 0, 0,
+ 0, 0, 0, 0 } },
+ { 0xFFD20104, 0, 16, /* INTAMASK */
+ { 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, INTCS } }
+};
+
+static struct intc_prio_reg intcs_prio_registers[] __initdata = {
+ /* IPRAS */
+ { 0xFFD20000, 0, 16, 4, { __IGNORE0(CTI), MVI3, _2DDMAC, ICB } },
+ /* IPRBS */
+ { 0xFFD20004, 0, 16, 4, { JPU, LCDC0, 0, __IGNORE0(LCRC) } },
+ /* IPRCS */
+ __IGNORE({ 0xFFD20008, 0, 16, 4, { BBIF2, 0, 0, 0 } })
+ /* IPRES */
+ { 0xFFD20010, 0, 16, 4, { RTDMAC1_1, CEU, __IGNORE0(MFI), VPU } },
+ /* IPRFS */
+ { 0xFFD20014, 0, 16, 4,
+ { __IGNORE0(KEYSC), RTDMAC1_2, __IGNORE0(CMT2), CMT0 } },
+ /* IPRGS */
+ { 0xFFD20018, 0, 16, 4, { TMU_TUNI0, TMU_TUNI1, TMU_TUNI2, TSIF1 } },
+ /* IPRHS */
+ { 0xFFD2001C, 0, 16, 4, { __IGNORE0(TTI20), 0, VEU, BEU } },
+ /* IPRIS */
+ { 0xFFD20020, 0, 16, 4, { 0, __IGNORE0(MSIOF), TSIF0, IIC0 } },
+ /* IPRJS */
+ __IGNORE({ 0xFFD20024, 0, 16, 4, { 0, SGX540, MSUG, MSU } })
+ /* IPRKS */
+ { 0xFFD20028, 0, 16, 4, { __IGNORE0(_2DG), ASA, LMB, PEP } },
+ /* IPRLS */
+ { 0xFFD2002C, 0, 16, 4, { IPMMU, 0, 0, HQE } },
+ /* IPRMS */
+ { 0xFFD20030, 0, 16, 4,
+ { IIC2, 0, __IGNORE0(RWDT1), __IGNORE0(RWDT0) } },
+ /* IPRAS3 */
+ { 0xFFD50000, 0, 16, 4, { RTDMAC2_1, 0, 0, 0 } },
+ /* IPRBS3 */
+ { 0xFFD50004, 0, 16, 4, { RTDMAC2_2, 0, 0, 0 } },
+ /* IPRIS3 */
+ { 0xFFD50020, 0, 16, 4, { FRC, 0, 0, 0 } },
+ /* IPRJS3 */
+ { 0xFFD50024, 0, 16, 4, { LCDC1, CSIRX, DSITX, 0 } },
+ /* IPRKS3 */
+ __IGNORE({ 0xFFD50028, 0, 16, 4, { SPU2, 0, FSI, FMSI } })
+ /* IPRLS3 */
+ __IGNORE({ 0xFFD5002C, 0, 16, 4, { SCUV, 0, 0, 0 } })
+ /* IPRMS3 */
+ { 0xFFD50030, 0, 16, 4, { TMU1, 0, 0, TSIF2 } },
+ /* IPRNS3 */
+ { 0xFFD50034, 0, 16, 4, { CMT4, 0, 0, 0 } },
+ /* IPROS3 */
+ { 0xFFD50038, 0, 16, 4, { __IGNORE0(MFIS2), CPORTS2R, 0, 0 } },
+};
+
+static struct resource intcs_resources[] __initdata = {
+ [0] = {
+ .start = 0xffd20000,
+ .end = 0xffd500ff,
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct intc_desc intcs_desc __initdata = {
+ .name = "sh7377-intcs",
+ .resource = intcs_resources,
+ .num_resources = ARRAY_SIZE(intcs_resources),
+ .hw = INTC_HW_DESC(intcs_vectors, intcs_groups,
+ intcs_mask_registers, intcs_prio_registers,
+ NULL, NULL),
+};
+
+static void intcs_demux(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *reg = (void *)get_irq_data(irq);
+ unsigned int evtcodeas = ioread32(reg);
+
+ generic_handle_irq(intcs_evt2irq(evtcodeas));
+}
+
+#define INTEVTSA 0xFFD20100
void __init sh7377_init_irq(void)
{
+ void __iomem *intevtsa = ioremap_nocache(INTEVTSA, PAGE_SIZE);
+
register_intc_controller(&intca_desc);
+ register_intc_controller(&intcs_desc);
+
+ /* demux using INTEVTSA */
+ set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
+ set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
}
diff --git a/arch/arm/mach-shmobile/setup-sh7367.c b/arch/arm/mach-shmobile/setup-sh7367.c
index eca90716140e..3148c11a550e 100644
--- a/arch/arm/mach-shmobile/setup-sh7367.c
+++ b/arch/arm/mach-shmobile/setup-sh7367.c
@@ -31,11 +31,13 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+/* SCIFA0 */
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xe6c40000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 80, 80, 80, 80 },
+ .irqs = { evt2irq(0xc00), evt2irq(0xc00),
+ evt2irq(0xc00), evt2irq(0xc00) },
};
static struct platform_device scif0_device = {
@@ -46,11 +48,13 @@ static struct platform_device scif0_device = {
},
};
+/* SCIFA1 */
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xe6c50000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 81, 81, 81, 81 },
+ .irqs = { evt2irq(0xc20), evt2irq(0xc20),
+ evt2irq(0xc20), evt2irq(0xc20) },
};
static struct platform_device scif1_device = {
@@ -61,11 +65,13 @@ static struct platform_device scif1_device = {
},
};
+/* SCIFA2 */
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xe6c60000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 82, 82, 82, 82 },
+ .irqs = { evt2irq(0xc40), evt2irq(0xc40),
+ evt2irq(0xc40), evt2irq(0xc40) },
};
static struct platform_device scif2_device = {
@@ -76,11 +82,13 @@ static struct platform_device scif2_device = {
},
};
+/* SCIFA3 */
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xe6c70000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 83, 83, 83, 83 },
+ .irqs = { evt2irq(0xc60), evt2irq(0xc60),
+ evt2irq(0xc60), evt2irq(0xc60) },
};
static struct platform_device scif3_device = {
@@ -91,11 +99,13 @@ static struct platform_device scif3_device = {
},
};
+/* SCIFA4 */
static struct plat_sci_port scif4_platform_data = {
.mapbase = 0xe6c80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 89, 89, 89, 89 },
+ .irqs = { evt2irq(0xd20), evt2irq(0xd20),
+ evt2irq(0xd20), evt2irq(0xd20) },
};
static struct platform_device scif4_device = {
@@ -106,11 +116,13 @@ static struct platform_device scif4_device = {
},
};
+/* SCIFA5 */
static struct plat_sci_port scif5_platform_data = {
.mapbase = 0xe6cb0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 90, 90, 90, 90 },
+ .irqs = { evt2irq(0xd40), evt2irq(0xd40),
+ evt2irq(0xd40), evt2irq(0xd40) },
};
static struct platform_device scif5_device = {
@@ -121,11 +133,13 @@ static struct platform_device scif5_device = {
},
};
+/* SCIFB */
static struct plat_sci_port scif6_platform_data = {
.mapbase = 0xe6c30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 91, 91, 91, 91 },
+ .irqs = { evt2irq(0xd60), evt2irq(0xd60),
+ evt2irq(0xd60), evt2irq(0xd60) },
};
static struct platform_device scif6_device = {
@@ -153,7 +167,7 @@ static struct resource cmt10_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 72,
+ .start = evt2irq(0xb00), /* CMT1_CMT10 */
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index 1d1153290f59..e26686c9d0b6 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -26,17 +26,21 @@
#include <linux/input.h>
#include <linux/io.h>
#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
#include <linux/sh_timer.h>
#include <mach/hardware.h>
+#include <mach/sh7372.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+/* SCIFA0 */
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xe6c40000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 80, 80, 80, 80 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c00), evt2irq(0x0c00),
+ evt2irq(0x0c00), evt2irq(0x0c00) },
};
static struct platform_device scif0_device = {
@@ -47,11 +51,13 @@ static struct platform_device scif0_device = {
},
};
+/* SCIFA1 */
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xe6c50000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 81, 81, 81, 81 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c20), evt2irq(0x0c20),
+ evt2irq(0x0c20), evt2irq(0x0c20) },
};
static struct platform_device scif1_device = {
@@ -62,11 +68,13 @@ static struct platform_device scif1_device = {
},
};
+/* SCIFA2 */
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xe6c60000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 82, 82, 82, 82 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c40), evt2irq(0x0c40),
+ evt2irq(0x0c40), evt2irq(0x0c40) },
};
static struct platform_device scif2_device = {
@@ -77,11 +85,13 @@ static struct platform_device scif2_device = {
},
};
+/* SCIFA3 */
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xe6c70000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 83, 83, 83, 83 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0c60), evt2irq(0x0c60),
+ evt2irq(0x0c60), evt2irq(0x0c60) },
};
static struct platform_device scif3_device = {
@@ -92,11 +102,13 @@ static struct platform_device scif3_device = {
},
};
+/* SCIFA4 */
static struct plat_sci_port scif4_platform_data = {
.mapbase = 0xe6c80000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 89, 89, 89, 89 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0d20), evt2irq(0x0d20),
+ evt2irq(0x0d20), evt2irq(0x0d20) },
};
static struct platform_device scif4_device = {
@@ -107,11 +119,13 @@ static struct platform_device scif4_device = {
},
};
+/* SCIFA5 */
static struct plat_sci_port scif5_platform_data = {
.mapbase = 0xe6cb0000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 90, 90, 90, 90 },
+ .type = PORT_SCIFA,
+ .irqs = { evt2irq(0x0d40), evt2irq(0x0d40),
+ evt2irq(0x0d40), evt2irq(0x0d40) },
};
static struct platform_device scif5_device = {
@@ -122,11 +136,13 @@ static struct platform_device scif5_device = {
},
};
+/* SCIFB */
static struct plat_sci_port scif6_platform_data = {
.mapbase = 0xe6c30000,
.flags = UPF_BOOT_AUTOCONF,
- .type = PORT_SCIF,
- .irqs = { 91, 91, 91, 91 },
+ .type = PORT_SCIFB,
+ .irqs = { evt2irq(0x0d60), evt2irq(0x0d60),
+ evt2irq(0x0d60), evt2irq(0x0d60) },
};
static struct platform_device scif6_device = {
@@ -137,11 +153,12 @@ static struct platform_device scif6_device = {
},
};
+/* CMT */
static struct sh_timer_config cmt10_platform_data = {
.name = "CMT10",
.channel_offset = 0x10,
.timer_bit = 0,
- .clk = "r_clk",
+ .clk = "cmt1",
.clockevent_rating = 125,
.clocksource_rating = 125,
};
@@ -154,7 +171,7 @@ static struct resource cmt10_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 72,
+ .start = evt2irq(0x0b00), /* CMT1_CMT10 */
.flags = IORESOURCE_IRQ,
},
};
@@ -169,6 +186,337 @@ static struct platform_device cmt10_device = {
.num_resources = ARRAY_SIZE(cmt10_resources),
};
+/* I2C */
+static struct resource iic0_resources[] = {
+ [0] = {
+ .name = "IIC0",
+ .start = 0xFFF20000,
+ .end = 0xFFF20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0xe00), /* IIC0_ALI0 */
+ .end = intcs_evt2irq(0xe60), /* IIC0_DTEI0 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic0_device = {
+ .name = "i2c-sh_mobile",
+ .id = 0, /* "i2c0" clock */
+ .num_resources = ARRAY_SIZE(iic0_resources),
+ .resource = iic0_resources,
+};
+
+static struct resource iic1_resources[] = {
+ [0] = {
+ .name = "IIC1",
+ .start = 0xE6C20000,
+ .end = 0xE6C20425 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x780), /* IIC1_ALI1 */
+ .end = evt2irq(0x7e0), /* IIC1_DTEI1 */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device iic1_device = {
+ .name = "i2c-sh_mobile",
+ .id = 1, /* "i2c1" clock */
+ .num_resources = ARRAY_SIZE(iic1_resources),
+ .resource = iic1_resources,
+};
+
+/* DMA */
+/* Transmit sizes and respective CHCR register values */
+enum {
+ XMIT_SZ_8BIT = 0,
+ XMIT_SZ_16BIT = 1,
+ XMIT_SZ_32BIT = 2,
+ XMIT_SZ_64BIT = 7,
+ XMIT_SZ_128BIT = 3,
+ XMIT_SZ_256BIT = 4,
+ XMIT_SZ_512BIT = 5,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+#define TS_SHIFT { \
+ [XMIT_SZ_8BIT] = 0, \
+ [XMIT_SZ_16BIT] = 1, \
+ [XMIT_SZ_32BIT] = 2, \
+ [XMIT_SZ_64BIT] = 3, \
+ [XMIT_SZ_128BIT] = 4, \
+ [XMIT_SZ_256BIT] = 5, \
+ [XMIT_SZ_512BIT] = 6, \
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \
+ (((i) & 0xc) << (20 - 2)))
+
+static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SCIF0_TX,
+ .addr = 0xe6c40020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x21,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF0_RX,
+ .addr = 0xe6c40024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x22,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_TX,
+ .addr = 0xe6c50020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x25,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF1_RX,
+ .addr = 0xe6c50024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x26,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_TX,
+ .addr = 0xe6c60020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x29,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF2_RX,
+ .addr = 0xe6c60024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_TX,
+ .addr = 0xe6c70020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF3_RX,
+ .addr = 0xe6c70024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x2e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_TX,
+ .addr = 0xe6c80020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x39,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF4_RX,
+ .addr = 0xe6c80024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3a,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_TX,
+ .addr = 0xe6cb0020,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x35,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF5_RX,
+ .addr = 0xe6cb0024,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x36,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_TX,
+ .addr = 0xe6c30040,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3d,
+ }, {
+ .slave_id = SHDMA_SLAVE_SCIF6_RX,
+ .addr = 0xe6c30060,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .mid_rid = 0x3e,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xe6850030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xe6850030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xe6860030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xe6860030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xe6870030,
+ .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xe6870030,
+ .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ },
+};
+
+static const struct sh_dmae_channel sh7372_dmae_channels[] = {
+ {
+ .offset = 0,
+ .dmars = 0,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x10,
+ .dmars = 0,
+ .dmars_bit = 8,
+ }, {
+ .offset = 0x20,
+ .dmars = 4,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x30,
+ .dmars = 4,
+ .dmars_bit = 8,
+ }, {
+ .offset = 0x50,
+ .dmars = 8,
+ .dmars_bit = 0,
+ }, {
+ .offset = 0x60,
+ .dmars = 8,
+ .dmars_bit = 8,
+ }
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata dma_platform_data = {
+ .slave = sh7372_dmae_slaves,
+ .slave_num = ARRAY_SIZE(sh7372_dmae_slaves),
+ .channel = sh7372_dmae_channels,
+ .channel_num = ARRAY_SIZE(sh7372_dmae_channels),
+ .ts_low_shift = 3,
+ .ts_low_mask = 0x18,
+ .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
+ .ts_high_mask = 0x00300000,
+ .ts_shift = ts_shift,
+ .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .dmaor_init = DMAOR_DME,
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe008020,
+ .end = 0xfe00808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe009000,
+ .end = 0xfe00900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = 246,
+ .end = 246,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = 240,
+ .end = 245,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe018020,
+ .end = 0xfe01808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe019000,
+ .end = 0xfe01900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = 254,
+ .end = 254,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = 248,
+ .end = 253,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource sh7372_dmae2_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe028020,
+ .end = 0xfe02808f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe029000,
+ .end = 0xfe02900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMA error IRQ */
+ .start = 262,
+ .end = 262,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = 256,
+ .end = 261,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = sh7372_dmae0_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae0_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh7372_dmae1_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae1_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma2_device = {
+ .name = "sh-dma-engine",
+ .id = 2,
+ .resource = sh7372_dmae2_resources,
+ .num_resources = ARRAY_SIZE(sh7372_dmae2_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
static struct platform_device *sh7372_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
@@ -178,6 +526,11 @@ static struct platform_device *sh7372_early_devices[] __initdata = {
&scif5_device,
&scif6_device,
&cmt10_device,
+ &iic0_device,
+ &iic1_device,
+ &dma0_device,
+ &dma1_device,
+ &dma2_device,
};
void __init sh7372_add_standard_devices(void)
@@ -186,14 +539,8 @@ void __init sh7372_add_standard_devices(void)
ARRAY_SIZE(sh7372_early_devices));
}
-#define SMSTPCR3 0xe615013c
-#define SMSTPCR3_CMT1 (1 << 29)
-
void __init sh7372_add_early_devices(void)
{
- /* enable clock to CMT1 */
- __raw_writel(__raw_readl(SMSTPCR3) & ~SMSTPCR3_CMT1, SMSTPCR3);
-
early_platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
}
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index 60e37774c35c..bb4adf17dbf4 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -32,11 +32,13 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+/* SCIFA0 */
static struct plat_sci_port scif0_platform_data = {
.mapbase = 0xe6c40000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 80, 80, 80, 80 },
+ .irqs = { evt2irq(0xc00), evt2irq(0xc00),
+ evt2irq(0xc00), evt2irq(0xc00) },
};
static struct platform_device scif0_device = {
@@ -47,11 +49,13 @@ static struct platform_device scif0_device = {
},
};
+/* SCIFA1 */
static struct plat_sci_port scif1_platform_data = {
.mapbase = 0xe6c50000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 81, 81, 81, 81 },
+ .irqs = { evt2irq(0xc20), evt2irq(0xc20),
+ evt2irq(0xc20), evt2irq(0xc20) },
};
static struct platform_device scif1_device = {
@@ -62,11 +66,13 @@ static struct platform_device scif1_device = {
},
};
+/* SCIFA2 */
static struct plat_sci_port scif2_platform_data = {
.mapbase = 0xe6c60000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 82, 82, 82, 82 },
+ .irqs = { evt2irq(0xc40), evt2irq(0xc40),
+ evt2irq(0xc40), evt2irq(0xc40) },
};
static struct platform_device scif2_device = {
@@ -77,11 +83,13 @@ static struct platform_device scif2_device = {
},
};
+/* SCIFA3 */
static struct plat_sci_port scif3_platform_data = {
.mapbase = 0xe6c70000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 83, 83, 83, 83 },
+ .irqs = { evt2irq(0xc60), evt2irq(0xc60),
+ evt2irq(0xc60), evt2irq(0xc60) },
};
static struct platform_device scif3_device = {
@@ -92,11 +100,13 @@ static struct platform_device scif3_device = {
},
};
+/* SCIFA4 */
static struct plat_sci_port scif4_platform_data = {
.mapbase = 0xe6c80000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 89, 89, 89, 89 },
+ .irqs = { evt2irq(0xd20), evt2irq(0xd20),
+ evt2irq(0xd20), evt2irq(0xd20) },
};
static struct platform_device scif4_device = {
@@ -107,11 +117,13 @@ static struct platform_device scif4_device = {
},
};
+/* SCIFA5 */
static struct plat_sci_port scif5_platform_data = {
.mapbase = 0xe6cb0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 90, 90, 90, 90 },
+ .irqs = { evt2irq(0xd40), evt2irq(0xd40),
+ evt2irq(0xd40), evt2irq(0xd40) },
};
static struct platform_device scif5_device = {
@@ -122,11 +134,13 @@ static struct platform_device scif5_device = {
},
};
+/* SCIFA6 */
static struct plat_sci_port scif6_platform_data = {
.mapbase = 0xe6cc0000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 196, 196, 196, 196 },
+ .irqs = { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
+ intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
};
static struct platform_device scif6_device = {
@@ -137,11 +151,13 @@ static struct platform_device scif6_device = {
},
};
+/* SCIFB */
static struct plat_sci_port scif7_platform_data = {
.mapbase = 0xe6c30000,
.flags = UPF_BOOT_AUTOCONF,
.type = PORT_SCIF,
- .irqs = { 91, 91, 91, 91 },
+ .irqs = { evt2irq(0xd60), evt2irq(0xd60),
+ evt2irq(0xd60), evt2irq(0xd60) },
};
static struct platform_device scif7_device = {
@@ -169,7 +185,7 @@ static struct resource cmt10_resources[] = {
.flags = IORESOURCE_MEM,
},
[1] = {
- .start = 72,
+ .start = evt2irq(0xb00), /* CMT1_CMT10 */
.flags = IORESOURCE_IRQ,
},
};
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
new file mode 100644
index 000000000000..a57713c1954a
--- /dev/null
+++ b/arch/arm/mach-tegra/Kconfig
@@ -0,0 +1,50 @@
+if ARCH_TEGRA
+
+comment "NVIDIA Tegra options"
+
+choice
+ prompt "Select Tegra processor family for target system"
+
+config ARCH_TEGRA_2x_SOC
+ bool "Tegra 2 family"
+ select CPU_V7
+ select ARM_GIC
+ select ARCH_REQUIRE_GPIOLIB
+ help
+ Support for NVIDIA Tegra AP20 and T20 processors, based on the
+ ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
+
+endchoice
+
+comment "Tegra board type"
+
+config MACH_HARMONY
+ bool "Harmony board"
+ help
+ Support for nVidia Harmony development platform
+
+choice
+ prompt "Low-level debug console UART"
+ default TEGRA_DEBUG_UART_NONE
+
+config TEGRA_DEBUG_UART_NONE
+ bool "None"
+
+config TEGRA_DEBUG_UARTA
+ bool "UART-A"
+
+config TEGRA_DEBUG_UARTB
+ bool "UART-B"
+
+config TEGRA_DEBUG_UARTC
+ bool "UART-C"
+
+config TEGRA_DEBUG_UARTD
+ bool "UART-D"
+
+config TEGRA_DEBUG_UARTE
+ bool "UART-E"
+
+endchoice
+
+endif
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
new file mode 100644
index 000000000000..51e9370eed99
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile
@@ -0,0 +1,14 @@
+obj-y += common.o
+obj-y += io.o
+obj-y += irq.o
+obj-y += clock.o
+obj-y += timer.o
+obj-y += gpio.o
+obj-y += pinmux.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += clock.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
+obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
+obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
+
+obj-${CONFIG_MACH_HARMONY} += board-harmony.o
+obj-${CONFIG_MACH_HARMONY} += board-harmony-pinmux.o
diff --git a/arch/arm/mach-tegra/Makefile.boot b/arch/arm/mach-tegra/Makefile.boot
new file mode 100644
index 000000000000..db52d61a7386
--- /dev/null
+++ b/arch/arm/mach-tegra/Makefile.boot
@@ -0,0 +1,3 @@
+zreladdr-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00008000
+params_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00000100
+initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
diff --git a/arch/arm/mach-tegra/board-harmony-pinmux.c b/arch/arm/mach-tegra/board-harmony-pinmux.c
new file mode 100644
index 000000000000..50b15d500cac
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony-pinmux.c
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/mach-tegra/board-harmony-pinmux.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <mach/pinmux.h>
+
+#include "board-harmony.h"
+
+static struct tegra_pingroup_config harmony_pinmux[] = {
+ {TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATB, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATC, TEGRA_MUX_NAND, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_ATE, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_PLLP_OUT4, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CRTP, TEGRA_MUX_CRT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CSUS, TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP1, TEGRA_MUX_DAP1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP2, TEGRA_MUX_DAP2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DAP4, TEGRA_MUX_DAP4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DDC, TEGRA_MUX_I2C2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DTA, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTB, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTC, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTD, TEGRA_MUX_SDIO2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTE, TEGRA_MUX_RSVD1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_DTF, TEGRA_MUX_I2C3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GMA, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMB, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMC, TEGRA_MUX_UARTD, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GMD, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GME, TEGRA_MUX_SDIO4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPU, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_GPU7, TEGRA_MUX_RTCK, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_GPV, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_I2CP, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_IRRX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_IRTX, TEGRA_MUX_UARTA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_KBCA, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCB, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCC, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCD, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCE, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_KBCF, TEGRA_MUX_KBC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LCSN, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LD0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD10, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD11, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD12, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD13, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD14, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD15, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD16, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD17, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD3, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD4, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD5, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD6, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD7, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD8, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LD9, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LDC, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHP2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LHS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LM1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPP, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LPW1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LPW2, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LSC1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSCK, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDA, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSDI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LSPI, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVP0, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_LVP1, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_LVS, TEGRA_MUX_DISPLAYA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_OWC, TEGRA_MUX_RSVD2, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_PMC, TEGRA_MUX_PWR_ON, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PTA, TEGRA_MUX_HDMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_RM, TEGRA_MUX_I2C, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDB, TEGRA_MUX_PWM, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDC, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SDD, TEGRA_MUX_PWM, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXA, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXC, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXD, TEGRA_MUX_SPDIF, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SLXK, TEGRA_MUX_PCIE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDI, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPDO, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIB, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_SPID, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIE, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIF, TEGRA_MUX_SPI1, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_SPIH, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAA, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAB, TEGRA_MUX_ULPI, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UAD, TEGRA_MUX_IRDA, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCA, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UCB, TEGRA_MUX_UARTC, TEGRA_PUPD_PULL_UP, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_UDA, TEGRA_MUX_ULPI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
+ {TEGRA_PINGROUP_CK32, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_DDRC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCA, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCB, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCC, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCD, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_PMCE, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2C, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+ {TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
+};
+
+void harmony_pinmux_init(void)
+{
+ tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
+}
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
new file mode 100644
index 000000000000..05e78dd9b50c
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -0,0 +1,127 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/pda_power.h>
+#include <linux/io.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+
+#include "board.h"
+#include "board-harmony.h"
+#include "clock.h"
+
+/* NVidia bootloader tags */
+#define ATAG_NVIDIA 0x41000801
+
+#define ATAG_NVIDIA_RM 0x1
+#define ATAG_NVIDIA_DISPLAY 0x2
+#define ATAG_NVIDIA_FRAMEBUFFER 0x3
+#define ATAG_NVIDIA_CHIPSHMOO 0x4
+#define ATAG_NVIDIA_CHIPSHMOOPHYS 0x5
+#define ATAG_NVIDIA_PRESERVED_MEM_0 0x10000
+#define ATAG_NVIDIA_PRESERVED_MEM_N 2
+#define ATAG_NVIDIA_FORCE_32 0x7fffffff
+
+struct tag_tegra {
+ __u32 bootarg_key;
+ __u32 bootarg_len;
+ char bootarg[1];
+};
+
+static int __init parse_tag_nvidia(const struct tag *tag)
+{
+
+ return 0;
+}
+__tagtable(ATAG_NVIDIA, parse_tag_nvidia);
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+ {
+ .membase = IO_ADDRESS(TEGRA_UARTD_BASE),
+ .mapbase = TEGRA_UARTD_BASE,
+ .irq = INT_UARTD,
+ .flags = UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 216000000,
+ }, {
+ .flags = 0
+ }
+};
+
+static struct platform_device debug_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = debug_uart_platform_data,
+ },
+};
+
+static struct platform_device *harmony_devices[] __initdata = {
+ &debug_uart,
+};
+
+static void __init tegra_harmony_fixup(struct machine_desc *desc,
+ struct tag *tags, char **cmdline, struct meminfo *mi)
+{
+ mi->nr_banks = 2;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+ mi->bank[0].size = 448 * SZ_1M;
+ mi->bank[1].start = SZ_512M;
+ mi->bank[1].node = PHYS_TO_NID(SZ_512M);
+ mi->bank[1].size = SZ_512M;
+}
+
+static __initdata struct tegra_clk_init_table harmony_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "uartd", "pll_p", 216000000, true },
+ { NULL, NULL, 0, 0},
+};
+
+static void __init tegra_harmony_init(void)
+{
+ tegra_common_init();
+
+ tegra_clk_init_from_table(harmony_clk_init_table);
+
+ harmony_pinmux_init();
+
+ platform_add_devices(harmony_devices, ARRAY_SIZE(harmony_devices));
+}
+
+MACHINE_START(HARMONY, "harmony")
+ .boot_params = 0x00000100,
+ .phys_io = IO_APB_PHYS,
+ .io_pg_offst = ((IO_APB_VIRT) >> 18) & 0xfffc,
+ .fixup = tegra_harmony_fixup,
+ .init_irq = tegra_init_irq,
+ .init_machine = tegra_harmony_init,
+ .map_io = tegra_map_common_io,
+ .timer = &tegra_timer,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-harmony.h b/arch/arm/mach-tegra/board-harmony.h
new file mode 100644
index 000000000000..09ca7755dd55
--- /dev/null
+++ b/arch/arm/mach-tegra/board-harmony.h
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _MACH_TEGRA_BOARD_HARMONY_H
+#define _MACH_TEGRA_BOARD_HARMONY_H
+
+void harmony_pinmux_init(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/board.h b/arch/arm/mach-tegra/board.h
new file mode 100644
index 000000000000..3d06354136f2
--- /dev/null
+++ b/arch/arm/mach-tegra/board.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-tegra/board.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_BOARD_H
+#define __MACH_TEGRA_BOARD_H
+
+#include <linux/types.h>
+
+void __init tegra_common_init(void);
+void __init tegra_map_common_io(void);
+void __init tegra_init_irq(void);
+void __init tegra_init_clock(void);
+
+extern struct sys_timer tegra_timer;
+#endif
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
new file mode 100644
index 000000000000..03ad578349b9
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.c
@@ -0,0 +1,488 @@
+/*
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/list.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/seq_file.h>
+#include <asm/clkdev.h>
+
+#include "clock.h"
+
+static LIST_HEAD(clocks);
+
+static DEFINE_SPINLOCK(clock_lock);
+
+struct clk *tegra_get_clock_by_name(const char *name)
+{
+ struct clk *c;
+ struct clk *ret = NULL;
+ unsigned long flags;
+ spin_lock_irqsave(&clock_lock, flags);
+ list_for_each_entry(c, &clocks, node) {
+ if (strcmp(c->name, name) == 0) {
+ ret = c;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&clock_lock, flags);
+ return ret;
+}
+
+int clk_reparent(struct clk *c, struct clk *parent)
+{
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->refcnt && c->parent)
+ clk_disable_locked(c->parent);
+ c->parent = parent;
+ if (c->refcnt && c->parent)
+ clk_enable_locked(c->parent);
+ list_del(&c->sibling);
+ list_add_tail(&c->sibling, &parent->children);
+ return 0;
+}
+
+static void propagate_rate(struct clk *c)
+{
+ struct clk *clkp;
+ pr_debug("%s: %s\n", __func__, c->name);
+ list_for_each_entry(clkp, &c->children, sibling) {
+ pr_debug(" %s\n", clkp->name);
+ if (clkp->ops->recalculate_rate)
+ clkp->ops->recalculate_rate(clkp);
+ propagate_rate(clkp);
+ }
+}
+
+void clk_init(struct clk *c)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&clock_lock, flags);
+
+ INIT_LIST_HEAD(&c->children);
+ INIT_LIST_HEAD(&c->sibling);
+
+ if (c->ops && c->ops->init)
+ c->ops->init(c);
+
+ list_add(&c->node, &clocks);
+
+ if (c->parent)
+ list_add_tail(&c->sibling, &c->parent->children);
+
+ spin_unlock_irqrestore(&clock_lock, flags);
+}
+
+int clk_enable_locked(struct clk *c)
+{
+ int ret;
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->refcnt == 0) {
+ if (c->parent) {
+ ret = clk_enable_locked(c->parent);
+ if (ret)
+ return ret;
+ }
+
+ if (c->ops && c->ops->enable) {
+ ret = c->ops->enable(c);
+ if (ret) {
+ if (c->parent)
+ clk_disable_locked(c->parent);
+ return ret;
+ }
+ c->state = ON;
+#ifdef CONFIG_DEBUG_FS
+ c->set = 1;
+#endif
+ }
+ }
+ c->refcnt++;
+
+ return 0;
+}
+
+int clk_enable(struct clk *c)
+{
+ int ret;
+ unsigned long flags;
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk_enable_locked(c);
+ spin_unlock_irqrestore(&clock_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable_locked(struct clk *c)
+{
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->refcnt == 0) {
+ WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
+ return;
+ }
+ if (c->refcnt == 1) {
+ if (c->ops && c->ops->disable)
+ c->ops->disable(c);
+
+ if (c->parent)
+ clk_disable_locked(c->parent);
+
+ c->state = OFF;
+ }
+ c->refcnt--;
+}
+
+void clk_disable(struct clk *c)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&clock_lock, flags);
+ clk_disable_locked(c);
+ spin_unlock_irqrestore(&clock_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+int clk_set_parent_locked(struct clk *c, struct clk *parent)
+{
+ int ret;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ if (!c->ops || !c->ops->set_parent)
+ return -ENOSYS;
+
+ ret = c->ops->set_parent(c, parent);
+
+ if (ret)
+ return ret;
+
+ propagate_rate(c);
+
+ return 0;
+}
+
+int clk_set_parent(struct clk *c, struct clk *parent)
+{
+ int ret;
+ unsigned long flags;
+ spin_lock_irqsave(&clock_lock, flags);
+ ret = clk_set_parent_locked(c, parent);
+ spin_unlock_irqrestore(&clock_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+struct clk *clk_get_parent(struct clk *c)
+{
+ return c->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
+int clk_set_rate(struct clk *c, unsigned long rate)
+{
+ int ret = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&clock_lock, flags);
+
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ if (c->ops && c->ops->set_rate)
+ ret = c->ops->set_rate(c, rate);
+ else
+ ret = -ENOSYS;
+
+ propagate_rate(c);
+
+ spin_unlock_irqrestore(&clock_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+unsigned long clk_get_rate(struct clk *c)
+{
+ unsigned long flags;
+ unsigned long ret;
+
+ spin_lock_irqsave(&clock_lock, flags);
+
+ pr_debug("%s: %s\n", __func__, c->name);
+
+ ret = c->rate;
+
+ spin_unlock_irqrestore(&clock_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
+{
+ struct clk *c;
+ struct clk *p;
+
+ int ret = 0;
+
+ c = tegra_get_clock_by_name(table->name);
+
+ if (!c) {
+ pr_warning("Unable to initialize clock %s\n",
+ table->name);
+ return -ENODEV;
+ }
+
+ if (table->parent) {
+ p = tegra_get_clock_by_name(table->parent);
+ if (!p) {
+ pr_warning("Unable to find parent %s of clock %s\n",
+ table->parent, table->name);
+ return -ENODEV;
+ }
+
+ if (c->parent != p) {
+ ret = clk_set_parent(c, p);
+ if (ret) {
+ pr_warning("Unable to set parent %s of clock %s: %d\n",
+ table->parent, table->name, ret);
+ return -EINVAL;
+ }
+ }
+ }
+
+ if (table->rate && table->rate != clk_get_rate(c)) {
+ ret = clk_set_rate(c, table->rate);
+ if (ret) {
+ pr_warning("Unable to set clock %s to rate %lu: %d\n",
+ table->name, table->rate, ret);
+ return -EINVAL;
+ }
+ }
+
+ if (table->enabled) {
+ ret = clk_enable(c);
+ if (ret) {
+ pr_warning("Unable to enable clock %s: %d\n",
+ table->name, ret);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
+{
+ for (; table->name; table++)
+ tegra_clk_init_one_from_table(table);
+}
+EXPORT_SYMBOL(tegra_clk_init_from_table);
+
+void tegra_periph_reset_deassert(struct clk *c)
+{
+ tegra2_periph_reset_deassert(c);
+}
+EXPORT_SYMBOL(tegra_periph_reset_deassert);
+
+void tegra_periph_reset_assert(struct clk *c)
+{
+ tegra2_periph_reset_assert(c);
+}
+EXPORT_SYMBOL(tegra_periph_reset_assert);
+
+int __init tegra_init_clock(void)
+{
+ tegra2_init_clocks();
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *clk_debugfs_root;
+
+
+static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
+{
+ struct clk *child;
+ struct clk *safe;
+ const char *state = "uninit";
+ char div[5] = {0};
+
+ if (c->state == ON)
+ state = "on";
+ else if (c->state == OFF)
+ state = "off";
+
+ if (c->mul != 0 && c->div != 0) {
+ BUG_ON(c->mul > 2);
+ if (c->mul > c->div)
+ snprintf(div, sizeof(div), "x%d", c->mul / c->div);
+ else
+ snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
+ (c->div % c->mul) ? ".5" : "");
+ }
+
+ seq_printf(s, "%*s%-*s %-6s %-3d %-5s %-10lu\n",
+ level * 3 + 1, c->set ? "" : "*",
+ 30 - level * 3, c->name,
+ state, c->refcnt, div, c->rate);
+ list_for_each_entry_safe(child, safe, &c->children, sibling) {
+ clock_tree_show_one(s, child, level + 1);
+ }
+}
+
+static int clock_tree_show(struct seq_file *s, void *data)
+{
+ struct clk *c;
+ unsigned long flags;
+ seq_printf(s, " clock state ref div rate \n");
+ seq_printf(s, "-----------------------------------------------------------\n");
+ spin_lock_irqsave(&clock_lock, flags);
+ list_for_each_entry(c, &clocks, node)
+ if (c->parent == NULL)
+ clock_tree_show_one(s, c, 0);
+ spin_unlock_irqrestore(&clock_lock, flags);
+ return 0;
+}
+
+static int clock_tree_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, clock_tree_show, inode->i_private);
+}
+
+static const struct file_operations clock_tree_fops = {
+ .open = clock_tree_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int possible_parents_show(struct seq_file *s, void *data)
+{
+ struct clk *c = s->private;
+ int i;
+
+ for (i = 0; c->inputs[i].input; i++) {
+ char *first = (i == 0) ? "" : " ";
+ seq_printf(s, "%s%s", first, c->inputs[i].input->name);
+ }
+ seq_printf(s, "\n");
+ return 0;
+}
+
+static int possible_parents_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, possible_parents_show, inode->i_private);
+}
+
+static const struct file_operations possible_parents_fops = {
+ .open = possible_parents_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int clk_debugfs_register_one(struct clk *c)
+{
+ struct dentry *d, *child, *child_tmp;
+
+ d = debugfs_create_dir(c->name, clk_debugfs_root);
+ if (!d)
+ return -ENOMEM;
+ c->dent = d;
+
+ d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
+ if (!d)
+ goto err_out;
+
+ d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
+ if (!d)
+ goto err_out;
+
+ d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
+ if (!d)
+ goto err_out;
+
+ if (c->inputs) {
+ d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
+ c, &possible_parents_fops);
+ if (!d)
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ d = c->dent;
+ list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
+ debugfs_remove(child);
+ debugfs_remove(c->dent);
+ return -ENOMEM;
+}
+
+static int clk_debugfs_register(struct clk *c)
+{
+ int err;
+ struct clk *pa = c->parent;
+
+ if (pa && !pa->dent) {
+ err = clk_debugfs_register(pa);
+ if (err)
+ return err;
+ }
+
+ if (!c->dent) {
+ err = clk_debugfs_register_one(c);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int __init clk_debugfs_init(void)
+{
+ struct clk *c;
+ struct dentry *d;
+ int err = -ENOMEM;
+
+ d = debugfs_create_dir("clock", NULL);
+ if (!d)
+ return -ENOMEM;
+ clk_debugfs_root = d;
+
+ d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
+ &clock_tree_fops);
+ if (!d)
+ goto err_out;
+
+ list_for_each_entry(c, &clocks, node) {
+ err = clk_debugfs_register(c);
+ if (err)
+ goto err_out;
+ }
+ return 0;
+err_out:
+ debugfs_remove_recursive(clk_debugfs_root);
+ return err;
+}
+
+late_initcall(clk_debugfs_init);
+#endif
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
new file mode 100644
index 000000000000..af7c70e2a3ba
--- /dev/null
+++ b/arch/arm/mach-tegra/clock.h
@@ -0,0 +1,147 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clock.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_CLOCK_H
+#define __MACH_TEGRA_CLOCK_H
+
+#include <linux/list.h>
+#include <asm/clkdev.h>
+
+#define DIV_BUS (1 << 0)
+#define DIV_U71 (1 << 1)
+#define DIV_U71_FIXED (1 << 2)
+#define DIV_2 (1 << 3)
+#define PLL_FIXED (1 << 4)
+#define PLL_HAS_CPCON (1 << 5)
+#define MUX (1 << 6)
+#define PLLD (1 << 7)
+#define PERIPH_NO_RESET (1 << 8)
+#define PERIPH_NO_ENB (1 << 9)
+#define PERIPH_EMC_ENB (1 << 10)
+#define PERIPH_MANUAL_RESET (1 << 11)
+#define PLL_ALT_MISC_REG (1 << 12)
+#define ENABLE_ON_INIT (1 << 28)
+
+struct clk;
+
+struct clk_mux_sel {
+ struct clk *input;
+ u32 value;
+};
+
+struct clk_pll_table {
+ unsigned long input_rate;
+ unsigned long output_rate;
+ u16 n;
+ u16 m;
+ u8 p;
+ u8 cpcon;
+};
+
+struct clk_ops {
+ void (*init)(struct clk *);
+ int (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+ void (*recalc)(struct clk *);
+ int (*set_parent)(struct clk *, struct clk *);
+ int (*set_rate)(struct clk *, unsigned long);
+ unsigned long (*get_rate)(struct clk *);
+ long (*round_rate)(struct clk *, unsigned long);
+ unsigned long (*recalculate_rate)(struct clk *);
+};
+
+enum clk_state {
+ UNINITIALIZED = 0,
+ ON,
+ OFF,
+};
+
+struct clk {
+ /* node for master clocks list */
+ struct list_head node;
+ struct list_head children; /* list of children */
+ struct list_head sibling; /* node for children */
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *dent;
+ struct dentry *parent_dent;
+#endif
+ struct clk_ops *ops;
+ struct clk *parent;
+ struct clk_lookup lookup;
+ unsigned long rate;
+ u32 flags;
+ u32 refcnt;
+ const char *name;
+ u32 reg;
+ u32 reg_shift;
+ unsigned int clk_num;
+ enum clk_state state;
+#ifdef CONFIG_DEBUG_FS
+ bool set;
+#endif
+
+ /* PLL */
+ unsigned long input_min;
+ unsigned long input_max;
+ unsigned long cf_min;
+ unsigned long cf_max;
+ unsigned long vco_min;
+ unsigned long vco_max;
+ u32 m;
+ u32 n;
+ u32 p;
+ u32 cpcon;
+ const struct clk_pll_table *pll_table;
+
+ /* DIV */
+ u32 div;
+ u32 mul;
+
+ /* MUX */
+ const struct clk_mux_sel *inputs;
+ u32 sel;
+ u32 reg_mask;
+};
+
+
+struct clk_duplicate {
+ const char *name;
+ struct clk_lookup lookup;
+};
+
+struct tegra_clk_init_table {
+ const char *name;
+ const char *parent;
+ unsigned long rate;
+ bool enabled;
+};
+
+void tegra2_init_clocks(void);
+void tegra2_periph_reset_deassert(struct clk *c);
+void tegra2_periph_reset_assert(struct clk *c);
+void clk_init(struct clk *clk);
+struct clk *tegra_get_clock_by_name(const char *name);
+unsigned long clk_measure_input_freq(void);
+void clk_disable_locked(struct clk *c);
+int clk_enable_locked(struct clk *c);
+int clk_set_parent_locked(struct clk *c, struct clk *parent);
+int clk_reparent(struct clk *c, struct clk *parent);
+void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
+
+#endif
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
new file mode 100644
index 000000000000..039a514b61ef
--- /dev/null
+++ b/arch/arm/mach-tegra/common.c
@@ -0,0 +1,61 @@
+/*
+ * arch/arm/mach-tegra/board-harmony.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@android.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/iomap.h>
+
+#include "board.h"
+#include "clock.h"
+
+static __initdata struct tegra_clk_init_table common_clk_init_table[] = {
+ /* name parent rate enabled */
+ { "clk_m", NULL, 0, true },
+ { "pll_p", "clk_m", 216000000, true },
+ { "pll_p_out1", "pll_p", 28800000, true },
+ { "pll_p_out2", "pll_p", 48000000, true },
+ { "pll_p_out3", "pll_p", 72000000, true },
+ { "pll_p_out4", "pll_p", 108000000, true },
+ { "sys", "pll_p_out4", 108000000, true },
+ { "hclk", "sys", 108000000, true },
+ { "pclk", "hclk", 54000000, true },
+ { NULL, NULL, 0, 0},
+};
+
+void __init tegra_init_cache(void)
+{
+#ifdef CONFIG_CACHE_L2X0
+ void __iomem *p = IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x3000;
+
+ writel(0x331, p + L2X0_TAG_LATENCY_CTRL);
+ writel(0x441, p + L2X0_DATA_LATENCY_CTRL);
+
+ l2x0_init(p, 0x6C080001, 0x8200c3fe);
+#endif
+}
+
+void __init tegra_common_init(void)
+{
+ tegra_init_clock();
+ tegra_clk_init_from_table(common_clk_init_table);
+ tegra_init_cache();
+}
diff --git a/arch/arm/mach-tegra/gpio-names.h b/arch/arm/mach-tegra/gpio-names.h
new file mode 100644
index 000000000000..f28220a641b2
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio-names.h
@@ -0,0 +1,247 @@
+/*
+ * arch/arm/mach-tegra/include/mach/gpio-names.h
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_TEGRA_GPIO_NAMES_H
+#define __MACH_TEGRA_GPIO_NAMES_H
+
+#define TEGRA_GPIO_PA0 0
+#define TEGRA_GPIO_PA1 1
+#define TEGRA_GPIO_PA2 2
+#define TEGRA_GPIO_PA3 3
+#define TEGRA_GPIO_PA4 4
+#define TEGRA_GPIO_PA5 5
+#define TEGRA_GPIO_PA6 6
+#define TEGRA_GPIO_PA7 7
+#define TEGRA_GPIO_PB0 8
+#define TEGRA_GPIO_PB1 9
+#define TEGRA_GPIO_PB2 10
+#define TEGRA_GPIO_PB3 11
+#define TEGRA_GPIO_PB4 12
+#define TEGRA_GPIO_PB5 13
+#define TEGRA_GPIO_PB6 14
+#define TEGRA_GPIO_PB7 15
+#define TEGRA_GPIO_PC0 16
+#define TEGRA_GPIO_PC1 17
+#define TEGRA_GPIO_PC2 18
+#define TEGRA_GPIO_PC3 19
+#define TEGRA_GPIO_PC4 20
+#define TEGRA_GPIO_PC5 21
+#define TEGRA_GPIO_PC6 22
+#define TEGRA_GPIO_PC7 23
+#define TEGRA_GPIO_PD0 24
+#define TEGRA_GPIO_PD1 25
+#define TEGRA_GPIO_PD2 26
+#define TEGRA_GPIO_PD3 27
+#define TEGRA_GPIO_PD4 28
+#define TEGRA_GPIO_PD5 29
+#define TEGRA_GPIO_PD6 30
+#define TEGRA_GPIO_PD7 31
+#define TEGRA_GPIO_PE0 32
+#define TEGRA_GPIO_PE1 33
+#define TEGRA_GPIO_PE2 34
+#define TEGRA_GPIO_PE3 35
+#define TEGRA_GPIO_PE4 36
+#define TEGRA_GPIO_PE5 37
+#define TEGRA_GPIO_PE6 38
+#define TEGRA_GPIO_PE7 39
+#define TEGRA_GPIO_PF0 40
+#define TEGRA_GPIO_PF1 41
+#define TEGRA_GPIO_PF2 42
+#define TEGRA_GPIO_PF3 43
+#define TEGRA_GPIO_PF4 44
+#define TEGRA_GPIO_PF5 45
+#define TEGRA_GPIO_PF6 46
+#define TEGRA_GPIO_PF7 47
+#define TEGRA_GPIO_PG0 48
+#define TEGRA_GPIO_PG1 49
+#define TEGRA_GPIO_PG2 50
+#define TEGRA_GPIO_PG3 51
+#define TEGRA_GPIO_PG4 52
+#define TEGRA_GPIO_PG5 53
+#define TEGRA_GPIO_PG6 54
+#define TEGRA_GPIO_PG7 55
+#define TEGRA_GPIO_PH0 56
+#define TEGRA_GPIO_PH1 57
+#define TEGRA_GPIO_PH2 58
+#define TEGRA_GPIO_PH3 59
+#define TEGRA_GPIO_PH4 60
+#define TEGRA_GPIO_PH5 61
+#define TEGRA_GPIO_PH6 62
+#define TEGRA_GPIO_PH7 63
+#define TEGRA_GPIO_PI0 64
+#define TEGRA_GPIO_PI1 65
+#define TEGRA_GPIO_PI2 66
+#define TEGRA_GPIO_PI3 67
+#define TEGRA_GPIO_PI4 68
+#define TEGRA_GPIO_PI5 69
+#define TEGRA_GPIO_PI6 70
+#define TEGRA_GPIO_PI7 71
+#define TEGRA_GPIO_PJ0 72
+#define TEGRA_GPIO_PJ1 73
+#define TEGRA_GPIO_PJ2 74
+#define TEGRA_GPIO_PJ3 75
+#define TEGRA_GPIO_PJ4 76
+#define TEGRA_GPIO_PJ5 77
+#define TEGRA_GPIO_PJ6 78
+#define TEGRA_GPIO_PJ7 79
+#define TEGRA_GPIO_PK0 80
+#define TEGRA_GPIO_PK1 81
+#define TEGRA_GPIO_PK2 82
+#define TEGRA_GPIO_PK3 83
+#define TEGRA_GPIO_PK4 84
+#define TEGRA_GPIO_PK5 85
+#define TEGRA_GPIO_PK6 86
+#define TEGRA_GPIO_PK7 87
+#define TEGRA_GPIO_PL0 88
+#define TEGRA_GPIO_PL1 89
+#define TEGRA_GPIO_PL2 90
+#define TEGRA_GPIO_PL3 91
+#define TEGRA_GPIO_PL4 92
+#define TEGRA_GPIO_PL5 93
+#define TEGRA_GPIO_PL6 94
+#define TEGRA_GPIO_PL7 95
+#define TEGRA_GPIO_PM0 96
+#define TEGRA_GPIO_PM1 97
+#define TEGRA_GPIO_PM2 98
+#define TEGRA_GPIO_PM3 99
+#define TEGRA_GPIO_PM4 100
+#define TEGRA_GPIO_PM5 101
+#define TEGRA_GPIO_PM6 102
+#define TEGRA_GPIO_PM7 103
+#define TEGRA_GPIO_PN0 104
+#define TEGRA_GPIO_PN1 105
+#define TEGRA_GPIO_PN2 106
+#define TEGRA_GPIO_PN3 107
+#define TEGRA_GPIO_PN4 108
+#define TEGRA_GPIO_PN5 109
+#define TEGRA_GPIO_PN6 110
+#define TEGRA_GPIO_PN7 111
+#define TEGRA_GPIO_PO0 112
+#define TEGRA_GPIO_PO1 113
+#define TEGRA_GPIO_PO2 114
+#define TEGRA_GPIO_PO3 115
+#define TEGRA_GPIO_PO4 116
+#define TEGRA_GPIO_PO5 117
+#define TEGRA_GPIO_PO6 118
+#define TEGRA_GPIO_PO7 119
+#define TEGRA_GPIO_PP0 120
+#define TEGRA_GPIO_PP1 121
+#define TEGRA_GPIO_PP2 122
+#define TEGRA_GPIO_PP3 123
+#define TEGRA_GPIO_PP4 124
+#define TEGRA_GPIO_PP5 125
+#define TEGRA_GPIO_PP6 126
+#define TEGRA_GPIO_PP7 127
+#define TEGRA_GPIO_PQ0 128
+#define TEGRA_GPIO_PQ1 129
+#define TEGRA_GPIO_PQ2 130
+#define TEGRA_GPIO_PQ3 131
+#define TEGRA_GPIO_PQ4 132
+#define TEGRA_GPIO_PQ5 133
+#define TEGRA_GPIO_PQ6 134
+#define TEGRA_GPIO_PQ7 135
+#define TEGRA_GPIO_PR0 136
+#define TEGRA_GPIO_PR1 137
+#define TEGRA_GPIO_PR2 138
+#define TEGRA_GPIO_PR3 139
+#define TEGRA_GPIO_PR4 140
+#define TEGRA_GPIO_PR5 141
+#define TEGRA_GPIO_PR6 142
+#define TEGRA_GPIO_PR7 143
+#define TEGRA_GPIO_PS0 144
+#define TEGRA_GPIO_PS1 145
+#define TEGRA_GPIO_PS2 146
+#define TEGRA_GPIO_PS3 147
+#define TEGRA_GPIO_PS4 148
+#define TEGRA_GPIO_PS5 149
+#define TEGRA_GPIO_PS6 150
+#define TEGRA_GPIO_PS7 151
+#define TEGRA_GPIO_PT0 152
+#define TEGRA_GPIO_PT1 153
+#define TEGRA_GPIO_PT2 154
+#define TEGRA_GPIO_PT3 155
+#define TEGRA_GPIO_PT4 156
+#define TEGRA_GPIO_PT5 157
+#define TEGRA_GPIO_PT6 158
+#define TEGRA_GPIO_PT7 159
+#define TEGRA_GPIO_PU0 160
+#define TEGRA_GPIO_PU1 161
+#define TEGRA_GPIO_PU2 162
+#define TEGRA_GPIO_PU3 163
+#define TEGRA_GPIO_PU4 164
+#define TEGRA_GPIO_PU5 165
+#define TEGRA_GPIO_PU6 166
+#define TEGRA_GPIO_PU7 167
+#define TEGRA_GPIO_PV0 168
+#define TEGRA_GPIO_PV1 169
+#define TEGRA_GPIO_PV2 170
+#define TEGRA_GPIO_PV3 171
+#define TEGRA_GPIO_PV4 172
+#define TEGRA_GPIO_PV5 173
+#define TEGRA_GPIO_PV6 174
+#define TEGRA_GPIO_PV7 175
+#define TEGRA_GPIO_PW0 176
+#define TEGRA_GPIO_PW1 177
+#define TEGRA_GPIO_PW2 178
+#define TEGRA_GPIO_PW3 179
+#define TEGRA_GPIO_PW4 180
+#define TEGRA_GPIO_PW5 181
+#define TEGRA_GPIO_PW6 182
+#define TEGRA_GPIO_PW7 183
+#define TEGRA_GPIO_PX0 184
+#define TEGRA_GPIO_PX1 185
+#define TEGRA_GPIO_PX2 186
+#define TEGRA_GPIO_PX3 187
+#define TEGRA_GPIO_PX4 188
+#define TEGRA_GPIO_PX5 189
+#define TEGRA_GPIO_PX6 190
+#define TEGRA_GPIO_PX7 191
+#define TEGRA_GPIO_PY0 192
+#define TEGRA_GPIO_PY1 193
+#define TEGRA_GPIO_PY2 194
+#define TEGRA_GPIO_PY3 195
+#define TEGRA_GPIO_PY4 196
+#define TEGRA_GPIO_PY5 197
+#define TEGRA_GPIO_PY6 198
+#define TEGRA_GPIO_PY7 199
+#define TEGRA_GPIO_PZ0 200
+#define TEGRA_GPIO_PZ1 201
+#define TEGRA_GPIO_PZ2 202
+#define TEGRA_GPIO_PZ3 203
+#define TEGRA_GPIO_PZ4 204
+#define TEGRA_GPIO_PZ5 205
+#define TEGRA_GPIO_PZ6 206
+#define TEGRA_GPIO_PZ7 207
+#define TEGRA_GPIO_PAA0 208
+#define TEGRA_GPIO_PAA1 209
+#define TEGRA_GPIO_PAA2 210
+#define TEGRA_GPIO_PAA3 211
+#define TEGRA_GPIO_PAA4 212
+#define TEGRA_GPIO_PAA5 213
+#define TEGRA_GPIO_PAA6 214
+#define TEGRA_GPIO_PAA7 215
+#define TEGRA_GPIO_PBB0 216
+#define TEGRA_GPIO_PBB1 217
+#define TEGRA_GPIO_PBB2 218
+#define TEGRA_GPIO_PBB3 219
+#define TEGRA_GPIO_PBB4 220
+#define TEGRA_GPIO_PBB5 221
+#define TEGRA_GPIO_PBB6 222
+#define TEGRA_GPIO_PBB7 223
+
+#endif
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
new file mode 100644
index 000000000000..fe78fba25f3c
--- /dev/null
+++ b/arch/arm/mach-tegra/gpio.c
@@ -0,0 +1,348 @@
+/*
+ * arch/arm/mach-tegra/gpio.c
+ *
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/iomap.h>
+
+#define GPIO_BANK(x) ((x) >> 5)
+#define GPIO_PORT(x) (((x) >> 3) & 0x3)
+#define GPIO_BIT(x) ((x) & 0x7)
+
+#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
+ GPIO_BANK(x) * 0x80 + \
+ GPIO_PORT(x) * 4)
+
+#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
+#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
+#define GPIO_OUT(x) (GPIO_REG(x) + 0X20)
+#define GPIO_IN(x) (GPIO_REG(x) + 0x30)
+#define GPIO_INT_STA(x) (GPIO_REG(x) + 0x40)
+#define GPIO_INT_ENB(x) (GPIO_REG(x) + 0x50)
+#define GPIO_INT_LVL(x) (GPIO_REG(x) + 0x60)
+#define GPIO_INT_CLR(x) (GPIO_REG(x) + 0x70)
+
+#define GPIO_MSK_CNF(x) (GPIO_REG(x) + 0x800)
+#define GPIO_MSK_OE(x) (GPIO_REG(x) + 0x810)
+#define GPIO_MSK_OUT(x) (GPIO_REG(x) + 0X820)
+#define GPIO_MSK_INT_STA(x) (GPIO_REG(x) + 0x840)
+#define GPIO_MSK_INT_ENB(x) (GPIO_REG(x) + 0x850)
+#define GPIO_MSK_INT_LVL(x) (GPIO_REG(x) + 0x860)
+
+#define GPIO_INT_LVL_MASK 0x010101
+#define GPIO_INT_LVL_EDGE_RISING 0x000101
+#define GPIO_INT_LVL_EDGE_FALLING 0x000100
+#define GPIO_INT_LVL_EDGE_BOTH 0x010100
+#define GPIO_INT_LVL_LEVEL_HIGH 0x000001
+#define GPIO_INT_LVL_LEVEL_LOW 0x000000
+
+struct tegra_gpio_bank {
+ int bank;
+ int irq;
+ spinlock_t lvl_lock[4];
+};
+
+
+static struct tegra_gpio_bank tegra_gpio_banks[] = {
+ {.bank = 0, .irq = INT_GPIO1},
+ {.bank = 1, .irq = INT_GPIO2},
+ {.bank = 2, .irq = INT_GPIO3},
+ {.bank = 3, .irq = INT_GPIO4},
+ {.bank = 4, .irq = INT_GPIO5},
+ {.bank = 5, .irq = INT_GPIO6},
+ {.bank = 6, .irq = INT_GPIO7},
+};
+
+static int tegra_gpio_compose(int bank, int port, int bit)
+{
+ return (bank << 5) | ((port & 0x3) << 3) | (bit & 0x7);
+}
+
+static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
+{
+ u32 val;
+
+ val = 0x100 << GPIO_BIT(gpio);
+ if (value)
+ val |= 1 << GPIO_BIT(gpio);
+ __raw_writel(val, reg);
+}
+
+void tegra_gpio_enable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 1);
+}
+
+void tegra_gpio_disable(int gpio)
+{
+ tegra_gpio_mask_write(GPIO_MSK_CNF(gpio), gpio, 0);
+}
+
+static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OUT(offset), offset, value);
+}
+
+static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
+}
+
+static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 0);
+ return 0;
+}
+
+static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ tegra_gpio_set(chip, offset, value);
+ tegra_gpio_mask_write(GPIO_MSK_OE(offset), offset, 1);
+ return 0;
+}
+
+
+
+static struct gpio_chip tegra_gpio_chip = {
+ .label = "tegra-gpio",
+ .direction_input = tegra_gpio_direction_input,
+ .get = tegra_gpio_get,
+ .direction_output = tegra_gpio_direction_output,
+ .set = tegra_gpio_set,
+ .base = 0,
+ .ngpio = ARCH_NR_GPIOS,
+};
+
+static void tegra_gpio_irq_ack(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ __raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
+}
+
+static void tegra_gpio_irq_mask(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
+}
+
+static void tegra_gpio_irq_unmask(unsigned int irq)
+{
+ int gpio = irq - INT_GPIO_BASE;
+
+ tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
+}
+
+static int tegra_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+ int gpio = irq - INT_GPIO_BASE;
+ struct tegra_gpio_bank *bank = get_irq_chip_data(irq);
+ int port = GPIO_PORT(gpio);
+ int lvl_type;
+ int val;
+ unsigned long flags;
+
+ switch (type & IRQ_TYPE_SENSE_MASK) {
+ case IRQ_TYPE_EDGE_RISING:
+ lvl_type = GPIO_INT_LVL_EDGE_RISING;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ lvl_type = GPIO_INT_LVL_EDGE_FALLING;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ lvl_type = GPIO_INT_LVL_EDGE_BOTH;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ lvl_type = GPIO_INT_LVL_LEVEL_HIGH;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ lvl_type = GPIO_INT_LVL_LEVEL_LOW;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&bank->lvl_lock[port], flags);
+
+ val = __raw_readl(GPIO_INT_LVL(gpio));
+ val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
+ val |= lvl_type << GPIO_BIT(gpio);
+ __raw_writel(val, GPIO_INT_LVL(gpio));
+
+ spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
+
+ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+ __set_irq_handler_unlocked(irq, handle_level_irq);
+ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+ __set_irq_handler_unlocked(irq, handle_edge_irq);
+
+ return 0;
+}
+
+static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ struct tegra_gpio_bank *bank;
+ int port;
+ int pin;
+ int unmasked = 0;
+
+ desc->chip->ack(irq);
+
+ bank = get_irq_data(irq);
+
+ for (port = 0; port < 4; port++) {
+ int gpio = tegra_gpio_compose(bank->bank, port, 0);
+ unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
+ __raw_readl(GPIO_INT_ENB(gpio));
+ u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
+
+ for_each_set_bit(pin, &sta, 8) {
+ __raw_writel(1 << pin, GPIO_INT_CLR(gpio));
+
+ /* if gpio is edge triggered, clear condition
+ * before executing the hander so that we don't
+ * miss edges
+ */
+ if (lvl & (0x100 << pin)) {
+ unmasked = 1;
+ desc->chip->unmask(irq);
+ }
+
+ generic_handle_irq(gpio_to_irq(gpio + pin));
+ }
+ }
+
+ if (!unmasked)
+ desc->chip->unmask(irq);
+
+}
+
+
+static struct irq_chip tegra_gpio_irq_chip = {
+ .name = "GPIO",
+ .ack = tegra_gpio_irq_ack,
+ .mask = tegra_gpio_irq_mask,
+ .unmask = tegra_gpio_irq_unmask,
+ .set_type = tegra_gpio_irq_set_type,
+};
+
+
+/* This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static int __init tegra_gpio_init(void)
+{
+ struct tegra_gpio_bank *bank;
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ __raw_writel(0x00, GPIO_INT_ENB(gpio));
+ }
+ }
+
+ gpiochip_add(&tegra_gpio_chip);
+
+ for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + ARCH_NR_GPIOS); i++) {
+ bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
+
+ lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class);
+ set_irq_chip_data(i, bank);
+ set_irq_chip(i, &tegra_gpio_irq_chip);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ bank = &tegra_gpio_banks[i];
+
+ set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler);
+ set_irq_data(bank->irq, bank);
+
+ for (j = 0; j < 4; j++)
+ spin_lock_init(&bank->lvl_lock[j]);
+ }
+
+ return 0;
+}
+
+postcore_initcall(tegra_gpio_init);
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static int dbg_gpio_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int j;
+
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 4; j++) {
+ int gpio = tegra_gpio_compose(i, j, 0);
+ seq_printf(s, "%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
+ i, j,
+ __raw_readl(GPIO_CNF(gpio)),
+ __raw_readl(GPIO_OE(gpio)),
+ __raw_readl(GPIO_OUT(gpio)),
+ __raw_readl(GPIO_IN(gpio)),
+ __raw_readl(GPIO_INT_STA(gpio)),
+ __raw_readl(GPIO_INT_ENB(gpio)),
+ __raw_readl(GPIO_INT_LVL(gpio)));
+ }
+ }
+ return 0;
+}
+
+static int dbg_gpio_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_gpio_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_gpio_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_gpio_debuginit(void)
+{
+ (void) debugfs_create_file("tegra_gpio", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ return 0;
+}
+late_initcall(tegra_gpio_debuginit);
+#endif
diff --git a/arch/arm/mach-tegra/headsmp.S b/arch/arm/mach-tegra/headsmp.S
new file mode 100644
index 000000000000..b5349b2f13d2
--- /dev/null
+++ b/arch/arm/mach-tegra/headsmp.S
@@ -0,0 +1,61 @@
+#include <linux/linkage.h>
+#include <linux/init.h>
+
+ .section ".text.head", "ax"
+ __CPUINIT
+
+/*
+ * Tegra specific entry point for secondary CPUs.
+ * The secondary kernel init calls v7_flush_dcache_all before it enables
+ * the L1; however, the L1 comes out of reset in an undefined state, so
+ * the clean + invalidate performed by v7_flush_dcache_all causes a bunch
+ * of cache lines with uninitialized data and uninitialized tags to get
+ * written out to memory, which does really unpleasant things to the main
+ * processor. We fix this by performing an invalidate, rather than a
+ * clean + invalidate, before jumping into the kernel.
+ */
+ENTRY(v7_invalidate_l1)
+ mov r0, #0
+ mcr p15, 2, r0, c0, c0, 0
+ mrc p15, 1, r0, c0, c0, 0
+
+ ldr r1, =0x7fff
+ and r2, r1, r0, lsr #13
+
+ ldr r1, =0x3ff
+
+ and r3, r1, r0, lsr #3 @ NumWays - 1
+ add r2, r2, #1 @ NumSets
+
+ and r0, r0, #0x7
+ add r0, r0, #4 @ SetShift
+
+ clz r1, r3 @ WayShift
+ add r4, r3, #1 @ NumWays
+1: sub r2, r2, #1 @ NumSets--
+ mov r3, r4 @ Temp = NumWays
+2: subs r3, r3, #1 @ Temp--
+ mov r5, r3, lsl r1
+ mov r6, r2, lsl r0
+ orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift)
+ mcr p15, 0, r5, c7, c6, 2
+ bgt 2b
+ cmp r2, #0
+ bgt 1b
+ dsb
+ isb
+ mov pc, lr
+ENDPROC(v7_invalidate_l1)
+
+ENTRY(tegra_secondary_startup)
+ msr cpsr_fsxc, #0xd3
+ bl v7_invalidate_l1
+ mrc p15, 0, r0, c0, c0, 5
+ and r0, r0, #15
+ ldr r1, =0x6000f100
+ str r0, [r1]
+1: ldr r2, [r1]
+ cmp r0, r2
+ beq 1b
+ b secondary_startup
+ENDPROC(tegra_secondary_startup)
diff --git a/arch/arm/mach-tegra/hotplug.c b/arch/arm/mach-tegra/hotplug.c
new file mode 100644
index 000000000000..8e7f115aa21e
--- /dev/null
+++ b/arch/arm/mach-tegra/hotplug.c
@@ -0,0 +1,140 @@
+/*
+ * linux/arch/arm/mach-realview/hotplug.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+#include <linux/completion.h>
+
+#include <asm/cacheflush.h>
+
+static DECLARE_COMPLETION(cpu_killed);
+
+static inline void cpu_enter_lowpower(void)
+{
+ unsigned int v;
+
+ flush_cache_all();
+ asm volatile(
+ " mcr p15, 0, %1, c7, c5, 0\n"
+ " mcr p15, 0, %1, c7, c10, 4\n"
+ /*
+ * Turn off coherency
+ */
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " bic %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ " mrc p15, 0, %0, c1, c0, 0\n"
+ " bic %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ : "=&r" (v)
+ : "r" (0)
+ : "cc");
+}
+
+static inline void cpu_leave_lowpower(void)
+{
+ unsigned int v;
+
+ asm volatile(
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ " orr %0, %0, #0x04\n"
+ " mcr p15, 0, %0, c1, c0, 0\n"
+ " mrc p15, 0, %0, c1, c0, 1\n"
+ " orr %0, %0, #0x20\n"
+ " mcr p15, 0, %0, c1, c0, 1\n"
+ : "=&r" (v)
+ :
+ : "cc");
+}
+
+static inline void platform_do_lowpower(unsigned int cpu)
+{
+ /*
+ * there is no power-control hardware on this platform, so all
+ * we can do is put the core into WFI; this is safe as the calling
+ * code will have already disabled interrupts
+ */
+ for (;;) {
+ /*
+ * here's the WFI
+ */
+ asm(".word 0xe320f003\n"
+ :
+ :
+ : "memory", "cc");
+
+ /*if (pen_release == cpu) {*/
+ /*
+ * OK, proper wakeup, we're done
+ */
+ break;
+ /*}*/
+
+ /*
+ * getting here, means that we have come out of WFI without
+ * having been woken up - this shouldn't happen
+ *
+ * The trouble is, letting people know about this is not really
+ * possible, since we are currently running incoherently, and
+ * therefore cannot safely call printk() or anything else
+ */
+#ifdef DEBUG
+ printk(KERN_WARN "CPU%u: spurious wakeup call\n", cpu);
+#endif
+ }
+}
+
+int platform_cpu_kill(unsigned int cpu)
+{
+ return wait_for_completion_timeout(&cpu_killed, 5000);
+}
+
+/*
+ * platform-specific code to shutdown a CPU
+ *
+ * Called with IRQs disabled
+ */
+void platform_cpu_die(unsigned int cpu)
+{
+#ifdef DEBUG
+ unsigned int this_cpu = hard_smp_processor_id();
+
+ if (cpu != this_cpu) {
+ printk(KERN_CRIT "Eek! platform_cpu_die running on %u, should be %u\n",
+ this_cpu, cpu);
+ BUG();
+ }
+#endif
+
+ printk(KERN_NOTICE "CPU%u: shutdown\n", cpu);
+ complete(&cpu_killed);
+
+ /*
+ * we're ready for shutdown now, so do it
+ */
+ cpu_enter_lowpower();
+ platform_do_lowpower(cpu);
+
+ /*
+ * bring this CPU back into the world of cache
+ * coherency, and then restore interrupts
+ */
+ cpu_leave_lowpower();
+}
+
+int platform_cpu_disable(unsigned int cpu)
+{
+ /*
+ * we don't allow CPU 0 to be shutdown (it is still too special
+ * e.g. clock tick interrupts)
+ */
+ return cpu == 0 ? -EPERM : 0;
+}
diff --git a/arch/arm/mach-tegra/include/mach/barriers.h b/arch/arm/mach-tegra/include/mach/barriers.h
new file mode 100644
index 000000000000..cc115174899b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/barriers.h
@@ -0,0 +1,30 @@
+/*
+ * arch/arm/mach-realview/include/mach/barriers.h
+ *
+ * Copyright (C) 2010 ARM Ltd.
+ * Written by Catalin Marinas <catalin.marinas@arm.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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_BARRIERS_H
+#define __MACH_BARRIERS_H
+
+#include <asm/outercache.h>
+
+#define rmb() dmb()
+#define wmb() do { dsb(); outer_sync(); } while (0)
+#define mb() wmb()
+
+#endif /* __MACH_BARRIERS_H */
diff --git a/arch/arm/mach-tegra/include/mach/clk.h b/arch/arm/mach-tegra/include/mach/clk.h
new file mode 100644
index 000000000000..2896f25ebfb5
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clk.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clk.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_CLK_H
+#define __MACH_CLK_H
+
+void tegra_periph_reset_deassert(struct clk *c);
+void tegra_periph_reset_assert(struct clk *c);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/clkdev.h b/arch/arm/mach-tegra/include/mach/clkdev.h
new file mode 100644
index 000000000000..412f5c63e65a
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/clkdev.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-tegra/include/mach/clkdev.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_CLKDEV_H
+#define __MACH_CLKDEV_H
+
+static inline int __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+static inline void __clk_put(struct clk *clk)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
new file mode 100644
index 000000000000..55a39564b43c
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -0,0 +1,46 @@
+/*
+ * arch/arm/mach-tegra/include/mach/debug-macro.S
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <mach/io.h>
+
+ .macro addruart,rx, tmp
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =IO_APB_PHYS @ physical
+ ldrne \rx, =IO_APB_VIRT @ virtual
+#if defined(CONFIG_TEGRA_DEBUG_UART_NONE)
+#error "A debug UART must be selected in the kernel config to use DEBUG_LL"
+#elif defined(CONFIG_TEGRA_DEBUG_UARTA)
+ orr \rx, \rx, #0x6000
+#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
+ ldr \tmp, =0x6040
+ orr \rx, \rx, \tmp
+#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
+ orr \rx, \rx, #0x6200
+#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
+ orr \rx, \rx, #0x6300
+#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
+ orr \rx, \rx, #0x6400
+#endif
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
+
diff --git a/arch/arm/mach-tegra/include/mach/entry-macro.S b/arch/arm/mach-tegra/include/mach/entry-macro.S
new file mode 100644
index 000000000000..2ba9e5c9d2f6
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/entry-macro.S
@@ -0,0 +1,118 @@
+/* arch/arm/mach-tegra/include/mach/entry-macro.S
+ *
+ * Copyright (C) 2009 Palm, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include <mach/iomap.h>
+#include <mach/io.h>
+
+#if defined(CONFIG_ARM_GIC)
+
+#include <asm/hardware/gic.h>
+
+ /* Uses the GIC interrupt controller built into the cpu */
+#define ICTRL_BASE (IO_CPU_VIRT + 0x100)
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ movw \base, #(ICTRL_BASE & 0x0000ffff)
+ movt \base, #((ICTRL_BASE & 0xffff0000) >> 16)
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ /*
+ * The interrupt numbering scheme is defined in the
+ * interrupt controller spec. To wit:
+ *
+ * Interrupts 0-15 are IPI
+ * 16-28 are reserved
+ * 29-31 are local. We allow 30 to be used for the watchdog.
+ * 32-1020 are global
+ * 1021-1022 are reserved
+ * 1023 is "spurious" (no interrupt)
+ *
+ * For now, we ignore all local interrupts so only return an interrupt
+ * if it's between 30 and 1020. The test_for_ipi routine below will
+ * pick up on IPIs.
+ *
+ * A simple read from the controller will tell us the number of the
+ * highest priority enabled interrupt. We then just need to check
+ * whether it is in the valid range for an IRQ (30-1020 inclusive).
+ */
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+ /* bits 12-10 = src CPU, 9-0 = int # */
+ ldr \irqstat, [\base, #GIC_CPU_INTACK]
+
+ ldr \tmp, =1021
+
+ bic \irqnr, \irqstat, #0x1c00
+
+ cmp \irqnr, #29
+ cmpcc \irqnr, \irqnr
+ cmpne \irqnr, \tmp
+ cmpcs \irqnr, \irqnr
+
+ .endm
+
+ /* We assume that irqstat (the raw value of the IRQ acknowledge
+ * register) is preserved from the macro above.
+ * If there is an IPI, we immediately signal end of interrupt on the
+ * controller, since this requires the original irqstat value which
+ * we won't easily be able to recreate later.
+ */
+
+ .macro test_for_ipi, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ cmp \irqnr, #16
+ strcc \irqstat, [\base, #GIC_CPU_EOI]
+ cmpcs \irqnr, \irqnr
+ .endm
+
+ /* As above, this assumes that irqstat and base are preserved.. */
+
+ .macro test_for_ltirq, irqnr, irqstat, base, tmp
+ bic \irqnr, \irqstat, #0x1c00
+ mov \tmp, #0
+ cmp \irqnr, #29
+ moveq \tmp, #1
+ streq \irqstat, [\base, #GIC_CPU_EOI]
+ cmp \tmp, #0
+ .endm
+
+#else
+ /* legacy interrupt controller for AP16 */
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ @ enable imprecise aborts
+ cpsie a
+ @ EVP base at 0xf010f000
+ mov \base, #0xf0000000
+ orr \base, #0x00100000
+ orr \base, #0x0000f000
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x20] @ EVT_IRQ_STS
+ cmp \irqnr, #0x80
+ .endm
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/gpio.h b/arch/arm/mach-tegra/include/mach/gpio.h
new file mode 100644
index 000000000000..540e822e50f7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/gpio.h
@@ -0,0 +1,53 @@
+/*
+ * arch/arm/mach-tegra/include/mach/gpio.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_GPIO_H
+#define __MACH_TEGRA_GPIO_H
+
+#include <mach/irqs.h>
+
+#define ARCH_NR_GPIOS INT_GPIO_NR
+
+#include <asm-generic/gpio.h>
+
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
+#define TEGRA_IRQ_TO_GPIO(irq) ((gpio) - INT_GPIO_BASE)
+
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ if (gpio < ARCH_NR_GPIOS)
+ return INT_GPIO_BASE + gpio;
+ return -EINVAL;
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ if ((irq >= INT_GPIO_BASE) && (irq < INT_GPIO_BASE + INT_GPIO_NR))
+ return irq - INT_GPIO_BASE;
+ return -EINVAL;
+}
+
+void tegra_gpio_enable(int gpio);
+void tegra_gpio_disable(int gpio);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/hardware.h b/arch/arm/mach-tegra/include/mach/hardware.h
new file mode 100644
index 000000000000..6014edf60d93
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/hardware.h
@@ -0,0 +1,24 @@
+/*
+ * arch/arm/mach-tegra/include/mach/hardware.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_HARDWARE_H
+#define __MACH_TEGRA_HARDWARE_H
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/io.h b/arch/arm/mach-tegra/include/mach/io.h
new file mode 100644
index 000000000000..35edfc32ffc9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/io.h
@@ -0,0 +1,79 @@
+/*
+ * arch/arm/mach-tegra/include/mach/io.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IO_H
+#define __MACH_TEGRA_IO_H
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* On TEGRA, many peripherals are very closely packed in
+ * two 256MB io windows (that actually only use about 64KB
+ * at the start of each).
+ *
+ * We will just map the first 1MB of each window (to minimize
+ * pt entries needed) and provide a macro to transform physical
+ * io addresses to an appropriate void __iomem *.
+ *
+ */
+
+#define IO_CPU_PHYS 0x50040000
+#define IO_CPU_VIRT 0xFE000000
+#define IO_CPU_SIZE SZ_16K
+
+#define IO_PPSB_PHYS 0x60000000
+#define IO_PPSB_VIRT 0xFE200000
+#define IO_PPSB_SIZE SZ_1M
+
+#define IO_APB_PHYS 0x70000000
+#define IO_APB_VIRT 0xFE300000
+#define IO_APB_SIZE SZ_1M
+
+#define IO_TO_VIRT_BETWEEN(p, st, sz) ((p) >= (st) && (p) < ((st) + (sz)))
+#define IO_TO_VIRT_XLATE(p, pst, vst) (((p) - (pst) + (vst)))
+
+#define IO_TO_VIRT(n) ( \
+ IO_TO_VIRT_BETWEEN((n), IO_PPSB_PHYS, IO_PPSB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_PPSB_PHYS, IO_PPSB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_APB_PHYS, IO_APB_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_APB_PHYS, IO_APB_VIRT) : \
+ IO_TO_VIRT_BETWEEN((n), IO_CPU_PHYS, IO_CPU_SIZE) ? \
+ IO_TO_VIRT_XLATE((n), IO_CPU_PHYS, IO_CPU_VIRT) : \
+ 0)
+
+#ifndef __ASSEMBLER__
+
+#define __arch_ioremap(p, s, t) tegra_ioremap(p, s, t)
+#define __arch_iounmap(v) tegra_iounmap(v)
+
+void __iomem *tegra_ioremap(unsigned long phys, size_t size, unsigned int type);
+void tegra_iounmap(volatile void __iomem *addr);
+
+#define IO_ADDRESS(n) ((void __iomem *) IO_TO_VIRT(n))
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
new file mode 100644
index 000000000000..1741f7dd7a9b
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -0,0 +1,203 @@
+/*
+ * arch/arm/mach-tegra/include/mach/iomap.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IOMAP_H
+#define __MACH_TEGRA_IOMAP_H
+
+#include <asm/sizes.h>
+
+#define TEGRA_ARM_PERIF_BASE 0x50040000
+#define TEGRA_ARM_PERIF_SIZE SZ_8K
+
+#define TEGRA_ARM_INT_DIST_BASE 0x50041000
+#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
+
+#define TEGRA_DISPLAY_BASE 0x54200000
+#define TEGRA_DISPLAY_SIZE SZ_256K
+
+#define TEGRA_DISPLAY2_BASE 0x54240000
+#define TEGRA_DISPLAY2_SIZE SZ_256K
+
+#define TEGRA_PRIMARY_ICTLR_BASE 0x60004000
+#define TEGRA_PRIMARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_SECONDARY_ICTLR_BASE 0x60004100
+#define TEGRA_SECONDARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TERTIARY_ICTLR_BASE 0x60004200
+#define TEGRA_TERTIARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_QUATERNARY_ICTLR_BASE 0x60004300
+#define TEGRA_QUATERNARY_ICTLR_SIZE SZ_64
+
+#define TEGRA_TMR1_BASE 0x60005000
+#define TEGRA_TMR1_SIZE SZ_8
+
+#define TEGRA_TMR2_BASE 0x60005008
+#define TEGRA_TMR2_SIZE SZ_8
+
+#define TEGRA_TMRUS_BASE 0x60005010
+#define TEGRA_TMRUS_SIZE SZ_64
+
+#define TEGRA_TMR3_BASE 0x60005050
+#define TEGRA_TMR3_SIZE SZ_8
+
+#define TEGRA_TMR4_BASE 0x60005058
+#define TEGRA_TMR4_SIZE SZ_8
+
+#define TEGRA_CLK_RESET_BASE 0x60006000
+#define TEGRA_CLK_RESET_SIZE SZ_4K
+
+#define TEGRA_FLOW_CTRL_BASE 0x60007000
+#define TEGRA_FLOW_CTRL_SIZE 20
+
+#define TEGRA_STATMON_BASE 0x6000C4000
+#define TEGRA_STATMON_SIZE SZ_1K
+
+#define TEGRA_GPIO_BASE 0x6000D000
+#define TEGRA_GPIO_SIZE SZ_4K
+
+#define TEGRA_EXCEPTION_VECTORS_BASE 0x6000F000
+#define TEGRA_EXCEPTION_VECTORS_SIZE SZ_4K
+
+#define TEGRA_APB_MISC_BASE 0x70000000
+#define TEGRA_APB_MISC_SIZE SZ_4K
+
+#define TEGRA_AC97_BASE 0x70002000
+#define TEGRA_AC97_SIZE SZ_512
+
+#define TEGRA_SPDIF_BASE 0x70002400
+#define TEGRA_SPDIF_SIZE SZ_512
+
+#define TEGRA_I2S1_BASE 0x70002800
+#define TEGRA_I2S1_SIZE SZ_256
+
+#define TEGRA_I2S2_BASE 0x70002A00
+#define TEGRA_I2S2_SIZE SZ_256
+
+#define TEGRA_UARTA_BASE 0x70006000
+#define TEGRA_UARTA_SIZE SZ_64
+
+#define TEGRA_UARTB_BASE 0x70006040
+#define TEGRA_UARTB_SIZE SZ_64
+
+#define TEGRA_UARTC_BASE 0x70006200
+#define TEGRA_UARTC_SIZE SZ_256
+
+#define TEGRA_UARTD_BASE 0x70006300
+#define TEGRA_UARTD_SIZE SZ_256
+
+#define TEGRA_UARTE_BASE 0x70006400
+#define TEGRA_UARTE_SIZE SZ_256
+
+#define TEGRA_NAND_BASE 0x70008000
+#define TEGRA_NAND_SIZE SZ_256
+
+#define TEGRA_HSMMC_BASE 0x70008500
+#define TEGRA_HSMMC_SIZE SZ_256
+
+#define TEGRA_SNOR_BASE 0x70009000
+#define TEGRA_SNOR_SIZE SZ_4K
+
+#define TEGRA_PWFM_BASE 0x7000A000
+#define TEGRA_PWFM_SIZE SZ_256
+
+#define TEGRA_MIPI_BASE 0x7000B000
+#define TEGRA_MIPI_SIZE SZ_256
+
+#define TEGRA_I2C_BASE 0x7000C000
+#define TEGRA_I2C_SIZE SZ_256
+
+#define TEGRA_TWC_BASE 0x7000C100
+#define TEGRA_TWC_SIZE SZ_256
+
+#define TEGRA_SPI_BASE 0x7000C380
+#define TEGRA_SPI_SIZE 48
+
+#define TEGRA_I2C2_BASE 0x7000C400
+#define TEGRA_I2C2_SIZE SZ_256
+
+#define TEGRA_I2C3_BASE 0x7000C500
+#define TEGRA_I2C3_SIZE SZ_256
+
+#define TEGRA_OWR_BASE 0x7000D000
+#define TEGRA_OWR_SIZE 80
+
+#define TEGRA_DVC_BASE 0x7000D000
+#define TEGRA_DVC_SIZE SZ_512
+
+#define TEGRA_SPI1_BASE 0x7000D400
+#define TEGRA_SPI1_SIZE SZ_512
+
+#define TEGRA_SPI2_BASE 0x7000D600
+#define TEGRA_SPI2_SIZE SZ_512
+
+#define TEGRA_SPI3_BASE 0x7000D800
+#define TEGRA_SPI3_SIZE SZ_512
+
+#define TEGRA_SPI4_BASE 0x7000DA00
+#define TEGRA_SPI4_SIZE SZ_512
+
+#define TEGRA_RTC_BASE 0x7000E000
+#define TEGRA_RTC_SIZE SZ_256
+
+#define TEGRA_KBC_BASE 0x7000E200
+#define TEGRA_KBC_SIZE SZ_256
+
+#define TEGRA_PMC_BASE 0x7000E400
+#define TEGRA_PMC_SIZE SZ_256
+
+#define TEGRA_MC_BASE 0x7000F000
+#define TEGRA_MC_SIZE SZ_1K
+
+#define TEGRA_EMC_BASE 0x7000F400
+#define TEGRA_EMC_SIZE SZ_1K
+
+#define TEGRA_FUSE_BASE 0x7000F800
+#define TEGRA_FUSE_SIZE SZ_1K
+
+#define TEGRA_KFUSE_BASE 0x7000FC00
+#define TEGRA_KFUSE_SIZE SZ_1K
+
+#define TEGRA_CSITE_BASE 0x70040000
+#define TEGRA_CSITE_SIZE SZ_256K
+
+#define TEGRA_USB_BASE 0xC5000000
+#define TEGRA_USB_SIZE SZ_16K
+
+#define TEGRA_USB1_BASE 0xC5004000
+#define TEGRA_USB1_SIZE SZ_16K
+
+#define TEGRA_USB2_BASE 0xC5008000
+#define TEGRA_USB2_SIZE SZ_16K
+
+#define TEGRA_SDMMC1_BASE 0xC8000000
+#define TEGRA_SDMMC1_SIZE SZ_512
+
+#define TEGRA_SDMMC2_BASE 0xC8000200
+#define TEGRA_SDMMC2_SIZE SZ_512
+
+#define TEGRA_SDMMC3_BASE 0xC8000400
+#define TEGRA_SDMMC3_SIZE SZ_512
+
+#define TEGRA_SDMMC4_BASE 0xC8000600
+#define TEGRA_SDMMC4_SIZE SZ_512
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
new file mode 100644
index 000000000000..20f640edaa0d
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-tegra/include/mach/irqs.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_IRQS_H
+#define __MACH_TEGRA_IRQS_H
+
+#define INT_GIC_BASE 0
+
+#define IRQ_LOCALTIMER 29
+
+/* Primary Interrupt Controller */
+#define INT_PRI_BASE (INT_GIC_BASE + 32)
+#define INT_TMR1 (INT_PRI_BASE + 0)
+#define INT_TMR2 (INT_PRI_BASE + 1)
+#define INT_RTC (INT_PRI_BASE + 2)
+#define INT_I2S2 (INT_PRI_BASE + 3)
+#define INT_SHR_SEM_INBOX_IBF (INT_PRI_BASE + 4)
+#define INT_SHR_SEM_INBOX_IBE (INT_PRI_BASE + 5)
+#define INT_SHR_SEM_OUTBOX_IBF (INT_PRI_BASE + 6)
+#define INT_SHR_SEM_OUTBOX_IBE (INT_PRI_BASE + 7)
+#define INT_VDE_UCQ_ERROR (INT_PRI_BASE + 8)
+#define INT_VDE_SYNC_TOKEN (INT_PRI_BASE + 9)
+#define INT_VDE_BSE_V (INT_PRI_BASE + 10)
+#define INT_VDE_BSE_A (INT_PRI_BASE + 11)
+#define INT_VDE_SXE (INT_PRI_BASE + 12)
+#define INT_I2S1 (INT_PRI_BASE + 13)
+#define INT_SDMMC1 (INT_PRI_BASE + 14)
+#define INT_SDMMC2 (INT_PRI_BASE + 15)
+#define INT_XIO (INT_PRI_BASE + 16)
+#define INT_VDE (INT_PRI_BASE + 17)
+#define INT_AVP_UCQ (INT_PRI_BASE + 18)
+#define INT_SDMMC3 (INT_PRI_BASE + 19)
+#define INT_USB (INT_PRI_BASE + 20)
+#define INT_USB2 (INT_PRI_BASE + 21)
+#define INT_PRI_RES_22 (INT_PRI_BASE + 22)
+#define INT_EIDE (INT_PRI_BASE + 23)
+#define INT_NANDFLASH (INT_PRI_BASE + 24)
+#define INT_VCP (INT_PRI_BASE + 25)
+#define INT_APB_DMA (INT_PRI_BASE + 26)
+#define INT_AHB_DMA (INT_PRI_BASE + 27)
+#define INT_GNT_0 (INT_PRI_BASE + 28)
+#define INT_GNT_1 (INT_PRI_BASE + 29)
+#define INT_OWR (INT_PRI_BASE + 30)
+#define INT_SDMMC4 (INT_PRI_BASE + 31)
+
+/* Secondary Interrupt Controller */
+#define INT_SEC_BASE (INT_PRI_BASE + 32)
+#define INT_GPIO1 (INT_SEC_BASE + 0)
+#define INT_GPIO2 (INT_SEC_BASE + 1)
+#define INT_GPIO3 (INT_SEC_BASE + 2)
+#define INT_GPIO4 (INT_SEC_BASE + 3)
+#define INT_UARTA (INT_SEC_BASE + 4)
+#define INT_UARTB (INT_SEC_BASE + 5)
+#define INT_I2C (INT_SEC_BASE + 6)
+#define INT_SPI (INT_SEC_BASE + 7)
+#define INT_TWC (INT_SEC_BASE + 8)
+#define INT_TMR3 (INT_SEC_BASE + 9)
+#define INT_TMR4 (INT_SEC_BASE + 10)
+#define INT_FLOW_RSM0 (INT_SEC_BASE + 11)
+#define INT_FLOW_RSM1 (INT_SEC_BASE + 12)
+#define INT_SPDIF (INT_SEC_BASE + 13)
+#define INT_UARTC (INT_SEC_BASE + 14)
+#define INT_MIPI (INT_SEC_BASE + 15)
+#define INT_EVENTA (INT_SEC_BASE + 16)
+#define INT_EVENTB (INT_SEC_BASE + 17)
+#define INT_EVENTC (INT_SEC_BASE + 18)
+#define INT_EVENTD (INT_SEC_BASE + 19)
+#define INT_VFIR (INT_SEC_BASE + 20)
+#define INT_DVC (INT_SEC_BASE + 21)
+#define INT_SYS_STATS_MON (INT_SEC_BASE + 22)
+#define INT_GPIO5 (INT_SEC_BASE + 23)
+#define INT_CPU0_PMU_INTR (INT_SEC_BASE + 24)
+#define INT_CPU2_PMU_INTR (INT_SEC_BASE + 25)
+#define INT_SEC_RES_26 (INT_SEC_BASE + 26)
+#define INT_S_LINK1 (INT_SEC_BASE + 27)
+#define INT_APB_DMA_COP (INT_SEC_BASE + 28)
+#define INT_AHB_DMA_COP (INT_SEC_BASE + 29)
+#define INT_DMA_TX (INT_SEC_BASE + 30)
+#define INT_DMA_RX (INT_SEC_BASE + 31)
+
+/* Tertiary Interrupt Controller */
+#define INT_TRI_BASE (INT_SEC_BASE + 32)
+#define INT_HOST1X_COP_SYNCPT (INT_TRI_BASE + 0)
+#define INT_HOST1X_MPCORE_SYNCPT (INT_TRI_BASE + 1)
+#define INT_HOST1X_COP_GENERAL (INT_TRI_BASE + 2)
+#define INT_HOST1X_MPCORE_GENERAL (INT_TRI_BASE + 3)
+#define INT_MPE_GENERAL (INT_TRI_BASE + 4)
+#define INT_VI_GENERAL (INT_TRI_BASE + 5)
+#define INT_EPP_GENERAL (INT_TRI_BASE + 6)
+#define INT_ISP_GENERAL (INT_TRI_BASE + 7)
+#define INT_2D_GENERAL (INT_TRI_BASE + 8)
+#define INT_DISPLAY_GENERAL (INT_TRI_BASE + 9)
+#define INT_DISPLAY_B_GENERAL (INT_TRI_BASE + 10)
+#define INT_HDMI (INT_TRI_BASE + 11)
+#define INT_TVO_GENERAL (INT_TRI_BASE + 12)
+#define INT_MC_GENERAL (INT_TRI_BASE + 13)
+#define INT_EMC_GENERAL (INT_TRI_BASE + 14)
+#define INT_TRI_RES_15 (INT_TRI_BASE + 15)
+#define INT_TRI_RES_16 (INT_TRI_BASE + 16)
+#define INT_AC97 (INT_TRI_BASE + 17)
+#define INT_SPI_2 (INT_TRI_BASE + 18)
+#define INT_SPI_3 (INT_TRI_BASE + 19)
+#define INT_I2C2 (INT_TRI_BASE + 20)
+#define INT_KBC (INT_TRI_BASE + 21)
+#define INT_EXTERNAL_PMU (INT_TRI_BASE + 22)
+#define INT_GPIO6 (INT_TRI_BASE + 23)
+#define INT_TVDAC (INT_TRI_BASE + 24)
+#define INT_GPIO7 (INT_TRI_BASE + 25)
+#define INT_UARTD (INT_TRI_BASE + 26)
+#define INT_UARTE (INT_TRI_BASE + 27)
+#define INT_I2C3 (INT_TRI_BASE + 28)
+#define INT_SPI_4 (INT_TRI_BASE + 29)
+#define INT_TRI_RES_30 (INT_TRI_BASE + 30)
+#define INT_SW_RESERVED (INT_TRI_BASE + 31)
+
+/* Quaternary Interrupt Controller */
+#define INT_QUAD_BASE (INT_TRI_BASE + 32)
+#define INT_SNOR (INT_QUAD_BASE + 0)
+#define INT_USB3 (INT_QUAD_BASE + 1)
+#define INT_PCIE_INTR (INT_QUAD_BASE + 2)
+#define INT_PCIE_MSI (INT_QUAD_BASE + 3)
+#define INT_QUAD_RES_4 (INT_QUAD_BASE + 4)
+#define INT_QUAD_RES_5 (INT_QUAD_BASE + 5)
+#define INT_QUAD_RES_6 (INT_QUAD_BASE + 6)
+#define INT_QUAD_RES_7 (INT_QUAD_BASE + 7)
+#define INT_APB_DMA_CH0 (INT_QUAD_BASE + 8)
+#define INT_APB_DMA_CH1 (INT_QUAD_BASE + 9)
+#define INT_APB_DMA_CH2 (INT_QUAD_BASE + 10)
+#define INT_APB_DMA_CH3 (INT_QUAD_BASE + 11)
+#define INT_APB_DMA_CH4 (INT_QUAD_BASE + 12)
+#define INT_APB_DMA_CH5 (INT_QUAD_BASE + 13)
+#define INT_APB_DMA_CH6 (INT_QUAD_BASE + 14)
+#define INT_APB_DMA_CH7 (INT_QUAD_BASE + 15)
+#define INT_APB_DMA_CH8 (INT_QUAD_BASE + 16)
+#define INT_APB_DMA_CH9 (INT_QUAD_BASE + 17)
+#define INT_APB_DMA_CH10 (INT_QUAD_BASE + 18)
+#define INT_APB_DMA_CH11 (INT_QUAD_BASE + 19)
+#define INT_APB_DMA_CH12 (INT_QUAD_BASE + 20)
+#define INT_APB_DMA_CH13 (INT_QUAD_BASE + 21)
+#define INT_APB_DMA_CH14 (INT_QUAD_BASE + 22)
+#define INT_APB_DMA_CH15 (INT_QUAD_BASE + 23)
+#define INT_QUAD_RES_24 (INT_QUAD_BASE + 24)
+#define INT_QUAD_RES_25 (INT_QUAD_BASE + 25)
+#define INT_QUAD_RES_26 (INT_QUAD_BASE + 26)
+#define INT_QUAD_RES_27 (INT_QUAD_BASE + 27)
+#define INT_QUAD_RES_28 (INT_QUAD_BASE + 28)
+#define INT_QUAD_RES_29 (INT_QUAD_BASE + 29)
+#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
+#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
+
+#define INT_GPIO_BASE (INT_QUAD_BASE + 32)
+#define INT_GPIO_NR (28 * 8)
+
+#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/memory.h b/arch/arm/mach-tegra/include/mach/memory.h
new file mode 100644
index 000000000000..6151bab62af2
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/memory.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-tegra/include/mach/memory.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_MEMORY_H
+#define __MACH_TEGRA_MEMORY_H
+
+/* physical offset of RAM */
+#define PHYS_OFFSET UL(0)
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644
index 000000000000..41c8ce5b7c27
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pinmux.h
@@ -0,0 +1,348 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_H
+#define __MACH_TEGRA_PINMUX_H
+
+enum tegra_pingroup {
+ TEGRA_PINGROUP_ATA = 0,
+ TEGRA_PINGROUP_ATB,
+ TEGRA_PINGROUP_ATC,
+ TEGRA_PINGROUP_ATD,
+ TEGRA_PINGROUP_ATE,
+ TEGRA_PINGROUP_CDEV1,
+ TEGRA_PINGROUP_CDEV2,
+ TEGRA_PINGROUP_CRTP,
+ TEGRA_PINGROUP_CSUS,
+ TEGRA_PINGROUP_DAP1,
+ TEGRA_PINGROUP_DAP2,
+ TEGRA_PINGROUP_DAP3,
+ TEGRA_PINGROUP_DAP4,
+ TEGRA_PINGROUP_DDC,
+ TEGRA_PINGROUP_DTA,
+ TEGRA_PINGROUP_DTB,
+ TEGRA_PINGROUP_DTC,
+ TEGRA_PINGROUP_DTD,
+ TEGRA_PINGROUP_DTE,
+ TEGRA_PINGROUP_DTF,
+ TEGRA_PINGROUP_GMA,
+ TEGRA_PINGROUP_GMB,
+ TEGRA_PINGROUP_GMC,
+ TEGRA_PINGROUP_GMD,
+ TEGRA_PINGROUP_GME,
+ TEGRA_PINGROUP_GPU,
+ TEGRA_PINGROUP_GPU7,
+ TEGRA_PINGROUP_GPV,
+ TEGRA_PINGROUP_HDINT,
+ TEGRA_PINGROUP_I2CP,
+ TEGRA_PINGROUP_IRRX,
+ TEGRA_PINGROUP_IRTX,
+ TEGRA_PINGROUP_KBCA,
+ TEGRA_PINGROUP_KBCB,
+ TEGRA_PINGROUP_KBCC,
+ TEGRA_PINGROUP_KBCD,
+ TEGRA_PINGROUP_KBCE,
+ TEGRA_PINGROUP_KBCF,
+ TEGRA_PINGROUP_LCSN,
+ TEGRA_PINGROUP_LD0,
+ TEGRA_PINGROUP_LD1,
+ TEGRA_PINGROUP_LD10,
+ TEGRA_PINGROUP_LD11,
+ TEGRA_PINGROUP_LD12,
+ TEGRA_PINGROUP_LD13,
+ TEGRA_PINGROUP_LD14,
+ TEGRA_PINGROUP_LD15,
+ TEGRA_PINGROUP_LD16,
+ TEGRA_PINGROUP_LD17,
+ TEGRA_PINGROUP_LD2,
+ TEGRA_PINGROUP_LD3,
+ TEGRA_PINGROUP_LD4,
+ TEGRA_PINGROUP_LD5,
+ TEGRA_PINGROUP_LD6,
+ TEGRA_PINGROUP_LD7,
+ TEGRA_PINGROUP_LD8,
+ TEGRA_PINGROUP_LD9,
+ TEGRA_PINGROUP_LDC,
+ TEGRA_PINGROUP_LDI,
+ TEGRA_PINGROUP_LHP0,
+ TEGRA_PINGROUP_LHP1,
+ TEGRA_PINGROUP_LHP2,
+ TEGRA_PINGROUP_LHS,
+ TEGRA_PINGROUP_LM0,
+ TEGRA_PINGROUP_LM1,
+ TEGRA_PINGROUP_LPP,
+ TEGRA_PINGROUP_LPW0,
+ TEGRA_PINGROUP_LPW1,
+ TEGRA_PINGROUP_LPW2,
+ TEGRA_PINGROUP_LSC0,
+ TEGRA_PINGROUP_LSC1,
+ TEGRA_PINGROUP_LSCK,
+ TEGRA_PINGROUP_LSDA,
+ TEGRA_PINGROUP_LSDI,
+ TEGRA_PINGROUP_LSPI,
+ TEGRA_PINGROUP_LVP0,
+ TEGRA_PINGROUP_LVP1,
+ TEGRA_PINGROUP_LVS,
+ TEGRA_PINGROUP_OWC,
+ TEGRA_PINGROUP_PMC,
+ TEGRA_PINGROUP_PTA,
+ TEGRA_PINGROUP_RM,
+ TEGRA_PINGROUP_SDB,
+ TEGRA_PINGROUP_SDC,
+ TEGRA_PINGROUP_SDD,
+ TEGRA_PINGROUP_SDIO1,
+ TEGRA_PINGROUP_SLXA,
+ TEGRA_PINGROUP_SLXC,
+ TEGRA_PINGROUP_SLXD,
+ TEGRA_PINGROUP_SLXK,
+ TEGRA_PINGROUP_SPDI,
+ TEGRA_PINGROUP_SPDO,
+ TEGRA_PINGROUP_SPIA,
+ TEGRA_PINGROUP_SPIB,
+ TEGRA_PINGROUP_SPIC,
+ TEGRA_PINGROUP_SPID,
+ TEGRA_PINGROUP_SPIE,
+ TEGRA_PINGROUP_SPIF,
+ TEGRA_PINGROUP_SPIG,
+ TEGRA_PINGROUP_SPIH,
+ TEGRA_PINGROUP_UAA,
+ TEGRA_PINGROUP_UAB,
+ TEGRA_PINGROUP_UAC,
+ TEGRA_PINGROUP_UAD,
+ TEGRA_PINGROUP_UCA,
+ TEGRA_PINGROUP_UCB,
+ TEGRA_PINGROUP_UDA,
+ /* these pin groups only have pullup and pull down control */
+ TEGRA_PINGROUP_CK32,
+ TEGRA_PINGROUP_DDRC,
+ TEGRA_PINGROUP_PMCA,
+ TEGRA_PINGROUP_PMCB,
+ TEGRA_PINGROUP_PMCC,
+ TEGRA_PINGROUP_PMCD,
+ TEGRA_PINGROUP_PMCE,
+ TEGRA_PINGROUP_XM2C,
+ TEGRA_PINGROUP_XM2D,
+ TEGRA_MAX_PINGROUP,
+};
+
+enum tegra_mux_func {
+ TEGRA_MUX_RSVD = 0x8000,
+ TEGRA_MUX_RSVD1 = 0x8000,
+ TEGRA_MUX_RSVD2 = 0x8001,
+ TEGRA_MUX_RSVD3 = 0x8002,
+ TEGRA_MUX_RSVD4 = 0x8003,
+ TEGRA_MUX_NONE = -1,
+ TEGRA_MUX_AHB_CLK,
+ TEGRA_MUX_APB_CLK,
+ TEGRA_MUX_AUDIO_SYNC,
+ TEGRA_MUX_CRT,
+ TEGRA_MUX_DAP1,
+ TEGRA_MUX_DAP2,
+ TEGRA_MUX_DAP3,
+ TEGRA_MUX_DAP4,
+ TEGRA_MUX_DAP5,
+ TEGRA_MUX_DISPLAYA,
+ TEGRA_MUX_DISPLAYB,
+ TEGRA_MUX_EMC_TEST0_DLL,
+ TEGRA_MUX_EMC_TEST1_DLL,
+ TEGRA_MUX_GMI,
+ TEGRA_MUX_GMI_INT,
+ TEGRA_MUX_HDMI,
+ TEGRA_MUX_I2C,
+ TEGRA_MUX_I2C2,
+ TEGRA_MUX_I2C3,
+ TEGRA_MUX_IDE,
+ TEGRA_MUX_IRDA,
+ TEGRA_MUX_KBC,
+ TEGRA_MUX_MIO,
+ TEGRA_MUX_MIPI_HS,
+ TEGRA_MUX_NAND,
+ TEGRA_MUX_OSC,
+ TEGRA_MUX_OWR,
+ TEGRA_MUX_PCIE,
+ TEGRA_MUX_PLLA_OUT,
+ TEGRA_MUX_PLLC_OUT1,
+ TEGRA_MUX_PLLM_OUT1,
+ TEGRA_MUX_PLLP_OUT2,
+ TEGRA_MUX_PLLP_OUT3,
+ TEGRA_MUX_PLLP_OUT4,
+ TEGRA_MUX_PWM,
+ TEGRA_MUX_PWR_INTR,
+ TEGRA_MUX_PWR_ON,
+ TEGRA_MUX_RTCK,
+ TEGRA_MUX_SDIO1,
+ TEGRA_MUX_SDIO2,
+ TEGRA_MUX_SDIO3,
+ TEGRA_MUX_SDIO4,
+ TEGRA_MUX_SFLASH,
+ TEGRA_MUX_SPDIF,
+ TEGRA_MUX_SPI1,
+ TEGRA_MUX_SPI2,
+ TEGRA_MUX_SPI2_ALT,
+ TEGRA_MUX_SPI3,
+ TEGRA_MUX_SPI4,
+ TEGRA_MUX_TRACE,
+ TEGRA_MUX_TWC,
+ TEGRA_MUX_UARTA,
+ TEGRA_MUX_UARTB,
+ TEGRA_MUX_UARTC,
+ TEGRA_MUX_UARTD,
+ TEGRA_MUX_UARTE,
+ TEGRA_MUX_ULPI,
+ TEGRA_MUX_VI,
+ TEGRA_MUX_VI_SENSOR_CLK,
+ TEGRA_MUX_XIO,
+ TEGRA_MAX_MUX,
+};
+
+enum tegra_pullupdown {
+ TEGRA_PUPD_NORMAL = 0,
+ TEGRA_PUPD_PULL_DOWN,
+ TEGRA_PUPD_PULL_UP,
+};
+
+enum tegra_tristate {
+ TEGRA_TRI_NORMAL = 0,
+ TEGRA_TRI_TRISTATE = 1,
+};
+
+struct tegra_pingroup_config {
+ enum tegra_pingroup pingroup;
+ enum tegra_mux_func func;
+ enum tegra_pullupdown pupd;
+ enum tegra_tristate tristate;
+};
+
+enum tegra_slew {
+ TEGRA_SLEW_FASTEST = 0,
+ TEGRA_SLEW_FAST,
+ TEGRA_SLEW_SLOW,
+ TEGRA_SLEW_SLOWEST,
+ TEGRA_MAX_SLEW,
+};
+
+enum tegra_pull_strength {
+ TEGRA_PULL_0 = 0,
+ TEGRA_PULL_1,
+ TEGRA_PULL_2,
+ TEGRA_PULL_3,
+ TEGRA_PULL_4,
+ TEGRA_PULL_5,
+ TEGRA_PULL_6,
+ TEGRA_PULL_7,
+ TEGRA_PULL_8,
+ TEGRA_PULL_9,
+ TEGRA_PULL_10,
+ TEGRA_PULL_11,
+ TEGRA_PULL_12,
+ TEGRA_PULL_13,
+ TEGRA_PULL_14,
+ TEGRA_PULL_15,
+ TEGRA_PULL_16,
+ TEGRA_PULL_17,
+ TEGRA_PULL_18,
+ TEGRA_PULL_19,
+ TEGRA_PULL_20,
+ TEGRA_PULL_21,
+ TEGRA_PULL_22,
+ TEGRA_PULL_23,
+ TEGRA_PULL_24,
+ TEGRA_PULL_25,
+ TEGRA_PULL_26,
+ TEGRA_PULL_27,
+ TEGRA_PULL_28,
+ TEGRA_PULL_29,
+ TEGRA_PULL_30,
+ TEGRA_PULL_31,
+ TEGRA_MAX_PULL,
+};
+
+enum tegra_drive_pingroup {
+ TEGRA_DRIVE_PINGROUP_AO1 = 0,
+ TEGRA_DRIVE_PINGROUP_AO2,
+ TEGRA_DRIVE_PINGROUP_AT1,
+ TEGRA_DRIVE_PINGROUP_AT2,
+ TEGRA_DRIVE_PINGROUP_CDEV1,
+ TEGRA_DRIVE_PINGROUP_CDEV2,
+ TEGRA_DRIVE_PINGROUP_CSUS,
+ TEGRA_DRIVE_PINGROUP_DAP1,
+ TEGRA_DRIVE_PINGROUP_DAP2,
+ TEGRA_DRIVE_PINGROUP_DAP3,
+ TEGRA_DRIVE_PINGROUP_DAP4,
+ TEGRA_DRIVE_PINGROUP_DBG,
+ TEGRA_DRIVE_PINGROUP_LCD1,
+ TEGRA_DRIVE_PINGROUP_LCD2,
+ TEGRA_DRIVE_PINGROUP_SDMMC2,
+ TEGRA_DRIVE_PINGROUP_SDMMC3,
+ TEGRA_DRIVE_PINGROUP_SPI,
+ TEGRA_DRIVE_PINGROUP_UAA,
+ TEGRA_DRIVE_PINGROUP_UAB,
+ TEGRA_DRIVE_PINGROUP_UART2,
+ TEGRA_DRIVE_PINGROUP_UART3,
+ TEGRA_DRIVE_PINGROUP_VI1,
+ TEGRA_DRIVE_PINGROUP_VI2,
+ TEGRA_DRIVE_PINGROUP_XM2A,
+ TEGRA_DRIVE_PINGROUP_XM2C,
+ TEGRA_DRIVE_PINGROUP_XM2D,
+ TEGRA_DRIVE_PINGROUP_XM2CLK,
+ TEGRA_DRIVE_PINGROUP_MEMCOMP,
+ TEGRA_MAX_DRIVE_PINGROUP,
+};
+
+enum tegra_drive {
+ TEGRA_DRIVE_DIV_8 = 0,
+ TEGRA_DRIVE_DIV_4,
+ TEGRA_DRIVE_DIV_2,
+ TEGRA_DRIVE_DIV_1,
+ TEGRA_MAX_DRIVE,
+};
+
+enum tegra_hsm {
+ TEGRA_HSM_DISABLE = 0,
+ TEGRA_HSM_ENABLE,
+};
+
+enum tegra_schmitt {
+ TEGRA_SCHMITT_DISABLE = 0,
+ TEGRA_SCHMITT_ENABLE,
+};
+
+struct tegra_drive_pingroup_config {
+ enum tegra_drive_pingroup pingroup;
+ enum tegra_hsm hsm;
+ enum tegra_schmitt schmitt;
+ enum tegra_drive drive;
+ enum tegra_pull_strength pull_down;
+ enum tegra_pull_strength pull_up;
+ enum tegra_slew slew_rising;
+ enum tegra_slew slew_falling;
+};
+
+int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func);
+int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate);
+int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd);
+
+void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
+ enum tegra_mux_func func, enum tegra_pullupdown pupd,
+ enum tegra_tristate tristate);
+
+void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len);
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+ int len);
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/smp.h b/arch/arm/mach-tegra/include/mach/smp.h
new file mode 100644
index 000000000000..8b42dab79a70
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/smp.h
@@ -0,0 +1,30 @@
+#ifndef ASMARM_ARCH_SMP_H
+#define ASMARM_ARCH_SMP_H
+
+
+#include <asm/hardware/gic.h>
+
+#define hard_smp_processor_id() \
+ ({ \
+ unsigned int cpunum; \
+ __asm__("mrc p15, 0, %0, c0, c0, 5" \
+ : "=r" (cpunum)); \
+ cpunum &= 0x0F; \
+ })
+
+/*
+ * We use IRQ1 as the IPI
+ */
+static inline void smp_cross_call(const struct cpumask *mask)
+{
+ gic_raise_softirq(mask, 1);
+}
+
+/*
+ * Do nothing on MPcore.
+ */
+static inline void smp_cross_call_done(cpumask_t callmap)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/arch/arm/mach-tegra/include/mach/system.h
new file mode 100644
index 000000000000..84d5d46113f7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/system.h
@@ -0,0 +1,39 @@
+/*
+ * arch/arm/mach-tegra/include/mach/system.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_SYSTEM_H
+#define __MACH_TEGRA_SYSTEM_H
+
+#include <mach/hardware.h>
+#include <mach/iomap.h>
+
+static inline void arch_idle(void)
+{
+}
+
+static inline void arch_reset(char mode, const char *cmd)
+{
+ void __iomem *reset = IO_ADDRESS(TEGRA_CLK_RESET_BASE + 0x04);
+ u32 reg = readl(reset);
+ reg |= 0x04;
+ writel(reg, reset);
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/timex.h b/arch/arm/mach-tegra/include/mach/timex.h
new file mode 100644
index 000000000000..a44ccbdb7dbf
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/timex.h
@@ -0,0 +1,26 @@
+/*
+ * arch/arm/mach-tegra/include/mach/timex.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_TIMEX_H
+#define __MACH_TEGRA_TIMEX_H
+
+#define CLOCK_TICK_RATE 1000000
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
new file mode 100644
index 000000000000..6c4dd815abd7
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-tegra/include/mach/uncompress.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_UNCOMPRESS_H
+#define __MACH_TEGRA_UNCOMPRESS_H
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <mach/iomap.h>
+
+#if defined(CONFIG_TEGRA_DEBUG_UARTA)
+#define DEBUG_UART_BASE TEGRA_UARTA_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTB)
+#define DEBUG_UART_BASE TEGRA_UARTB_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTC)
+#define DEBUG_UART_BASE TEGRA_UARTC_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTD)
+#define DEBUG_UART_BASE TEGRA_UARTD_BASE
+#elif defined(CONFIG_TEGRA_DEBUG_UARTE)
+#define DEBUG_UART_BASE TEGRA_UARTE_BASE
+#else
+#define DEBUG_UART_BASE NULL
+#endif
+
+static void putc(int c)
+{
+ volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE;
+ int shift = 2;
+
+ if (uart == NULL)
+ return;
+
+ while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+ barrier();
+ uart[UART_TX << shift] = c;
+}
+
+static inline void flush(void)
+{
+}
+
+static inline void arch_decomp_setup(void)
+{
+ volatile u8 *uart = (volatile u8 *)DEBUG_UART_BASE;
+ int shift = 2;
+
+ if (uart == NULL)
+ return;
+
+ uart[UART_LCR << shift] |= UART_LCR_DLAB;
+ uart[UART_DLL << shift] = 0x75;
+ uart[UART_DLM << shift] = 0x0;
+ uart[UART_LCR << shift] = 3;
+}
+
+static inline void arch_decomp_wdog(void)
+{
+}
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/vmalloc.h b/arch/arm/mach-tegra/include/mach/vmalloc.h
new file mode 100644
index 000000000000..267a141730d9
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/vmalloc.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-tegra/include/mach/vmalloc.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_VMALLOC_H
+#define __MACH_TEGRA_VMALLOC_H
+
+#include <asm/sizes.h>
+
+#define VMALLOC_END 0xFE000000
+
+#endif
diff --git a/arch/arm/mach-tegra/io.c b/arch/arm/mach-tegra/io.c
new file mode 100644
index 000000000000..9fe2c5c683d4
--- /dev/null
+++ b/arch/arm/mach-tegra/io.c
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-tegra/io.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ * Erik Gilling <konkers@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/mach/map.h>
+
+#include "board.h"
+
+static struct map_desc tegra_io_desc[] __initdata = {
+ {
+ .virtual = IO_PPSB_VIRT,
+ .pfn = __phys_to_pfn(IO_PPSB_PHYS),
+ .length = IO_PPSB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_APB_VIRT,
+ .pfn = __phys_to_pfn(IO_APB_PHYS),
+ .length = IO_APB_SIZE,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = IO_CPU_VIRT,
+ .pfn = __phys_to_pfn(IO_CPU_PHYS),
+ .length = IO_CPU_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init tegra_map_common_io(void)
+{
+ iotable_init(tegra_io_desc, ARRAY_SIZE(tegra_io_desc));
+}
+
+/*
+ * Intercept ioremap() requests for addresses in our fixed mapping regions.
+ */
+void __iomem *tegra_ioremap(unsigned long p, size_t size, unsigned int type)
+{
+ void __iomem *v = IO_ADDRESS(p);
+ if (v == NULL)
+ v = __arm_ioremap(p, size, type);
+ return v;
+}
+EXPORT_SYMBOL(tegra_ioremap);
+
+void tegra_iounmap(volatile void __iomem *addr)
+{
+ unsigned long virt = (unsigned long)addr;
+
+ if (virt >= VMALLOC_START && virt < VMALLOC_END)
+ __iounmap(addr);
+}
+EXPORT_SYMBOL(tegra_iounmap);
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
new file mode 100644
index 000000000000..1fdbe708d43d
--- /dev/null
+++ b/arch/arm/mach-tegra/irq.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+
+#include <asm/hardware/gic.h>
+
+#include <mach/iomap.h>
+
+#include "board.h"
+
+void __init tegra_init_irq(void)
+{
+ gic_dist_init(0, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE), 29);
+ gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
+}
diff --git a/arch/arm/mach-tegra/localtimer.c b/arch/arm/mach-tegra/localtimer.c
new file mode 100644
index 000000000000..f81ca7cbbc1f
--- /dev/null
+++ b/arch/arm/mach-tegra/localtimer.c
@@ -0,0 +1,25 @@
+/*
+ * arch/arm/mach-tegra/localtimer.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/clockchips.h>
+#include <asm/irq.h>
+#include <asm/smp_twd.h>
+#include <asm/localtimer.h>
+
+/*
+ * Setup the local clock events for a CPU.
+ */
+void __cpuinit local_timer_setup(struct clock_event_device *evt)
+{
+ evt->irq = IRQ_LOCALTIMER;
+ twd_timer_setup(evt);
+}
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644
index 000000000000..13ae10237e84
--- /dev/null
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -0,0 +1,945 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <mach/iomap.h>
+#include <mach/pinmux.h>
+
+
+#define TEGRA_TRI_STATE(x) (0x14 + (4 * (x)))
+#define TEGRA_PP_MUX_CTL(x) (0x80 + (4 * (x)))
+#define TEGRA_PP_PU_PD(x) (0xa0 + (4 * (x)))
+
+#define REG_A 0
+#define REG_B 1
+#define REG_C 2
+#define REG_D 3
+#define REG_E 4
+#define REG_F 5
+#define REG_G 6
+
+#define REG_N -1
+
+#define HSM_EN(reg) (((reg) >> 2) & 0x1)
+#define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
+#define LPMD(reg) (((reg) >> 4) & 0x3)
+#define DRVDN(reg) (((reg) >> 12) & 0x1f)
+#define DRVUP(reg) (((reg) >> 20) & 0x1f)
+#define SLWR(reg) (((reg) >> 28) & 0x3)
+#define SLWF(reg) (((reg) >> 30) & 0x3)
+
+struct tegra_pingroup_desc {
+ const char *name;
+ int funcs[4];
+ s8 tri_reg; /* offset into the TRISTATE_REG_* register bank */
+ s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */
+ s8 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
+ s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */
+ s8 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
+ s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */
+};
+
+#define PINGROUP(pg_name, f0, f1, f2, f3, \
+ tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
+ [TEGRA_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .funcs = { \
+ TEGRA_MUX_ ## f0, \
+ TEGRA_MUX_ ## f1, \
+ TEGRA_MUX_ ## f2, \
+ TEGRA_MUX_ ## f3, \
+ }, \
+ .tri_reg = REG_ ## tri_r, \
+ .tri_bit = tri_b, \
+ .mux_reg = REG_ ## mux_r, \
+ .mux_bit = mux_b, \
+ .pupd_reg = REG_ ## pupd_r, \
+ .pupd_bit = pupd_b, \
+ }
+
+static const struct tegra_pingroup_desc pingroups[TEGRA_MAX_PINGROUP] = {
+ PINGROUP(ATA, IDE, NAND, GMI, RSVD, A, 0, A, 24, A, 0),
+ PINGROUP(ATB, IDE, NAND, GMI, SDIO4, A, 1, A, 16, A, 2),
+ PINGROUP(ATC, IDE, NAND, GMI, SDIO4, A, 2, A, 22, A, 4),
+ PINGROUP(ATD, IDE, NAND, GMI, SDIO4, A, 3, A, 20, A, 6),
+ PINGROUP(ATE, IDE, NAND, GMI, RSVD, B, 25, A, 12, A, 8),
+ PINGROUP(CDEV1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, A, 4, C, 2, C, 0),
+ PINGROUP(CDEV2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, A, 5, C, 4, C, 2),
+ PINGROUP(CRTP, CRT, RSVD, RSVD, RSVD, D, 14, G, 20, B, 24),
+ PINGROUP(CSUS, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, A, 6, C, 6, D, 24),
+ PINGROUP(DAP1, DAP1, RSVD, GMI, SDIO2, A, 7, C, 20, A, 10),
+ PINGROUP(DAP2, DAP2, TWC, RSVD, GMI, A, 8, C, 22, A, 12),
+ PINGROUP(DAP3, DAP3, RSVD, RSVD, RSVD, A, 9, C, 24, A, 14),
+ PINGROUP(DAP4, DAP4, RSVD, GMI, RSVD, A, 10, C, 26, A, 16),
+ PINGROUP(DDC, I2C2, RSVD, RSVD, RSVD, B, 31, C, 0, E, 28),
+ PINGROUP(DTA, RSVD, SDIO2, VI, RSVD, A, 11, B, 20, A, 18),
+ PINGROUP(DTB, RSVD, RSVD, VI, SPI1, A, 12, B, 22, A, 20),
+ PINGROUP(DTC, RSVD, RSVD, VI, RSVD, A, 13, B, 26, A, 22),
+ PINGROUP(DTD, RSVD, SDIO2, VI, RSVD, A, 14, B, 28, A, 24),
+ PINGROUP(DTE, RSVD, RSVD, VI, SPI1, A, 15, B, 30, A, 26),
+ PINGROUP(DTF, I2C3, RSVD, VI, RSVD, D, 12, G, 30, A, 28),
+ PINGROUP(GMA, UARTE, SPI3, GMI, SDIO4, A, 28, B, 0, E, 20),
+ PINGROUP(GMB, IDE, NAND, GMI, GMI_INT, B, 29, C, 28, E, 22),
+ PINGROUP(GMC, UARTD, SPI4, GMI, SFLASH, A, 29, B, 2, E, 24),
+ PINGROUP(GMD, RSVD, NAND, GMI, SFLASH, B, 30, C, 30, E, 26),
+ PINGROUP(GME, RSVD, DAP5, GMI, SDIO4, B, 0, D, 0, C, 24),
+ PINGROUP(GPU, PWM, UARTA, GMI, RSVD, A, 16, D, 4, B, 20),
+ PINGROUP(GPU7, RTCK, RSVD, RSVD, RSVD, D, 11, G, 28, B, 6),
+ PINGROUP(GPV, PCIE, RSVD, RSVD, RSVD, A, 17, D, 2, A, 30),
+ PINGROUP(HDINT, HDMI, RSVD, RSVD, RSVD, C, 23, B, 4, D, 22),
+ PINGROUP(I2CP, I2C, RSVD, RSVD, RSVD, A, 18, C, 8, B, 2),
+ PINGROUP(IRRX, UARTA, UARTB, GMI, SPI4, A, 20, C, 18, C, 22),
+ PINGROUP(IRTX, UARTA, UARTB, GMI, SPI4, A, 19, C, 16, C, 20),
+ PINGROUP(KBCA, KBC, NAND, SDIO2, EMC_TEST0_DLL, A, 22, C, 10, B, 8),
+ PINGROUP(KBCB, KBC, NAND, SDIO2, MIO, A, 21, C, 12, B, 10),
+ PINGROUP(KBCC, KBC, NAND, TRACE, EMC_TEST1_DLL, B, 26, C, 14, B, 12),
+ PINGROUP(KBCD, KBC, NAND, SDIO2, MIO, D, 10, G, 26, B, 14),
+ PINGROUP(KBCE, KBC, NAND, OWR, RSVD, A, 26, A, 28, E, 2),
+ PINGROUP(KBCF, KBC, NAND, TRACE, MIO, A, 27, A, 26, E, 0),
+ PINGROUP(LCSN, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 31, E, 12, D, 20),
+ PINGROUP(LD0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 0, F, 0, D, 12),
+ PINGROUP(LD1, DISPLAYA, DISPLAYB, XIO, RSVD, C, 1, F, 2, D, 12),
+ PINGROUP(LD10, DISPLAYA, DISPLAYB, XIO, RSVD, C, 10, F, 20, D, 12),
+ PINGROUP(LD11, DISPLAYA, DISPLAYB, XIO, RSVD, C, 11, F, 22, D, 12),
+ PINGROUP(LD12, DISPLAYA, DISPLAYB, XIO, RSVD, C, 12, F, 24, D, 12),
+ PINGROUP(LD13, DISPLAYA, DISPLAYB, XIO, RSVD, C, 13, F, 26, D, 12),
+ PINGROUP(LD14, DISPLAYA, DISPLAYB, XIO, RSVD, C, 14, F, 28, D, 12),
+ PINGROUP(LD15, DISPLAYA, DISPLAYB, XIO, RSVD, C, 15, F, 30, D, 12),
+ PINGROUP(LD16, DISPLAYA, DISPLAYB, XIO, RSVD, C, 16, G, 0, D, 12),
+ PINGROUP(LD17, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 17, G, 2, D, 12),
+ PINGROUP(LD2, DISPLAYA, DISPLAYB, XIO, RSVD, C, 2, F, 4, D, 12),
+ PINGROUP(LD3, DISPLAYA, DISPLAYB, XIO, RSVD, C, 3, F, 6, D, 12),
+ PINGROUP(LD4, DISPLAYA, DISPLAYB, XIO, RSVD, C, 4, F, 8, D, 12),
+ PINGROUP(LD5, DISPLAYA, DISPLAYB, XIO, RSVD, C, 5, F, 10, D, 12),
+ PINGROUP(LD6, DISPLAYA, DISPLAYB, XIO, RSVD, C, 6, F, 12, D, 12),
+ PINGROUP(LD7, DISPLAYA, DISPLAYB, XIO, RSVD, C, 7, F, 14, D, 12),
+ PINGROUP(LD8, DISPLAYA, DISPLAYB, XIO, RSVD, C, 8, F, 16, D, 12),
+ PINGROUP(LD9, DISPLAYA, DISPLAYB, XIO, RSVD, C, 9, F, 18, D, 12),
+ PINGROUP(LDC, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 30, E, 14, D, 20),
+ PINGROUP(LDI, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 6, G, 16, D, 18),
+ PINGROUP(LHP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 18, G, 10, D, 16),
+ PINGROUP(LHP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 19, G, 4, D, 14),
+ PINGROUP(LHP2, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 20, G, 6, D, 14),
+ PINGROUP(LHS, DISPLAYA, DISPLAYB, XIO, RSVD, D, 7, E, 22, D, 22),
+ PINGROUP(LM0, DISPLAYA, DISPLAYB, SPI3, RSVD, C, 24, E, 26, D, 22),
+ PINGROUP(LM1, DISPLAYA, DISPLAYB, RSVD, CRT, C, 25, E, 28, D, 22),
+ PINGROUP(LPP, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 8, G, 14, D, 18),
+ PINGROUP(LPW0, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 3, E, 0, D, 20),
+ PINGROUP(LPW1, DISPLAYA, DISPLAYB, RSVD, RSVD, D, 4, E, 2, D, 20),
+ PINGROUP(LPW2, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 5, E, 4, D, 20),
+ PINGROUP(LSC0, DISPLAYA, DISPLAYB, XIO, RSVD, C, 27, E, 18, D, 22),
+ PINGROUP(LSC1, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 28, E, 20, D, 20),
+ PINGROUP(LSCK, DISPLAYA, DISPLAYB, SPI3, HDMI, C, 29, E, 16, D, 20),
+ PINGROUP(LSDA, DISPLAYA, DISPLAYB, SPI3, HDMI, D, 1, E, 8, D, 20),
+ PINGROUP(LSDI, DISPLAYA, DISPLAYB, SPI3, RSVD, D, 2, E, 6, D, 20),
+ PINGROUP(LSPI, DISPLAYA, DISPLAYB, XIO, HDMI, D, 0, E, 10, D, 22),
+ PINGROUP(LVP0, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 21, E, 30, D, 22),
+ PINGROUP(LVP1, DISPLAYA, DISPLAYB, RSVD, RSVD, C, 22, G, 8, D, 16),
+ PINGROUP(LVS, DISPLAYA, DISPLAYB, XIO, RSVD, C, 26, E, 24, D, 22),
+ PINGROUP(OWC, OWR, RSVD, RSVD, RSVD, A, 31, B, 8, E, 30),
+ PINGROUP(PMC, PWR_ON, PWR_INTR, RSVD, RSVD, A, 23, G, 18, N, -1),
+ PINGROUP(PTA, I2C2, HDMI, GMI, RSVD, A, 24, G, 22, B, 4),
+ PINGROUP(RM, I2C, RSVD, RSVD, RSVD, A, 25, A, 14, B, 0),
+ PINGROUP(SDB, UARTA, PWM, SDIO3, SPI2, D, 15, D, 10, N, -1),
+ PINGROUP(SDC, PWM, TWC, SDIO3, SPI3, B, 1, D, 12, D, 28),
+ PINGROUP(SDD, UARTA, PWM, SDIO3, SPI3, B, 2, D, 14, D, 30),
+ PINGROUP(SDIO1, SDIO1, RSVD, UARTE, UARTA, A, 30, A, 30, E, 18),
+ PINGROUP(SLXA, PCIE, SPI4, SDIO3, SPI2, B, 3, B, 6, B, 22),
+ PINGROUP(SLXC, SPDIF, SPI4, SDIO3, SPI2, B, 5, B, 10, B, 26),
+ PINGROUP(SLXD, SPDIF, SPI4, SDIO3, SPI2, B, 6, B, 12, B, 28),
+ PINGROUP(SLXK, PCIE, SPI4, SDIO3, SPI2, B, 7, B, 14, B, 30),
+ PINGROUP(SPDI, SPDIF, RSVD, I2C, SDIO2, B, 8, D, 8, B, 16),
+ PINGROUP(SPDO, SPDIF, RSVD, I2C, SDIO2, B, 9, D, 6, B, 18),
+ PINGROUP(SPIA, SPI1, SPI2, SPI3, GMI, B, 10, D, 30, C, 4),
+ PINGROUP(SPIB, SPI1, SPI2, SPI3, GMI, B, 11, D, 28, C, 6),
+ PINGROUP(SPIC, SPI1, SPI2, SPI3, GMI, B, 12, D, 26, C, 8),
+ PINGROUP(SPID, SPI2, SPI1, SPI2_ALT, GMI, B, 13, D, 24, C, 10),
+ PINGROUP(SPIE, SPI2, SPI1, SPI2_ALT, GMI, B, 14, D, 22, C, 12),
+ PINGROUP(SPIF, SPI3, SPI1, SPI2, RSVD, B, 15, D, 20, C, 14),
+ PINGROUP(SPIG, SPI3, SPI2, SPI2_ALT, I2C, B, 16, D, 18, C, 16),
+ PINGROUP(SPIH, SPI3, SPI2, SPI2_ALT, I2C, B, 17, D, 16, C, 18),
+ PINGROUP(UAA, SPI3, MIPI_HS, UARTA, ULPI, B, 18, A, 0, D, 0),
+ PINGROUP(UAB, SPI2, MIPI_HS, UARTA, ULPI, B, 19, A, 2, D, 2),
+ PINGROUP(UAC, OWR, RSVD, RSVD, RSVD, B, 20, A, 4, D, 4),
+ PINGROUP(UAD, IRDA, SPDIF, UARTA, SPI4, B, 21, A, 6, D, 6),
+ PINGROUP(UCA, UARTC, RSVD, GMI, RSVD, B, 22, B, 16, D, 8),
+ PINGROUP(UCB, UARTC, PWM, GMI, RSVD, B, 23, B, 18, D, 10),
+ PINGROUP(UDA, SPI1, RSVD, UARTD, ULPI, D, 13, A, 8, E, 16),
+ /* these pin groups only have pullup and pull down control */
+ PINGROUP(CK32, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 14),
+ PINGROUP(DDRC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, D, 26),
+ PINGROUP(PMCA, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 4),
+ PINGROUP(PMCB, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 6),
+ PINGROUP(PMCC, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 8),
+ PINGROUP(PMCD, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 10),
+ PINGROUP(PMCE, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, E, 12),
+ PINGROUP(XM2C, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 30),
+ PINGROUP(XM2D, RSVD, RSVD, RSVD, RSVD, N, -1, N, -1, C, 28),
+};
+
+static char *tegra_mux_names[TEGRA_MAX_MUX] = {
+ [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
+ [TEGRA_MUX_APB_CLK] = "APB_CLK",
+ [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
+ [TEGRA_MUX_CRT] = "CRT",
+ [TEGRA_MUX_DAP1] = "DAP1",
+ [TEGRA_MUX_DAP2] = "DAP2",
+ [TEGRA_MUX_DAP3] = "DAP3",
+ [TEGRA_MUX_DAP4] = "DAP4",
+ [TEGRA_MUX_DAP5] = "DAP5",
+ [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
+ [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
+ [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
+ [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
+ [TEGRA_MUX_GMI] = "GMI",
+ [TEGRA_MUX_GMI_INT] = "GMI_INT",
+ [TEGRA_MUX_HDMI] = "HDMI",
+ [TEGRA_MUX_I2C] = "I2C",
+ [TEGRA_MUX_I2C2] = "I2C2",
+ [TEGRA_MUX_I2C3] = "I2C3",
+ [TEGRA_MUX_IDE] = "IDE",
+ [TEGRA_MUX_IRDA] = "IRDA",
+ [TEGRA_MUX_KBC] = "KBC",
+ [TEGRA_MUX_MIO] = "MIO",
+ [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
+ [TEGRA_MUX_NAND] = "NAND",
+ [TEGRA_MUX_OSC] = "OSC",
+ [TEGRA_MUX_OWR] = "OWR",
+ [TEGRA_MUX_PCIE] = "PCIE",
+ [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
+ [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
+ [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
+ [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
+ [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
+ [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
+ [TEGRA_MUX_PWM] = "PWM",
+ [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
+ [TEGRA_MUX_PWR_ON] = "PWR_ON",
+ [TEGRA_MUX_RTCK] = "RTCK",
+ [TEGRA_MUX_SDIO1] = "SDIO1",
+ [TEGRA_MUX_SDIO2] = "SDIO2",
+ [TEGRA_MUX_SDIO3] = "SDIO3",
+ [TEGRA_MUX_SDIO4] = "SDIO4",
+ [TEGRA_MUX_SFLASH] = "SFLASH",
+ [TEGRA_MUX_SPDIF] = "SPDIF",
+ [TEGRA_MUX_SPI1] = "SPI1",
+ [TEGRA_MUX_SPI2] = "SPI2",
+ [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
+ [TEGRA_MUX_SPI3] = "SPI3",
+ [TEGRA_MUX_SPI4] = "SPI4",
+ [TEGRA_MUX_TRACE] = "TRACE",
+ [TEGRA_MUX_TWC] = "TWC",
+ [TEGRA_MUX_UARTA] = "UARTA",
+ [TEGRA_MUX_UARTB] = "UARTB",
+ [TEGRA_MUX_UARTC] = "UARTC",
+ [TEGRA_MUX_UARTD] = "UARTD",
+ [TEGRA_MUX_UARTE] = "UARTE",
+ [TEGRA_MUX_ULPI] = "ULPI",
+ [TEGRA_MUX_VI] = "VI",
+ [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
+ [TEGRA_MUX_XIO] = "XIO",
+};
+
+struct tegra_drive_pingroup_desc {
+ const char *name;
+ s16 reg;
+};
+
+#define DRIVE_PINGROUP(pg_name, r) \
+ [TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
+ .name = #pg_name, \
+ .reg = r \
+ }
+
+static const struct tegra_drive_pingroup_desc drive_pingroups[TEGRA_MAX_PINGROUP] = {
+ DRIVE_PINGROUP(AO1, 0x868),
+ DRIVE_PINGROUP(AO2, 0x86c),
+ DRIVE_PINGROUP(AT1, 0x870),
+ DRIVE_PINGROUP(AT2, 0x874),
+ DRIVE_PINGROUP(CDEV1, 0x878),
+ DRIVE_PINGROUP(CDEV2, 0x87c),
+ DRIVE_PINGROUP(CSUS, 0x880),
+ DRIVE_PINGROUP(DAP1, 0x884),
+ DRIVE_PINGROUP(DAP2, 0x888),
+ DRIVE_PINGROUP(DAP3, 0x88c),
+ DRIVE_PINGROUP(DAP4, 0x890),
+ DRIVE_PINGROUP(DBG, 0x894),
+ DRIVE_PINGROUP(LCD1, 0x898),
+ DRIVE_PINGROUP(LCD2, 0x89c),
+ DRIVE_PINGROUP(SDMMC2, 0x8a0),
+ DRIVE_PINGROUP(SDMMC3, 0x8a4),
+ DRIVE_PINGROUP(SPI, 0x8a8),
+ DRIVE_PINGROUP(UAA, 0x8ac),
+ DRIVE_PINGROUP(UAB, 0x8b0),
+ DRIVE_PINGROUP(UART2, 0x8b4),
+ DRIVE_PINGROUP(UART3, 0x8b8),
+ DRIVE_PINGROUP(VI1, 0x8bc),
+ DRIVE_PINGROUP(VI2, 0x8c0),
+ DRIVE_PINGROUP(XM2A, 0x8c4),
+ DRIVE_PINGROUP(XM2C, 0x8c8),
+ DRIVE_PINGROUP(XM2D, 0x8cc),
+ DRIVE_PINGROUP(XM2CLK, 0x8d0),
+ DRIVE_PINGROUP(MEMCOMP, 0x8d4),
+};
+
+static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
+ [TEGRA_DRIVE_DIV_8] = "DIV_8",
+ [TEGRA_DRIVE_DIV_4] = "DIV_4",
+ [TEGRA_DRIVE_DIV_2] = "DIV_2",
+ [TEGRA_DRIVE_DIV_1] = "DIV_1",
+};
+
+static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
+ [TEGRA_SLEW_FASTEST] = "FASTEST",
+ [TEGRA_SLEW_FAST] = "FAST",
+ [TEGRA_SLEW_SLOW] = "SLOW",
+ [TEGRA_SLEW_SLOWEST] = "SLOWEST",
+};
+
+static DEFINE_SPINLOCK(mux_lock);
+
+static const char *pingroup_name(enum tegra_pingroup pg)
+{
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return "<UNKNOWN>";
+
+ return pingroups[pg].name;
+}
+
+static const char *func_name(enum tegra_mux_func func)
+{
+ if (func == TEGRA_MUX_RSVD1)
+ return "RSVD1";
+
+ if (func == TEGRA_MUX_RSVD2)
+ return "RSVD2";
+
+ if (func == TEGRA_MUX_RSVD3)
+ return "RSVD3";
+
+ if (func == TEGRA_MUX_RSVD4)
+ return "RSVD4";
+
+ if (func == TEGRA_MUX_NONE)
+ return "NONE";
+
+ if (func < 0 || func >= TEGRA_MAX_MUX)
+ return "<UNKNOWN>";
+
+ return tegra_mux_names[func];
+}
+
+
+static const char *tri_name(unsigned long val)
+{
+ return val ? "TRISTATE" : "NORMAL";
+}
+
+static const char *pupd_name(unsigned long val)
+{
+ switch (val) {
+ case 0:
+ return "NORMAL";
+
+ case 1:
+ return "PULL_DOWN";
+
+ case 2:
+ return "PULL_UP";
+
+ default:
+ return "RSVD";
+ }
+}
+
+
+static inline unsigned long pg_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+static inline void pg_writel(unsigned long value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
+}
+
+int tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func)
+{
+ int mux = -1;
+ int i;
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg == REG_N)
+ return -EINVAL;
+
+ if (func < 0)
+ return -ERANGE;
+
+ if (func & TEGRA_MUX_RSVD) {
+ mux = func & 0x3;
+ } else {
+ for (i = 0; i < 4; i++) {
+ if (pingroups[pg].funcs[i] == func) {
+ mux = i;
+ break;
+ }
+ }
+ }
+
+ if (mux < 0)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
+ reg &= ~(0x3 << pingroups[pg].mux_bit);
+ reg |= mux << pingroups[pg].mux_bit;
+ pg_writel(reg, TEGRA_PP_MUX_CTL(pingroups[pg].mux_reg));
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
+ enum tegra_tristate tristate)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].tri_reg == REG_N)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(TEGRA_TRI_STATE(pingroups[pg].tri_reg));
+ reg &= ~(0x1 << pingroups[pg].tri_bit);
+ if (tristate)
+ reg |= 1 << pingroups[pg].tri_bit;
+ pg_writel(reg, TEGRA_TRI_STATE(pingroups[pg].tri_reg));
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
+ enum tegra_pullupdown pupd)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].pupd_reg == REG_N)
+ return -EINVAL;
+
+ if (pupd != TEGRA_PUPD_NORMAL &&
+ pupd != TEGRA_PUPD_PULL_DOWN &&
+ pupd != TEGRA_PUPD_PULL_UP)
+ return -EINVAL;
+
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
+ reg &= ~(0x3 << pingroups[pg].pupd_bit);
+ reg |= pupd << pingroups[pg].pupd_bit;
+ pg_writel(reg, TEGRA_PP_PU_PD(pingroups[pg].pupd_reg));
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
+ enum tegra_mux_func func,
+ enum tegra_pullupdown pupd,
+ enum tegra_tristate tristate)
+{
+ int err;
+
+ if (pingroups[pingroup].mux_reg != REG_N) {
+ err = tegra_pinmux_set_func(pingroup, func);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
+ pingroup_name(pingroup), func_name(func), err);
+ }
+
+ if (pingroups[pingroup].pupd_reg != REG_N) {
+ err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
+ pingroup_name(pingroup), pupd_name(pupd), err);
+ }
+
+ if (pingroups[pingroup].tri_reg != REG_N) {
+ err = tegra_pinmux_set_tristate(pingroup, tristate);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
+ pingroup_name(pingroup), tri_name(func), err);
+ }
+}
+
+
+
+void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ tegra_pinmux_config_pingroup(config[i].pingroup,
+ config[i].func,
+ config[i].pupd,
+ config[i].tristate);
+}
+
+static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
+{
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return "<UNKNOWN>";
+
+ return drive_pingroups[pg].name;
+}
+
+static const char *enable_name(unsigned long val)
+{
+ return val ? "ENABLE" : "DISABLE";
+}
+
+static const char *drive_name(unsigned long val)
+{
+ if (val >= TEGRA_MAX_DRIVE)
+ return "<UNKNOWN>";
+
+ return tegra_drive_names[val];
+}
+
+static const char *slew_name(unsigned long val)
+{
+ if (val >= TEGRA_MAX_SLEW)
+ return "<UNKNOWN>";
+
+ return tegra_slew_names[val];
+}
+
+static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
+ enum tegra_hsm hsm)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ if (hsm == TEGRA_HSM_ENABLE)
+ reg |= (1 << 2);
+ else
+ reg &= ~(1 << 2);
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
+ enum tegra_schmitt schmitt)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ if (schmitt == TEGRA_SCHMITT_ENABLE)
+ reg |= (1 << 3);
+ else
+ reg &= ~(1 << 3);
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
+ enum tegra_drive drive)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 4);
+ reg |= drive << 4;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
+ enum tegra_pull_strength pull_down)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x1f << 12);
+ reg |= pull_down << 12;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
+ enum tegra_pull_strength pull_up)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x1f << 12);
+ reg |= pull_up << 12;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
+ enum tegra_slew slew_rising)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 28);
+ reg |= slew_rising << 28;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
+ enum tegra_slew slew_falling)
+{
+ unsigned long flags;
+ u32 reg;
+ if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
+ return -ERANGE;
+
+ if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
+ return -EINVAL;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(drive_pingroups[pg].reg);
+ reg &= ~(0x3 << 30);
+ reg |= slew_falling << 30;
+ pg_writel(reg, drive_pingroups[pg].reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
+ enum tegra_hsm hsm,
+ enum tegra_schmitt schmitt,
+ enum tegra_drive drive,
+ enum tegra_pull_strength pull_down,
+ enum tegra_pull_strength pull_up,
+ enum tegra_slew slew_rising,
+ enum tegra_slew slew_falling)
+{
+ int err;
+
+ err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ enable_name(hsm), err);
+
+ err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ enable_name(schmitt), err);
+
+ err = tegra_drive_pinmux_set_drive(pingroup, drive);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ drive_name(drive), err);
+
+ err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
+ drive_pinmux_name(pingroup),
+ pull_down, err);
+
+ err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
+ drive_pinmux_name(pingroup),
+ pull_up, err);
+
+ err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ slew_name(slew_rising), err);
+
+ err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
+ drive_pinmux_name(pingroup),
+ slew_name(slew_falling), err);
+}
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++)
+ tegra_drive_pinmux_config_pingroup(config[i].pingroup,
+ config[i].hsm,
+ config[i].schmitt,
+ config[i].drive,
+ config[i].pull_down,
+ config[i].pull_up,
+ config[i].slew_rising,
+ config[i].slew_falling);
+}
+
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void dbg_pad_field(struct seq_file *s, int len)
+{
+ seq_putc(s, ',');
+
+ while (len-- > -1)
+ seq_putc(s, ' ');
+}
+
+static int dbg_pinmux_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int len;
+
+ for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
+ unsigned long tri;
+ unsigned long mux;
+ unsigned long pupd;
+
+ seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
+ len = strlen(pingroups[i].name);
+ dbg_pad_field(s, 5 - len);
+
+ if (pingroups[i].mux_reg == REG_N) {
+ seq_printf(s, "TEGRA_MUX_NONE");
+ len = strlen("NONE");
+ } else {
+ mux = (pg_readl(TEGRA_PP_MUX_CTL(pingroups[i].mux_reg)) >>
+ pingroups[i].mux_bit) & 0x3;
+ if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
+ seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
+ len = 5;
+ } else {
+ seq_printf(s, "TEGRA_MUX_%s",
+ tegra_mux_names[pingroups[i].funcs[mux]]);
+ len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
+ }
+ }
+ dbg_pad_field(s, 13-len);
+
+ if (pingroups[i].mux_reg == REG_N) {
+ seq_printf(s, "TEGRA_PUPD_NORMAL");
+ len = strlen("NORMAL");
+ } else {
+ pupd = (pg_readl(TEGRA_PP_PU_PD(pingroups[i].pupd_reg)) >>
+ pingroups[i].pupd_bit) & 0x3;
+ seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
+ len = strlen(pupd_name(pupd));
+ }
+ dbg_pad_field(s, 9 - len);
+
+ if (pingroups[i].tri_reg == REG_N) {
+ seq_printf(s, "TEGRA_TRI_NORMAL");
+ } else {
+ tri = (pg_readl(TEGRA_TRI_STATE(pingroups[i].tri_reg)) >>
+ pingroups[i].tri_bit) & 0x1;
+
+ seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
+ }
+ seq_printf(s, "},\n");
+ }
+ return 0;
+}
+
+static int dbg_pinmux_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+ .open = dbg_pinmux_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
+{
+ int i;
+ int len;
+
+ for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
+ u32 reg;
+
+ seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
+ drive_pingroups[i].name);
+ len = strlen(drive_pingroups[i].name);
+ dbg_pad_field(s, 7 - len);
+
+
+ reg = pg_readl(drive_pingroups[i].reg);
+ if (HSM_EN(reg)) {
+ seq_printf(s, "TEGRA_HSM_ENABLE");
+ len = 16;
+ } else {
+ seq_printf(s, "TEGRA_HSM_DISABLE");
+ len = 17;
+ }
+ dbg_pad_field(s, 17 - len);
+
+ if (SCHMT_EN(reg)) {
+ seq_printf(s, "TEGRA_SCHMITT_ENABLE");
+ len = 21;
+ } else {
+ seq_printf(s, "TEGRA_SCHMITT_DISABLE");
+ len = 22;
+ }
+ dbg_pad_field(s, 22 - len);
+
+ seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
+ len = strlen(drive_name(LPMD(reg)));
+ dbg_pad_field(s, 5 - len);
+
+ seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
+ len = DRVDN(reg) < 10 ? 1 : 2;
+ dbg_pad_field(s, 2 - len);
+
+ seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
+ len = DRVUP(reg) < 10 ? 1 : 2;
+ dbg_pad_field(s, 2 - len);
+
+ seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
+ len = strlen(slew_name(SLWR(reg)));
+ dbg_pad_field(s, 7 - len);
+
+ seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
+
+ seq_printf(s, "},\n");
+ }
+ return 0;
+}
+
+static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_drive_fops = {
+ .open = dbg_drive_pinmux_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init tegra_pinmux_debuginit(void)
+{
+ (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
+ NULL, NULL, &debug_fops);
+ (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
+ NULL, NULL, &debug_drive_fops);
+ return 0;
+}
+late_initcall(tegra_pinmux_debuginit);
+#endif
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c
new file mode 100644
index 000000000000..1c0fd92cab39
--- /dev/null
+++ b/arch/arm/mach-tegra/platsmp.c
@@ -0,0 +1,156 @@
+/*
+ * linux/arch/arm/mach-tegra/platsmp.c
+ *
+ * Copyright (C) 2002 ARM Ltd.
+ * All Rights Reserved
+ *
+ * Copyright (C) 2009 Palm
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/localtimer.h>
+#include <asm/smp_scu.h>
+
+#include <mach/iomap.h>
+
+extern void tegra_secondary_startup(void);
+
+static DEFINE_SPINLOCK(boot_lock);
+static void __iomem *scu_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE);
+
+#define EVP_CPU_RESET_VECTOR \
+ (IO_ADDRESS(TEGRA_EXCEPTION_VECTORS_BASE) + 0x100)
+#define CLK_RST_CONTROLLER_CLK_CPU_CMPLX \
+ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x4c)
+#define CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR \
+ (IO_ADDRESS(TEGRA_CLK_RESET_BASE) + 0x344)
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ trace_hardirqs_off();
+
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_cpu_init(0, IO_ADDRESS(TEGRA_ARM_PERIF_BASE) + 0x100);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long old_boot_vector;
+ unsigned long boot_vector;
+ unsigned long timeout;
+ u32 reg;
+
+ /*
+ * set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+
+ /* set the reset vector to point to the secondary_startup routine */
+
+ boot_vector = virt_to_phys(tegra_secondary_startup);
+ old_boot_vector = readl(EVP_CPU_RESET_VECTOR);
+ writel(boot_vector, EVP_CPU_RESET_VECTOR);
+
+ /* enable cpu clock on cpu1 */
+ reg = readl(CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+ writel(reg & ~(1<<9), CLK_RST_CONTROLLER_CLK_CPU_CMPLX);
+
+ reg = (1<<13) | (1<<9) | (1<<5) | (1<<1);
+ writel(reg, CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR);
+
+ smp_wmb();
+ flush_cache_all();
+
+ /* unhalt the cpu */
+ writel(0, IO_ADDRESS(TEGRA_FLOW_CTRL_BASE) + 0x14);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ if (readl(EVP_CPU_RESET_VECTOR) != boot_vector)
+ break;
+ udelay(10);
+ }
+
+ /* put the old boot vector back */
+ writel(old_boot_vector, EVP_CPU_RESET_VECTOR);
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+ unsigned int i, ncores = scu_get_core_count(scu_base);
+
+ for (i = 0; i < ncores; i++)
+ cpu_set(i, cpu_possible_map);
+}
+
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ unsigned int ncores = scu_get_core_count(scu_base);
+ unsigned int cpu = smp_processor_id();
+ int i;
+
+ smp_store_cpu_info(cpu);
+
+ /*
+ * are we trying to boot more cores than exist?
+ */
+ if (max_cpus > ncores)
+ max_cpus = ncores;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ /*
+ * Initialise the SCU if there are more than one CPU and let
+ * them know where to start. Note that, on modern versions of
+ * MILO, the "poke" doesn't actually do anything until each
+ * individual core is sent a soft interrupt to get it out of
+ * WFI
+ */
+ if (max_cpus > 1) {
+ percpu_timer_setup();
+ scu_enable(scu_base);
+ }
+}
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
new file mode 100644
index 000000000000..426163231fff
--- /dev/null
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -0,0 +1,1359 @@
+/*
+ * arch/arm/mach-tegra/tegra2_clocks.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/hrtimer.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/iomap.h>
+
+#include "clock.h"
+
+#define RST_DEVICES 0x004
+#define RST_DEVICES_SET 0x300
+#define RST_DEVICES_CLR 0x304
+
+#define CLK_OUT_ENB 0x010
+#define CLK_OUT_ENB_SET 0x320
+#define CLK_OUT_ENB_CLR 0x324
+
+#define OSC_CTRL 0x50
+#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
+#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
+#define OSC_CTRL_OSC_FREQ_19_2MHZ (1<<30)
+#define OSC_CTRL_OSC_FREQ_12MHZ (2<<30)
+#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
+
+#define OSC_FREQ_DET 0x58
+#define OSC_FREQ_DET_TRIG (1<<31)
+
+#define OSC_FREQ_DET_STATUS 0x5C
+#define OSC_FREQ_DET_BUSY (1<<31)
+#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+
+#define PERIPH_CLK_SOURCE_MASK (3<<30)
+#define PERIPH_CLK_SOURCE_SHIFT 30
+#define PERIPH_CLK_SOURCE_ENABLE (1<<28)
+#define PERIPH_CLK_SOURCE_DIV_MASK 0xFF
+#define PERIPH_CLK_SOURCE_DIV_SHIFT 0
+
+#define PLL_BASE 0x0
+#define PLL_BASE_BYPASS (1<<31)
+#define PLL_BASE_ENABLE (1<<30)
+#define PLL_BASE_REF_ENABLE (1<<29)
+#define PLL_BASE_OVERRIDE (1<<28)
+#define PLL_BASE_LOCK (1<<27)
+#define PLL_BASE_DIVP_MASK (0x7<<20)
+#define PLL_BASE_DIVP_SHIFT 20
+#define PLL_BASE_DIVN_MASK (0x3FF<<8)
+#define PLL_BASE_DIVN_SHIFT 8
+#define PLL_BASE_DIVM_MASK (0x1F)
+#define PLL_BASE_DIVM_SHIFT 0
+
+#define PLL_OUT_RATIO_MASK (0xFF<<8)
+#define PLL_OUT_RATIO_SHIFT 8
+#define PLL_OUT_OVERRIDE (1<<2)
+#define PLL_OUT_CLKEN (1<<1)
+#define PLL_OUT_RESET_DISABLE (1<<0)
+
+#define PLL_MISC(c) (((c)->flags & PLL_ALT_MISC_REG) ? 0x4 : 0xc)
+#define PLL_MISC_DCCON_SHIFT 20
+#define PLL_MISC_LOCK_ENABLE (1<<18)
+#define PLL_MISC_CPCON_SHIFT 8
+#define PLL_MISC_CPCON_MASK (0xF<<PLL_MISC_CPCON_SHIFT)
+#define PLL_MISC_LFCON_SHIFT 4
+#define PLL_MISC_LFCON_MASK (0xF<<PLL_MISC_LFCON_SHIFT)
+#define PLL_MISC_VCOCON_SHIFT 0
+#define PLL_MISC_VCOCON_MASK (0xF<<PLL_MISC_VCOCON_SHIFT)
+
+#define PLLD_MISC_CLKENABLE (1<<30)
+#define PLLD_MISC_DIV_RST (1<<23)
+#define PLLD_MISC_DCCON_SHIFT 12
+
+#define PERIPH_CLK_TO_ENB_REG(c) ((c->clk_num / 32) * 4)
+#define PERIPH_CLK_TO_ENB_SET_REG(c) ((c->clk_num / 32) * 8)
+#define PERIPH_CLK_TO_ENB_BIT(c) (1 << (c->clk_num % 32))
+
+#define SUPER_CLK_MUX 0x00
+#define SUPER_STATE_SHIFT 28
+#define SUPER_STATE_MASK (0xF << SUPER_STATE_SHIFT)
+#define SUPER_STATE_STANDBY (0x0 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IDLE (0x1 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_RUN (0x2 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_IRQ (0x3 << SUPER_STATE_SHIFT)
+#define SUPER_STATE_FIQ (0x4 << SUPER_STATE_SHIFT)
+#define SUPER_SOURCE_MASK 0xF
+#define SUPER_FIQ_SOURCE_SHIFT 12
+#define SUPER_IRQ_SOURCE_SHIFT 8
+#define SUPER_RUN_SOURCE_SHIFT 4
+#define SUPER_IDLE_SOURCE_SHIFT 0
+
+#define SUPER_CLK_DIVIDER 0x04
+
+#define BUS_CLK_DISABLE (1<<3)
+#define BUS_CLK_DIV_MASK 0x3
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+
+#define clk_writel(value, reg) \
+ __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+ __raw_readl((u32)reg_clk_base + (reg))
+
+unsigned long clk_measure_input_freq(void)
+{
+ u32 clock_autodetect;
+ clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+ do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+ clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+ if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
+ return 12000000;
+ } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
+ return 13000000;
+ } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
+ return 19200000;
+ } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
+ return 26000000;
+ } else {
+ pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
+ BUG();
+ return 0;
+ }
+}
+
+static int clk_div71_get_divider(struct clk *c, unsigned long rate)
+{
+ unsigned long divider_u71;
+
+ divider_u71 = DIV_ROUND_UP(c->rate * 2, rate);
+
+ if (divider_u71 - 2 > 255 || divider_u71 - 2 < 0)
+ return -EINVAL;
+
+ return divider_u71 - 2;
+}
+
+static unsigned long tegra2_clk_recalculate_rate(struct clk *c)
+{
+ unsigned long rate;
+ rate = c->parent->rate;
+
+ if (c->mul != 0 && c->div != 0)
+ c->rate = rate * c->mul / c->div;
+ else
+ c->rate = rate;
+ return c->rate;
+}
+
+
+/* clk_m functions */
+static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
+{
+ u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
+
+ c->rate = clk_measure_input_freq();
+ switch (c->rate) {
+ case 12000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
+ break;
+ case 13000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_13MHZ;
+ break;
+ case 19200000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_19_2MHZ;
+ break;
+ case 26000000:
+ auto_clock_control |= OSC_CTRL_OSC_FREQ_26MHZ;
+ break;
+ default:
+ pr_err("%s: Unexpected clock rate %ld", __func__, c->rate);
+ BUG();
+ }
+ clk_writel(auto_clock_control, OSC_CTRL);
+ return c->rate;
+}
+
+static void tegra2_clk_m_init(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ tegra2_clk_m_autodetect_rate(c);
+}
+
+static int tegra2_clk_m_enable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ return 0;
+}
+
+static void tegra2_clk_m_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ BUG();
+}
+
+static struct clk_ops tegra_clk_m_ops = {
+ .init = tegra2_clk_m_init,
+ .enable = tegra2_clk_m_enable,
+ .disable = tegra2_clk_m_disable,
+};
+
+/* super clock functions */
+/* "super clocks" on tegra have two-stage muxes and a clock skipping
+ * super divider. We will ignore the clock skipping divider, since we
+ * can't lower the voltage when using the clock skip, but we can if we
+ * lower the PLL frequency.
+ */
+static void tegra2_super_clk_init(struct clk *c)
+{
+ u32 val;
+ int source;
+ int shift;
+ const struct clk_mux_sel *sel;
+ val = clk_readl(c->reg + SUPER_CLK_MUX);
+ c->state = ON;
+ BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+ ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+ shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+ SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+ source = (val >> shift) & SUPER_SOURCE_MASK;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->value == source)
+ break;
+ }
+ BUG_ON(sel->input == NULL);
+ c->parent = sel->input;
+ tegra2_clk_recalculate_rate(c);
+}
+
+static int tegra2_super_clk_enable(struct clk *c)
+{
+ clk_writel(0, c->reg + SUPER_CLK_DIVIDER);
+ return 0;
+}
+
+static void tegra2_super_clk_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ /* oops - don't disable the CPU clock! */
+ BUG();
+}
+
+static int tegra2_super_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ int shift;
+ val = clk_readl(c->reg + SUPER_CLK_MUX);;
+ BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
+ ((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
+ shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
+ SUPER_IDLE_SOURCE_SHIFT : SUPER_RUN_SOURCE_SHIFT;
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ clk_reparent(c, p);
+ val &= ~(SUPER_SOURCE_MASK << shift);
+ val |= sel->value << shift;
+ clk_writel(val, c->reg);
+ c->rate = c->parent->rate;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_super_ops = {
+ .init = tegra2_super_clk_init,
+ .enable = tegra2_super_clk_enable,
+ .disable = tegra2_super_clk_disable,
+ .set_parent = tegra2_super_clk_set_parent,
+ .recalculate_rate = tegra2_clk_recalculate_rate,
+};
+
+/* bus clock functions */
+static void tegra2_bus_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ c->state = ((val >> c->reg_shift) & BUS_CLK_DISABLE) ? OFF : ON;
+ c->div = ((val >> c->reg_shift) & BUS_CLK_DIV_MASK) + 1;
+ c->mul = 1;
+ tegra2_clk_recalculate_rate(c);
+}
+
+static int tegra2_bus_clk_enable(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ val &= ~(BUS_CLK_DISABLE << c->reg_shift);
+ clk_writel(val, c->reg);
+ return 0;
+}
+
+static void tegra2_bus_clk_disable(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ val |= BUS_CLK_DISABLE << c->reg_shift;
+ clk_writel(val, c->reg);
+}
+
+static int tegra2_bus_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val = clk_readl(c->reg);
+ unsigned long parent_rate = c->parent->rate;
+ int i;
+ for (i = 1; i <= 4; i++) {
+ if (rate == parent_rate / i) {
+ val &= ~(BUS_CLK_DIV_MASK << c->reg_shift);
+ val |= (i - 1) << c->reg_shift;
+ clk_writel(val, c->reg);
+ c->div = i;
+ c->mul = 1;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_bus_ops = {
+ .init = tegra2_bus_clk_init,
+ .enable = tegra2_bus_clk_enable,
+ .disable = tegra2_bus_clk_disable,
+ .set_rate = tegra2_bus_clk_set_rate,
+ .recalculate_rate = tegra2_clk_recalculate_rate,
+};
+
+/* PLL Functions */
+static unsigned long tegra2_pll_clk_recalculate_rate(struct clk *c)
+{
+ u64 rate;
+ rate = c->parent->rate;
+ rate *= c->n;
+ do_div(rate, c->m);
+ if (c->p == 2)
+ rate >>= 1;
+ c->rate = rate;
+ return c->rate;
+}
+
+static int tegra2_pll_clk_wait_for_lock(struct clk *c)
+{
+ ktime_t before;
+
+ before = ktime_get();
+ while (!(clk_readl(c->reg + PLL_BASE) & PLL_BASE_LOCK)) {
+ if (ktime_us_delta(ktime_get(), before) > 5000) {
+ pr_err("Timed out waiting for lock bit on pll %s",
+ c->name);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void tegra2_pll_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg + PLL_BASE);
+
+ c->state = (val & PLL_BASE_ENABLE) ? ON : OFF;
+
+ if (c->flags & PLL_FIXED && !(val & PLL_BASE_OVERRIDE)) {
+ pr_warning("Clock %s has unknown fixed frequency\n", c->name);
+ c->n = 1;
+ c->m = 0;
+ c->p = 1;
+ } else if (val & PLL_BASE_BYPASS) {
+ c->n = 1;
+ c->m = 1;
+ c->p = 1;
+ } else {
+ c->n = (val & PLL_BASE_DIVN_MASK) >> PLL_BASE_DIVN_SHIFT;
+ c->m = (val & PLL_BASE_DIVM_MASK) >> PLL_BASE_DIVM_SHIFT;
+ c->p = (val & PLL_BASE_DIVP_MASK) ? 2 : 1;
+ }
+
+ val = clk_readl(c->reg + PLL_MISC(c));
+ if (c->flags & PLL_HAS_CPCON)
+ c->cpcon = (val & PLL_MISC_CPCON_MASK) >> PLL_MISC_CPCON_SHIFT;
+
+ tegra2_pll_clk_recalculate_rate(c);
+}
+
+static int tegra2_pll_clk_enable(struct clk *c)
+{
+ u32 val;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ val = clk_readl(c->reg + PLL_BASE);
+ val &= ~PLL_BASE_BYPASS;
+ val |= PLL_BASE_ENABLE;
+ clk_writel(val, c->reg + PLL_BASE);
+
+ val = clk_readl(c->reg + PLL_MISC(c));
+ val |= PLL_MISC_LOCK_ENABLE;
+ clk_writel(val, c->reg + PLL_MISC(c));
+
+ tegra2_pll_clk_wait_for_lock(c);
+
+ return 0;
+}
+
+static void tegra2_pll_clk_disable(struct clk *c)
+{
+ u32 val;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ val = clk_readl(c->reg);
+ val &= ~(PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+ clk_writel(val, c->reg);
+}
+
+static int tegra2_pll_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ unsigned long input_rate;
+ const struct clk_pll_table *sel;
+
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+ BUG_ON(c->refcnt != 0);
+
+ input_rate = c->parent->rate;
+ for (sel = c->pll_table; sel->input_rate != 0; sel++) {
+ if (sel->input_rate == input_rate && sel->output_rate == rate) {
+ c->n = sel->n;
+ c->m = sel->m;
+ c->p = sel->p;
+ c->cpcon = sel->cpcon;
+
+ val = clk_readl(c->reg + PLL_BASE);
+ if (c->flags & PLL_FIXED)
+ val |= PLL_BASE_OVERRIDE;
+ val &= ~(PLL_BASE_DIVP_MASK | PLL_BASE_DIVN_MASK |
+ PLL_BASE_DIVM_MASK);
+ val |= (c->m << PLL_BASE_DIVM_SHIFT) |
+ (c->n << PLL_BASE_DIVN_SHIFT);
+ BUG_ON(c->p > 2);
+ if (c->p == 2)
+ val |= 1 << PLL_BASE_DIVP_SHIFT;
+ clk_writel(val, c->reg + PLL_BASE);
+
+ if (c->flags & PLL_HAS_CPCON) {
+ val = c->cpcon << PLL_MISC_CPCON_SHIFT;
+ val |= PLL_MISC_LOCK_ENABLE;
+ clk_writel(val, c->reg + PLL_MISC(c));
+ }
+
+ if (c->state == ON)
+ tegra2_pll_clk_enable(c);
+
+ c->rate = rate;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_pll_ops = {
+ .init = tegra2_pll_clk_init,
+ .enable = tegra2_pll_clk_enable,
+ .disable = tegra2_pll_clk_disable,
+ .set_rate = tegra2_pll_clk_set_rate,
+ .recalculate_rate = tegra2_pll_clk_recalculate_rate,
+};
+
+/* Clock divider ops */
+static void tegra2_pll_div_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ u32 divu71;
+ val >>= c->reg_shift;
+ c->state = (val & PLL_OUT_CLKEN) ? ON : OFF;
+ if (!(val & PLL_OUT_RESET_DISABLE))
+ c->state = OFF;
+
+ if (c->flags & DIV_U71) {
+ divu71 = (val & PLL_OUT_RATIO_MASK) >> PLL_OUT_RATIO_SHIFT;
+ c->div = (divu71 + 2);
+ c->mul = 2;
+ } else if (c->flags & DIV_2) {
+ c->div = 2;
+ c->mul = 1;
+ } else {
+ c->div = 1;
+ c->mul = 1;
+ }
+
+ tegra2_clk_recalculate_rate(c);
+}
+
+static int tegra2_pll_div_clk_enable(struct clk *c)
+{
+ u32 val;
+ u32 new_val;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->flags & DIV_U71) {
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+
+ new_val |= PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE;
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ return 0;
+ } else if (c->flags & DIV_2) {
+ BUG_ON(!(c->flags & PLLD));
+ val = clk_readl(c->reg);
+ val &= ~PLLD_MISC_DIV_RST;
+ clk_writel(val, c->reg);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void tegra2_pll_div_clk_disable(struct clk *c)
+{
+ u32 val;
+ u32 new_val;
+
+ pr_debug("%s: %s\n", __func__, c->name);
+ if (c->flags & DIV_U71) {
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+
+ new_val &= ~(PLL_OUT_CLKEN | PLL_OUT_RESET_DISABLE);
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ } else if (c->flags & DIV_2) {
+ BUG_ON(!(c->flags & PLLD));
+ val = clk_readl(c->reg);
+ val |= PLLD_MISC_DIV_RST;
+ clk_writel(val, c->reg);
+ }
+}
+
+static int tegra2_pll_div_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ u32 new_val;
+ int divider_u71;
+ pr_debug("%s: %s %lu\n", __func__, c->name, rate);
+ if (c->flags & DIV_U71) {
+ divider_u71 = clk_div71_get_divider(c->parent, rate);
+ if (divider_u71 >= 0) {
+ val = clk_readl(c->reg);
+ new_val = val >> c->reg_shift;
+ new_val &= 0xFFFF;
+ if (c->flags & DIV_U71_FIXED)
+ new_val |= PLL_OUT_OVERRIDE;
+ new_val &= ~PLL_OUT_RATIO_MASK;
+ new_val |= divider_u71 << PLL_OUT_RATIO_SHIFT;
+
+ val &= ~(0xFFFF << c->reg_shift);
+ val |= new_val << c->reg_shift;
+ clk_writel(val, c->reg);
+ c->div = divider_u71 + 2;
+ c->mul = 2;
+ tegra2_clk_recalculate_rate(c);
+ return 0;
+ }
+ } else if (c->flags & DIV_2) {
+ if (c->parent->rate == rate * 2) {
+ c->rate = rate;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+
+static struct clk_ops tegra_pll_div_ops = {
+ .init = tegra2_pll_div_clk_init,
+ .enable = tegra2_pll_div_clk_enable,
+ .disable = tegra2_pll_div_clk_disable,
+ .set_rate = tegra2_pll_div_clk_set_rate,
+ .recalculate_rate = tegra2_clk_recalculate_rate,
+};
+
+/* Periph clk ops */
+
+static void tegra2_periph_clk_init(struct clk *c)
+{
+ u32 val = clk_readl(c->reg);
+ const struct clk_mux_sel *mux = 0;
+ const struct clk_mux_sel *sel;
+ if (c->flags & MUX) {
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (val >> PERIPH_CLK_SOURCE_SHIFT == sel->value)
+ mux = sel;
+ }
+ BUG_ON(!mux);
+
+ c->parent = mux->input;
+ } else {
+ c->parent = c->inputs[0].input;
+ }
+
+ if (c->flags & DIV_U71) {
+ u32 divu71 = val & PERIPH_CLK_SOURCE_DIV_MASK;
+ c->div = divu71 + 2;
+ c->mul = 2;
+ } else {
+ c->div = 1;
+ c->mul = 1;
+ }
+
+ c->state = ON;
+ if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c)))
+ c->state = OFF;
+ if (!(c->flags & PERIPH_NO_RESET))
+ if (clk_readl(RST_DEVICES + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c))
+ c->state = OFF;
+ tegra2_clk_recalculate_rate(c);
+}
+
+static int tegra2_periph_clk_enable(struct clk *c)
+{
+ u32 val;
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+ if (!(c->flags & PERIPH_NO_RESET) && !(c->flags & PERIPH_MANUAL_RESET))
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+ if (c->flags & PERIPH_EMC_ENB) {
+ /* The EMC peripheral clock has 2 extra enable bits */
+ /* FIXME: Do they need to be disabled? */
+ val = clk_readl(c->reg);
+ val |= 0x3 << 24;
+ clk_writel(val, c->reg);
+ }
+ return 0;
+}
+
+static void tegra2_periph_clk_disable(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ CLK_OUT_ENB_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+void tegra2_periph_reset_deassert(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ if (!(c->flags & PERIPH_NO_RESET))
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ RST_DEVICES_CLR + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+void tegra2_periph_reset_assert(struct clk *c)
+{
+ pr_debug("%s on clock %s\n", __func__, c->name);
+ if (!(c->flags & PERIPH_NO_RESET))
+ clk_writel(PERIPH_CLK_TO_ENB_BIT(c),
+ RST_DEVICES_SET + PERIPH_CLK_TO_ENB_SET_REG(c));
+}
+
+
+static int tegra2_periph_clk_set_parent(struct clk *c, struct clk *p)
+{
+ u32 val;
+ const struct clk_mux_sel *sel;
+ pr_debug("%s: %s %s\n", __func__, c->name, p->name);
+ for (sel = c->inputs; sel->input != NULL; sel++) {
+ if (sel->input == p) {
+ clk_reparent(c, p);
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_MASK;
+ val |= (sel->value) << PERIPH_CLK_SOURCE_SHIFT;
+ clk_writel(val, c->reg);
+ c->rate = c->parent->rate;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int tegra2_periph_clk_set_rate(struct clk *c, unsigned long rate)
+{
+ u32 val;
+ int divider_u71;
+ pr_debug("%s: %lu\n", __func__, rate);
+ if (c->flags & DIV_U71) {
+ divider_u71 = clk_div71_get_divider(c->parent, rate);
+ if (divider_u71 >= 0) {
+ val = clk_readl(c->reg);
+ val &= ~PERIPH_CLK_SOURCE_DIV_MASK;
+ val |= divider_u71;
+ clk_writel(val, c->reg);
+ c->div = divider_u71 + 2;
+ c->mul = 2;
+ tegra2_clk_recalculate_rate(c);
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static struct clk_ops tegra_periph_clk_ops = {
+ .init = &tegra2_periph_clk_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .set_parent = &tegra2_periph_clk_set_parent,
+ .set_rate = &tegra2_periph_clk_set_rate,
+ .recalculate_rate = &tegra2_clk_recalculate_rate,
+};
+
+/* Clock doubler ops */
+static void tegra2_clk_double_init(struct clk *c)
+{
+ c->mul = 2;
+ c->div = 1;
+ c->state = ON;
+ if (!(clk_readl(CLK_OUT_ENB + PERIPH_CLK_TO_ENB_REG(c)) &
+ PERIPH_CLK_TO_ENB_BIT(c)))
+ c->state = OFF;
+ tegra2_clk_recalculate_rate(c);
+};
+
+static struct clk_ops tegra_clk_double_ops = {
+ .init = &tegra2_clk_double_init,
+ .enable = &tegra2_periph_clk_enable,
+ .disable = &tegra2_periph_clk_disable,
+ .recalculate_rate = &tegra2_clk_recalculate_rate,
+};
+
+/* Clock definitions */
+static struct clk tegra_clk_32k = {
+ .name = "clk_32k",
+ .rate = 32678,
+ .ops = NULL,
+};
+
+static struct clk_pll_table tegra_pll_s_table[] = {
+ {32768, 12000000, 366, 1, 1, 0},
+ {32768, 13000000, 397, 1, 1, 0},
+ {32768, 19200000, 586, 1, 1, 0},
+ {32768, 26000000, 793, 1, 1, 0},
+ {0, 0, 0, 0, 0, 0},
+};
+
+static struct clk tegra_pll_s = {
+ .name = "pll_s",
+ .flags = PLL_ALT_MISC_REG,
+ .ops = &tegra_pll_ops,
+ .reg = 0xf0,
+ .input_min = 32768,
+ .input_max = 32768,
+ .parent = &tegra_clk_32k,
+ .cf_min = 0, /* FIXME */
+ .cf_max = 0, /* FIXME */
+ .vco_min = 12000000,
+ .vco_max = 26000000,
+ .pll_table = tegra_pll_s_table,
+};
+
+static struct clk_mux_sel tegra_clk_m_sel[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { .input = &tegra_pll_s, .value = 1},
+ { 0, 0},
+};
+static struct clk tegra_clk_m = {
+ .name = "clk_m",
+ .flags = ENABLE_ON_INIT,
+ .ops = &tegra_clk_m_ops,
+ .inputs = tegra_clk_m_sel,
+ .reg = 0x1fc,
+ .reg_mask = (1<<28),
+ .reg_shift = 28,
+};
+
+static struct clk_pll_table tegra_pll_c_table[] = {
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_c = {
+ .name = "pll_c",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x80,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_c_table,
+};
+
+static struct clk tegra_pll_c_out1 = {
+ .name = "pll_c_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_c,
+ .reg = 0x84,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_m_table[] = {
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_m = {
+ .name = "pll_m",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0x90,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1200000000,
+ .pll_table = tegra_pll_m_table,
+};
+
+static struct clk tegra_pll_m_out1 = {
+ .name = "pll_m_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_m,
+ .reg = 0x94,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_p_table[] = {
+ { 12000000, 216000000, 432, 12, 2, 8},
+ { 13000000, 216000000, 432, 13, 2, 8},
+ { 19200000, 216000000, 90, 4, 2, 1},
+ { 26000000, 216000000, 432, 26, 2, 8},
+ { 12000000, 432000000, 432, 12, 1, 8},
+ { 13000000, 432000000, 432, 13, 1, 8},
+ { 19200000, 432000000, 90, 4, 1, 1},
+ { 26000000, 432000000, 432, 26, 1, 8},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_p = {
+ .name = "pll_p",
+ .flags = ENABLE_ON_INIT | PLL_FIXED | PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xa0,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_p_table,
+};
+
+static struct clk tegra_pll_p_out1 = {
+ .name = "pll_p_out1",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 0,
+};
+
+static struct clk tegra_pll_p_out2 = {
+ .name = "pll_p_out2",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa4,
+ .reg_shift = 16,
+};
+
+static struct clk tegra_pll_p_out3 = {
+ .name = "pll_p_out3",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 0,
+};
+
+static struct clk tegra_pll_p_out4 = {
+ .name = "pll_p_out4",
+ .ops = &tegra_pll_div_ops,
+ .flags = ENABLE_ON_INIT | DIV_U71 | DIV_U71_FIXED,
+ .parent = &tegra_pll_p,
+ .reg = 0xa8,
+ .reg_shift = 16,
+};
+
+static struct clk_pll_table tegra_pll_a_table[] = {
+ { 28800000, 56448000, 49, 25, 1, 1},
+ { 28800000, 73728000, 64, 25, 1, 1},
+ { 28800000, 11289600, 49, 25, 1, 1},
+ { 28800000, 12288000, 64, 25, 1, 1},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_a = {
+ .name = "pll_a",
+ .flags = PLL_HAS_CPCON,
+ .ops = &tegra_pll_ops,
+ .reg = 0xb0,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_pll_p_out1,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1400000000,
+ .pll_table = tegra_pll_a_table,
+};
+
+static struct clk tegra_pll_a_out0 = {
+ .name = "pll_a_out0",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_U71,
+ .parent = &tegra_pll_a,
+ .reg = 0xb4,
+ .reg_shift = 0,
+};
+
+static struct clk_pll_table tegra_pll_d_table[] = {
+ { 12000000, 1000000000, 1000, 12, 1, 12},
+ { 13000000, 1000000000, 1000, 13, 1, 12},
+ { 19200000, 1000000000, 625, 12, 1, 8},
+ { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_d = {
+ .name = "pll_d",
+ .flags = PLL_HAS_CPCON | PLLD,
+ .ops = &tegra_pll_ops,
+ .reg = 0xd0,
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 40000000,
+ .vco_max = 1000000000,
+ .pll_table = tegra_pll_d_table,
+};
+
+static struct clk tegra_pll_d_out0 = {
+ .name = "pll_d_out0",
+ .ops = &tegra_pll_div_ops,
+ .flags = DIV_2 | PLLD,
+ .parent = &tegra_pll_d,
+};
+
+static struct clk_pll_table tegra_pll_u_table[] = {
+ { 12000000, 480000000, 960, 12, 1, 0},
+ { 13000000, 480000000, 960, 13, 1, 0},
+ { 19200000, 480000000, 200, 4, 1, 0},
+ { 26000000, 480000000, 960, 26, 1, 0},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_u = {
+ .name = "pll_u",
+ .flags = 0,
+ .ops = &tegra_pll_ops,
+ .reg = 0xc0,
+ .input_min = 2000000,
+ .input_max = 40000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 480000000,
+ .vco_max = 960000000,
+ .pll_table = tegra_pll_u_table,
+};
+
+static struct clk_pll_table tegra_pll_x_table[] = {
+ { 12000000, 1000000000, 1000, 12, 1, 12},
+ { 13000000, 1000000000, 1000, 13, 1, 12},
+ { 19200000, 1000000000, 625, 12, 1, 8},
+ { 26000000, 1000000000, 1000, 26, 1, 12},
+ { 12000000, 750000000, 750, 12, 1, 12},
+ { 13000000, 750000000, 750, 13, 1, 12},
+ { 19200000, 750000000, 625, 16, 1, 8},
+ { 26000000, 750000000, 750, 26, 1, 12},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
+static struct clk tegra_pll_x = {
+ .name = "pll_x",
+ .flags = PLL_HAS_CPCON | PLL_ALT_MISC_REG,
+ .ops = &tegra_pll_ops,
+ .reg = 0xe0,
+ .input_min = 2000000,
+ .input_max = 31000000,
+ .parent = &tegra_clk_m,
+ .cf_min = 1000000,
+ .cf_max = 6000000,
+ .vco_min = 20000000,
+ .vco_max = 1200000000,
+ .pll_table = tegra_pll_x_table,
+};
+
+static struct clk tegra_clk_d = {
+ .name = "clk_d",
+ .flags = PERIPH_NO_RESET,
+ .ops = &tegra_clk_double_ops,
+ .clk_num = 90,
+ .reg = 0x34,
+ .reg_shift = 12,
+ .parent = &tegra_clk_m,
+};
+
+/* FIXME: need tegra_audio
+static struct clk tegra_clk_audio_2x = {
+ .name = "clk_d",
+ .flags = PERIPH_NO_RESET,
+ .ops = &tegra_clk_double_ops,
+ .clk_num = 89,
+ .reg = 0x34,
+ .reg_shift = 8,
+ .parent = &tegra_audio,
+}
+*/
+
+static struct clk_mux_sel mux_cclk[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_clk_32k, .value = 2},
+ { .input = &tegra_pll_m, .value = 3},
+ { .input = &tegra_pll_p, .value = 4},
+ { .input = &tegra_pll_p_out4, .value = 5},
+ { .input = &tegra_pll_p_out3, .value = 6},
+ { .input = &tegra_clk_d, .value = 7},
+ { .input = &tegra_pll_x, .value = 8},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_sclk[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { .input = &tegra_pll_c_out1, .value = 1},
+ { .input = &tegra_pll_p_out4, .value = 2},
+ { .input = &tegra_pll_p_out3, .value = 3},
+ { .input = &tegra_pll_p_out2, .value = 4},
+ { .input = &tegra_clk_d, .value = 5},
+ { .input = &tegra_clk_32k, .value = 6},
+ { .input = &tegra_pll_m_out1, .value = 7},
+ { 0, 0},
+};
+
+static struct clk tegra_clk_cpu = {
+ .name = "cpu",
+ .inputs = mux_cclk,
+ .reg = 0x20,
+ .ops = &tegra_super_ops,
+};
+
+static struct clk tegra_clk_sys = {
+ .name = "sys",
+ .inputs = mux_sclk,
+ .reg = 0x28,
+ .ops = &tegra_super_ops,
+};
+
+static struct clk tegra_clk_hclk = {
+ .name = "hclk",
+ .flags = DIV_BUS,
+ .parent = &tegra_clk_sys,
+ .reg = 0x30,
+ .reg_shift = 4,
+ .ops = &tegra_bus_ops,
+};
+
+static struct clk tegra_clk_pclk = {
+ .name = "pclk",
+ .flags = DIV_BUS,
+ .parent = &tegra_clk_hclk,
+ .reg = 0x30,
+ .reg_shift = 0,
+ .ops = &tegra_bus_ops,
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_plla[] = {
+ { .input = &tegra_pll_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_p, .value = 2},
+ { .input = &tegra_pll_a_out0, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllm_pllc_pllp_clkm[] = {
+ { .input = &tegra_pll_m, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_p, .value = 2},
+ { .input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm_clkm[] = {
+ { .input = &tegra_pll_p, .value = 0},
+ { .input = &tegra_pll_c, .value = 1},
+ { .input = &tegra_pll_m, .value = 2},
+ { .input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_plla_audio_pllp_clkm[] = {
+ {.input = &tegra_pll_a, .value = 0},
+ /* FIXME: no mux defined for tegra_audio
+ {.input = &tegra_audio, .value = 1},*/
+ {.input = &tegra_pll_p, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_plld_pllc_clkm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_d_out0, .value = 1},
+ {.input = &tegra_pll_c, .value = 2},
+ {.input = &tegra_clk_m, .value = 3},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_audio_clkm_clk32[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ /* FIXME: no mux defined for tegra_audio
+ {.input = &tegra_audio, .value = 2},*/
+ {.input = &tegra_clk_m, .value = 3},
+ {.input = &tegra_clk_32k, .value = 4},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_pllc_pllm[] = {
+ {.input = &tegra_pll_p, .value = 0},
+ {.input = &tegra_pll_c, .value = 1},
+ {.input = &tegra_pll_m, .value = 2},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_m[] = {
+ { .input = &tegra_clk_m, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_pllp_out3[] = {
+ { .input = &tegra_pll_p_out3, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_plld[] = {
+ { .input = &tegra_pll_d, .value = 0},
+ { 0, 0},
+};
+
+static struct clk_mux_sel mux_clk_32k[] = {
+ { .input = &tegra_clk_32k, .value = 0},
+ { 0, 0},
+};
+
+#define PERIPH_CLK(_name, _dev, _con, _clk_num, _reg, _inputs, _flags) \
+ { \
+ .name = _name, \
+ .lookup = { \
+ .dev_id = _dev, \
+ .con_id = _con, \
+ }, \
+ .ops = &tegra_periph_clk_ops, \
+ .clk_num = _clk_num, \
+ .reg = _reg, \
+ .inputs = _inputs, \
+ .flags = _flags, \
+ }
+
+struct clk tegra_periph_clks[] = {
+ PERIPH_CLK("rtc", "rtc-tegra", NULL, 4, 0, mux_clk_32k, PERIPH_NO_RESET),
+ PERIPH_CLK("timer", "timer", NULL, 5, 0, mux_clk_m, 0),
+ PERIPH_CLK("i2s1", "i2s.0", NULL, 11, 0x100, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2s2", "i2s.1", NULL, 18, 0x104, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
+ /* FIXME: spdif has 2 clocks but 1 enable */
+ PERIPH_CLK("spdif_out", "spdif_out", NULL, 10, 0x108, mux_plla_audio_pllp_clkm, MUX | DIV_U71),
+ PERIPH_CLK("spdif_in", "spdif_in", NULL, 10, 0x10c, mux_pllp_pllc_pllm, MUX | DIV_U71),
+ PERIPH_CLK("pwm", "pwm", NULL, 17, 0x110, mux_pllp_pllc_audio_clkm_clk32, MUX | DIV_U71),
+ PERIPH_CLK("spi", "spi", NULL, 43, 0x114, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("xio", "xio", NULL, 45, 0x120, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("twc", "twc", NULL, 16, 0x12c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc1", "spi_tegra.0", NULL, 41, 0x134, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc2", "spi_tegra.1", NULL, 44, 0x118, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc3", "spi_tegra.2", NULL, 46, 0x11c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sbc4", "spi_tegra.3", NULL, 68, 0x1b4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("ide", "ide", NULL, 25, 0x144, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("ndflash", "tegra_nand", NULL, 13, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ /* FIXME: vfir shares an enable with uartb */
+ PERIPH_CLK("vfir", "vfir", NULL, 7, 0x168, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc1", "sdhci-tegra.0", NULL, 14, 0x150, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc2", "sdhci-tegra.1", NULL, 9, 0x154, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc3", "sdhci-tegra.2", NULL, 69, 0x1bc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("sdmmc4", "sdhci-tegra.3", NULL, 15, 0x160, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("vde", "vde", NULL, 61, 0x1c8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("csite", "csite", NULL, 73, 0x1d4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ /* FIXME: what is la? */
+ PERIPH_CLK("la", "la", NULL, 76, 0x1f8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("owr", "owr", NULL, 71, 0x1cc, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("nor", "nor", NULL, 42, 0x1d0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("mipi", "mipi", NULL, 50, 0x174, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2c1", "tegra-i2c.0", NULL, 12, 0x124, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2c2", "tegra-i2c.1", NULL, 54, 0x198, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2c3", "tegra-i2c.2", NULL, 67, 0x1b8, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("dvc", "tegra-i2c.3", NULL, 47, 0x128, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("i2c1_i2c", "tegra-i2c.0", "i2c", 0, 0, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c2_i2c", "tegra-i2c.1", "i2c", 0, 0, mux_pllp_out3, 0),
+ PERIPH_CLK("i2c3_i2c", "tegra-i2c.2", "i2c", 0, 0, mux_pllp_out3, 0),
+ PERIPH_CLK("dvc_i2c", "tegra-i2c.3", "i2c", 0, 0, mux_pllp_out3, 0),
+ PERIPH_CLK("uarta", "uart.0", NULL, 6, 0x178, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("uartb", "uart.1", NULL, 7, 0x17c, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("uartc", "uart.2", NULL, 55, 0x1a0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("uartd", "uart.3", NULL, 65, 0x1c0, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("uarte", "uart.4", NULL, 66, 0x1c4, mux_pllp_pllc_pllm_clkm, MUX | DIV_U71),
+ PERIPH_CLK("3d", "3d", NULL, 24, 0x158, mux_pllm_pllc_pllp_plla, MUX | DIV_U71 | PERIPH_MANUAL_RESET),
+ PERIPH_CLK("2d", "2d", NULL, 21, 0x15c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ /* FIXME: vi and vi_sensor share an enable */
+ PERIPH_CLK("vi", "vi", NULL, 20, 0x148, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("vi_sensor", "vi_sensor", NULL, 20, 0x1a8, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("epp", "epp", NULL, 19, 0x16c, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("mpe", "mpe", NULL, 60, 0x170, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ PERIPH_CLK("host1x", "host1x", NULL, 28, 0x180, mux_pllm_pllc_pllp_plla, MUX | DIV_U71),
+ /* FIXME: cve and tvo share an enable */
+ PERIPH_CLK("cve", "cve", NULL, 49, 0x140, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("tvo", "tvo", NULL, 49, 0x188, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("hdmi", "hdmi", NULL, 51, 0x18c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("tvdac", "tvdac", NULL, 53, 0x194, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("disp1", "tegrafb.0", NULL, 27, 0x138, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("disp2", "tegrafb.1", NULL, 26, 0x13c, mux_pllp_plld_pllc_clkm, MUX | DIV_U71),
+ PERIPH_CLK("usbd", "fsl-tegra-udc", NULL, 22, 0, mux_clk_m, 0),
+ PERIPH_CLK("usb2", "usb.1", NULL, 58, 0, mux_clk_m, 0),
+ PERIPH_CLK("usb3", "usb.2", NULL, 59, 0, mux_clk_m, 0),
+ PERIPH_CLK("emc", "emc", NULL, 57, 0x19c, mux_pllm_pllc_pllp_clkm, MUX | DIV_U71 | PERIPH_EMC_ENB),
+ PERIPH_CLK("dsi", "dsi", NULL, 48, 0, mux_plld, 0),
+};
+
+#define CLK_DUPLICATE(_name, _dev, _con) \
+ { \
+ .name = _name, \
+ .lookup = { \
+ .dev_id = _dev, \
+ .con_id = _con, \
+ }, \
+ }
+
+/* Some clocks may be used by different drivers depending on the board
+ * configuration. List those here to register them twice in the clock lookup
+ * table under two names.
+ */
+struct clk_duplicate tegra_clk_duplicates[] = {
+ CLK_DUPLICATE("uarta", "tegra_uart.0", NULL),
+ CLK_DUPLICATE("uartb", "tegra_uart.1", NULL),
+ CLK_DUPLICATE("uartc", "tegra_uart.2", NULL),
+ CLK_DUPLICATE("uartd", "tegra_uart.3", NULL),
+ CLK_DUPLICATE("uarte", "tegra_uart.4", NULL),
+};
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ }
+
+struct clk_lookup tegra_clk_lookups[] = {
+ /* external root sources */
+ CLK(NULL, "32k_clk", &tegra_clk_32k),
+ CLK(NULL, "pll_s", &tegra_pll_s),
+ CLK(NULL, "clk_m", &tegra_clk_m),
+ CLK(NULL, "pll_m", &tegra_pll_m),
+ CLK(NULL, "pll_m_out1", &tegra_pll_m_out1),
+ CLK(NULL, "pll_c", &tegra_pll_c),
+ CLK(NULL, "pll_c_out1", &tegra_pll_c_out1),
+ CLK(NULL, "pll_p", &tegra_pll_p),
+ CLK(NULL, "pll_p_out1", &tegra_pll_p_out1),
+ CLK(NULL, "pll_p_out2", &tegra_pll_p_out2),
+ CLK(NULL, "pll_p_out3", &tegra_pll_p_out3),
+ CLK(NULL, "pll_p_out4", &tegra_pll_p_out4),
+ CLK(NULL, "pll_a", &tegra_pll_a),
+ CLK(NULL, "pll_a_out0", &tegra_pll_a_out0),
+ CLK(NULL, "pll_d", &tegra_pll_d),
+ CLK(NULL, "pll_d_out0", &tegra_pll_d_out0),
+ CLK(NULL, "pll_u", &tegra_pll_u),
+ CLK(NULL, "pll_x", &tegra_pll_x),
+ CLK(NULL, "cpu", &tegra_clk_cpu),
+ CLK(NULL, "sys", &tegra_clk_sys),
+ CLK(NULL, "hclk", &tegra_clk_hclk),
+ CLK(NULL, "pclk", &tegra_clk_pclk),
+ CLK(NULL, "clk_d", &tegra_clk_d),
+};
+
+void __init tegra2_init_clocks(void)
+{
+ int i;
+ struct clk_lookup *cl;
+ struct clk *c;
+ struct clk_duplicate *cd;
+
+ for (i = 0; i < ARRAY_SIZE(tegra_clk_lookups); i++) {
+ cl = &tegra_clk_lookups[i];
+ clk_init(cl->clk);
+ clkdev_add(cl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_periph_clks); i++) {
+ c = &tegra_periph_clks[i];
+ cl = &c->lookup;
+ cl->clk = c;
+
+ clk_init(cl->clk);
+ clkdev_add(cl);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(tegra_clk_duplicates); i++) {
+ cd = &tegra_clk_duplicates[i];
+ c = tegra_get_clock_by_name(cd->name);
+ if (c) {
+ cl = &cd->lookup;
+ cl->clk = c;
+ clkdev_add(cl);
+ } else {
+ pr_err("%s: Unknown duplicate clock %s\n", __func__,
+ cd->name);
+ }
+ }
+}
diff --git a/arch/arm/mach-tegra/timer.c b/arch/arm/mach-tegra/timer.c
new file mode 100644
index 000000000000..2f420210d406
--- /dev/null
+++ b/arch/arm/mach-tegra/timer.c
@@ -0,0 +1,187 @@
+/*
+ * arch/arch/mach-tegra/timer.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cnt32_to_63.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/time.h>
+#include <asm/localtimer.h>
+
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+
+#include "board.h"
+#include "clock.h"
+
+#define TIMERUS_CNTR_1US 0x10
+#define TIMERUS_USEC_CFG 0x14
+#define TIMERUS_CNTR_FREEZE 0x4c
+
+#define TIMER1_BASE 0x0
+#define TIMER2_BASE 0x8
+#define TIMER3_BASE 0x50
+#define TIMER4_BASE 0x58
+
+#define TIMER_PTV 0x0
+#define TIMER_PCR 0x4
+
+struct tegra_timer;
+
+static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
+
+#define timer_writel(value, reg) \
+ __raw_writel(value, (u32)timer_reg_base + (reg))
+#define timer_readl(reg) \
+ __raw_readl((u32)timer_reg_base + (reg))
+
+static int tegra_timer_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ reg = 0x80000000 | ((cycles > 1) ? (cycles-1) : 0);
+ timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+
+ return 0;
+}
+
+static void tegra_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+
+ timer_writel(0, TIMER3_BASE + TIMER_PTV);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ reg = 0xC0000000 | ((1000000/HZ)-1);
+ timer_writel(reg, TIMER3_BASE + TIMER_PTV);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static cycle_t tegra_clocksource_read(struct clocksource *cs)
+{
+ return cnt32_to_63(timer_readl(TIMERUS_CNTR_1US));
+}
+
+static struct clock_event_device tegra_clockevent = {
+ .name = "timer0",
+ .rating = 300,
+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
+ .set_next_event = tegra_timer_set_next_event,
+ .set_mode = tegra_timer_set_mode,
+};
+
+static struct clocksource tegra_clocksource = {
+ .name = "timer_us",
+ .rating = 300,
+ .read = tegra_clocksource_read,
+ .mask = 0x7FFFFFFFFFFFFFFFULL,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+unsigned long long sched_clock(void)
+{
+ return clocksource_cyc2ns(tegra_clocksource.read(&tegra_clocksource),
+ tegra_clocksource.mult, tegra_clocksource.shift);
+}
+
+static irqreturn_t tegra_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = (struct clock_event_device *)dev_id;
+ timer_writel(1<<30, TIMER3_BASE + TIMER_PCR);
+ evt->event_handler(evt);
+ return IRQ_HANDLED;
+}
+
+static struct irqaction tegra_timer_irq = {
+ .name = "timer0",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_TRIGGER_HIGH,
+ .handler = tegra_timer_interrupt,
+ .dev_id = &tegra_clockevent,
+ .irq = INT_TMR3,
+};
+
+static void __init tegra_init_timer(void)
+{
+ unsigned long rate = clk_measure_input_freq();
+ int ret;
+
+#ifdef CONFIG_HAVE_ARM_TWD
+ twd_base = IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x600);
+#endif
+
+ switch (rate) {
+ case 12000000:
+ timer_writel(0x000b, TIMERUS_USEC_CFG);
+ break;
+ case 13000000:
+ timer_writel(0x000c, TIMERUS_USEC_CFG);
+ break;
+ case 19200000:
+ timer_writel(0x045f, TIMERUS_USEC_CFG);
+ break;
+ case 26000000:
+ timer_writel(0x0019, TIMERUS_USEC_CFG);
+ break;
+ default:
+ WARN(1, "Unknown clock rate");
+ }
+
+ if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
+ printk(KERN_ERR "Failed to register clocksource\n");
+ BUG();
+ }
+
+ ret = setup_irq(tegra_timer_irq.irq, &tegra_timer_irq);
+ if (ret) {
+ printk(KERN_ERR "Failed to register timer IRQ: %d\n", ret);
+ BUG();
+ }
+
+ clockevents_calc_mult_shift(&tegra_clockevent, 1000000, 5);
+ tegra_clockevent.max_delta_ns =
+ clockevent_delta2ns(0x1fffffff, &tegra_clockevent);
+ tegra_clockevent.min_delta_ns =
+ clockevent_delta2ns(0x1, &tegra_clockevent);
+ tegra_clockevent.cpumask = cpu_all_mask;
+ tegra_clockevent.irq = tegra_timer_irq.irq;
+ clockevents_register_device(&tegra_clockevent);
+
+ return;
+}
+
+struct sys_timer tegra_timer = {
+ .init = tegra_init_timer,
+};
diff --git a/arch/arm/mach-u300/u300.c b/arch/arm/mach-u300/u300.c
index d2a0b8847a18..4fb8660245bc 100644
--- a/arch/arm/mach-u300/u300.c
+++ b/arch/arm/mach-u300/u300.c
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
+#include <linux/lmb.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <mach/hardware.h>
@@ -22,6 +23,21 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+static void __init u300_reserve(void)
+{
+ /*
+ * U300 - This platform family can share physical memory
+ * between two ARM cpus, one running Linux and the other
+ * running another OS.
+ */
+#ifdef CONFIG_MACH_U300_SINGLE_RAM
+#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
+ CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
+ lmb_reserve(PHYS_OFFSET, 0x00100000);
+#endif
+#endif
+}
+
static void __init u300_init_machine(void)
{
u300_init_devices();
@@ -49,6 +65,7 @@ MACHINE_START(U300, MACH_U300_STRING)
.io_pg_offst = ((U300_AHB_PER_VIRT_BASE) >> 18) & 0xfffc,
.boot_params = BOOT_PARAMS_OFFSET,
.map_io = u300_map_io,
+ .reserve = u300_reserve,
.init_irq = u300_init_irq,
.timer = &u300_timer,
.init_machine = u300_init_machine,
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index bb8d7b771817..b83005e9b8fa 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -13,6 +13,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
#include <linux/spi/spi.h>
@@ -20,12 +21,33 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <plat/pincfg.h>
#include <plat/i2c.h>
#include <mach/hardware.h>
#include <mach/setup.h>
#include <mach/devices.h>
+#include "pins-db8500.h"
+
+static pin_cfg_t mop500_pins[] = {
+ /* SSP0 */
+ GPIO143_SSP0_CLK,
+ GPIO144_SSP0_FRM,
+ GPIO145_SSP0_RXD,
+ GPIO146_SSP0_TXD,
+
+ /* I2C */
+ GPIO147_I2C0_SCL,
+ GPIO148_I2C0_SDA,
+ GPIO16_I2C1_SCL,
+ GPIO17_I2C1_SDA,
+ GPIO10_I2C2_SDA,
+ GPIO11_I2C2_SCL,
+ GPIO229_I2C3_SDA,
+ GPIO230_I2C3_SCL,
+};
+
static void ab4500_spi_cs_control(u32 command)
{
/* set the FRM signal, which is CS - TODO */
@@ -118,6 +140,10 @@ static void __init u8500_init_machine(void)
{
int i;
+ u8500_init_devices();
+
+ nmk_config_pins(mop500_pins, ARRAY_SIZE(mop500_pins));
+
u8500_i2c0_device.dev.platform_data = &u8500_i2c0_data;
ux500_i2c1_device.dev.platform_data = &u8500_i2c1_data;
ux500_i2c2_device.dev.platform_data = &u8500_i2c2_data;
@@ -133,8 +159,6 @@ static void __init u8500_init_machine(void)
spi_register_board_info(u8500_spi_devices,
ARRAY_SIZE(u8500_spi_devices));
-
- u8500_init_devices();
}
MACHINE_START(U8500, "ST-Ericsson MOP500 platform")
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c
index fe84b9021c7a..0a1318fc8e2b 100644
--- a/arch/arm/mach-ux500/clock.c
+++ b/arch/arm/mach-ux500/clock.c
@@ -131,7 +131,7 @@ EXPORT_SYMBOL(clk_disable);
*/
static unsigned long clk_mtu_get_rate(struct clk *clk)
{
- void __iomem *addr = __io_address(U8500_PRCMU_BASE)
+ void __iomem *addr = __io_address(UX500_PRCMU_BASE)
+ PRCM_TCR;
u32 tcr = readl(addr);
int mtu = (int) clk->data;
diff --git a/arch/arm/mach-ux500/cpu-db5500.c b/arch/arm/mach-ux500/cpu-db5500.c
index 6a3ac4539f16..e9278f6d67aa 100644
--- a/arch/arm/mach-ux500/cpu-db5500.c
+++ b/arch/arm/mach-ux500/cpu-db5500.c
@@ -21,6 +21,7 @@ static struct map_desc u5500_io_desc[] __initdata = {
__IO_DEV_DESC(U5500_GPIO2_BASE, SZ_4K),
__IO_DEV_DESC(U5500_GPIO3_BASE, SZ_4K),
__IO_DEV_DESC(U5500_GPIO4_BASE, SZ_4K),
+ __IO_DEV_DESC(U5500_PRCMU_BASE, SZ_4K),
};
static struct platform_device *u5500_platform_devs[] __initdata = {
diff --git a/arch/arm/mach-ux500/pins-db8500.h b/arch/arm/mach-ux500/pins-db8500.h
new file mode 100644
index 000000000000..9055d5d3233c
--- /dev/null
+++ b/arch/arm/mach-ux500/pins-db8500.h
@@ -0,0 +1,742 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com>
+ */
+
+#ifndef __MACH_PINS_DB8500_H
+#define __MACH_PINS_DB8500_H
+
+/*
+ * TODO: Eventually encode all non-board specific pull up/down configuration
+ * here.
+ */
+
+#define GPIO0_GPIO PIN_CFG(0, GPIO)
+#define GPIO0_U0_CTSn PIN_CFG(0, ALT_A)
+#define GPIO0_TRIG_OUT PIN_CFG(0, ALT_B)
+#define GPIO0_IP_TDO PIN_CFG(0, ALT_C)
+
+#define GPIO1_GPIO PIN_CFG(1, GPIO)
+#define GPIO1_U0_RTSn PIN_CFG(1, ALT_A)
+#define GPIO1_TRIG_IN PIN_CFG(1, ALT_B)
+#define GPIO1_IP_TDI PIN_CFG(1, ALT_C)
+
+#define GPIO2_GPIO PIN_CFG(2, GPIO)
+#define GPIO2_U0_RXD PIN_CFG(2, ALT_A)
+#define GPIO2_NONE PIN_CFG(2, ALT_B)
+#define GPIO2_IP_TMS PIN_CFG(2, ALT_C)
+
+#define GPIO3_GPIO PIN_CFG(3, GPIO)
+#define GPIO3_U0_TXD PIN_CFG(3, ALT_A)
+#define GPIO3_NONE PIN_CFG(3, ALT_B)
+#define GPIO3_IP_TCK PIN_CFG(3, ALT_C)
+
+#define GPIO4_GPIO PIN_CFG(4, GPIO)
+#define GPIO4_U1_RXD PIN_CFG(4, ALT_A)
+#define GPIO4_I2C4_SCL PIN_CFG_PULL(4, ALT_B, UP)
+#define GPIO4_IP_TRSTn PIN_CFG(4, ALT_C)
+
+#define GPIO5_GPIO PIN_CFG(5, GPIO)
+#define GPIO5_U1_TXD PIN_CFG(5, ALT_A)
+#define GPIO5_I2C4_SDA PIN_CFG_PULL(5, ALT_B, UP)
+#define GPIO5_IP_GPIO6 PIN_CFG(5, ALT_C)
+
+#define GPIO6_GPIO PIN_CFG(6, GPIO)
+#define GPIO6_U1_CTSn PIN_CFG(6, ALT_A)
+#define GPIO6_I2C1_SCL PIN_CFG_PULL(6, ALT_B, UP)
+#define GPIO6_IP_GPIO0 PIN_CFG(6, ALT_C)
+
+#define GPIO7_GPIO PIN_CFG(7, GPIO)
+#define GPIO7_U1_RTSn PIN_CFG(7, ALT_A)
+#define GPIO7_I2C1_SDA PIN_CFG_PULL(7, ALT_B, UP)
+#define GPIO7_IP_GPIO1 PIN_CFG(7, ALT_C)
+
+#define GPIO8_GPIO PIN_CFG(8, GPIO)
+#define GPIO8_IPI2C_SDA PIN_CFG_PULL(8, ALT_A, UP)
+#define GPIO8_I2C2_SDA PIN_CFG_PULL(8, ALT_B, UP)
+
+#define GPIO9_GPIO PIN_CFG(9, GPIO)
+#define GPIO9_IPI2C_SCL PIN_CFG_PULL(9, ALT_A, UP)
+#define GPIO9_I2C2_SCL PIN_CFG_PULL(9, ALT_B, UP)
+
+#define GPIO10_GPIO PIN_CFG(10, GPIO)
+#define GPIO10_IPI2C_SDA PIN_CFG_PULL(10, ALT_A, UP)
+#define GPIO10_I2C2_SDA PIN_CFG_PULL(10, ALT_B, UP)
+#define GPIO10_IP_GPIO3 PIN_CFG(10, ALT_C)
+
+#define GPIO11_GPIO PIN_CFG(11, GPIO)
+#define GPIO11_IPI2C_SCL PIN_CFG_PULL(11, ALT_A, UP)
+#define GPIO11_I2C2_SCL PIN_CFG_PULL(11, ALT_B, UP)
+#define GPIO11_IP_GPIO2 PIN_CFG(11, ALT_C)
+
+#define GPIO12_GPIO PIN_CFG(12, GPIO)
+#define GPIO12_MSP0_TXD PIN_CFG(12, ALT_A)
+#define GPIO12_MSP0_RXD PIN_CFG(12, ALT_B)
+
+#define GPIO13_GPIO PIN_CFG(13, GPIO)
+#define GPIO13_MSP0_TFS PIN_CFG(13, ALT_A)
+
+#define GPIO14_GPIO PIN_CFG(14, GPIO)
+#define GPIO14_MSP0_TCK PIN_CFG(14, ALT_A)
+
+#define GPIO15_GPIO PIN_CFG(15, GPIO)
+#define GPIO15_MSP0_RXD PIN_CFG(15, ALT_A)
+#define GPIO15_MSP0_TXD PIN_CFG(15, ALT_B)
+
+#define GPIO16_GPIO PIN_CFG(16, GPIO)
+#define GPIO16_MSP0_RFS PIN_CFG(16, ALT_A)
+#define GPIO16_I2C1_SCL PIN_CFG_PULL(16, ALT_B, UP)
+#define GPIO16_SLIM0_DAT PIN_CFG(16, ALT_C)
+
+#define GPIO17_GPIO PIN_CFG(17, GPIO)
+#define GPIO17_MSP0_RCK PIN_CFG(17, ALT_A)
+#define GPIO17_I2C1_SDA PIN_CFG_PULL(17, ALT_B, UP)
+#define GPIO17_SLIM0_CLK PIN_CFG(17, ALT_C)
+
+#define GPIO18_GPIO PIN_CFG(18, GPIO)
+#define GPIO18_MC0_CMDDIR PIN_CFG(18, ALT_A)
+#define GPIO18_U2_RXD PIN_CFG(18, ALT_B)
+#define GPIO18_MS_IEP PIN_CFG(18, ALT_C)
+
+#define GPIO19_GPIO PIN_CFG(19, GPIO)
+#define GPIO19_MC0_DAT0DIR PIN_CFG(19, ALT_A)
+#define GPIO19_U2_TXD PIN_CFG(19, ALT_B)
+#define GPIO19_MS_DAT0DIR PIN_CFG(19, ALT_C)
+
+#define GPIO20_GPIO PIN_CFG(20, GPIO)
+#define GPIO20_MC0_DAT2DIR PIN_CFG(20, ALT_A)
+#define GPIO20_UARTMOD_TXD PIN_CFG(20, ALT_B)
+#define GPIO20_IP_TRIGOUT PIN_CFG(20, ALT_C)
+
+#define GPIO21_GPIO PIN_CFG(21, GPIO)
+#define GPIO21_MC0_DAT31DIR PIN_CFG(21, ALT_A)
+#define GPIO21_MSP0_SCK PIN_CFG(21, ALT_B)
+#define GPIO21_MS_DAT31DIR PIN_CFG(21, ALT_C)
+
+#define GPIO22_GPIO PIN_CFG(22, GPIO)
+#define GPIO22_MC0_FBCLK PIN_CFG(22, ALT_A)
+#define GPIO22_UARTMOD_RXD PIN_CFG(22, ALT_B)
+#define GPIO22_MS_FBCLK PIN_CFG(22, ALT_C)
+
+#define GPIO23_GPIO PIN_CFG(23, GPIO)
+#define GPIO23_MC0_CLK PIN_CFG(23, ALT_A)
+#define GPIO23_STMMOD_CLK PIN_CFG(23, ALT_B)
+#define GPIO23_MS_CLK PIN_CFG(23, ALT_C)
+
+#define GPIO24_GPIO PIN_CFG(24, GPIO)
+#define GPIO24_MC0_CMD PIN_CFG(24, ALT_A)
+#define GPIO24_UARTMOD_RXD PIN_CFG(24, ALT_B)
+#define GPIO24_MS_BS PIN_CFG(24, ALT_C)
+
+#define GPIO25_GPIO PIN_CFG(25, GPIO)
+#define GPIO25_MC0_DAT0 PIN_CFG(25, ALT_A)
+#define GPIO25_STMMOD_DAT0 PIN_CFG(25, ALT_B)
+#define GPIO25_MS_DAT0 PIN_CFG(25, ALT_C)
+
+#define GPIO26_GPIO PIN_CFG(26, GPIO)
+#define GPIO26_MC0_DAT1 PIN_CFG(26, ALT_A)
+#define GPIO26_STMMOD_DAT1 PIN_CFG(26, ALT_B)
+#define GPIO26_MS_DAT1 PIN_CFG(26, ALT_C)
+
+#define GPIO27_GPIO PIN_CFG(27, GPIO)
+#define GPIO27_MC0_DAT2 PIN_CFG(27, ALT_A)
+#define GPIO27_STMMOD_DAT2 PIN_CFG(27, ALT_B)
+#define GPIO27_MS_DAT2 PIN_CFG(27, ALT_C)
+
+#define GPIO28_GPIO PIN_CFG(28, GPIO)
+#define GPIO28_MC0_DAT3 PIN_CFG(28, ALT_A)
+#define GPIO28_STMMOD_DAT3 PIN_CFG(28, ALT_B)
+#define GPIO28_MS_DAT3 PIN_CFG(28, ALT_C)
+
+#define GPIO29_GPIO PIN_CFG(29, GPIO)
+#define GPIO29_MC0_DAT4 PIN_CFG(29, ALT_A)
+#define GPIO29_SPI3_CLK PIN_CFG(29, ALT_B)
+#define GPIO29_U2_RXD PIN_CFG(29, ALT_C)
+
+#define GPIO30_GPIO PIN_CFG(30, GPIO)
+#define GPIO30_MC0_DAT5 PIN_CFG(30, ALT_A)
+#define GPIO30_SPI3_RXD PIN_CFG(30, ALT_B)
+#define GPIO30_U2_TXD PIN_CFG(30, ALT_C)
+
+#define GPIO31_GPIO PIN_CFG(31, GPIO)
+#define GPIO31_MC0_DAT6 PIN_CFG(31, ALT_A)
+#define GPIO31_SPI3_FRM PIN_CFG(31, ALT_B)
+#define GPIO31_U2_CTSn PIN_CFG(31, ALT_C)
+
+#define GPIO32_GPIO PIN_CFG(32, GPIO)
+#define GPIO32_MC0_DAT7 PIN_CFG(32, ALT_A)
+#define GPIO32_SPI3_TXD PIN_CFG(32, ALT_B)
+#define GPIO32_U2_RTSn PIN_CFG(32, ALT_C)
+
+#define GPIO33_GPIO PIN_CFG(33, GPIO)
+#define GPIO33_MSP1_TXD PIN_CFG(33, ALT_A)
+#define GPIO33_MSP1_RXD PIN_CFG(33, ALT_B)
+#define GPIO33_U0_DTRn PIN_CFG(33, ALT_C)
+
+#define GPIO34_GPIO PIN_CFG(34, GPIO)
+#define GPIO34_MSP1_TFS PIN_CFG(34, ALT_A)
+#define GPIO34_NONE PIN_CFG(34, ALT_B)
+#define GPIO34_U0_DCDn PIN_CFG(34, ALT_C)
+
+#define GPIO35_GPIO PIN_CFG(35, GPIO)
+#define GPIO35_MSP1_TCK PIN_CFG(35, ALT_A)
+#define GPIO35_NONE PIN_CFG(35, ALT_B)
+#define GPIO35_U0_DSRn PIN_CFG(35, ALT_C)
+
+#define GPIO36_GPIO PIN_CFG(36, GPIO)
+#define GPIO36_MSP1_RXD PIN_CFG(36, ALT_A)
+#define GPIO36_MSP1_TXD PIN_CFG(36, ALT_B)
+#define GPIO36_U0_RIn PIN_CFG(36, ALT_C)
+
+#define GPIO64_GPIO PIN_CFG(64, GPIO)
+#define GPIO64_LCDB_DE PIN_CFG(64, ALT_A)
+#define GPIO64_KP_O1 PIN_CFG(64, ALT_B)
+#define GPIO64_IP_GPIO4 PIN_CFG(64, ALT_C)
+
+#define GPIO65_GPIO PIN_CFG(65, GPIO)
+#define GPIO65_LCDB_HSO PIN_CFG(65, ALT_A)
+#define GPIO65_KP_O0 PIN_CFG(65, ALT_B)
+#define GPIO65_IP_GPIO5 PIN_CFG(65, ALT_C)
+
+#define GPIO66_GPIO PIN_CFG(66, GPIO)
+#define GPIO66_LCDB_VSO PIN_CFG(66, ALT_A)
+#define GPIO66_KP_I1 PIN_CFG(66, ALT_B)
+#define GPIO66_IP_GPIO6 PIN_CFG(66, ALT_C)
+
+#define GPIO67_GPIO PIN_CFG(67, GPIO)
+#define GPIO67_LCDB_CLK PIN_CFG(67, ALT_A)
+#define GPIO67_KP_I0 PIN_CFG(67, ALT_B)
+#define GPIO67_IP_GPIO7 PIN_CFG(67, ALT_C)
+
+#define GPIO68_GPIO PIN_CFG(68, GPIO)
+#define GPIO68_LCD_VSI0 PIN_CFG(68, ALT_A)
+#define GPIO68_KP_O7 PIN_CFG(68, ALT_B)
+#define GPIO68_SM_CLE PIN_CFG(68, ALT_C)
+
+#define GPIO69_GPIO PIN_CFG(69, GPIO)
+#define GPIO69_LCD_VSI1 PIN_CFG(69, ALT_A)
+#define GPIO69_KP_I7 PIN_CFG(69, ALT_B)
+#define GPIO69_SM_ALE PIN_CFG(69, ALT_C)
+
+#define GPIO70_GPIO PIN_CFG(70, GPIO)
+#define GPIO70_LCD_D0 PIN_CFG(70, ALT_A)
+#define GPIO70_KP_O5 PIN_CFG(70, ALT_B)
+#define GPIO70_STMAPE_CLK PIN_CFG(70, ALT_C)
+
+#define GPIO71_GPIO PIN_CFG(71, GPIO)
+#define GPIO71_LCD_D1 PIN_CFG(71, ALT_A)
+#define GPIO71_KP_O4 PIN_CFG(71, ALT_B)
+#define GPIO71_STMAPE_DAT3 PIN_CFG(71, ALT_C)
+
+#define GPIO72_GPIO PIN_CFG(72, GPIO)
+#define GPIO72_LCD_D2 PIN_CFG(72, ALT_A)
+#define GPIO72_KP_O3 PIN_CFG(72, ALT_B)
+#define GPIO72_STMAPE_DAT2 PIN_CFG(72, ALT_C)
+
+#define GPIO73_GPIO PIN_CFG(73, GPIO)
+#define GPIO73_LCD_D3 PIN_CFG(73, ALT_A)
+#define GPIO73_KP_O2 PIN_CFG(73, ALT_B)
+#define GPIO73_STMAPE_DAT1 PIN_CFG(73, ALT_C)
+
+#define GPIO74_GPIO PIN_CFG(74, GPIO)
+#define GPIO74_LCD_D4 PIN_CFG(74, ALT_A)
+#define GPIO74_KP_I5 PIN_CFG(74, ALT_B)
+#define GPIO74_STMAPE_DAT0 PIN_CFG(74, ALT_C)
+
+#define GPIO75_GPIO PIN_CFG(75, GPIO)
+#define GPIO75_LCD_D5 PIN_CFG(75, ALT_A)
+#define GPIO75_KP_I4 PIN_CFG(75, ALT_B)
+#define GPIO75_U2_RXD PIN_CFG(75, ALT_C)
+
+#define GPIO76_GPIO PIN_CFG(76, GPIO)
+#define GPIO76_LCD_D6 PIN_CFG(76, ALT_A)
+#define GPIO76_KP_I3 PIN_CFG(76, ALT_B)
+#define GPIO76_U2_TXD PIN_CFG(76, ALT_C)
+
+#define GPIO77_GPIO PIN_CFG(77, GPIO)
+#define GPIO77_LCD_D7 PIN_CFG(77, ALT_A)
+#define GPIO77_KP_I2 PIN_CFG(77, ALT_B)
+#define GPIO77_NONE PIN_CFG(77, ALT_C)
+
+#define GPIO78_GPIO PIN_CFG(78, GPIO)
+#define GPIO78_LCD_D8 PIN_CFG(78, ALT_A)
+#define GPIO78_KP_O6 PIN_CFG(78, ALT_B)
+#define GPIO78_IP_GPIO2 PIN_CFG(78, ALT_C)
+
+#define GPIO79_GPIO PIN_CFG(79, GPIO)
+#define GPIO79_LCD_D9 PIN_CFG(79, ALT_A)
+#define GPIO79_KP_I6 PIN_CFG(79, ALT_B)
+#define GPIO79_IP_GPIO3 PIN_CFG(79, ALT_C)
+
+#define GPIO80_GPIO PIN_CFG(80, GPIO)
+#define GPIO80_LCD_D10 PIN_CFG(80, ALT_A)
+#define GPIO80_KP_SKA0 PIN_CFG(80, ALT_B)
+#define GPIO80_IP_GPIO4 PIN_CFG(80, ALT_C)
+
+#define GPIO81_GPIO PIN_CFG(81, GPIO)
+#define GPIO81_LCD_D11 PIN_CFG(81, ALT_A)
+#define GPIO81_KP_SKB0 PIN_CFG(81, ALT_B)
+#define GPIO81_IP_GPIO5 PIN_CFG(81, ALT_C)
+
+#define GPIO82_GPIO PIN_CFG(82, GPIO)
+#define GPIO82_LCD_D12 PIN_CFG(82, ALT_A)
+#define GPIO82_KP_O5 PIN_CFG(82, ALT_B)
+
+#define GPIO83_GPIO PIN_CFG(83, GPIO)
+#define GPIO83_LCD_D13 PIN_CFG(83, ALT_A)
+#define GPIO83_KP_O4 PIN_CFG(83, ALT_B)
+
+#define GPIO84_GPIO PIN_CFG(84, GPIO)
+#define GPIO84_LCD_D14 PIN_CFG(84, ALT_A)
+#define GPIO84_KP_I5 PIN_CFG(84, ALT_B)
+
+#define GPIO85_GPIO PIN_CFG(85, GPIO)
+#define GPIO85_LCD_D15 PIN_CFG(85, ALT_A)
+#define GPIO85_KP_I4 PIN_CFG(85, ALT_B)
+
+#define GPIO86_GPIO PIN_CFG(86, GPIO)
+#define GPIO86_LCD_D16 PIN_CFG(86, ALT_A)
+#define GPIO86_SM_ADQ0 PIN_CFG(86, ALT_B)
+#define GPIO86_MC5_DAT0 PIN_CFG(86, ALT_C)
+
+#define GPIO87_GPIO PIN_CFG(87, GPIO)
+#define GPIO87_LCD_D17 PIN_CFG(87, ALT_A)
+#define GPIO87_SM_ADQ1 PIN_CFG(87, ALT_B)
+#define GPIO87_MC5_DAT1 PIN_CFG(87, ALT_C)
+
+#define GPIO88_GPIO PIN_CFG(88, GPIO)
+#define GPIO88_LCD_D18 PIN_CFG(88, ALT_A)
+#define GPIO88_SM_ADQ2 PIN_CFG(88, ALT_B)
+#define GPIO88_MC5_DAT2 PIN_CFG(88, ALT_C)
+
+#define GPIO89_GPIO PIN_CFG(89, GPIO)
+#define GPIO89_LCD_D19 PIN_CFG(89, ALT_A)
+#define GPIO89_SM_ADQ3 PIN_CFG(89, ALT_B)
+#define GPIO89_MC5_DAT3 PIN_CFG(89, ALT_C)
+
+#define GPIO90_GPIO PIN_CFG(90, GPIO)
+#define GPIO90_LCD_D20 PIN_CFG(90, ALT_A)
+#define GPIO90_SM_ADQ4 PIN_CFG(90, ALT_B)
+#define GPIO90_MC5_CMD PIN_CFG(90, ALT_C)
+
+#define GPIO91_GPIO PIN_CFG(91, GPIO)
+#define GPIO91_LCD_D21 PIN_CFG(91, ALT_A)
+#define GPIO91_SM_ADQ5 PIN_CFG(91, ALT_B)
+#define GPIO91_MC5_FBCLK PIN_CFG(91, ALT_C)
+
+#define GPIO92_GPIO PIN_CFG(92, GPIO)
+#define GPIO92_LCD_D22 PIN_CFG(92, ALT_A)
+#define GPIO92_SM_ADQ6 PIN_CFG(92, ALT_B)
+#define GPIO92_MC5_CLK PIN_CFG(92, ALT_C)
+
+#define GPIO93_GPIO PIN_CFG(93, GPIO)
+#define GPIO93_LCD_D23 PIN_CFG(93, ALT_A)
+#define GPIO93_SM_ADQ7 PIN_CFG(93, ALT_B)
+#define GPIO93_MC5_DAT4 PIN_CFG(93, ALT_C)
+
+#define GPIO94_GPIO PIN_CFG(94, GPIO)
+#define GPIO94_KP_O7 PIN_CFG(94, ALT_A)
+#define GPIO94_SM_ADVn PIN_CFG(94, ALT_B)
+#define GPIO94_MC5_DAT5 PIN_CFG(94, ALT_C)
+
+#define GPIO95_GPIO PIN_CFG(95, GPIO)
+#define GPIO95_KP_I7 PIN_CFG(95, ALT_A)
+#define GPIO95_SM_CS0n PIN_CFG(95, ALT_B)
+#define GPIO95_SM_PS0n PIN_CFG(95, ALT_C)
+
+#define GPIO96_GPIO PIN_CFG(96, GPIO)
+#define GPIO96_KP_O6 PIN_CFG(96, ALT_A)
+#define GPIO96_SM_OEn PIN_CFG(96, ALT_B)
+#define GPIO96_MC5_DAT6 PIN_CFG(96, ALT_C)
+
+#define GPIO97_GPIO PIN_CFG(97, GPIO)
+#define GPIO97_KP_I6 PIN_CFG(97, ALT_A)
+#define GPIO97_SM_WEn PIN_CFG(97, ALT_B)
+#define GPIO97_MC5_DAT7 PIN_CFG(97, ALT_C)
+
+#define GPIO128_GPIO PIN_CFG(128, GPIO)
+#define GPIO128_MC2_CLK PIN_CFG(128, ALT_A)
+#define GPIO128_SM_CKO PIN_CFG(128, ALT_B)
+
+#define GPIO129_GPIO PIN_CFG(129, GPIO)
+#define GPIO129_MC2_CMD PIN_CFG(129, ALT_A)
+#define GPIO129_SM_WAIT0n PIN_CFG(129, ALT_B)
+
+#define GPIO130_GPIO PIN_CFG(130, GPIO)
+#define GPIO130_MC2_FBCLK PIN_CFG(130, ALT_A)
+#define GPIO130_SM_FBCLK PIN_CFG(130, ALT_B)
+#define GPIO130_MC2_RSTN PIN_CFG(130, ALT_C)
+
+#define GPIO131_GPIO PIN_CFG(131, GPIO)
+#define GPIO131_MC2_DAT0 PIN_CFG(131, ALT_A)
+#define GPIO131_SM_ADQ8 PIN_CFG(131, ALT_B)
+
+#define GPIO132_GPIO PIN_CFG(132, GPIO)
+#define GPIO132_MC2_DAT1 PIN_CFG(132, ALT_A)
+#define GPIO132_SM_ADQ9 PIN_CFG(132, ALT_B)
+
+#define GPIO133_GPIO PIN_CFG(133, GPIO)
+#define GPIO133_MC2_DAT2 PIN_CFG(133, ALT_A)
+#define GPIO133_SM_ADQ10 PIN_CFG(133, ALT_B)
+
+#define GPIO134_GPIO PIN_CFG(134, GPIO)
+#define GPIO134_MC2_DAT3 PIN_CFG(134, ALT_A)
+#define GPIO134_SM_ADQ11 PIN_CFG(134, ALT_B)
+
+#define GPIO135_GPIO PIN_CFG(135, GPIO)
+#define GPIO135_MC2_DAT4 PIN_CFG(135, ALT_A)
+#define GPIO135_SM_ADQ12 PIN_CFG(135, ALT_B)
+
+#define GPIO136_GPIO PIN_CFG(136, GPIO)
+#define GPIO136_MC2_DAT5 PIN_CFG(136, ALT_A)
+#define GPIO136_SM_ADQ13 PIN_CFG(136, ALT_B)
+
+#define GPIO137_GPIO PIN_CFG(137, GPIO)
+#define GPIO137_MC2_DAT6 PIN_CFG(137, ALT_A)
+#define GPIO137_SM_ADQ14 PIN_CFG(137, ALT_B)
+
+#define GPIO138_GPIO PIN_CFG(138, GPIO)
+#define GPIO138_MC2_DAT7 PIN_CFG(138, ALT_A)
+#define GPIO138_SM_ADQ15 PIN_CFG(138, ALT_B)
+
+#define GPIO139_GPIO PIN_CFG(139, GPIO)
+#define GPIO139_SSP1_RXD PIN_CFG(139, ALT_A)
+#define GPIO139_SM_WAIT1n PIN_CFG(139, ALT_B)
+#define GPIO139_KP_O8 PIN_CFG(139, ALT_C)
+
+#define GPIO140_GPIO PIN_CFG(140, GPIO)
+#define GPIO140_SSP1_TXD PIN_CFG(140, ALT_A)
+#define GPIO140_IP_GPIO7 PIN_CFG(140, ALT_B)
+#define GPIO140_KP_SKA1 PIN_CFG(140, ALT_C)
+
+#define GPIO141_GPIO PIN_CFG(141, GPIO)
+#define GPIO141_SSP1_CLK PIN_CFG(141, ALT_A)
+#define GPIO141_IP_GPIO2 PIN_CFG(141, ALT_B)
+#define GPIO141_KP_O9 PIN_CFG(141, ALT_C)
+
+#define GPIO142_GPIO PIN_CFG(142, GPIO)
+#define GPIO142_SSP1_FRM PIN_CFG(142, ALT_A)
+#define GPIO142_IP_GPIO3 PIN_CFG(142, ALT_B)
+#define GPIO142_KP_SKB1 PIN_CFG(142, ALT_C)
+
+#define GPIO143_GPIO PIN_CFG(143, GPIO)
+#define GPIO143_SSP0_CLK PIN_CFG(143, ALT_A)
+
+#define GPIO144_GPIO PIN_CFG(144, GPIO)
+#define GPIO144_SSP0_FRM PIN_CFG(144, ALT_A)
+
+#define GPIO145_GPIO PIN_CFG(145, GPIO)
+#define GPIO145_SSP0_RXD PIN_CFG(145, ALT_A)
+
+#define GPIO146_GPIO PIN_CFG(146, GPIO)
+#define GPIO146_SSP0_TXD PIN_CFG(146, ALT_A)
+
+#define GPIO147_GPIO PIN_CFG(147, GPIO)
+#define GPIO147_I2C0_SCL PIN_CFG_PULL(147, ALT_A, UP)
+
+#define GPIO148_GPIO PIN_CFG(148, GPIO)
+#define GPIO148_I2C0_SDA PIN_CFG_PULL(148, ALT_A, UP)
+
+#define GPIO149_GPIO PIN_CFG(149, GPIO)
+#define GPIO149_IP_GPIO0 PIN_CFG(149, ALT_A)
+#define GPIO149_SM_CS1n PIN_CFG(149, ALT_B)
+#define GPIO149_SM_PS1n PIN_CFG(149, ALT_C)
+
+#define GPIO150_GPIO PIN_CFG(150, GPIO)
+#define GPIO150_IP_GPIO1 PIN_CFG(150, ALT_A)
+#define GPIO150_LCDA_CLK PIN_CFG(150, ALT_B)
+
+#define GPIO151_GPIO PIN_CFG(151, GPIO)
+#define GPIO151_KP_SKA0 PIN_CFG(151, ALT_A)
+#define GPIO151_LCD_VSI0 PIN_CFG(151, ALT_B)
+#define GPIO151_KP_O8 PIN_CFG(151, ALT_C)
+
+#define GPIO152_GPIO PIN_CFG(152, GPIO)
+#define GPIO152_KP_SKB0 PIN_CFG(152, ALT_A)
+#define GPIO152_LCD_VSI1 PIN_CFG(152, ALT_B)
+#define GPIO152_KP_O9 PIN_CFG(152, ALT_C)
+
+#define GPIO153_GPIO PIN_CFG(153, GPIO)
+#define GPIO153_KP_I7 PIN_CFG(153, ALT_A)
+#define GPIO153_LCD_D24 PIN_CFG(153, ALT_B)
+#define GPIO153_U2_RXD PIN_CFG(153, ALT_C)
+
+#define GPIO154_GPIO PIN_CFG(154, GPIO)
+#define GPIO154_KP_I6 PIN_CFG(154, ALT_A)
+#define GPIO154_LCD_D25 PIN_CFG(154, ALT_B)
+#define GPIO154_U2_TXD PIN_CFG(154, ALT_C)
+
+#define GPIO155_GPIO PIN_CFG(155, GPIO)
+#define GPIO155_KP_I5 PIN_CFG(155, ALT_A)
+#define GPIO155_LCD_D26 PIN_CFG(155, ALT_B)
+#define GPIO155_STMAPE_CLK PIN_CFG(155, ALT_C)
+
+#define GPIO156_GPIO PIN_CFG(156, GPIO)
+#define GPIO156_KP_I4 PIN_CFG(156, ALT_A)
+#define GPIO156_LCD_D27 PIN_CFG(156, ALT_B)
+#define GPIO156_STMAPE_DAT3 PIN_CFG(156, ALT_C)
+
+#define GPIO157_GPIO PIN_CFG(157, GPIO)
+#define GPIO157_KP_O7 PIN_CFG(157, ALT_A)
+#define GPIO157_LCD_D28 PIN_CFG(157, ALT_B)
+#define GPIO157_STMAPE_DAT2 PIN_CFG(157, ALT_C)
+
+#define GPIO158_GPIO PIN_CFG(158, GPIO)
+#define GPIO158_KP_O6 PIN_CFG(158, ALT_A)
+#define GPIO158_LCD_D29 PIN_CFG(158, ALT_B)
+#define GPIO158_STMAPE_DAT1 PIN_CFG(158, ALT_C)
+
+#define GPIO159_GPIO PIN_CFG(159, GPIO)
+#define GPIO159_KP_O5 PIN_CFG(159, ALT_A)
+#define GPIO159_LCD_D30 PIN_CFG(159, ALT_B)
+#define GPIO159_STMAPE_DAT0 PIN_CFG(159, ALT_C)
+
+#define GPIO160_GPIO PIN_CFG(160, GPIO)
+#define GPIO160_KP_O4 PIN_CFG(160, ALT_A)
+#define GPIO160_LCD_D31 PIN_CFG(160, ALT_B)
+#define GPIO160_NONE PIN_CFG(160, ALT_C)
+
+#define GPIO161_GPIO PIN_CFG(161, GPIO)
+#define GPIO161_KP_I3 PIN_CFG(161, ALT_A)
+#define GPIO161_LCD_D32 PIN_CFG(161, ALT_B)
+#define GPIO161_UARTMOD_RXD PIN_CFG(161, ALT_C)
+
+#define GPIO162_GPIO PIN_CFG(162, GPIO)
+#define GPIO162_KP_I2 PIN_CFG(162, ALT_A)
+#define GPIO162_LCD_D33 PIN_CFG(162, ALT_B)
+#define GPIO162_UARTMOD_TXD PIN_CFG(162, ALT_C)
+
+#define GPIO163_GPIO PIN_CFG(163, GPIO)
+#define GPIO163_KP_I1 PIN_CFG(163, ALT_A)
+#define GPIO163_LCD_D34 PIN_CFG(163, ALT_B)
+#define GPIO163_STMMOD_CLK PIN_CFG(163, ALT_C)
+
+#define GPIO164_GPIO PIN_CFG(164, GPIO)
+#define GPIO164_KP_I0 PIN_CFG(164, ALT_A)
+#define GPIO164_LCD_D35 PIN_CFG(164, ALT_B)
+#define GPIO164_STMMOD_DAT3 PIN_CFG(164, ALT_C)
+
+#define GPIO165_GPIO PIN_CFG(165, GPIO)
+#define GPIO165_KP_O3 PIN_CFG(165, ALT_A)
+#define GPIO165_LCD_D36 PIN_CFG(165, ALT_B)
+#define GPIO165_STMMOD_DAT2 PIN_CFG(165, ALT_C)
+
+#define GPIO166_GPIO PIN_CFG(166, GPIO)
+#define GPIO166_KP_O2 PIN_CFG(166, ALT_A)
+#define GPIO166_LCD_D37 PIN_CFG(166, ALT_B)
+#define GPIO166_STMMOD_DAT1 PIN_CFG(166, ALT_C)
+
+#define GPIO167_GPIO PIN_CFG(167, GPIO)
+#define GPIO167_KP_O1 PIN_CFG(167, ALT_A)
+#define GPIO167_LCD_D38 PIN_CFG(167, ALT_B)
+#define GPIO167_STMMOD_DAT0 PIN_CFG(167, ALT_C)
+
+#define GPIO168_GPIO PIN_CFG(168, GPIO)
+#define GPIO168_KP_O0 PIN_CFG(168, ALT_A)
+#define GPIO168_LCD_D39 PIN_CFG(168, ALT_B)
+#define GPIO168_NONE PIN_CFG(168, ALT_C)
+
+#define GPIO169_GPIO PIN_CFG(169, GPIO)
+#define GPIO169_RF_PURn PIN_CFG(169, ALT_A)
+#define GPIO169_LCDA_DE PIN_CFG(169, ALT_B)
+#define GPIO169_USBSIM_PDC PIN_CFG(169, ALT_C)
+
+#define GPIO170_GPIO PIN_CFG(170, GPIO)
+#define GPIO170_MODEM_STATE PIN_CFG(170, ALT_A)
+#define GPIO170_LCDA_VSO PIN_CFG(170, ALT_B)
+#define GPIO170_KP_SKA1 PIN_CFG(170, ALT_C)
+
+#define GPIO171_GPIO PIN_CFG(171, GPIO)
+#define GPIO171_MODEM_PWREN PIN_CFG(171, ALT_A)
+#define GPIO171_LCDA_HSO PIN_CFG(171, ALT_B)
+#define GPIO171_KP_SKB1 PIN_CFG(171, ALT_C)
+
+#define GPIO192_GPIO PIN_CFG(192, GPIO)
+#define GPIO192_MSP2_SCK PIN_CFG(192, ALT_A)
+
+#define GPIO193_GPIO PIN_CFG(193, GPIO)
+#define GPIO193_MSP2_TXD PIN_CFG(193, ALT_A)
+
+#define GPIO194_GPIO PIN_CFG(194, GPIO)
+#define GPIO194_MSP2_TCK PIN_CFG(194, ALT_A)
+
+#define GPIO195_GPIO PIN_CFG(195, GPIO)
+#define GPIO195_MSP2_TFS PIN_CFG(195, ALT_A)
+
+#define GPIO196_GPIO PIN_CFG(196, GPIO)
+#define GPIO196_MSP2_RXD PIN_CFG(196, ALT_A)
+
+#define GPIO197_GPIO PIN_CFG(197, GPIO)
+#define GPIO197_MC4_DAT3 PIN_CFG(197, ALT_A)
+
+#define GPIO198_GPIO PIN_CFG(198, GPIO)
+#define GPIO198_MC4_DAT2 PIN_CFG(198, ALT_A)
+
+#define GPIO199_GPIO PIN_CFG(199, GPIO)
+#define GPIO199_MC4_DAT1 PIN_CFG(199, ALT_A)
+
+#define GPIO200_GPIO PIN_CFG(200, GPIO)
+#define GPIO200_MC4_DAT0 PIN_CFG(200, ALT_A)
+
+#define GPIO201_GPIO PIN_CFG(201, GPIO)
+#define GPIO201_MC4_CMD PIN_CFG(201, ALT_A)
+
+#define GPIO202_GPIO PIN_CFG(202, GPIO)
+#define GPIO202_MC4_FBCLK PIN_CFG(202, ALT_A)
+#define GPIO202_PWL PIN_CFG(202, ALT_B)
+#define GPIO202_MC4_RSTN PIN_CFG(202, ALT_C)
+
+#define GPIO203_GPIO PIN_CFG(203, GPIO)
+#define GPIO203_MC4_CLK PIN_CFG(203, ALT_A)
+
+#define GPIO204_GPIO PIN_CFG(204, GPIO)
+#define GPIO204_MC4_DAT7 PIN_CFG(204, ALT_A)
+
+#define GPIO205_GPIO PIN_CFG(205, GPIO)
+#define GPIO205_MC4_DAT6 PIN_CFG(205, ALT_A)
+
+#define GPIO206_GPIO PIN_CFG(206, GPIO)
+#define GPIO206_MC4_DAT5 PIN_CFG(206, ALT_A)
+
+#define GPIO207_GPIO PIN_CFG(207, GPIO)
+#define GPIO207_MC4_DAT4 PIN_CFG(207, ALT_A)
+
+#define GPIO208_GPIO PIN_CFG(208, GPIO)
+#define GPIO208_MC1_CLK PIN_CFG(208, ALT_A)
+
+#define GPIO209_GPIO PIN_CFG(209, GPIO)
+#define GPIO209_MC1_FBCLK PIN_CFG(209, ALT_A)
+#define GPIO209_SPI1_CLK PIN_CFG(209, ALT_B)
+
+#define GPIO210_GPIO PIN_CFG(210, GPIO)
+#define GPIO210_MC1_CMD PIN_CFG(210, ALT_A)
+
+#define GPIO211_GPIO PIN_CFG(211, GPIO)
+#define GPIO211_MC1_DAT0 PIN_CFG(211, ALT_A)
+
+#define GPIO212_GPIO PIN_CFG(212, GPIO)
+#define GPIO212_MC1_DAT1 PIN_CFG(212, ALT_A)
+#define GPIO212_SPI1_FRM PIN_CFG(212, ALT_B)
+
+#define GPIO213_GPIO PIN_CFG(213, GPIO)
+#define GPIO213_MC1_DAT2 PIN_CFG(213, ALT_A)
+#define GPIO213_SPI1_TXD PIN_CFG(213, ALT_B)
+
+#define GPIO214_GPIO PIN_CFG(214, GPIO)
+#define GPIO214_MC1_DAT3 PIN_CFG(214, ALT_A)
+#define GPIO214_SPI1_RXD PIN_CFG(214, ALT_B)
+
+#define GPIO215_GPIO PIN_CFG(215, GPIO)
+#define GPIO215_MC1_CMDDIR PIN_CFG(215, ALT_A)
+#define GPIO215_MC3_DAT2DIR PIN_CFG(215, ALT_B)
+#define GPIO215_CLKOUT1 PIN_CFG(215, ALT_C)
+
+#define GPIO216_GPIO PIN_CFG(216, GPIO)
+#define GPIO216_MC1_DAT2DIR PIN_CFG(216, ALT_A)
+#define GPIO216_MC3_CMDDIR PIN_CFG(216, ALT_B)
+#define GPIO216_I2C3_SDA PIN_CFG_PULL(216, ALT_C, UP)
+
+#define GPIO217_GPIO PIN_CFG(217, GPIO)
+#define GPIO217_MC1_DAT0DIR PIN_CFG(217, ALT_A)
+#define GPIO217_MC3_DAT31DIR PIN_CFG(217, ALT_B)
+#define GPIO217_CLKOUT2 PIN_CFG(217, ALT_C)
+
+#define GPIO218_GPIO PIN_CFG(218, GPIO)
+#define GPIO218_MC1_DAT31DIR PIN_CFG(218, ALT_A)
+#define GPIO218_MC3_DAT0DIR PIN_CFG(218, ALT_B)
+#define GPIO218_I2C3_SCL PIN_CFG_PULL(218, ALT_C, UP)
+
+#define GPIO219_GPIO PIN_CFG(219, GPIO)
+#define GPIO219_HSIR_FLA0 PIN_CFG(219, ALT_A)
+#define GPIO219_MC3_CLK PIN_CFG(219, ALT_B)
+
+#define GPIO220_GPIO PIN_CFG(220, GPIO)
+#define GPIO220_HSIR_DAT0 PIN_CFG(220, ALT_A)
+#define GPIO220_MC3_FBCLK PIN_CFG(220, ALT_B)
+#define GPIO220_SPI0_CLK PIN_CFG(220, ALT_C)
+
+#define GPIO221_GPIO PIN_CFG(221, GPIO)
+#define GPIO221_HSIR_RDY0 PIN_CFG(221, ALT_A)
+#define GPIO221_MC3_CMD PIN_CFG(221, ALT_B)
+
+#define GPIO222_GPIO PIN_CFG(222, GPIO)
+#define GPIO222_HSIT_FLA0 PIN_CFG(222, ALT_A)
+#define GPIO222_MC3_DAT0 PIN_CFG(222, ALT_B)
+
+#define GPIO223_GPIO PIN_CFG(223, GPIO)
+#define GPIO223_HSIT_DAT0 PIN_CFG(223, ALT_A)
+#define GPIO223_MC3_DAT1 PIN_CFG(223, ALT_B)
+#define GPIO223_SPI0_FRM PIN_CFG(223, ALT_C)
+
+#define GPIO224_GPIO PIN_CFG(224, GPIO)
+#define GPIO224_HSIT_RDY0 PIN_CFG(224, ALT_A)
+#define GPIO224_MC3_DAT2 PIN_CFG(224, ALT_B)
+#define GPIO224_SPI0_TXD PIN_CFG(224, ALT_C)
+
+#define GPIO225_GPIO PIN_CFG(225, GPIO)
+#define GPIO225_HSIT_CAWAKE0 PIN_CFG(225, ALT_A)
+#define GPIO225_MC3_DAT3 PIN_CFG(225, ALT_B)
+#define GPIO225_SPI0_RXD PIN_CFG(225, ALT_C)
+
+#define GPIO226_GPIO PIN_CFG(226, GPIO)
+#define GPIO226_HSIT_ACWAKE0 PIN_CFG(226, ALT_A)
+#define GPIO226_PWL PIN_CFG(226, ALT_B)
+#define GPIO226_USBSIM_PDC PIN_CFG(226, ALT_C)
+
+#define GPIO227_GPIO PIN_CFG(227, GPIO)
+#define GPIO227_CLKOUT1 PIN_CFG(227, ALT_A)
+
+#define GPIO228_GPIO PIN_CFG(228, GPIO)
+#define GPIO228_CLKOUT2 PIN_CFG(228, ALT_A)
+
+#define GPIO229_GPIO PIN_CFG(229, GPIO)
+#define GPIO229_CLKOUT1 PIN_CFG(229, ALT_A)
+#define GPIO229_PWL PIN_CFG(229, ALT_B)
+#define GPIO229_I2C3_SDA PIN_CFG_PULL(229, ALT_C, UP)
+
+#define GPIO230_GPIO PIN_CFG(230, GPIO)
+#define GPIO230_CLKOUT2 PIN_CFG(230, ALT_A)
+#define GPIO230_PWL PIN_CFG(230, ALT_B)
+#define GPIO230_I2C3_SCL PIN_CFG_PULL(230, ALT_C, UP)
+
+#define GPIO256_GPIO PIN_CFG(256, GPIO)
+#define GPIO256_USB_NXT PIN_CFG(256, ALT_A)
+
+#define GPIO257_GPIO PIN_CFG(257, GPIO)
+#define GPIO257_USB_STP PIN_CFG(257, ALT_A)
+
+#define GPIO258_GPIO PIN_CFG(258, GPIO)
+#define GPIO258_USB_XCLK PIN_CFG(258, ALT_A)
+#define GPIO258_NONE PIN_CFG(258, ALT_B)
+#define GPIO258_DDR_TRIG PIN_CFG(258, ALT_C)
+
+#define GPIO259_GPIO PIN_CFG(259, GPIO)
+#define GPIO259_USB_DIR PIN_CFG(259, ALT_A)
+
+#define GPIO260_GPIO PIN_CFG(260, GPIO)
+#define GPIO260_USB_DAT7 PIN_CFG(260, ALT_A)
+
+#define GPIO261_GPIO PIN_CFG(261, GPIO)
+#define GPIO261_USB_DAT6 PIN_CFG(261, ALT_A)
+
+#define GPIO262_GPIO PIN_CFG(262, GPIO)
+#define GPIO262_USB_DAT5 PIN_CFG(262, ALT_A)
+
+#define GPIO263_GPIO PIN_CFG(263, GPIO)
+#define GPIO263_USB_DAT4 PIN_CFG(263, ALT_A)
+
+#define GPIO264_GPIO PIN_CFG(264, GPIO)
+#define GPIO264_USB_DAT3 PIN_CFG(264, ALT_A)
+
+#define GPIO265_GPIO PIN_CFG(265, GPIO)
+#define GPIO265_USB_DAT2 PIN_CFG(265, ALT_A)
+
+#define GPIO266_GPIO PIN_CFG(266, GPIO)
+#define GPIO266_USB_DAT1 PIN_CFG(266, ALT_A)
+
+#define GPIO267_GPIO PIN_CFG(267, GPIO)
+#define GPIO267_USB_DAT0 PIN_CFG(267, ALT_A)
+
+#endif
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index 6353459bb567..577df6cccb08 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -16,6 +16,7 @@
#include <asm/hardware/gic.h>
#include <asm/mach-types.h>
#include <asm/pmu.h>
+#include <asm/smp_twd.h>
#include <mach/clkdev.h>
#include <mach/ct-ca9x4.h>
@@ -53,6 +54,7 @@ static struct map_desc ct_ca9x4_io_desc[] __initdata = {
static void __init ct_ca9x4_map_io(void)
{
+ twd_base = MMIO_P2V(A9_MPCORE_TWD);
v2m_map_io(ct_ca9x4_io_desc, ARRAY_SIZE(ct_ca9x4_io_desc));
}
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index 8650f04136ef..f9e2f8d22962 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -28,6 +28,7 @@
#define A9_MPCORE_SCU (CT_CA9X4_MPIC + 0x0000)
#define A9_MPCORE_GIC_CPU (CT_CA9X4_MPIC + 0x0100)
#define A9_MPCORE_GIT (CT_CA9X4_MPIC + 0x0200)
+#define A9_MPCORE_TWD (CT_CA9X4_MPIC + 0x0600)
#define A9_MPCORE_GIC_DIST (CT_CA9X4_MPIC + 0x1000)
/*
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 101105e52610..e1fd98fff8fa 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -717,17 +717,6 @@ config TLS_REG_EMUL
a few prototypes like that in existence) and therefore access to
that required register must be emulated.
-config HAS_TLS_REG
- bool
- depends on !TLS_REG_EMUL
- default y if SMP || CPU_32v7
- help
- This selects support for the CP15 thread register.
- It is defined to be available on some ARMv6 processors (including
- all SMP capable ARMv6's) or later processors. User space may
- assume directly accessing that register and always obtain the
- expected value only on ARMv7 and above.
-
config NEEDS_SYSCALL_FOR_CMPXCHG
bool
help
@@ -782,7 +771,8 @@ config CACHE_L2X0
bool "Enable the L2x0 outer cache controller"
depends on REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176 || \
REALVIEW_EB_A9MP || ARCH_MX35 || ARCH_MX31 || MACH_REALVIEW_PBX || \
- ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4
+ ARCH_NOMADIK || ARCH_OMAP4 || ARCH_U8500 || ARCH_VEXPRESS_CA9X4 || \
+ ARCH_TEGRA
default y
select OUTER_CACHE
select OUTER_CACHE_SYNC
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index e8d34a80851c..d63b6c413758 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -15,7 +15,6 @@ endif
obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o
-obj-$(CONFIG_DISCONTIGMEM) += discontig.o
obj-$(CONFIG_HIGHMEM) += highmem.o
obj-$(CONFIG_CPU_ABRT_NOMMU) += abort-nommu.o
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 9819869d2bc9..df4955885b21 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -218,6 +218,9 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
cache_id = readl(l2x0_base + L2X0_CACHE_ID);
aux = readl(l2x0_base + L2X0_AUX_CTRL);
+ aux &= aux_mask;
+ aux |= aux_val;
+
/* Determine the number of ways */
switch (cache_id & L2X0_CACHE_ID_PART_MASK) {
case L2X0_CACHE_ID_PART_L310:
@@ -248,8 +251,6 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
if (!(readl(l2x0_base + L2X0_CTRL) & 1)) {
/* l2x0 controller is disabled */
- aux &= aux_mask;
- aux |= aux_val;
writel(aux, l2x0_base + L2X0_AUX_CTRL);
l2x0_inv_all();
diff --git a/arch/arm/mm/discontig.c b/arch/arm/mm/discontig.c
deleted file mode 100644
index c8c0c4b0f0a3..000000000000
--- a/arch/arm/mm/discontig.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/arm/mm/discontig.c
- *
- * Discontiguous memory support.
- *
- * Initial code: Copyright (C) 1999-2000 Nicolas Pitre
- *
- * This program is free software; you can 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/mmzone.h>
-#include <linux/bootmem.h>
-
-#if MAX_NUMNODES != 4 && MAX_NUMNODES != 16
-# error Fix Me Please
-#endif
-
-/*
- * Our node_data structure for discontiguous memory.
- */
-
-pg_data_t discontig_node_data[MAX_NUMNODES] = {
- { .bdata = &bootmem_node_data[0] },
- { .bdata = &bootmem_node_data[1] },
- { .bdata = &bootmem_node_data[2] },
- { .bdata = &bootmem_node_data[3] },
-#if MAX_NUMNODES == 16
- { .bdata = &bootmem_node_data[4] },
- { .bdata = &bootmem_node_data[5] },
- { .bdata = &bootmem_node_data[6] },
- { .bdata = &bootmem_node_data[7] },
- { .bdata = &bootmem_node_data[8] },
- { .bdata = &bootmem_node_data[9] },
- { .bdata = &bootmem_node_data[10] },
- { .bdata = &bootmem_node_data[11] },
- { .bdata = &bootmem_node_data[12] },
- { .bdata = &bootmem_node_data[13] },
- { .bdata = &bootmem_node_data[14] },
- { .bdata = &bootmem_node_data[15] },
-#endif
-};
-
-EXPORT_SYMBOL(discontig_node_data);
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index f6a999465323..af871db7e5ee 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -17,6 +17,7 @@
#include <linux/initrd.h>
#include <linux/highmem.h>
#include <linux/gfp.h>
+#include <linux/lmb.h>
#include <asm/mach-types.h>
#include <asm/sections.h>
@@ -79,38 +80,37 @@ struct meminfo meminfo;
void show_mem(void)
{
int free = 0, total = 0, reserved = 0;
- int shared = 0, cached = 0, slab = 0, node, i;
+ int shared = 0, cached = 0, slab = 0, i;
struct meminfo * mi = &meminfo;
printk("Mem-info:\n");
show_free_areas();
- for_each_online_node(node) {
- for_each_nodebank (i,mi,node) {
- struct membank *bank = &mi->bank[i];
- unsigned int pfn1, pfn2;
- struct page *page, *end;
-
- pfn1 = bank_pfn_start(bank);
- pfn2 = bank_pfn_end(bank);
-
- page = pfn_to_page(pfn1);
- end = pfn_to_page(pfn2 - 1) + 1;
-
- do {
- total++;
- if (PageReserved(page))
- reserved++;
- else if (PageSwapCache(page))
- cached++;
- else if (PageSlab(page))
- slab++;
- else if (!page_count(page))
- free++;
- else
- shared += page_count(page) - 1;
- page++;
- } while (page < end);
- }
+
+ for_each_bank (i, mi) {
+ struct membank *bank = &mi->bank[i];
+ unsigned int pfn1, pfn2;
+ struct page *page, *end;
+
+ pfn1 = bank_pfn_start(bank);
+ pfn2 = bank_pfn_end(bank);
+
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
+
+ do {
+ total++;
+ if (PageReserved(page))
+ reserved++;
+ else if (PageSwapCache(page))
+ cached++;
+ else if (PageSlab(page))
+ slab++;
+ else if (!page_count(page))
+ free++;
+ else
+ shared += page_count(page) - 1;
+ page++;
+ } while (page < end);
}
printk("%d pages of RAM\n", total);
@@ -121,7 +121,7 @@ void show_mem(void)
printk("%d pages swap cached\n", cached);
}
-static void __init find_node_limits(int node, struct meminfo *mi,
+static void __init find_limits(struct meminfo *mi,
unsigned long *min, unsigned long *max_low, unsigned long *max_high)
{
int i;
@@ -129,7 +129,7 @@ static void __init find_node_limits(int node, struct meminfo *mi,
*min = -1UL;
*max_low = *max_high = 0;
- for_each_nodebank(i, mi, node) {
+ for_each_bank (i, mi) {
struct membank *bank = &mi->bank[i];
unsigned long start, end;
@@ -147,155 +147,64 @@ static void __init find_node_limits(int node, struct meminfo *mi,
}
}
-/*
- * FIXME: We really want to avoid allocating the bootmap bitmap
- * over the top of the initrd. Hopefully, this is located towards
- * the start of a bank, so if we allocate the bootmap bitmap at
- * the end, we won't clash.
- */
-static unsigned int __init
-find_bootmap_pfn(int node, struct meminfo *mi, unsigned int bootmap_pages)
-{
- unsigned int start_pfn, i, bootmap_pfn;
-
- start_pfn = PAGE_ALIGN(__pa(_end)) >> PAGE_SHIFT;
- bootmap_pfn = 0;
-
- for_each_nodebank(i, mi, node) {
- struct membank *bank = &mi->bank[i];
- unsigned int start, end;
-
- start = bank_pfn_start(bank);
- end = bank_pfn_end(bank);
-
- if (end < start_pfn)
- continue;
-
- if (start < start_pfn)
- start = start_pfn;
-
- if (end <= start)
- continue;
-
- if (end - start >= bootmap_pages) {
- bootmap_pfn = start;
- break;
- }
- }
-
- if (bootmap_pfn == 0)
- BUG();
-
- return bootmap_pfn;
-}
-
-static int __init check_initrd(struct meminfo *mi)
-{
- int initrd_node = -2;
-#ifdef CONFIG_BLK_DEV_INITRD
- unsigned long end = phys_initrd_start + phys_initrd_size;
-
- /*
- * Make sure that the initrd is within a valid area of
- * memory.
- */
- if (phys_initrd_size) {
- unsigned int i;
-
- initrd_node = -1;
-
- for (i = 0; i < mi->nr_banks; i++) {
- struct membank *bank = &mi->bank[i];
- if (bank_phys_start(bank) <= phys_initrd_start &&
- end <= bank_phys_end(bank))
- initrd_node = bank->node;
- }
- }
-
- if (initrd_node == -1) {
- printk(KERN_ERR "INITRD: 0x%08lx+0x%08lx extends beyond "
- "physical memory - disabling initrd\n",
- phys_initrd_start, phys_initrd_size);
- phys_initrd_start = phys_initrd_size = 0;
- }
-#endif
-
- return initrd_node;
-}
-
-static void __init bootmem_init_node(int node, struct meminfo *mi,
+static void __init arm_bootmem_init(struct meminfo *mi,
unsigned long start_pfn, unsigned long end_pfn)
{
- unsigned long boot_pfn;
unsigned int boot_pages;
+ phys_addr_t bitmap;
pg_data_t *pgdat;
int i;
/*
- * Allocate the bootmem bitmap page.
+ * Allocate the bootmem bitmap page. This must be in a region
+ * of memory which has already been mapped.
*/
boot_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
- boot_pfn = find_bootmap_pfn(node, mi, boot_pages);
+ bitmap = lmb_alloc_base(boot_pages << PAGE_SHIFT, L1_CACHE_BYTES,
+ __pfn_to_phys(end_pfn));
/*
- * Initialise the bootmem allocator for this node, handing the
+ * Initialise the bootmem allocator, handing the
* memory banks over to bootmem.
*/
- node_set_online(node);
- pgdat = NODE_DATA(node);
- init_bootmem_node(pgdat, boot_pfn, start_pfn, end_pfn);
+ node_set_online(0);
+ pgdat = NODE_DATA(0);
+ init_bootmem_node(pgdat, __phys_to_pfn(bitmap), start_pfn, end_pfn);
- for_each_nodebank(i, mi, node) {
+ for_each_bank(i, mi) {
struct membank *bank = &mi->bank[i];
if (!bank->highmem)
- free_bootmem_node(pgdat, bank_phys_start(bank), bank_phys_size(bank));
+ free_bootmem(bank_phys_start(bank), bank_phys_size(bank));
}
/*
- * Reserve the bootmem bitmap for this node.
+ * Reserve the LMB reserved regions in bootmem.
*/
- reserve_bootmem_node(pgdat, boot_pfn << PAGE_SHIFT,
- boot_pages << PAGE_SHIFT, BOOTMEM_DEFAULT);
-}
-
-static void __init bootmem_reserve_initrd(int node)
-{
-#ifdef CONFIG_BLK_DEV_INITRD
- pg_data_t *pgdat = NODE_DATA(node);
- int res;
-
- res = reserve_bootmem_node(pgdat, phys_initrd_start,
- phys_initrd_size, BOOTMEM_EXCLUSIVE);
-
- if (res == 0) {
- initrd_start = __phys_to_virt(phys_initrd_start);
- initrd_end = initrd_start + phys_initrd_size;
- } else {
- printk(KERN_ERR
- "INITRD: 0x%08lx+0x%08lx overlaps in-use "
- "memory region - disabling initrd\n",
- phys_initrd_start, phys_initrd_size);
+ for (i = 0; i < lmb.reserved.cnt; i++) {
+ phys_addr_t start = lmb_start_pfn(&lmb.reserved, i);
+ if (start >= start_pfn &&
+ lmb_end_pfn(&lmb.reserved, i) <= end_pfn)
+ reserve_bootmem_node(pgdat, __pfn_to_phys(start),
+ lmb_size_bytes(&lmb.reserved, i),
+ BOOTMEM_DEFAULT);
}
-#endif
}
-static void __init bootmem_free_node(int node, struct meminfo *mi)
+static void __init arm_bootmem_free(struct meminfo *mi, unsigned long min,
+ unsigned long max_low, unsigned long max_high)
{
unsigned long zone_size[MAX_NR_ZONES], zhole_size[MAX_NR_ZONES];
- unsigned long min, max_low, max_high;
int i;
- find_node_limits(node, mi, &min, &max_low, &max_high);
-
/*
- * initialise the zones within this node.
+ * initialise the zones.
*/
memset(zone_size, 0, sizeof(zone_size));
/*
- * The size of this node has already been determined. If we need
- * to do anything fancy with the allocation of this memory to the
- * zones, now is the time to do it.
+ * The memory size has already been determined. If we need
+ * to do anything fancy with the allocation of this memory
+ * to the zones, now is the time to do it.
*/
zone_size[0] = max_low - min;
#ifdef CONFIG_HIGHMEM
@@ -303,11 +212,11 @@ static void __init bootmem_free_node(int node, struct meminfo *mi)
#endif
/*
- * For each bank in this node, calculate the size of the holes.
- * holes = node_size - sum(bank_sizes_in_node)
+ * Calculate the size of the holes.
+ * holes = node_size - sum(bank_sizes)
*/
memcpy(zhole_size, zone_size, sizeof(zhole_size));
- for_each_nodebank(i, mi, node) {
+ for_each_bank(i, mi) {
int idx = 0;
#ifdef CONFIG_HIGHMEM
if (mi->bank[i].highmem)
@@ -320,24 +229,23 @@ static void __init bootmem_free_node(int node, struct meminfo *mi)
* Adjust the sizes according to any special requirements for
* this machine type.
*/
- arch_adjust_zones(node, zone_size, zhole_size);
+ arch_adjust_zones(zone_size, zhole_size);
- free_area_init_node(node, zone_size, min, zhole_size);
+ free_area_init_node(0, zone_size, min, zhole_size);
}
#ifndef CONFIG_SPARSEMEM
int pfn_valid(unsigned long pfn)
{
- struct meminfo *mi = &meminfo;
- unsigned int left = 0, right = mi->nr_banks;
+ struct lmb_region *mem = &lmb.memory;
+ unsigned int left = 0, right = mem->cnt;
do {
unsigned int mid = (right + left) / 2;
- struct membank *bank = &mi->bank[mid];
- if (pfn < bank_pfn_start(bank))
+ if (pfn < lmb_start_pfn(mem, mid))
right = mid;
- else if (pfn >= bank_pfn_end(bank))
+ else if (pfn >= lmb_end_pfn(mem, mid))
left = mid + 1;
else
return 1;
@@ -346,73 +254,69 @@ int pfn_valid(unsigned long pfn)
}
EXPORT_SYMBOL(pfn_valid);
-static void arm_memory_present(struct meminfo *mi, int node)
+static void arm_memory_present(void)
{
}
#else
-static void arm_memory_present(struct meminfo *mi, int node)
+static void arm_memory_present(void)
{
int i;
- for_each_nodebank(i, mi, node) {
- struct membank *bank = &mi->bank[i];
- memory_present(node, bank_pfn_start(bank), bank_pfn_end(bank));
- }
+ for (i = 0; i < lmb.memory.cnt; i++)
+ memory_present(0, lmb_start_pfn(&lmb.memory, i),
+ lmb_end_pfn(&lmb.memory, i));
}
#endif
-void __init bootmem_init(void)
+void __init arm_lmb_init(struct meminfo *mi, struct machine_desc *mdesc)
{
- struct meminfo *mi = &meminfo;
- unsigned long min, max_low, max_high;
- int node, initrd_node;
+ int i;
- /*
- * Locate which node contains the ramdisk image, if any.
- */
- initrd_node = check_initrd(mi);
+ lmb_init();
+ for (i = 0; i < mi->nr_banks; i++)
+ lmb_add(mi->bank[i].start, mi->bank[i].size);
- max_low = max_high = 0;
+ /* Register the kernel text, kernel data and initrd with lmb. */
+#ifdef CONFIG_XIP_KERNEL
+ lmb_reserve(__pa(_data), _end - _data);
+#else
+ lmb_reserve(__pa(_stext), _end - _stext);
+#endif
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (phys_initrd_size) {
+ lmb_reserve(phys_initrd_start, phys_initrd_size);
- /*
- * Run through each node initialising the bootmem allocator.
- */
- for_each_node(node) {
- unsigned long node_low, node_high;
+ /* Now convert initrd to virtual addresses */
+ initrd_start = __phys_to_virt(phys_initrd_start);
+ initrd_end = initrd_start + phys_initrd_size;
+ }
+#endif
- find_node_limits(node, mi, &min, &node_low, &node_high);
+ arm_mm_lmb_reserve();
- if (node_low > max_low)
- max_low = node_low;
- if (node_high > max_high)
- max_high = node_high;
+ /* reserve any platform specific lmb areas */
+ if (mdesc->reserve)
+ mdesc->reserve();
- /*
- * If there is no memory in this node, ignore it.
- * (We can't have nodes which have no lowmem)
- */
- if (node_low == 0)
- continue;
+ lmb_analyze();
+ lmb_dump_all();
+}
- bootmem_init_node(node, mi, min, node_low);
+void __init bootmem_init(void)
+{
+ struct meminfo *mi = &meminfo;
+ unsigned long min, max_low, max_high;
- /*
- * Reserve any special node zero regions.
- */
- if (node == 0)
- reserve_node_zero(NODE_DATA(node));
+ max_low = max_high = 0;
- /*
- * If the initrd is in this node, reserve its memory.
- */
- if (node == initrd_node)
- bootmem_reserve_initrd(node);
+ find_limits(mi, &min, &max_low, &max_high);
- /*
- * Sparsemem tries to allocate bootmem in memory_present(),
- * so must be done after the fixed reservations
- */
- arm_memory_present(mi, node);
- }
+ arm_bootmem_init(mi, min, max_low);
+
+ /*
+ * Sparsemem tries to allocate bootmem in memory_present(),
+ * so must be done after the fixed reservations
+ */
+ arm_memory_present();
/*
* sparse_init() needs the bootmem allocator up and running.
@@ -420,12 +324,11 @@ void __init bootmem_init(void)
sparse_init();
/*
- * Now free memory in each node - free_area_init_node needs
+ * Now free the memory - free_area_init_node needs
* the sparse mem_map arrays initialized by sparse_init()
* for memmap_init_zone(), otherwise all PFNs are invalid.
*/
- for_each_node(node)
- bootmem_free_node(node, mi);
+ arm_bootmem_free(mi, min, max_low, max_high);
high_memory = __va((max_low << PAGE_SHIFT) - 1) + 1;
@@ -460,7 +363,7 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s)
}
static inline void
-free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
+free_memmap(unsigned long start_pfn, unsigned long end_pfn)
{
struct page *start_pg, *end_pg;
unsigned long pg, pgend;
@@ -483,40 +386,39 @@ free_memmap(int node, unsigned long start_pfn, unsigned long end_pfn)
* free the section of the memmap array.
*/
if (pg < pgend)
- free_bootmem_node(NODE_DATA(node), pg, pgend - pg);
+ free_bootmem(pg, pgend - pg);
}
/*
* The mem_map array can get very big. Free the unused area of the memory map.
*/
-static void __init free_unused_memmap_node(int node, struct meminfo *mi)
+static void __init free_unused_memmap(struct meminfo *mi)
{
unsigned long bank_start, prev_bank_end = 0;
unsigned int i;
/*
- * [FIXME] This relies on each bank being in address order. This
- * may not be the case, especially if the user has provided the
- * information on the command line.
+ * This relies on each bank being in address order.
+ * The banks are sorted previously in bootmem_init().
*/
- for_each_nodebank(i, mi, node) {
+ for_each_bank(i, mi) {
struct membank *bank = &mi->bank[i];
bank_start = bank_pfn_start(bank);
- if (bank_start < prev_bank_end) {
- printk(KERN_ERR "MEM: unordered memory banks. "
- "Not freeing memmap.\n");
- break;
- }
/*
* If we had a previous bank, and there is a space
* between the current bank and the previous, free it.
*/
- if (prev_bank_end && prev_bank_end != bank_start)
- free_memmap(node, prev_bank_end, bank_start);
+ if (prev_bank_end && prev_bank_end < bank_start)
+ free_memmap(prev_bank_end, bank_start);
- prev_bank_end = bank_pfn_end(bank);
+ /*
+ * Align up here since the VM subsystem insists that the
+ * memmap entries are valid from the bank end aligned to
+ * MAX_ORDER_NR_PAGES.
+ */
+ prev_bank_end = ALIGN(bank_pfn_end(bank), MAX_ORDER_NR_PAGES);
}
}
@@ -528,21 +430,14 @@ static void __init free_unused_memmap_node(int node, struct meminfo *mi)
void __init mem_init(void)
{
unsigned long reserved_pages, free_pages;
- int i, node;
+ int i;
-#ifndef CONFIG_DISCONTIGMEM
max_mapnr = pfn_to_page(max_pfn + PHYS_PFN_OFFSET) - mem_map;
-#endif
/* this will put all unused low memory onto the freelists */
- for_each_online_node(node) {
- pg_data_t *pgdat = NODE_DATA(node);
+ free_unused_memmap(&meminfo);
- free_unused_memmap_node(node, &meminfo);
-
- if (pgdat->node_spanned_pages != 0)
- totalram_pages += free_all_bootmem_node(pgdat);
- }
+ totalram_pages += free_all_bootmem();
#ifdef CONFIG_SA1111
/* now that our DMA memory is actually so designated, we can free it */
@@ -552,39 +447,35 @@ void __init mem_init(void)
#ifdef CONFIG_HIGHMEM
/* set highmem page free */
- for_each_online_node(node) {
- for_each_nodebank (i, &meminfo, node) {
- unsigned long start = bank_pfn_start(&meminfo.bank[i]);
- unsigned long end = bank_pfn_end(&meminfo.bank[i]);
- if (start >= max_low_pfn + PHYS_PFN_OFFSET)
- totalhigh_pages += free_area(start, end, NULL);
- }
+ for_each_bank (i, &meminfo) {
+ unsigned long start = bank_pfn_start(&meminfo.bank[i]);
+ unsigned long end = bank_pfn_end(&meminfo.bank[i]);
+ if (start >= max_low_pfn + PHYS_PFN_OFFSET)
+ totalhigh_pages += free_area(start, end, NULL);
}
totalram_pages += totalhigh_pages;
#endif
reserved_pages = free_pages = 0;
- for_each_online_node(node) {
- for_each_nodebank(i, &meminfo, node) {
- struct membank *bank = &meminfo.bank[i];
- unsigned int pfn1, pfn2;
- struct page *page, *end;
-
- pfn1 = bank_pfn_start(bank);
- pfn2 = bank_pfn_end(bank);
-
- page = pfn_to_page(pfn1);
- end = pfn_to_page(pfn2 - 1) + 1;
-
- do {
- if (PageReserved(page))
- reserved_pages++;
- else if (!page_count(page))
- free_pages++;
- page++;
- } while (page < end);
- }
+ for_each_bank(i, &meminfo) {
+ struct membank *bank = &meminfo.bank[i];
+ unsigned int pfn1, pfn2;
+ struct page *page, *end;
+
+ pfn1 = bank_pfn_start(bank);
+ pfn2 = bank_pfn_end(bank);
+
+ page = pfn_to_page(pfn1);
+ end = pfn_to_page(pfn2 - 1) + 1;
+
+ do {
+ if (PageReserved(page))
+ reserved_pages++;
+ else if (!page_count(page))
+ free_pages++;
+ page++;
+ } while (page < end);
}
/*
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 28c8b950ef04..03f11935ed08 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -268,6 +268,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
if (pfn >= 0x100000 && (__pfn_to_phys(pfn) & ~SUPERSECTION_MASK))
return NULL;
+ /*
+ * Don't allow RAM to be mapped - this causes problems with ARMv6+
+ */
+ if (WARN_ON(pfn_valid(pfn)))
+ return NULL;
+
type = get_mem_type(mtype);
if (!type)
return NULL;
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 815d08eecbb0..3c26e4cc1bdc 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -28,7 +28,5 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#endif
-struct pglist_data;
-
void __init bootmem_init(void);
-void reserve_node_zero(struct pglist_data *pgdat);
+void arm_mm_lmb_reserve(void);
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index f5abc51c5a07..4f5b39687df5 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -7,6 +7,7 @@
#include <linux/shm.h>
#include <linux/sched.h>
#include <linux/io.h>
+#include <linux/random.h>
#include <asm/cputype.h>
#include <asm/system.h>
@@ -80,6 +81,9 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr,
start_addr = addr = TASK_UNMAPPED_BASE;
mm->cached_hole_size = 0;
}
+ /* 8 bits of randomness in 20 address space bits */
+ if (current->flags & PF_RANDOMIZE)
+ addr += (get_random_int() % (1 << 8)) << PAGE_SHIFT;
full_search:
if (do_align)
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 285894171186..f61c21ca5040 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -11,13 +11,12 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <linux/mman.h>
#include <linux/nodemask.h>
+#include <linux/lmb.h>
#include <linux/sort.h>
#include <asm/cputype.h>
-#include <asm/mach-types.h>
#include <asm/sections.h>
#include <asm/cachetype.h>
#include <asm/setup.h>
@@ -488,18 +487,28 @@ static void __init build_mem_type_table(void)
#define vectors_base() (vectors_high() ? 0xffff0000 : 0)
-static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
- unsigned long end, unsigned long pfn,
- const struct mem_type *type)
+static void __init *early_alloc(unsigned long sz)
{
- pte_t *pte;
+ void *ptr = __va(lmb_alloc(sz, sz));
+ memset(ptr, 0, sz);
+ return ptr;
+}
+static pte_t *early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
+{
if (pmd_none(*pmd)) {
- pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
- __pmd_populate(pmd, __pa(pte) | type->prot_l1);
+ pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t));
+ __pmd_populate(pmd, __pa(pte) | prot);
}
+ BUG_ON(pmd_bad(*pmd));
+ return pte_offset_kernel(pmd, addr);
+}
- pte = pte_offset_kernel(pmd, addr);
+static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
+ unsigned long end, unsigned long pfn,
+ const struct mem_type *type)
+{
+ pte_t *pte = early_pte_alloc(pmd, addr, type->prot_l1);
do {
set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)), 0);
pfn++;
@@ -668,7 +677,7 @@ void __init iotable_init(struct map_desc *io_desc, int nr)
create_mapping(io_desc + i);
}
-static unsigned long __initdata vmalloc_reserve = SZ_128M;
+static void * __initdata vmalloc_min = (void *)(VMALLOC_END - SZ_128M);
/*
* vmalloc=size forces the vmalloc area to be exactly 'size'
@@ -677,7 +686,7 @@ static unsigned long __initdata vmalloc_reserve = SZ_128M;
*/
static int __init early_vmalloc(char *arg)
{
- vmalloc_reserve = memparse(arg, NULL);
+ unsigned long vmalloc_reserve = memparse(arg, NULL);
if (vmalloc_reserve < SZ_16M) {
vmalloc_reserve = SZ_16M;
@@ -692,22 +701,26 @@ static int __init early_vmalloc(char *arg)
"vmalloc area is too big, limiting to %luMB\n",
vmalloc_reserve >> 20);
}
+
+ vmalloc_min = (void *)(VMALLOC_END - vmalloc_reserve);
return 0;
}
early_param("vmalloc", early_vmalloc);
-#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve)
+phys_addr_t lowmem_end_addr;
static void __init sanity_check_meminfo(void)
{
int i, j, highmem = 0;
+ lowmem_end_addr = __pa(vmalloc_min - 1) + 1;
+
for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
struct membank *bank = &meminfo.bank[j];
*bank = meminfo.bank[i];
#ifdef CONFIG_HIGHMEM
- if (__va(bank->start) > VMALLOC_MIN ||
+ if (__va(bank->start) > vmalloc_min ||
__va(bank->start) < (void *)PAGE_OFFSET)
highmem = 1;
@@ -717,8 +730,8 @@ static void __init sanity_check_meminfo(void)
* Split those memory banks which are partially overlapping
* the vmalloc area greatly simplifying things later.
*/
- if (__va(bank->start) < VMALLOC_MIN &&
- bank->size > VMALLOC_MIN - __va(bank->start)) {
+ if (__va(bank->start) < vmalloc_min &&
+ bank->size > vmalloc_min - __va(bank->start)) {
if (meminfo.nr_banks >= NR_BANKS) {
printk(KERN_CRIT "NR_BANKS too low, "
"ignoring high memory\n");
@@ -727,12 +740,12 @@ static void __init sanity_check_meminfo(void)
(meminfo.nr_banks - i) * sizeof(*bank));
meminfo.nr_banks++;
i++;
- bank[1].size -= VMALLOC_MIN - __va(bank->start);
- bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
+ bank[1].size -= vmalloc_min - __va(bank->start);
+ bank[1].start = __pa(vmalloc_min - 1) + 1;
bank[1].highmem = highmem = 1;
j++;
}
- bank->size = VMALLOC_MIN - __va(bank->start);
+ bank->size = vmalloc_min - __va(bank->start);
}
#else
bank->highmem = highmem;
@@ -741,7 +754,7 @@ static void __init sanity_check_meminfo(void)
* Check whether this memory bank would entirely overlap
* the vmalloc area.
*/
- if (__va(bank->start) >= VMALLOC_MIN ||
+ if (__va(bank->start) >= vmalloc_min ||
__va(bank->start) < (void *)PAGE_OFFSET) {
printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
"(vmalloc region overlap).\n",
@@ -753,9 +766,9 @@ static void __init sanity_check_meminfo(void)
* Check whether this memory bank would partially overlap
* the vmalloc area.
*/
- if (__va(bank->start + bank->size) > VMALLOC_MIN ||
+ if (__va(bank->start + bank->size) > vmalloc_min ||
__va(bank->start + bank->size) < __va(bank->start)) {
- unsigned long newsize = VMALLOC_MIN - __va(bank->start);
+ unsigned long newsize = vmalloc_min - __va(bank->start);
printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
"to -%.8lx (vmalloc region overlap).\n",
bank->start, bank->start + bank->size - 1,
@@ -827,101 +840,23 @@ static inline void prepare_page_table(void)
}
/*
- * Reserve the various regions of node 0
+ * Reserve the special regions of memory
*/
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
{
- unsigned long res_size = 0;
-
- /*
- * Register the kernel text and data with bootmem.
- * Note that this can only be in node 0.
- */
-#ifdef CONFIG_XIP_KERNEL
- reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
- BOOTMEM_DEFAULT);
-#else
- reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
- BOOTMEM_DEFAULT);
-#endif
-
/*
* Reserve the page tables. These are already in use,
* and can only be in node 0.
*/
- reserve_bootmem_node(pgdat, __pa(swapper_pg_dir),
- PTRS_PER_PGD * sizeof(pgd_t), BOOTMEM_DEFAULT);
-
- /*
- * Hmm... This should go elsewhere, but we really really need to
- * stop things allocating the low memory; ideally we need a better
- * implementation of GFP_DMA which does not assume that DMA-able
- * memory starts at zero.
- */
- if (machine_is_integrator() || machine_is_cintegrator())
- res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
-
- /*
- * These should likewise go elsewhere. They pre-reserve the
- * screen memory region at the start of main system memory.
- */
- if (machine_is_edb7211())
- res_size = 0x00020000;
- if (machine_is_p720t())
- res_size = 0x00014000;
-
- /* H1940, RX3715 and RX1950 need to reserve this for suspend */
-
- if (machine_is_h1940() || machine_is_rx3715()
- || machine_is_rx1950()) {
- reserve_bootmem_node(pgdat, 0x30003000, 0x1000,
- BOOTMEM_DEFAULT);
- reserve_bootmem_node(pgdat, 0x30081000, 0x1000,
- BOOTMEM_DEFAULT);
- }
-
- if (machine_is_palmld() || machine_is_palmtx()) {
- reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
- BOOTMEM_EXCLUSIVE);
- reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
- BOOTMEM_EXCLUSIVE);
- }
-
- if (machine_is_treo680() || machine_is_centro()) {
- reserve_bootmem_node(pgdat, 0xa0000000, 0x1000,
- BOOTMEM_EXCLUSIVE);
- reserve_bootmem_node(pgdat, 0xa2000000, 0x1000,
- BOOTMEM_EXCLUSIVE);
- }
-
- if (machine_is_palmt5())
- reserve_bootmem_node(pgdat, 0xa0200000, 0x1000,
- BOOTMEM_EXCLUSIVE);
-
- /*
- * U300 - This platform family can share physical memory
- * between two ARM cpus, one running Linux and the other
- * running another OS.
- */
- if (machine_is_u300()) {
-#ifdef CONFIG_MACH_U300_SINGLE_RAM
-#if ((CONFIG_MACH_U300_ACCESS_MEM_SIZE & 1) == 1) && \
- CONFIG_MACH_U300_2MB_ALIGNMENT_FIX
- res_size = 0x00100000;
-#endif
-#endif
- }
+ lmb_reserve(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(pgd_t));
#ifdef CONFIG_SA1111
/*
* Because of the SA1111 DMA bug, we want to preserve our
* precious DMA-able memory...
*/
- res_size = __pa(swapper_pg_dir) - PHYS_OFFSET;
+ lmb_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
#endif
- if (res_size)
- reserve_bootmem_node(pgdat, PHYS_OFFSET, res_size,
- BOOTMEM_DEFAULT);
}
/*
@@ -940,7 +875,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
/*
* Allocate the vector page early.
*/
- vectors = alloc_bootmem_low_pages(PAGE_SIZE);
+ vectors = early_alloc(PAGE_SIZE);
for (addr = VMALLOC_END; addr; addr += PGDIR_SIZE)
pmd_clear(pmd_off_k(addr));
@@ -1011,11 +946,8 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
static void __init kmap_init(void)
{
#ifdef CONFIG_HIGHMEM
- pmd_t *pmd = pmd_off_k(PKMAP_BASE);
- pte_t *pte = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * sizeof(pte_t));
- BUG_ON(!pmd_none(*pmd) || !pte);
- __pmd_populate(pmd, __pa(pte) | _PAGE_KERNEL_TABLE);
- pkmap_page_table = pte + PTRS_PER_PTE;
+ pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
+ PKMAP_BASE, _PAGE_KERNEL_TABLE);
#endif
}
@@ -1066,17 +998,16 @@ void __init paging_init(struct machine_desc *mdesc)
sanity_check_meminfo();
prepare_page_table();
map_lowmem();
- bootmem_init();
devicemaps_init(mdesc);
kmap_init();
top_pmd = pmd_off_k(0xffff0000);
- /*
- * allocate the zero page. Note that this always succeeds and
- * returns a zeroed result.
- */
- zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ /* allocate the zero page. */
+ zero_page = early_alloc(PAGE_SIZE);
+
+ bootmem_init();
+
empty_zero_page = virt_to_page(zero_page);
__flush_dcache_page(NULL, empty_zero_page);
}
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c
index 33b327379f07..ea2433ebae9c 100644
--- a/arch/arm/mm/nommu.c
+++ b/arch/arm/mm/nommu.c
@@ -6,8 +6,8 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
-#include <linux/bootmem.h>
#include <linux/io.h>
+#include <linux/lmb.h>
#include <asm/cacheflush.h>
#include <asm/sections.h>
@@ -17,30 +17,14 @@
#include "mm.h"
-/*
- * Reserve the various regions of node 0
- */
-void __init reserve_node_zero(pg_data_t *pgdat)
+void __init arm_mm_lmb_reserve(void)
{
/*
- * Register the kernel text and data with bootmem.
- * Note that this can only be in node 0.
- */
-#ifdef CONFIG_XIP_KERNEL
- reserve_bootmem_node(pgdat, __pa(_data), _end - _data,
- BOOTMEM_DEFAULT);
-#else
- reserve_bootmem_node(pgdat, __pa(_stext), _end - _stext,
- BOOTMEM_DEFAULT);
-#endif
-
- /*
* Register the exception vector page.
* some architectures which the DRAM is the exception vector to trap,
* alloc_page breaks with error, although it is not NULL, but "0."
*/
- reserve_bootmem_node(pgdat, CONFIG_VECTORS_BASE, PAGE_SIZE,
- BOOTMEM_DEFAULT);
+ lmb_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
}
/*
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 7a5337ed7d68..2f5a3c23a0fe 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -239,7 +239,8 @@ __v6_proc_info:
b __v6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA
+ /* See also feat_v6_fixup() for HWCAP_TLS */
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_JAVA|HWCAP_TLS
.long cpu_v6_name
.long v6_processor_functions
.long v6wbi_tlb_fns
@@ -262,7 +263,7 @@ __pj4_v6_proc_info:
b __v6_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
.long cpu_pj4_name
.long v6_processor_functions
.long v6wbi_tlb_fns
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 7aaf88a3b7aa..8071bcd4c995 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -344,7 +344,7 @@ __v7_proc_info:
b __v7_setup
.long cpu_arch_name
.long cpu_elf_name
- .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
.long cpu_v7_name
.long v7_processor_functions
.long v7wbi_tlb_fns
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
new file mode 100644
index 000000000000..639c54a07992
--- /dev/null
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010 Jason Wang <jason77.wang@gmail.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/smsc911x.h>
+
+#include <mach/hardware.h>
+
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR(n) (n + 0x0)
+/* External UART */
+#define UARTA_BASE_ADDR(n) (n + 0x8000)
+#define UARTB_BASE_ADDR(n) (n + 0x10000)
+
+#define BOARD_IO_ADDR(n) (n + 0x20000)
+/* LED switchs */
+#define LED_SWITCH_REG 0x00
+/* buttons */
+#define SWITCH_BUTTONS_REG 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG 0x10
+#define INTR_MASK_REG 0x38
+#define INTR_RESET_REG 0x20
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG 0x40
+#define MAGIC_NUMBER2_REG 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG 0x50
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER3_REG 0x58
+/* module reset register*/
+#define MODULE_RESET_REG 0x60
+/* CPU ID and Personality ID */
+#define MCU_BOARD_ID_REG 0x68
+
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_BOARD_IRQ_START)
+#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_INTERNAL_IRQS)
+
+#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
+#define MXC_MAX_EXP_IO_LINES 16
+
+/* interrupts like external uart , external ethernet etc*/
+#define EXPIO_INT_ENET (MXC_BOARD_IRQ_START + 0)
+#define EXPIO_INT_XUART_A (MXC_BOARD_IRQ_START + 1)
+#define EXPIO_INT_XUART_B (MXC_BOARD_IRQ_START + 2)
+#define EXPIO_INT_BUTTON_A (MXC_BOARD_IRQ_START + 3)
+#define EXPIO_INT_BUTTON_B (MXC_BOARD_IRQ_START + 4)
+
+static void __iomem *brd_io;
+static void expio_ack_irq(u32 irq);
+
+static struct resource smsc911x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ } , {
+ .start = EXPIO_INT_ENET,
+ .end = EXPIO_INT_ENET,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config smsc911x_config = {
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .flags = SMSC911X_USE_32BIT | SMSC911X_FORCE_INTERNAL_PHY,
+};
+
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .platform_data = &smsc911x_config,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ imr_val = __raw_readw(brd_io + INTR_MASK_REG);
+ int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
+
+ expio_irq = MXC_BOARD_IRQ_START;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ struct irq_desc *d;
+ if ((int_valid & 1) == 0)
+ continue;
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq)))
+ pr_err("\nEXPIO irq: %d unhandled\n", expio_irq);
+ else
+ d->handle_irq(expio_irq, d);
+ }
+
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * Irq is an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg |= (1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static void expio_ack_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+
+ __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ expio_mask_irq(irq);
+}
+
+static void expio_unmask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg &= ~(1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+int __init mxc_expio_init(u32 base, u32 p_irq)
+{
+ int i;
+
+ brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K);
+ if (brd_io == NULL)
+ return -ENOMEM;
+
+ if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
+ pr_info("3-Stack Debug board not detected\n");
+ iounmap(brd_io);
+ brd_io = NULL;
+ return -ENODEV;
+ }
+
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
+ readw(brd_io + CPLD_CODE_VER_REG));
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq");
+ gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq));
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0, brd_io + INTR_MASK_REG);
+ __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ __raw_writew(0x1F, brd_io + INTR_MASK_REG);
+ for (i = MXC_EXP_IO_BASE;
+ i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(p_irq, IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(p_irq, mxc_expio_irq_handler);
+
+ /* Register Lan device on the debugboard */
+ smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
+ smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
+ platform_device_register(&smsc_lan9217_device);
+
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 7f7ad6f289bd..0527e65318f4 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -1,5 +1,7 @@
if ARCH_MXC
+source "arch/arm/plat-mxc/devices/Kconfig"
+
menu "Freescale MXC Implementations"
choice
@@ -8,15 +10,12 @@ choice
config ARCH_MX1
bool "MX1-based"
- select CPU_ARM920T
- select IMX_HAVE_IOMUX_V1
+ select SOC_IMX1
help
This enables support for systems based on the Freescale i.MX1 family
config ARCH_MX2
bool "MX2-based"
- select CPU_ARM926T
- select IMX_HAVE_IOMUX_V1
help
This enables support for systems based on the Freescale i.MX2 family
@@ -25,6 +24,7 @@ config ARCH_MX25
select CPU_ARM926T
select ARCH_MXC_IOMUX_V3
select HAVE_FB_IMX
+ select ARCH_MXC_AUDMUX_V2
help
This enables support for systems based on the Freescale i.MX25 family
@@ -48,8 +48,7 @@ config ARCH_MX5
endchoice
-source "arch/arm/mach-mx1/Kconfig"
-source "arch/arm/mach-mx2/Kconfig"
+source "arch/arm/mach-imx/Kconfig"
source "arch/arm/mach-mx3/Kconfig"
source "arch/arm/mach-mx25/Kconfig"
source "arch/arm/mach-mxc91231/Kconfig"
@@ -81,6 +80,17 @@ config MXC_PWM
help
Enable support for the i.MX PWM controller(s).
+config MXC_DEBUG_BOARD
+ bool "Enable MXC debug board(for 3-stack)"
+ help
+ The debug board is an integral part of the MXC 3-stack(PDK)
+ platforms, it can be attached or removed from the peripheral
+ board. On debug board, several debug devices(ethernet, UART,
+ buttons, LEDs and JTAG) are implemented. Between the MCU and
+ these devices, a CPLD is added as a bridge which performs
+ data/address de-multiplexing and decode, signal level shift,
+ interrupt control and various board functions.
+
config MXC_ULPI
bool
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 895bc3c5e0c0..78d405ed8616 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -8,8 +8,6 @@ obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
obj-$(CONFIG_MXC_TZIC) += tzic.o
-obj-$(CONFIG_ARCH_MX1) += dma-mx1-mx2.o
-obj-$(CONFIG_ARCH_MX2) += dma-mx1-mx2.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
obj-$(CONFIG_MXC_PWM) += pwm.o
@@ -17,7 +15,10 @@ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
+obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
ifdef CONFIG_SND_IMX_SOC
obj-y += ssi-fiq.o
obj-y += ssi-fiq-ksym.o
endif
+
+obj-y += devices/
diff --git a/arch/arm/plat-mxc/audmux-v1.c b/arch/arm/plat-mxc/audmux-v1.c
index b62917ca3f95..1180bef7664b 100644
--- a/arch/arm/plat-mxc/audmux-v1.c
+++ b/arch/arm/plat-mxc/audmux-v1.c
@@ -13,10 +13,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 0c2cc5cd4d83..f9e7cdbd0005 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -13,10 +13,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
@@ -191,6 +187,7 @@ static int mxc_audmux_v2_init(void)
{
int ret;
+#if defined(CONFIG_ARCH_MX3)
if (cpu_is_mx31())
audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
@@ -204,7 +201,19 @@ static int mxc_audmux_v2_init(void)
}
audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
}
-
+#endif
+#if defined(CONFIG_ARCH_MX25)
+ if (cpu_is_mx25()) {
+ audmux_clk = clk_get(NULL, "audmux");
+ if (IS_ERR(audmux_clk)) {
+ ret = PTR_ERR(audmux_clk);
+ printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
+ ret);
+ return ret;
+ }
+ audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
+ }
+#endif
audmux_debugfs_init();
return 0;
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 323ff8ccc877..2ed3ab173add 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -52,13 +52,14 @@ static void __clk_disable(struct clk *clk)
{
if (clk == NULL || IS_ERR(clk))
return;
-
- __clk_disable(clk->parent);
- __clk_disable(clk->secondary);
-
WARN_ON(!clk->usecount);
- if (!(--clk->usecount) && clk->disable)
- clk->disable(clk);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
}
static int __clk_enable(struct clk *clk)
@@ -66,12 +67,13 @@ static int __clk_enable(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
- __clk_enable(clk->parent);
- __clk_enable(clk->secondary);
-
- if (clk->usecount++ == 0 && clk->enable)
- clk->enable(clk);
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+ if (clk->enable)
+ clk->enable(clk);
+ }
return 0;
}
@@ -160,17 +162,28 @@ EXPORT_SYMBOL(clk_set_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
int ret = -EINVAL;
+ struct clk *old;
if (clk == NULL || IS_ERR(clk) || parent == NULL ||
IS_ERR(parent) || clk->set_parent == NULL)
return ret;
+ if (clk->usecount)
+ clk_enable(parent);
+
mutex_lock(&clocks_mutex);
ret = clk->set_parent(clk, parent);
- if (ret == 0)
+ if (ret == 0) {
+ old = clk->parent;
clk->parent = parent;
+ } else {
+ old = parent;
+ }
mutex_unlock(&clocks_mutex);
+ if (clk->usecount)
+ clk_disable(old);
+
return ret;
}
EXPORT_SYMBOL(clk_set_parent);
diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c
index 56f2fb5cc456..735776d84956 100644
--- a/arch/arm/plat-mxc/devices.c
+++ b/arch/arm/plat-mxc/devices.c
@@ -18,6 +18,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/err.h>
#include <linux/platform_device.h>
#include <mach/common.h>
@@ -35,3 +36,35 @@ int __init mxc_register_device(struct platform_device *pdev, void *data)
return ret;
}
+struct platform_device *__init imx_add_platform_device(const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
new file mode 100644
index 000000000000..09230f8c802a
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -0,0 +1,11 @@
+config IMX_HAVE_PLATFORM_IMX_I2C
+ bool
+
+config IMX_HAVE_PLATFORM_IMX_UART
+ bool
+
+config IMX_HAVE_PLATFORM_MXC_NAND
+ bool
+
+config IMX_HAVE_PLATFORM_SPI_IMX
+ bool
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
new file mode 100644
index 000000000000..5ecbb244d210
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_I2C) += platform-imx-i2c.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) += platform-spi_imx.o
diff --git a/arch/arm/plat-mxc/devices/platform-imx-i2c.c b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
new file mode 100644
index 000000000000..d0af9f7d8aed
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-i2c.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/devices-common.h>
+
+struct platform_device *__init imx_add_imx_i2c(int id,
+ resource_size_t iobase, resource_size_t iosize, int irq,
+ const struct imxi2c_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-i2c", id, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-uart.c b/arch/arm/plat-mxc/devices/platform-imx-uart.c
new file mode 100644
index 000000000000..fa3dff1433e8
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-imx-uart.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <mach/devices-common.h>
+
+struct platform_device *__init imx_add_imx_uart_3irq(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irqrx, resource_size_t irqtx,
+ resource_size_t irqrts,
+ const struct imxuart_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irqrx,
+ .end = irqrx,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = irqtx,
+ .end = irqtx,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = irqrts,
+ .end = irqrx,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_add_imx_uart_1irq(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irq,
+ const struct imxuart_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("imx-uart", id, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/devices/platform-mxc_nand.c b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
new file mode 100644
index 000000000000..1c286418d123
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-mxc_nand.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <asm/sizes.h>
+#include <mach/devices-common.h>
+
+static struct platform_device *__init imx_add_mxc_nand(resource_size_t iobase,
+ int irq, const struct mxc_nand_platform_data *pdata,
+ resource_size_t iosize)
+{
+ static int id = 0;
+
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("mxc_nand", id++, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
+ int irq, const struct mxc_nand_platform_data *pdata)
+{
+ return imx_add_mxc_nand(iobase, irq, pdata, SZ_4K);
+}
+
+struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
+ int irq, const struct mxc_nand_platform_data *pdata)
+{
+ return imx_add_mxc_nand(iobase, irq, pdata, SZ_8K);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-spi_imx.c b/arch/arm/plat-mxc/devices/platform-spi_imx.c
new file mode 100644
index 000000000000..2831a6d3eb4b
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-spi_imx.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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 <asm/sizes.h>
+#include <mach/devices-common.h>
+
+struct platform_device *__init imx_add_spi_imx(int id,
+ resource_size_t iobase, resource_size_t iosize, int irq,
+ const struct spi_imx_master *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = iobase,
+ .end = iobase + iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = irq,
+ .end = irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return imx_add_platform_device("spi_imx", id, res, ARRAY_SIZE(res),
+ pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index 2a8646173c2f..35a064ff02ba 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -11,10 +11,6 @@
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/platform_device.h>
@@ -73,7 +69,51 @@
int mxc_initialize_usb_hw(int port, unsigned int flags)
{
unsigned int v;
-#ifdef CONFIG_ARCH_MX3
+#if defined(CONFIG_ARCH_MX25)
+ if (cpu_is_mx25()) {
+ v = readl(MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+
+ switch (port) {
+ case 0: /* OTG port */
+ v &= ~(MX35_OTG_SIC_MASK | MX35_OTG_PM_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK)
+ << MX35_OTG_SIC_SHIFT;
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX35_OTG_PM_BIT;
+
+ break;
+ case 1: /* H1 port */
+ v &= ~(MX35_H1_SIC_MASK | MX35_H1_PM_BIT | MX35_H1_TLL_BIT |
+ MX35_H1_USBTE_BIT | MX35_H1_IPPUE_DOWN_BIT | MX35_H1_IPPUE_UP_BIT);
+ v |= (flags & MXC_EHCI_INTERFACE_MASK)
+ << MX35_H1_SIC_SHIFT;
+ if (!(flags & MXC_EHCI_POWER_PINS_ENABLED))
+ v |= MX35_H1_PM_BIT;
+
+ if (!(flags & MXC_EHCI_TTL_ENABLED))
+ v |= MX35_H1_TLL_BIT;
+
+ if (flags & MXC_EHCI_INTERNAL_PHY)
+ v |= MX35_H1_USBTE_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_DOWN)
+ v |= MX35_H1_IPPUE_DOWN_BIT;
+
+ if (flags & MXC_EHCI_IPPUE_UP)
+ v |= MX35_H1_IPPUE_UP_BIT;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ writel(v, MX25_IO_ADDRESS(MX25_OTG_BASE_ADDR +
+ USBCTRL_OTGBASE_OFFSET));
+ return 0;
+ }
+#endif /* CONFIG_ARCH_MX25 */
+#if defined(CONFIG_ARCH_MX3)
if (cpu_is_mx31()) {
v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
USBCTRL_OTGBASE_OFFSET));
diff --git a/arch/arm/plat-mxc/include/mach/3ds_debugboard.h b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
new file mode 100644
index 000000000000..a384fdd49c62
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/3ds_debugboard.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_3DS_DB_H__
+#define __ASM_ARCH_MXC_3DS_DB_H__
+
+extern int __init mxc_expio_init(u32 base, u32 p_irq);
+
+#endif /* __ASM_ARCH_MXC_3DS_DB_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h b/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
deleted file mode 100644
index 0376c133c9f4..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-armadillo5x0.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>.
- * All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
-#define __ASM_ARCH_MXC_BOARD_ARMADILLO5X0_H__
-
-#endif
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx25.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx25.h
new file mode 100644
index 000000000000..5c9901e7d8d0
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx25.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on board-pcm038.h which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX25_H__
+#define __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX25_H__
+
+#ifndef __ASSEMBLY__
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own baseboard init function and call it from
+ * inside eukrea_cpuimx25_init().
+ *
+ * This example here is for the development board. Refer
+ * eukrea_mbimx25-baseboard.c
+ */
+
+extern void eukrea_mbimxsd_baseboard_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX25_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
index a1fd5830af48..45b2fb8bed61 100644
--- a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
+++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx27.h
@@ -25,7 +25,7 @@
#ifndef __ASSEMBLY__
/*
* This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
+ * its own devices, it calls the baseboard's init function.
* TODO: Add your own baseboard init function and call it from
* inside eukrea_cpuimx27_init().
*
diff --git a/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx35.h b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx35.h
new file mode 100644
index 000000000000..116eee723455
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/board-eukrea_cpuimx35.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on board-pcm038.h which is :
+ * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX35_H__
+#define __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX35_H__
+
+#ifndef __ASSEMBLY__
+/*
+ * This CPU module needs a baseboard to work. After basic initializing
+ * its own devices, it calls baseboard's init function.
+ * TODO: Add your own baseboard init function and call it from
+ * inside eukrea_cpuimx25_init().
+ *
+ * This example here is for the development board. Refer
+ * eukrea_mbimx25-baseboard.c
+ */
+
+extern void eukrea_mbimxsd_baseboard_init(void);
+
+#endif
+
+#endif /* __ASM_ARCH_MXC_BOARD_EUKREA_CPUIMX35_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-kzmarm11.h b/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
deleted file mode 100644
index 93cc66f104c7..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-kzmarm11.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 Yoichi Yuasa <yuasa@linux-mips.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __ARM_ARCH_BOARD_KZM_ARM11_H
-#define __ARM_ARCH_BOARD_KZM_ARM11_H
-
-/*
- * KZM-ARM11-01 Board Control Registers on FPGA
- */
-#define KZM_ARM11_CTL1 (MX31_CS4_BASE_ADDR + 0x1000)
-#define KZM_ARM11_CTL2 (MX31_CS4_BASE_ADDR + 0x1001)
-#define KZM_ARM11_RSW1 (MX31_CS4_BASE_ADDR + 0x1002)
-#define KZM_ARM11_BACK_LIGHT (MX31_CS4_BASE_ADDR + 0x1004)
-#define KZM_ARM11_FPGA_REV (MX31_CS4_BASE_ADDR + 0x1008)
-#define KZM_ARM11_7SEG_LED (MX31_CS4_BASE_ADDR + 0x1010)
-#define KZM_ARM11_LEDS (MX31_CS4_BASE_ADDR + 0x1020)
-#define KZM_ARM11_DIPSW2 (MX31_CS4_BASE_ADDR + 0x1003)
-
-/*
- * External UART for touch panel on FPGA
- */
-#define KZM_ARM11_16550 (MX31_CS4_BASE_ADDR + 0x1050)
-
-#endif /* __ARM_ARCH_BOARD_KZM_ARM11_H */
-
diff --git a/arch/arm/plat-mxc/include/mach/board-mx21ads.h b/arch/arm/plat-mxc/include/mach/board-mx21ads.h
deleted file mode 100644
index 0cf4fa29510c..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx21ads.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX21ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX21ADS_H__
-
-/*
- * Memory-mapped I/O on MX21ADS base board
- */
-#define MX21ADS_MMIO_BASE_ADDR 0xF5000000
-#define MX21ADS_MMIO_SIZE SZ_16M
-
-#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
- (MX21ADS_MMIO_BASE_ADDR + (offset))
-
-#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
-#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
-#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
-#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
-#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
-
-/* MX21ADS_IO_REG bit definitions */
-#define MX21ADS_IO_SD_WP 0x0001 /* read */
-#define MX21ADS_IO_TP6 0x0001 /* write */
-#define MX21ADS_IO_SW_SEL 0x0002 /* read */
-#define MX21ADS_IO_TP7 0x0002 /* write */
-#define MX21ADS_IO_RESET_E_UART 0x0004
-#define MX21ADS_IO_RESET_BASE 0x0008
-#define MX21ADS_IO_CSI_CTL2 0x0010
-#define MX21ADS_IO_CSI_CTL1 0x0020
-#define MX21ADS_IO_CSI_CTL0 0x0040
-#define MX21ADS_IO_UART1_EN 0x0080
-#define MX21ADS_IO_UART4_EN 0x0100
-#define MX21ADS_IO_LCDON 0x0200
-#define MX21ADS_IO_IRDA_EN 0x0400
-#define MX21ADS_IO_IRDA_FIR_SEL 0x0800
-#define MX21ADS_IO_IRDA_MD0_B 0x1000
-#define MX21ADS_IO_IRDA_MD1 0x2000
-#define MX21ADS_IO_LED4_ON 0x4000
-#define MX21ADS_IO_LED3_ON 0x8000
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX21ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h
deleted file mode 100644
index 7776d230327f..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * The code contained herein is licensed under the GNU General Public
- * License. You may obtain a copy of the GNU General Public License
- * Version 2 or later at the following locations:
- *
- * http://www.opensource.org/licenses/gpl-license.html
- * http://www.gnu.org/copyleft/gpl.html
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX27ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX27ADS_H__
-
-/* external interrupt multiplexer */
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-
-#define MXC_VIRTUAL_INTS_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES)
-#define MXC_SDIO1_CARD_IRQ MXC_VIRTUAL_INTS_BASE
-#define MXC_SDIO2_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 1)
-#define MXC_SDIO3_CARD_IRQ (MXC_VIRTUAL_INTS_BASE + 2)
-
-#define MXC_MAX_BOARD_INTS (MXC_MAX_EXP_IO_LINES + \
- MXC_MAX_VIRTUAL_INTS)
-
-/*
- * @name Memory Size parameters
- */
-
-/*
- * Size of SDRAM memory
- */
-#define SDRAM_MEM_SIZE SZ_128M
-
-/*
- * PBC Controller parameters
- */
-
-/*
- * Base address of PBC controller, CS4
- */
-#define PBC_BASE_ADDRESS 0xf4300000
-#define PBC_REG_ADDR(offset) (void __force __iomem *) \
- (PBC_BASE_ADDRESS + (offset))
-
-/*
- * PBC Interupt name definitions
- */
-#define PBC_GPIO1_0 0
-#define PBC_GPIO1_1 1
-#define PBC_GPIO1_2 2
-#define PBC_GPIO1_3 3
-#define PBC_GPIO1_4 4
-#define PBC_GPIO1_5 5
-
-#define PBC_INTR_MAX_NUM 6
-#define PBC_INTR_SHARED_MAX_NUM 8
-
-/* When the PBC address connection is fixed in h/w, defined as 1 */
-#define PBC_ADDR_SH 0
-
-/* Offsets for the PBC Controller register */
-/*
- * PBC Board version register offset
- */
-#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 1 set address.
- */
-#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 1 clear address.
- */
-#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
-/*
- * PBC Board control register 2 set address.
- */
-#define PBC_BCTRL2_SET_REG PBC_REG_ADDR(0x00010 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 2 clear address.
- */
-#define PBC_BCTRL2_CLEAR_REG PBC_REG_ADDR(0x00014 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 3 set address.
- */
-#define PBC_BCTRL3_SET_REG PBC_REG_ADDR(0x00018 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 3 clear address.
- */
-#define PBC_BCTRL3_CLEAR_REG PBC_REG_ADDR(0x0001C >> PBC_ADDR_SH)
-/*
- * PBC Board control register 3 set address.
- */
-#define PBC_BCTRL4_SET_REG PBC_REG_ADDR(0x00020 >> PBC_ADDR_SH)
-/*
- * PBC Board control register 4 clear address.
- */
-#define PBC_BCTRL4_CLEAR_REG PBC_REG_ADDR(0x00024 >> PBC_ADDR_SH)
-/*PBC_ADDR_SH
- * PBC Board status register 1.
- */
-#define PBC_BSTAT1_REG PBC_REG_ADDR(0x00028 >> PBC_ADDR_SH)
-/*
- * PBC Board interrupt status register.
- */
-#define PBC_INTSTATUS_REG PBC_REG_ADDR(0x0002C >> PBC_ADDR_SH)
-/*
- * PBC Board interrupt current status register.
- */
-#define PBC_INTCURR_STATUS_REG PBC_REG_ADDR(0x00034 >> PBC_ADDR_SH)
-/*
- * PBC Interrupt mask register set address.
- */
-#define PBC_INTMASK_SET_REG PBC_REG_ADDR(0x00038 >> PBC_ADDR_SH)
-/*
- * PBC Interrupt mask register clear address.
- */
-#define PBC_INTMASK_CLEAR_REG PBC_REG_ADDR(0x0003C >> PBC_ADDR_SH)
-/*
- * External UART A.
- */
-#define PBC_SC16C652_UARTA_REG PBC_REG_ADDR(0x20000 >> PBC_ADDR_SH)
-/*
- * UART 4 Expanding Signal Status.
- */
-#define PBC_UART_STATUS_REG PBC_REG_ADDR(0x22000 >> PBC_ADDR_SH)
-/*
- * UART 4 Expanding Signal Control Set.
- */
-#define PBC_UCTRL_SET_REG PBC_REG_ADDR(0x24000 >> PBC_ADDR_SH)
-/*
- * UART 4 Expanding Signal Control Clear.
- */
-#define PBC_UCTRL_CLR_REG PBC_REG_ADDR(0x26000 >> PBC_ADDR_SH)
-/*
- * Ethernet Controller IO base address.
- */
-#define PBC_CS8900A_IOBASE_REG PBC_REG_ADDR(0x40000 >> PBC_ADDR_SH)
-/*
- * Ethernet Controller Memory base address.
- */
-#define PBC_CS8900A_MEMBASE_REG PBC_REG_ADDR(0x42000 >> PBC_ADDR_SH)
-/*
- * Ethernet Controller DMA base address.
- */
-#define PBC_CS8900A_DMABASE_REG PBC_REG_ADDR(0x44000 >> PBC_ADDR_SH)
-
-/* PBC Board Version Register bit definition */
-#define PBC_VERSION_ADS 0x8000 /* Bit15=1 means version for ads */
-#define PBC_VERSION_EVB_REVB 0x4000 /* BIT14=1 means version for evb revb */
-
-/* PBC Board Control Register 1 bit definitions */
-#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */
-#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */
-#define PBC_BCTRL1_FRST 0x0004 /* FEC Reset */
-#define PBC_BCTRL1_ESLEEP 0x0010 /* Enable ethernet Sleep */
-#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
-
-/* PBC Board Control Register 2 bit definitions */
-#define PBC_BCTRL2_VCC_EN 0x0004 /* Enable VCC */
-#define PBC_BCTRL2_VPP_EN 0x0008 /* Enable Vpp */
-#define PBC_BCTRL2_ATAFEC_EN 0X0010
-#define PBC_BCTRL2_ATAFEC_SEL 0X0020
-#define PBC_BCTRL2_ATA_EN 0X0040
-#define PBC_BCTRL2_IRDA_SD 0X0080
-#define PBC_BCTRL2_IRDA_EN 0X0100
-#define PBC_BCTRL2_CCTL10 0X0200
-#define PBC_BCTRL2_CCTL11 0X0400
-
-/* PBC Board Control Register 3 bit definitions */
-#define PBC_BCTRL3_HSH_EN 0X0020
-#define PBC_BCTRL3_FSH_MOD 0X0040
-#define PBC_BCTRL3_OTG_HS_EN 0X0080
-#define PBC_BCTRL3_OTG_VBUS_EN 0X0100
-#define PBC_BCTRL3_FSH_VBUS_EN 0X0200
-#define PBC_BCTRL3_USB_OTG_ON 0X0800
-#define PBC_BCTRL3_USB_FSH_ON 0X1000
-
-/* PBC Board Control Register 4 bit definitions */
-#define PBC_BCTRL4_REGEN_SEL 0X0001
-#define PBC_BCTRL4_USER_OFF 0X0002
-#define PBC_BCTRL4_VIB_EN 0X0004
-#define PBC_BCTRL4_PWRGT1_EN 0X0008
-#define PBC_BCTRL4_PWRGT2_EN 0X0010
-#define PBC_BCTRL4_STDBY_PRI 0X0020
-
-#ifndef __ASSEMBLY__
-/*
- * Enumerations for SD cards and memory stick card. This corresponds to
- * the card EN bits in the IMR: SD1_EN | MS_EN | SD3_EN | SD2_EN.
- */
-enum mxc_card_no {
- MXC_CARD_SD2 = 0,
- MXC_CARD_SD3,
- MXC_CARD_MS,
- MXC_CARD_SD1,
- MXC_CARD_MIN = MXC_CARD_SD2,
- MXC_CARD_MAX = MXC_CARD_SD1,
-};
-#endif
-
-#define MXC_CPLD_VER_1_50 0x01
-
-/*
- * PBC BSTAT Register bit definitions
- */
-#define PBC_BSTAT_PRI_INT 0X0001
-#define PBC_BSTAT_USB_BYP 0X0002
-#define PBC_BSTAT_ATA_IOCS16 0X0004
-#define PBC_BSTAT_ATA_CBLID 0X0008
-#define PBC_BSTAT_ATA_DASP 0X0010
-#define PBC_BSTAT_PWR_RDY 0X0020
-#define PBC_BSTAT_SD3_WP 0X0100
-#define PBC_BSTAT_SD2_WP 0X0200
-#define PBC_BSTAT_SD1_WP 0X0400
-#define PBC_BSTAT_SD3_DET 0X0800
-#define PBC_BSTAT_SD2_DET 0X1000
-#define PBC_BSTAT_SD1_DET 0X2000
-#define PBC_BSTAT_MS_DET 0X4000
-#define PBC_BSTAT_SD3_DET_BIT 11
-#define PBC_BSTAT_SD2_DET_BIT 12
-#define PBC_BSTAT_SD1_DET_BIT 13
-#define PBC_BSTAT_MS_DET_BIT 14
-#define MXC_BSTAT_BIT(n) ((n == MXC_CARD_SD2) ? PBC_BSTAT_SD2_DET : \
- ((n == MXC_CARD_SD3) ? PBC_BSTAT_SD3_DET : \
- ((n == MXC_CARD_SD1) ? PBC_BSTAT_SD1_DET : \
- ((n == MXC_CARD_MS) ? PBC_BSTAT_MS_DET : \
- 0x0))))
-
-/*
- * PBC UART Control Register bit definitions
- */
-#define PBC_UCTRL_DCE_DCD 0X0001
-#define PBC_UCTRL_DCE_DSR 0X0002
-#define PBC_UCTRL_DCE_RI 0X0004
-#define PBC_UCTRL_DTE_DTR 0X0100
-
-/*
- * PBC UART Status Register bit definitions
- */
-#define PBC_USTAT_DTE_DCD 0X0001
-#define PBC_USTAT_DTE_DSR 0X0002
-#define PBC_USTAT_DTE_RI 0X0004
-#define PBC_USTAT_DCE_DTR 0X0100
-
-/*
- * PBC Interupt mask register bit definitions
- */
-#define PBC_INTR_SD3_R_EN_BIT 4
-#define PBC_INTR_SD2_R_EN_BIT 0
-#define PBC_INTR_SD1_R_EN_BIT 6
-#define PBC_INTR_MS_R_EN_BIT 5
-#define PBC_INTR_SD3_EN_BIT 13
-#define PBC_INTR_SD2_EN_BIT 12
-#define PBC_INTR_MS_EN_BIT 14
-#define PBC_INTR_SD1_EN_BIT 15
-
-#define PBC_INTR_SD2_R_EN 0x0001
-#define PBC_INTR_LOW_BAT 0X0002
-#define PBC_INTR_OTG_FSOVER 0X0004
-#define PBC_INTR_FSH_OVER 0X0008
-#define PBC_INTR_SD3_R_EN 0x0010
-#define PBC_INTR_MS_R_EN 0x0020
-#define PBC_INTR_SD1_R_EN 0x0040
-#define PBC_INTR_FEC_INT 0X0080
-#define PBC_INTR_ENET_INT 0X0100
-#define PBC_INTR_OTGFS_INT 0X0200
-#define PBC_INTR_XUART_INT 0X0400
-#define PBC_INTR_CCTL12 0X0800
-#define PBC_INTR_SD2_EN 0x1000
-#define PBC_INTR_SD3_EN 0x2000
-#define PBC_INTR_MS_EN 0x4000
-#define PBC_INTR_SD1_EN 0x8000
-
-
-
-/* For interrupts like xuart, enet etc */
-#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX27_PIN_TIN)
-#define MXC_MAX_EXP_IO_LINES 16
-
-/*
- * This corresponds to PBC_INTMASK_SET_REG at offset 0x38.
- *
- */
-#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 1)
-#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2)
-#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3)
-#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4)
-#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5)
-#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6)
-#define EXPIO_INT_FEC (MXC_EXP_IO_BASE + 7)
-#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
-#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9)
-#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
-#define EXPIO_INT_CCTL12_INT (MXC_EXP_IO_BASE + 11)
-#define EXPIO_INT_SD2_EN (MXC_EXP_IO_BASE + 12)
-#define EXPIO_INT_SD3_EN (MXC_EXP_IO_BASE + 13)
-#define EXPIO_INT_MS_EN (MXC_EXP_IO_BASE + 14)
-#define EXPIO_INT_SD1_EN (MXC_EXP_IO_BASE + 15)
-
-/*
- * This is System IRQ used by CS8900A for interrupt generation
- * taken from platform.h
- */
-#define CS8900AIRQ EXPIO_INT_ENET_INT
-/* This is I/O Base address used to access registers of CS8900A on MXC ADS */
-#define CS8900A_BASE_ADDRESS (PBC_CS8900A_IOBASE_REG + 0x300)
-
-#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX27_PIN_TOUT)
-
-/*
-* This is used to detect if the CPLD version is for mx27 evb board rev-a
-*/
-#define PBC_CPLD_VERSION_IS_REVA() \
- ((__raw_readw(PBC_VERSION_REG) & \
- (PBC_VERSION_ADS | PBC_VERSION_EVB_REVB))\
- == 0)
-
-/* This is used to active or inactive ata signal in CPLD .
- * It is dependent with hardware
- */
-#define PBC_ATA_SIGNAL_ACTIVE() \
- __raw_writew( \
- PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \
- PBC_BCTRL2_CLEAR_REG)
-
-#define PBC_ATA_SIGNAL_INACTIVE() \
- __raw_writew( \
- PBC_BCTRL2_ATAFEC_EN|PBC_BCTRL2_ATAFEC_SEL|PBC_BCTRL2_ATA_EN, \
- PBC_BCTRL2_SET_REG)
-
-#define MXC_BD_LED1 (1 << 5)
-#define MXC_BD_LED2 (1 << 6)
-#define MXC_BD_LED_ON(led) \
- __raw_writew(led, PBC_BCTRL1_SET_REG)
-#define MXC_BD_LED_OFF(led) \
- __raw_writew(led, PBC_BCTRL1_CLEAR_REG)
-
-/* to determine the correct external crystal reference */
-#define CKIH_27MHZ_BIT_SET (1 << 3)
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX27ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27lite.h b/arch/arm/plat-mxc/include/mach/board-mx27lite.h
deleted file mode 100644
index ea87551d2736..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx27lite.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX27LITE_H__
-#define __ASM_ARCH_MXC_BOARD_MX27LITE_H__
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX27LITE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h b/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
deleted file mode 100644
index fec1bcfa9164..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx27pdk.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX27PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX27PDK_H__
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX27PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h b/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
deleted file mode 100644
index da92933a233b..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx31_3ds.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
-#define __ASM_ARCH_MXC_BOARD_MX31_3DS_H__
-
-/* Definitions for components on the Debug board */
-
-/* Base address of CPLD controller on the Debug board */
-#define DEBUG_BASE_ADDRESS CS5_IO_ADDRESS(CS5_BASE_ADDR)
-
-/* LAN9217 ethernet base address */
-#define LAN9217_BASE_ADDR CS5_BASE_ADDR
-
-/* CPLD config and interrupt base address */
-#define CPLD_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
-
-/* LED switchs */
-#define CPLD_LED_REG (CPLD_ADDR + 0x00)
-/* buttons */
-#define CPLD_SWITCH_BUTTONS_REG (EXPIO_ADDR + 0x08)
-/* status, interrupt */
-#define CPLD_INT_STATUS_REG (CPLD_ADDR + 0x10)
-#define CPLD_INT_MASK_REG (CPLD_ADDR + 0x38)
-#define CPLD_INT_RESET_REG (CPLD_ADDR + 0x20)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER1_REG (CPLD_ADDR + 0x40)
-#define CPLD_MAGIC_NUMBER2_REG (CPLD_ADDR + 0x48)
-/* CPLD code version */
-#define CPLD_CODE_VER_REG (CPLD_ADDR + 0x50)
-/* magic word for debug CPLD */
-#define CPLD_MAGIC_NUMBER3_REG (CPLD_ADDR + 0x58)
-/* module reset register */
-#define CPLD_MODULE_RESET_REG (CPLD_ADDR + 0x60)
-/* CPU ID and Personality ID */
-#define CPLD_MCU_BOARD_ID_REG (CPLD_ADDR + 0x68)
-
-/* CPLD IRQ line for external uart, external ethernet etc */
-#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
-
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
-#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1)
-#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2)
-#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3)
-#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4)
-
-#define MXC_MAX_EXP_IO_LINES 16
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31_3DS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
deleted file mode 100644
index 095a199591c6..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-
-#include <mach/hardware.h>
-
-/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
-/* Offsets for the PBC Controller register */
-
-/* PBC Board status register offset */
-#define PBC_BSTAT 0x000002
-
-/* PBC Board control register 1 set address */
-#define PBC_BCTRL1_SET 0x000004
-
-/* PBC Board control register 1 clear address */
-#define PBC_BCTRL1_CLEAR 0x000006
-
-/* PBC Board control register 2 set address */
-#define PBC_BCTRL2_SET 0x000008
-
-/* PBC Board control register 2 clear address */
-#define PBC_BCTRL2_CLEAR 0x00000A
-
-/* PBC Board control register 3 set address */
-#define PBC_BCTRL3_SET 0x00000C
-
-/* PBC Board control register 3 clear address */
-#define PBC_BCTRL3_CLEAR 0x00000E
-
-/* PBC Board control register 4 set address */
-#define PBC_BCTRL4_SET 0x000010
-
-/* PBC Board control register 4 clear address */
-#define PBC_BCTRL4_CLEAR 0x000012
-
-/* PBC Board status register 1 */
-#define PBC_BSTAT1 0x000014
-
-/* PBC Board interrupt status register */
-#define PBC_INTSTATUS 0x000016
-
-/* PBC Board interrupt current status register */
-#define PBC_INTCURR_STATUS 0x000018
-
-/* PBC Interrupt mask register set address */
-#define PBC_INTMASK_SET 0x00001A
-
-/* PBC Interrupt mask register clear address */
-#define PBC_INTMASK_CLEAR 0x00001C
-
-/* External UART A */
-#define PBC_SC16C652_UARTA 0x010000
-
-/* External UART B */
-#define PBC_SC16C652_UARTB 0x010010
-
-/* Ethernet Controller IO base address */
-#define PBC_CS8900A_IOBASE 0x020000
-
-/* Ethernet Controller Memory base address */
-#define PBC_CS8900A_MEMBASE 0x021000
-
-/* Ethernet Controller DMA base address */
-#define PBC_CS8900A_DMABASE 0x022000
-
-/* External chip select 0 */
-#define PBC_XCS0 0x040000
-
-/* LCD Display enable */
-#define PBC_LCD_EN_B 0x060000
-
-/* Code test debug enable */
-#define PBC_CODE_B 0x070000
-
-/* PSRAM memory select */
-#define PBC_PSRAM_B 0x5000000
-
-#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS)
-#define PBC_INTCURR_STATUS_REG (PBC_INTCURR_STATUS + PBC_BASE_ADDRESS)
-#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS)
-#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
-#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
-
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 0)
-#define EXPIO_INT_PB_IRQ (MXC_EXP_IO_BASE + 1)
-#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2)
-#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3)
-#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4)
-#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5)
-#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6)
-#define EXPIO_INT_RES7 (MXC_EXP_IO_BASE + 7)
-#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
-#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9)
-#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
-#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11)
-#define EXPIO_INT_SYNTH_IRQ (MXC_EXP_IO_BASE + 12)
-#define EXPIO_INT_CE_INT1 (MXC_EXP_IO_BASE + 13)
-#define EXPIO_INT_CE_INT2 (MXC_EXP_IO_BASE + 14)
-#define EXPIO_INT_RES15 (MXC_EXP_IO_BASE + 15)
-
-#define MXC_MAX_EXP_IO_LINES 16
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
index eb5a5024622e..0df71bfefbb1 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lilly.h
@@ -31,7 +31,7 @@ enum mx31lilly_boards {
/*
* This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
+ * its own devices, it calls the baseboard's init function.
*/
extern void mx31lilly_db_init(void);
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31lite.h b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
index 2b2da0367578..c1ad0ae807cc 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31lite.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31lite.h
@@ -32,7 +32,7 @@ enum mx31lite_boards {
/*
* This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
+ * its own devices, it calls the baseboard's init function.
*/
extern void mx31lite_db_init(void);
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
index 36ff3cedee1a..de14543891cf 100644
--- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
+++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h
@@ -31,7 +31,7 @@ enum mx31moboard_boards {
/*
* This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
+ * its own devices, it calls the baseboard's init function.
*/
extern void mx31moboard_devboard_init(void);
diff --git a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h b/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
deleted file mode 100644
index 383f1c04df06..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx35pdk.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX35PDK_H__
-#define __ASM_ARCH_MXC_BOARD_MX35PDK_H__
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX35PDK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm037.h b/arch/arm/plat-mxc/include/mach/board-pcm037.h
deleted file mode 100644
index 13411709b13a..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-pcm037.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_PCM037_H__
-#define __ASM_ARCH_MXC_BOARD_PCM037_H__
-
-#endif /* __ASM_ARCH_MXC_BOARD_PCM037_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm038.h b/arch/arm/plat-mxc/include/mach/board-pcm038.h
index 410f9786ed22..6f371e35753d 100644
--- a/arch/arm/plat-mxc/include/mach/board-pcm038.h
+++ b/arch/arm/plat-mxc/include/mach/board-pcm038.h
@@ -22,7 +22,7 @@
#ifndef __ASSEMBLY__
/*
* This CPU module needs a baseboard to work. After basic initializing
- * its own devices, it calls baseboard's init function.
+ * its own devices, it calls the baseboard's init function.
* TODO: Add your own baseboard init function and call it from
* inside pcm038_init().
*
diff --git a/arch/arm/plat-mxc/include/mach/board-pcm043.h b/arch/arm/plat-mxc/include/mach/board-pcm043.h
deleted file mode 100644
index 1ac4e1682e5c..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-pcm043.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (C) 2008 Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_PCM043_H__
-#define __ASM_ARCH_MXC_BOARD_PCM043_H__
-
-#endif /* __ASM_ARCH_MXC_BOARD_PCM043_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h
deleted file mode 100644
index 6d88c7af4b23..000000000000
--- a/arch/arm/plat-mxc/include/mach/board-qong.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, <yanok@emcraft.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_ARCH_MXC_BOARD_QONG_H__
-#define __ASM_ARCH_MXC_BOARD_QONG_H__
-
-/* NOR FLASH */
-#define QONG_NOR_SIZE (128*1024*1024)
-
-#endif /* __ASM_ARCH_MXC_BOARD_QONG_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
new file mode 100644
index 000000000000..05c8d3f0a08f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.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/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *imx_add_platform_device(const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data);
+
+#include <mach/i2c.h>
+struct platform_device *__init imx_add_imx_i2c(int id,
+ resource_size_t iobase, resource_size_t iosize, int irq,
+ const struct imxi2c_platform_data *pdata);
+
+#include <mach/imx-uart.h>
+struct platform_device *__init imx_add_imx_uart_3irq(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irqrx, resource_size_t irqtx,
+ resource_size_t irqrts,
+ const struct imxuart_platform_data *pdata);
+struct platform_device *__init imx_add_imx_uart_1irq(int id,
+ resource_size_t iobase, resource_size_t iosize,
+ resource_size_t irq,
+ const struct imxuart_platform_data *pdata);
+
+#include <mach/mxc_nand.h>
+struct platform_device *__init imx_add_mxc_nand_v1(resource_size_t iobase,
+ int irq, const struct mxc_nand_platform_data *pdata);
+struct platform_device *__init imx_add_mxc_nand_v21(resource_size_t iobase,
+ int irq, const struct mxc_nand_platform_data *pdata);
+
+#include <mach/spi.h>
+struct platform_device *__init imx_add_spi_imx(int id,
+ resource_size_t iobase, resource_size_t iosize, int irq,
+ const struct spi_imx_master *pdata);
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx25.h b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
index f39220d1b67a..d7f52c91f82e 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx25.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx25.h
@@ -252,6 +252,7 @@
#define MX25_PAD_OE_ACD__GPIO_1_25 IOMUX_PAD(0x30c, 0x114, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CONTRAST__CONTRAST IOMUX_PAD(0x310, 0x118, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CONTRAST__PWM4_PWMO IOMUX_PAD(0x310, 0x118, 0x14, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_CONTRAST__FEC_CRS IOMUX_PAD(0x310, 0x118, 0x15, 0x508, 1, NO_PAD_CTRL)
#define MX25_PAD_PWM__PWM IOMUX_PAD(0x314, 0x11c, 0x10, 0, 0, NO_PAD_CTRL)
@@ -371,30 +372,41 @@
#define MX25_PAD_SD1_DATA3__FEC_CRS IOMUX_PAD(0x39c, 0x1a4, 0x10, 0x508, 2, NO_PAD_CTRL)
#define MX25_PAD_SD1_DATA3__GPIO_2_28 IOMUX_PAD(0x39c, 0x1a4, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, PAD_CTL_PKE)
+#define KPP_CTL_ROW (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define KPP_CTL_COL (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | PAD_CTL_ODE)
+
+#define MX25_PAD_KPP_ROW0__KPP_ROW0 IOMUX_PAD(0x3a0, 0x1a8, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW0__GPIO_2_29 IOMUX_PAD(0x3a0, 0x1a8, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW1__KPP_ROW1 IOMUX_PAD(0x3a4, 0x1ac, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW1__GPIO_2_30 IOMUX_PAD(0x3a4, 0x1ac, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW2__KPP_ROW2 IOMUX_PAD(0x3a8, 0x1b0, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW2__CSI_D0 IOMUX_PAD(0x3a8, 0x1b0, 0x13, 0x488, 2, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW2__GPIO_2_31 IOMUX_PAD(0x3a8, 0x1b0, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, PAD_CTL_PKE)
+#define MX25_PAD_KPP_ROW3__KPP_ROW3 IOMUX_PAD(0x3ac, 0x1b4, 0x10, 0, 0, KPP_CTL_ROW)
#define MX25_PAD_KPP_ROW3__CSI_LD1 IOMUX_PAD(0x3ac, 0x1b4, 0x13, 0x48c, 2, NO_PAD_CTRL)
#define MX25_PAD_KPP_ROW3__GPIO_3_0 IOMUX_PAD(0x3ac, 0x1b4, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL0__KPP_COL0 IOMUX_PAD(0x3b0, 0x1b8, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL0__UART4_RXD_MUX IOMUX_PAD(0x3b0, 0x1b8, 0x11, 0x570, 1, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL0__AUD5_TXD IOMUX_PAD(0x3b0, 0x1b8, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL0__GPIO_3_1 IOMUX_PAD(0x3b0, 0x1b8, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL1__KPP_COL1 IOMUX_PAD(0x3b4, 0x1bc, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL1__UART4_TXD_MUX IOMUX_PAD(0x3b4, 0x1bc, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL1__AUD5_RXD IOMUX_PAD(0x3b4, 0x1bc, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL1__GPIO_3_2 IOMUX_PAD(0x3b4, 0x1bc, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL2__KPP_COL2 IOMUX_PAD(0x3b8, 0x1c0, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL2__UART4_RTS IOMUX_PAD(0x3b8, 0x1c0, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL2__AUD5_TXC IOMUX_PAD(0x3b8, 0x1c0, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL2__GPIO_3_3 IOMUX_PAD(0x3b8, 0x1c0, 0x15, 0, 0, NO_PAD_CTRL)
-#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, PAD_CTL_PKE | PAD_CTL_ODE)
+#define MX25_PAD_KPP_COL3__KPP_COL3 IOMUX_PAD(0x3bc, 0x1c4, 0x10, 0, 0, KPP_CTL_COL)
+#define MX25_PAD_KPP_COL3__UART4_CTS IOMUX_PAD(0x3bc, 0x1c4, 0x11, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_KPP_COL3__AUD5_TXFS IOMUX_PAD(0x3bc, 0x1c4, 0x12, 0, 0, PAD_CTL_PKE | PAD_CTL_PUS_100K_UP)
#define MX25_PAD_KPP_COL3__GPIO_3_4 IOMUX_PAD(0x3bc, 0x1c4, 0x15, 0, 0, NO_PAD_CTRL)
#define MX25_PAD_FEC_MDC__FEC_MDC IOMUX_PAD(0x3c0, 0x1c8, 0x10, 0, 0, NO_PAD_CTRL)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index ab0f95d953d0..56ed0a6ac5e6 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -27,8 +27,8 @@ typedef enum iomux_config {
IOMUX_CONFIG_ALT5,
IOMUX_CONFIG_ALT6,
IOMUX_CONFIG_ALT7,
- IOMUX_CONFIG_GPIO, /* added to help user use GPIO mode */
- IOMUX_CONFIG_SION = 0x1 << 4, /* LOOPBACK:MUX SION bit */
+ IOMUX_CONFIG_GPIO, /* added to help user use GPIO mode */
+ IOMUX_CONFIG_SION = 0x1 << 4, /* LOOPBACK:MUX SION bit */
} iomux_pin_cfg_t;
/* Pad control groupings */
@@ -38,6 +38,8 @@ typedef enum iomux_config {
PAD_CTL_SRE_FAST)
#define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
PAD_CTL_SRE_FAST)
+#define MX51_I2C_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_ODE | \
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS)
#define MX51_USBH1_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
PAD_CTL_PKE | PAD_CTL_HYS)
@@ -46,289 +48,272 @@ typedef enum iomux_config {
/*
* The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
- * If <padname> or <padmode> refers to a GPIO, it is named
- * GPIO_<unit>_<num> see also iomux-v3.h
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux-v3.h
*/
-/*
- * FIXME: This was converted using scripts from existing Freescale code to
- * this form used upstream. Need to verify the name format.
- */
-
-/* PAD MUX ALT INPSE PATH PADCTRL */
-
-#define MX51_PAD_GPIO_2_0__EIM_D16 IOMUX_PAD(0x3f0, 0x05c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_1__EIM_D17 IOMUX_PAD(0x3f4, 0x060, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_2__EIM_D18 IOMUX_PAD(0x3f8, 0x064, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_3__EIM_D19 IOMUX_PAD(0x3fc, 0x068, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_4__EIM_D20 IOMUX_PAD(0x400, 0x06c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_5__EIM_D21 IOMUX_PAD(0x404, 0x070, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D21__GPIO_2_5 IOMUX_PAD(0x404, 0x070, IOMUX_CONFIG_ALT1, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_6__EIM_D22 IOMUX_PAD(0x408, 0x074, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_7__EIM_D23 IOMUX_PAD(0x40c, 0x078, 1, 0x0, 0, NO_PAD_CTRL)
-
-/* Babbage UART3 */
-#define MX51_PAD_EIM_D24__UART3_CTS IOMUX_PAD(0x410, 0x07c, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D25__UART3_RXD IOMUX_PAD(0x414, 0x080, IOMUX_CONFIG_ALT3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D26__UART3_TXD IOMUX_PAD(0x418, 0x084, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
-#define MX51_PAD_EIM_D27__UART3_RTS IOMUX_PAD(0x41c, 0x088, IOMUX_CONFIG_ALT3, 0x9f0, 0, MX51_UART3_PAD_CTRL)
-
-#define MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x08c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x090, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x094, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42c, 0x09c, 0, 0x0, 0, NO_PAD_CTRL)
-
-#define MX51_PAD_GPIO_2_10__EIM_A16 IOMUX_PAD(0x430, 0x09c, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_11__EIM_A17 IOMUX_PAD(0x434, 0x0a0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_12__EIM_A18 IOMUX_PAD(0x438, 0x0a4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_13__EIM_A19 IOMUX_PAD(0x43c, 0x0a8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_14__EIM_A20 IOMUX_PAD(0x440, 0x0ac, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_15__EIM_A21 IOMUX_PAD(0x444, 0x0b0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_16__EIM_A22 IOMUX_PAD(0x448, 0x0b4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_17__EIM_A23 IOMUX_PAD(0x44c, 0x0b8, 1, 0x0, 0, NO_PAD_CTRL)
-
-#define MX51_PAD_GPIO_2_18__EIM_A24 IOMUX_PAD(0x450, 0x0bc, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_19__EIM_A25 IOMUX_PAD(0x454, 0x0c0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_20__EIM_A26 IOMUX_PAD(0x458, 0x0c4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_21__EIM_A27 IOMUX_PAD(0x45c, 0x0c8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_22__EIM_EB2 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_23__EIM_EB3 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL)
-
-#define MX51_PAD_GPIO_2_24__EIM_OE IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_25__EIM_CS0 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_26__EIM_CS1 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_27__EIM_CS2 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_28__EIM_CS3 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_29__EIM_CS4 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_30__EIM_CS5 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_2_31__EIM_DTACK IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL)
-
-#define MX51_PAD_GPIO_3_1__EIM_LBA IOMUX_PAD(0x494, 0xFC, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_2__EIM_CRE IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_3__NANDF_WE_B IOMUX_PAD(0x4E4, 0x108, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_4__NANDF_RE_B IOMUX_PAD(0x4E8, 0x10C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_5__NANDF_ALE IOMUX_PAD(0x4EC, 0x110, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_6__NANDF_CLE IOMUX_PAD(0x4F0, 0x114, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_7__NANDF_WP_B IOMUX_PAD(0x4F4, 0x118, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_8__NANDF_RB0 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_9__NANDF_RB1 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_10__NANDF_RB2 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_11__NANDF_RB3 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_12__GPIO_NAND IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
-/* REVISIT: Not sure of these values
-
- #define MX51_PAD_GPIO_1___NANDF_RB4 IOMUX_PAD(, , , 0x0, 0, NO_PAD_CTRL)
- #define MX51_PAD_GPIO_3_13__NANDF_RB5 IOMUX_PAD(0x5D8, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
- #define MX51_PAD_GPIO_3_15__NANDF_RB7 IOMUX_PAD(0x5E0, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
-*/
-#define MX51_PAD_GPIO_3_14__NANDF_RB6 IOMUX_PAD(0x5DC, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_16__NANDF_CS0 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_17__NANDF_CS1 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_18__NANDF_CS2 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_19__NANDF_CS3 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_20__NANDF_CS4 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_21__NANDF_CS5 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_22__NANDF_CS6 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_23__NANDF_CS7 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_24__NANDF_RDY_INT IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_25__NANDF_D15 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_26__NANDF_D14 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_27__NANDF_D13 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_28__NANDF_D12 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_29__NANDF_D11 IOMUX_PAD(0x54C, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_30__NANDF_D10 IOMUX_PAD(0x550, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_31__NANDF_D9 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_0__NANDF_D8 IOMUX_PAD(0x558, 0x170, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_1__NANDF_D7 IOMUX_PAD(0x55C, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_2__NANDF_D6 IOMUX_PAD(0x560, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_3__NANDF_D5 IOMUX_PAD(0x564, 0x17C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_4__NANDF_D4 IOMUX_PAD(0x568, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_5__NANDF_D3 IOMUX_PAD(0x56C, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_6__NANDF_D2 IOMUX_PAD(0x570, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_7__NANDF_D1 IOMUX_PAD(0x574, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_8__NANDF_D0 IOMUX_PAD(0x578, 0x190, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_12__CSI1_D8 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_13__CSI1_D9 IOMUX_PAD(0x580, 0x198, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5B4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5B8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI1_PKE0__CSI1_PKE0 IOMUX_PAD(0x860, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_9__CSI2_D12 IOMUX_PAD(0x5BC, 0x1CC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_10__CSI2_D13 IOMUX_PAD(0x5C0, 0x1D0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_11__CSI2_D14 IOMUX_PAD(0x5C4, 0x1D4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_12__CSI2_D15 IOMUX_PAD(0x5C8, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_11__CSI2_D16 IOMUX_PAD(0x5CC, 0x1DC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_12__CSI2_D17 IOMUX_PAD(0x5D0, 0x1E0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_11__CSI2_D18 IOMUX_PAD(0x5D4, 0x1E4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_12__CSI2_D19 IOMUX_PAD(0x5D8, 0x1E8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_13__CSI2_VSYNC IOMUX_PAD(0x5DC, 0x1EC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_14__CSI2_HSYNC IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_15__CSI2_PIXCLK IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_CSI2_PKE0__CSI2_PKE0 IOMUX_PAD(0x81C, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_16__I2C1_CLK IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_17__I2C1_DAT IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_18__AUD3_BB_TXD IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_19__AUD3_BB_RXD IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_20__AUD3_BB_CK IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_21__AUD3_BB_FS IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_22__CSPI1_MOSI IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_23__CSPI1_MISO IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_24__CSPI1_SS0 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_25__CSPI1_SS1 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_26__CSPI1_RDY IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_4_27__CSPI1_SCLK IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
-
-/* Babbage UART1 */
-#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, IOMUX_CONFIG_ALT0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
-#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
-#define MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, IOMUX_CONFIG_ALT0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
-#define MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL)
-
-/* Babbage UART2 */
-#define MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, IOMUX_CONFIG_ALT0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
-#define MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62C, 0x23C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART2_PAD_CTRL)
-
-#define MX51_PAD_GPIO_1_22__UART3_RXD IOMUX_PAD(0x630, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_23__UART3_TXD IOMUX_PAD(0x634, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_24__OWIRE_LINE IOMUX_PAD(0x638, 0x248, 3, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_STP__GPIO_1_27 IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_GPIO, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
-#define MX51_PAD_GPIO_3_0__DI1_PIN11 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_1__DI1_PIN12 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_2__DI1_PIN13 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_3__DI1_D0_CS IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_4__DI1_D1_CS IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_5__DISPB2_SER_DIN IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_6__DISPB2_SER_DIO IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_7__DISPB2_SER_CLK IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_3_8__DISPB2_SER_RS IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP1__DI_GP1 IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP2__DI_GP2 IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP3__DI_GP3 IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DI_GP4__DI_GP4 IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_19__DISP2_DAT6 IOMUX_PAD(0x774, 0x36C, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_29__DISP2_DAT7 IOMUX_PAD(0x778, 0x370, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_30__DISP2_DAT8 IOMUX_PAD(0x77C, 0x374, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_31__DISP2_DAT9 IOMUX_PAD(0x780, 0x378, 5, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_0__GPIO1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_1__GPIO1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_2__GPIO1_2 IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_3__GPIO1_3 IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_6__GPIO1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, \
- (PAD_CTL_SRE_SLOW | PAD_CTL_DSE_MED | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS))
-#define MX51_PAD_GPIO_1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
-
-/* EIM */
-#define MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x7a8, 0x01c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x7a8, 0x020, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x7a8, 0x024, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x7a8, 0x028, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x7ac, 0x02c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x7ac, 0x030, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x7ac, 0x034, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x7ac, 0x038, 0, 0x0, 0, NO_PAD_CTRL)
-
-#define MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x7b0, 0x03c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x7b0, 0x040, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x7b0, 0x044, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x7b0, 0x048, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x7bc, 0x04c, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x7bc, 0x050, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x7bc, 0x054, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x7bc, 0x058, 0, 0x0, 0, NO_PAD_CTRL)
+/* PAD MUX ALT INPSE PATH PADCTRL */
+#define MX51_PAD_EIM_DA0__EIM_DA0 IOMUX_PAD(0x7a8, 0x01c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA1__EIM_DA1 IOMUX_PAD(0x7a8, 0x020, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA2__EIM_DA2 IOMUX_PAD(0x7a8, 0x024, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA3__EIM_DA3 IOMUX_PAD(0x7a8, 0x028, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA4__EIM_DA4 IOMUX_PAD(0x7ac, 0x02c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA5__EIM_DA5 IOMUX_PAD(0x7ac, 0x030, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA6__EIM_DA6 IOMUX_PAD(0x7ac, 0x034, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA7__EIM_DA7 IOMUX_PAD(0x7ac, 0x038, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA8__EIM_DA8 IOMUX_PAD(0x7b0, 0x03c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA9__EIM_DA9 IOMUX_PAD(0x7b0, 0x040, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA10__EIM_DA10 IOMUX_PAD(0x7b0, 0x044, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA11__EIM_DA11 IOMUX_PAD(0x7b0, 0x048, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA12__EIM_DA12 IOMUX_PAD(0x7bc, 0x04c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA13__EIM_DA13 IOMUX_PAD(0x7bc, 0x050, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA14__EIM_DA14 IOMUX_PAD(0x7bc, 0x054, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA15__EIM_DA15 IOMUX_PAD(0x7bc, 0x058, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D16__GPIO_2_0 IOMUX_PAD(0x3f0, 0x05c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D16__I2C1_SDA IOMUX_PAD(0x3f0, 0x05c, (4 | IOMUX_CONFIG_SION), \
+ 0x09b4, 0, MX51_I2C_PAD_CTRL)
+#define MX51_PAD_EIM_D17__GPIO_2_1 IOMUX_PAD(0x3f4, 0x060, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D18__GPIO_2_2 IOMUX_PAD(0x3f8, 0x064, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D19__GPIO_2_3 IOMUX_PAD(0x3fc, 0x068, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D19__I2C1_SCL IOMUX_PAD(0x3fc, 0x068, (4 | IOMUX_CONFIG_SION), \
+ 0x09b0, 0, MX51_I2C_PAD_CTRL)
+#define MX51_PAD_EIM_D20__GPIO_2_4 IOMUX_PAD(0x400, 0x06c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D21__GPIO_2_5 IOMUX_PAD(0x404, 0x070, 1, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_EIM_D22__GPIO_2_6 IOMUX_PAD(0x408, 0x074, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D23__GPIO_2_7 IOMUX_PAD(0x40c, 0x078, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D24__UART3_CTS IOMUX_PAD(0x410, 0x07c, 3, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D25__UART3_RXD IOMUX_PAD(0x414, 0x080, 3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D25__UART2_CTS IOMUX_PAD(0x414, 0x080, 4, 0x0, 0, MX51_UART2_PAD_CTRL)
+#define MX51_PAD_EIM_D26__UART3_TXD IOMUX_PAD(0x418, 0x084, 3, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D26__UART2_RTS IOMUX_PAD(0x418, 0x084, 4, 0x9e8, 3, MX51_UART2_PAD_CTRL)
+#define MX51_PAD_EIM_D27__UART3_RTS IOMUX_PAD(0x41c, 0x088, 3, 0x9f0, 3, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_EIM_D28__EIM_D28 IOMUX_PAD(0x420, 0x08c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D29__EIM_D29 IOMUX_PAD(0x424, 0x090, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D30__EIM_D30 IOMUX_PAD(0x428, 0x094, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D31__EIM_D31 IOMUX_PAD(0x42c, 0x09c, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A16__GPIO_2_10 IOMUX_PAD(0x430, 0x09c, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A17__GPIO_2_11 IOMUX_PAD(0x434, 0x0a0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A18__GPIO_2_12 IOMUX_PAD(0x438, 0x0a4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A19__GPIO_2_13 IOMUX_PAD(0x43c, 0x0a8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A20__GPIO_2_14 IOMUX_PAD(0x440, 0x0ac, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A21__GPIO_2_15 IOMUX_PAD(0x444, 0x0b0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A22__GPIO_2_16 IOMUX_PAD(0x448, 0x0b4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A23__GPIO_2_17 IOMUX_PAD(0x44c, 0x0b8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A24__GPIO_2_18 IOMUX_PAD(0x450, 0x0bc, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A25__GPIO_2_19 IOMUX_PAD(0x454, 0x0c0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A26__GPIO_2_20 IOMUX_PAD(0x458, 0x0c4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_A27__GPIO_2_21 IOMUX_PAD(0x45c, 0x0c8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB0__EIM_EB0 IOMUX_PAD(0x460, 0x0cc, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB1__EIM_EB1 IOMUX_PAD(0x464, 0x0d0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB2__GPIO_2_22 IOMUX_PAD(0x468, 0x0d4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB3__GPIO_2_23 IOMUX_PAD(0x46c, 0x0d8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_OE__GPIO_2_24 IOMUX_PAD(0x470, 0x0dc, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS0__GPIO_2_25 IOMUX_PAD(0x474, 0x0e0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS1__GPIO_2_26 IOMUX_PAD(0x478, 0x0e4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS2__GPIO_2_27 IOMUX_PAD(0x47c, 0x0e8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS3__GPIO_2_28 IOMUX_PAD(0x480, 0x0ec, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS4__GPIO_2_29 IOMUX_PAD(0x484, 0x0f0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CS5__GPIO_2_30 IOMUX_PAD(0x488, 0x0f4, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DTACK__GPIO_2_31 IOMUX_PAD(0x48c, 0x0f8, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_LBA__GPIO_3_1 IOMUX_PAD(0x494, 0x0FC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_CRE__GPIO_3_2 IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DRAM_CS1__DRAM_CS1 IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_WE_B__GPIO_3_3 IOMUX_PAD(0x4E4, 0x108, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RE_B__GPIO_3_4 IOMUX_PAD(0x4E8, 0x10C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_ALE__GPIO_3_5 IOMUX_PAD(0x4EC, 0x110, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CLE__GPIO_3_6 IOMUX_PAD(0x4F0, 0x114, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_WP_B__GPIO_3_7 IOMUX_PAD(0x4F4, 0x118, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB0__GPIO_3_8 IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB1__GPIO_3_9 IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB2__GPIO_3_10 IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RB3__GPIO_3_11 IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_NAND__GPIO_3_12 IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS0__GPIO_3_16 IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS1__GPIO_3_17 IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS2__GPIO_3_18 IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS3__GPIO_3_19 IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS4__GPIO_3_20 IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS5__GPIO_3_21 IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS6__GPIO_3_22 IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_CS7__GPIO_3_23 IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_RDY_INT__GPIO_3_24 IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D15__GPIO_3_25 IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D14__GPIO_3_26 IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D13__GPIO_3_27 IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D12__GPIO_3_28 IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D11__GPIO_3_29 IOMUX_PAD(0x54C, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D10__GPIO_3_30 IOMUX_PAD(0x550, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D9__GPIO_3_31 IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D8__GPIO_4_0 IOMUX_PAD(0x558, 0x170, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D7__GPIO_4_1 IOMUX_PAD(0x55C, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D6__GPIO_4_2 IOMUX_PAD(0x560, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D5__GPIO_4_3 IOMUX_PAD(0x564, 0x17C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D4__GPIO_4_4 IOMUX_PAD(0x568, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D3__GPIO_4_5 IOMUX_PAD(0x56C, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D2__GPIO_4_6 IOMUX_PAD(0x570, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D1__GPIO_4_7 IOMUX_PAD(0x574, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_NANDF_D0__GPIO_4_8 IOMUX_PAD(0x578, 0x190, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D8__GPIO_3_12 IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D9__GPIO_3_13 IOMUX_PAD(0x580, 0x198, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D10__CSI1_D10 IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D11__CSI1_D11 IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D12__CSI1_D12 IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D13__CSI1_D13 IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D14__CSI1_D14 IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D15__CSI1_D15 IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D16__CSI1_D16 IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D17__CSI1_D17 IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D18__CSI1_D18 IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D19__CSI1_D19 IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK IOMUX_PAD(0x5B4, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK IOMUX_PAD(0x5B8, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PKE0__CSI1_PKE0 IOMUX_PAD(0x860, 0x000, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D12__GPIO_4_9 IOMUX_PAD(0x5BC, 0x1CC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D13__GPIO_4_10 IOMUX_PAD(0x5C0, 0x1D0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D14__GPIO_4_11 IOMUX_PAD(0x5C4, 0x1D4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D15__GPIO_4_12 IOMUX_PAD(0x5C8, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D16__GPIO_4_11 IOMUX_PAD(0x5CC, 0x1DC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D17__GPIO_4_12 IOMUX_PAD(0x5D0, 0x1E0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D18__GPIO_4_11 IOMUX_PAD(0x5D4, 0x1E4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_D19__GPIO_4_12 IOMUX_PAD(0x5D8, 0x1E8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_VSYNC__GPIO_4_13 IOMUX_PAD(0x5DC, 0x1EC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_HSYNC__GPIO_4_14 IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_PIXCLK__GPIO_4_15 IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_CLK__GPIO_4_16 IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_CLK__HSI2C_CLK IOMUX_PAD(0x5E8, 0x1F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_DAT__GPIO_4_17 IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_I2C1_DAT__HSI2C_DAT IOMUX_PAD(0x5EC, 0x1FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_TXD__GPIO_4_18 IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_RXD__GPIO_4_19 IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_CK__GPIO_4_20 IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_AUD3_BB_FS__GPIO_4_21 IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MOSI__GPIO_4_22 IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_MISO__GPIO_4_23 IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS0__GPIO_4_24 IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SS1__GPIO_4_25 IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_RDY__GPIO_4_26 IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSPI1_SCLK__GPIO_4_27 IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART1_RXD__UART1_RXD IOMUX_PAD(0x618, 0x228, 0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_PAD_UART1_TXD__UART1_TXD IOMUX_PAD(0x61C, 0x22C, 0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_PAD_UART1_RTS__UART1_RTS IOMUX_PAD(0x620, 0x230, 0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
+#define MX51_PAD_UART1_CTS__UART1_CTS IOMUX_PAD(0x624, 0x234, 0, 0x0, 0, MX51_UART1_PAD_CTRL)
+#define MX51_PAD_UART2_RXD__UART2_RXD IOMUX_PAD(0x628, 0x238, 0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
+#define MX51_PAD_UART2_TXD__UART2_TXD IOMUX_PAD(0x62C, 0x23C, 0, 0x0, 0, MX51_UART2_PAD_CTRL)
+#define MX51_PAD_UART3_RXD__UART3_RXD IOMUX_PAD(0x630, 0x240, 1, 0x9f4, 4, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_UART3_RXD__GPIO_1_22 IOMUX_PAD(0x630, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_UART3_TXD__UART3_TXD IOMUX_PAD(0x634, 0x244, 1, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_PAD_UART3_TXD__GPIO_1_23 IOMUX_PAD(0x634, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_OWIRE_LINE__GPIO_1_24 IOMUX_PAD(0x638, 0x248, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW0__KEY_ROW0 IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW1__KEY_ROW1 IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW2__KEY_ROW2 IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW3__KEY_ROW3 IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL0__KEY_COL0 IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL1__KEY_COL1 IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL2__KEY_COL2 IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL4__I2C2_SCL IOMUX_PAD(0x65C, 0x26C, (3 | IOMUX_CONFIG_SION), \
+ 0x09b8, 1, MX51_I2C_PAD_CTRL)
+#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL5__I2C2_SDA IOMUX_PAD(0x660, 0x270, (3 | IOMUX_CONFIG_SION), \
+ 0x09bc, 1, MX51_I2C_PAD_CTRL)
+#define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__GPIO_1_27 IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_DI1_PIN11__GPIO_3_0 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN12__GPIO_3_1 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN13__GPIO_3_2 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D0_CS__GPIO_3_3 IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_D1_CS__GPIO_3_4 IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIN__GPIO_3_5 IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_DIO__GPIO_3_6 IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_CLK__GPIO_3_7 IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISPB2_SER_RS__GPIO_3_8 IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN3__DI1_PIN3 IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN2__DI1_PIN2 IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP1__DI_GP1 IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP2__DI_GP2 IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP3__DI_GP3 IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN4__DI2_PIN4 IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN2__DI2_PIN2 IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN3__DI2_PIN3 IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP4__DI_GP4 IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT6__GPIO_1_19 IOMUX_PAD(0x774, 0x36C, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT7__GPIO_1_29 IOMUX_PAD(0x778, 0x370, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT8__GPIO_1_30 IOMUX_PAD(0x77C, 0x374, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT9__GPIO_1_31 IOMUX_PAD(0x780, 0x378, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_0__GPIO_1_0 IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_1__GPIO_1_1 IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_2__GPIO_1_2 IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_3__GPIO_1_3 IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_4__GPIO_1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_5__GPIO_1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_6__GPIO_1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_7__GPIO_1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_8__GPIO_1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, MX51_GPIO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_9__GPIO_1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
index 3887f3fe29d4..15d59510f597 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
@@ -12,10 +12,6 @@
* 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 __MACH_IOMUX_MXC91231_H__
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index f2f73d31d5ba..0880a4a1aed1 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -89,6 +89,21 @@ struct pad_desc {
#define PAD_CTL_SRE_FAST (1 << 0)
#define PAD_CTL_SRE_SLOW (0 << 0)
+
+#define MX51_NUM_GPIO_PORT 4
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA (0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB (1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC (2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD (3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE (4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF (5 << GPIO_PORT_SHIFT)
+
/*
* setups a single pad in the iomuxer
*/
diff --git a/arch/arm/plat-mxc/include/mach/mmc.h b/arch/arm/plat-mxc/include/mach/mmc.h
index de2128dada5c..29115f405af9 100644
--- a/arch/arm/plat-mxc/include/mach/mmc.h
+++ b/arch/arm/plat-mxc/include/mach/mmc.h
@@ -31,6 +31,9 @@ struct imxmmc_platform_data {
/* adjust slot voltage */
void (*setpower)(struct device *, unsigned int vdd);
+
+ /* enable card detect using DAT3 */
+ int dat3_card_detect;
};
#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx1.h b/arch/arm/plat-mxc/include/mach/mx1.h
index 5eba7e6785de..641b24618239 100644
--- a/arch/arm/plat-mxc/include/mach/mx1.h
+++ b/arch/arm/plat-mxc/include/mach/mx1.h
@@ -91,24 +91,24 @@
#define MX1_SIM_DATA_INT 16
#define MX1_RTC_INT 17
#define MX1_RTC_SAMINT 18
-#define MX1_UART2_MINT_PFERR 19
-#define MX1_UART2_MINT_RTS 20
-#define MX1_UART2_MINT_DTR 21
-#define MX1_UART2_MINT_UARTC 22
-#define MX1_UART2_MINT_TX 23
-#define MX1_UART2_MINT_RX 24
-#define MX1_UART1_MINT_PFERR 25
-#define MX1_UART1_MINT_RTS 26
-#define MX1_UART1_MINT_DTR 27
-#define MX1_UART1_MINT_UARTC 28
-#define MX1_UART1_MINT_TX 29
-#define MX1_UART1_MINT_RX 30
+#define MX1_INT_UART2PFERR 19
+#define MX1_INT_UART2RTS 20
+#define MX1_INT_UART2DTR 21
+#define MX1_INT_UART2UARTC 22
+#define MX1_INT_UART2TX 23
+#define MX1_INT_UART2RX 24
+#define MX1_INT_UART1PFERR 25
+#define MX1_INT_UART1RTS 26
+#define MX1_INT_UART1DTR 27
+#define MX1_INT_UART1UARTC 28
+#define MX1_INT_UART1TX 29
+#define MX1_INT_UART1RX 30
#define MX1_VOICE_DAC_INT 31
#define MX1_VOICE_ADC_INT 32
#define MX1_PEN_DATA_INT 33
#define MX1_PWM_INT 34
#define MX1_SDHC_INT 35
-#define MX1_I2C_INT 39
+#define MX1_INT_I2C 39
#define MX1_CSPI_INT 41
#define MX1_SSI_TX_INT 42
#define MX1_SSI_TX_ERR_INT 43
@@ -245,7 +245,7 @@
#define PEN_DATA_INT MX1_PEN_DATA_INT
#define PWM_INT MX1_PWM_INT
#define SDHC_INT MX1_SDHC_INT
-#define I2C_INT MX1_I2C_INT
+#define I2C_INT MX1_INT_I2C
#define CSPI_INT MX1_CSPI_INT
#define SSI_TX_INT MX1_SSI_TX_INT
#define SSI_TX_ERR_INT MX1_SSI_TX_ERR_INT
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
index 4eb6e334bda5..2f2aad1032c1 100644
--- a/arch/arm/plat-mxc/include/mach/mx25.h
+++ b/arch/arm/plat-mxc/include/mach/mx25.h
@@ -11,6 +11,10 @@
#define MX25_AVIC_BASE_ADDR_VIRT 0xfc400000
#define MX25_AVIC_SIZE SZ_1M
+#define MX25_I2C1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x80000)
+#define MX25_I2C3_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x84000)
+#define MX25_I2C2_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0x98000)
+#define MX25_CSPI1_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xa4000)
#define MX25_IOMUXC_BASE_ADDR (MX25_AIPS1_BASE_ADDR + 0xac000)
#define MX25_CRM_BASE_ADDR (MX25_AIPS2_BASE_ADDR + 0x80000)
@@ -29,16 +33,42 @@
#define MX25_UART1_BASE_ADDR 0x43f90000
#define MX25_UART2_BASE_ADDR 0x43f94000
+#define MX25_AUDMUX_BASE_ADDR 0x43fb0000
+#define MX25_UART3_BASE_ADDR 0x5000c000
+#define MX25_UART4_BASE_ADDR 0x50008000
+#define MX25_UART5_BASE_ADDR 0x5002c000
+#define MX25_CSPI3_BASE_ADDR 0x50004000
+#define MX25_CSPI2_BASE_ADDR 0x50010000
#define MX25_FEC_BASE_ADDR 0x50038000
+#define MX25_SSI2_BASE_ADDR 0x50014000
+#define MX25_SSI1_BASE_ADDR 0x50034000
#define MX25_NFC_BASE_ADDR 0xbb000000
#define MX25_DRYICE_BASE_ADDR 0x53ffc000
#define MX25_LCDC_BASE_ADDR 0x53fbc000
+#define MX25_KPP_BASE_ADDR 0x43fa8000
+#define MX25_OTG_BASE_ADDR 0x53ff4000
+#define MX25_CSI_BASE_ADDR 0x53ff8000
-#define MX25_INT_DRYICE 25
-#define MX25_INT_FEC 57
-#define MX25_INT_NANDFC 33
-#define MX25_INT_LCDC 39
+#define MX25_INT_CSPI3 0
+#define MX25_INT_I2C1 3
+#define MX25_INT_I2C2 4
+#define MX25_INT_UART4 5
+#define MX25_INT_I2C3 10
+#define MX25_INT_SSI2 11
+#define MX25_INT_SSI1 12
+#define MX25_INT_CSPI2 13
+#define MX25_INT_CSPI1 14
+#define MX25_INT_CSI 17
+#define MX25_INT_UART3 18
+#define MX25_INT_KPP 24
+#define MX25_INT_DRYICE 25
+#define MX25_INT_UART2 32
+#define MX25_INT_NANDFC 33
+#define MX25_INT_LCDC 39
+#define MX25_INT_UART5 40
+#define MX25_INT_UART1 45
+#define MX25_INT_FEC 57
#if defined(IMX_NEEDS_DEPRECATED_SYMBOLS)
#define UART1_BASE_ADDR MX25_UART1_BASE_ADDR
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index bae9cd75beee..a8ab2e02a8ca 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -48,7 +48,7 @@
#define MX27_CSPI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x0f000)
#define MX27_SSI1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x10000)
#define MX27_SSI2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x11000)
-#define MX27_I2C_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x12000)
+#define MX27_I2C1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x12000)
#define MX27_SDHC1_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x13000)
#define MX27_SDHC2_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x14000)
#define MX27_GPIO_BASE_ADDR (MX27_AIPI_BASE_ADDR + 0x15000)
@@ -150,7 +150,7 @@ static inline void mx27_setup_weimcs(size_t cs,
#define MX27_INT_SDHC3 9
#define MX27_INT_SDHC2 10
#define MX27_INT_SDHC1 11
-#define MX27_INT_I2C 12
+#define MX27_INT_I2C1 12
#define MX27_INT_SSI2 13
#define MX27_INT_SSI1 14
#define MX27_INT_CSPI2 15
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index fb90e119c2b5..afee3ab9d62e 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -23,7 +23,7 @@
#define MX31_ETB_SLOT4_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x10000)
#define MX31_ETB_SLOT5_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x14000)
#define MX31_ECT_CTIO_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x18000)
-#define MX31_I2C_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x80000)
+#define MX31_I2C1_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x80000)
#define MX31_I2C3_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x84000)
#define MX31_OTG_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x88000)
#define MX31_ATA_BASE_ADDR (MX31_AIPS1_BASE_ADDR + 0x8c000)
@@ -145,7 +145,7 @@ static inline void mx31_setup_weimcs(size_t cs,
#define MX31_INT_FIRI 7
#define MX31_INT_MMC_SDHC2 8
#define MX31_INT_MMC_SDHC1 9
-#define MX31_INT_I2C 10
+#define MX31_INT_I2C1 10
#define MX31_INT_SSI2 11
#define MX31_INT_SSI1 12
#define MX31_INT_CSPI2 13
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
index 526a55842ae5..cda60c715127 100644
--- a/arch/arm/plat-mxc/include/mach/mx35.h
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -18,7 +18,7 @@
#define MX35_ETB_SLOT4_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x10000)
#define MX35_ETB_SLOT5_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x14000)
#define MX35_ECT_CTIO_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x18000)
-#define MX35_I2C_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x80000)
+#define MX35_I2C1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x80000)
#define MX35_I2C3_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x84000)
#define MX35_UART1_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x90000)
#define MX35_UART2_BASE_ADDR (MX35_AIPS1_BASE_ADDR + 0x94000)
@@ -123,7 +123,7 @@
#define MX35_INT_MMC_SDHC1 7
#define MX35_INT_MMC_SDHC2 8
#define MX35_INT_MMC_SDHC3 9
-#define MX35_INT_I2C 10
+#define MX35_INT_I2C1 10
#define MX35_INT_SSI1 11
#define MX35_INT_SSI2 12
#define MX35_INT_CSPI2 13
diff --git a/arch/arm/plat-mxc/include/mach/mx3_camera.h b/arch/arm/plat-mxc/include/mach/mx3_camera.h
index 36d7ff27b5e2..f226ee3777e1 100644
--- a/arch/arm/plat-mxc/include/mach/mx3_camera.h
+++ b/arch/arm/plat-mxc/include/mach/mx3_camera.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _MX3_CAMERA_H_
diff --git a/arch/arm/plat-mxc/include/mach/mxc91231.h b/arch/arm/plat-mxc/include/mach/mxc91231.h
index 5182b986b785..0ca3101ebf36 100644
--- a/arch/arm/plat-mxc/include/mach/mxc91231.h
+++ b/arch/arm/plat-mxc/include/mach/mxc91231.h
@@ -13,10 +13,6 @@
* 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 __MACH_MXC91231_H__
#define __MACH_MXC91231_H__
diff --git a/arch/arm/plat-mxc/include/mach/mxc_nand.h b/arch/arm/plat-mxc/include/mach/mxc_nand.h
index 5d2d21d414e0..04c0d060d814 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_nand.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_nand.h
@@ -20,9 +20,13 @@
#ifndef __ASM_ARCH_NAND_H
#define __ASM_ARCH_NAND_H
+#include <linux/mtd/partitions.h>
+
struct mxc_nand_platform_data {
- int width; /* data bus width in bytes */
- int hw_ecc:1; /* 0 if supress hardware ECC */
- int flash_bbt:1; /* set to 1 to use a flash based bbt */
+ unsigned int width; /* data bus width in bytes */
+ unsigned int hw_ecc:1; /* 0 if supress hardware ECC */
+ unsigned int flash_bbt:1; /* set to 1 to use a flash based bbt */
+ struct mtd_partition *parts; /* partition table */
+ int nr_parts; /* size of parts */
};
#endif /* __ASM_ARCH_NAND_H */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index ef00199568de..4acd1143a9bd 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -12,10 +12,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_MXC_SYSTEM_H__
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
index 024416ed11cd..2d9624697cc9 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -11,10 +11,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_MXC_TIMEX_H__
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index b6d3d0fddc48..d9bd37e4667a 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -13,10 +13,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_MXC_UNCOMPRESS_H__
#define __ASM_ARCH_MXC_UNCOMPRESS_H__
diff --git a/arch/arm/plat-mxc/include/mach/vmalloc.h b/arch/arm/plat-mxc/include/mach/vmalloc.h
index 44243a278434..ef6379c474be 100644
--- a/arch/arm/plat-mxc/include/mach/vmalloc.h
+++ b/arch/arm/plat-mxc/include/mach/vmalloc.h
@@ -11,10 +11,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __ASM_ARCH_MXC_VMALLOC_H__
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 778ddfe57d89..7331f2ace5fe 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -142,9 +142,6 @@ void __init mxc_init_irq(void __iomem *irqbase)
for (i = 0; i < 8; i++)
__raw_writel(0, avic_base + AVIC_NIPRIORITY(i));
- /* init architectures chained interrupt handler */
- mxc_register_gpios();
-
#ifdef CONFIG_FIQ
/* Initialize FIQ */
init_FIQ();
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 97f42799fa58..925bce4607e7 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -14,10 +14,6 @@
* 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>
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 9b86d2a60d43..b3da9aad4295 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -145,8 +145,6 @@ void __init tzic_init_irq(void __iomem *irqbase)
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
- mxc_register_gpios();
-
pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
}
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 5a6ef252c38b..977c8f9a07a2 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -23,6 +23,7 @@
#include <linux/irq.h>
#include <linux/slab.h>
+#include <plat/pincfg.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
@@ -46,28 +47,217 @@ struct nmk_gpio_chip {
u32 edge_falling;
};
+static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, int gpio_mode)
+{
+ u32 bit = 1 << offset;
+ u32 afunc, bfunc;
+
+ afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+ bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+ if (gpio_mode & NMK_GPIO_ALT_A)
+ afunc |= bit;
+ if (gpio_mode & NMK_GPIO_ALT_B)
+ bfunc |= bit;
+ writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+ writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+}
+
+static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, enum nmk_gpio_slpm mode)
+{
+ u32 bit = 1 << offset;
+ u32 slpm;
+
+ slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+ if (mode == NMK_GPIO_SLPM_NOCHANGE)
+ slpm |= bit;
+ else
+ slpm &= ~bit;
+ writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset, enum nmk_gpio_pull pull)
+{
+ u32 bit = 1 << offset;
+ u32 pdis;
+
+ pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
+ if (pull == NMK_GPIO_PULL_NONE)
+ pdis |= bit;
+ else
+ pdis &= ~bit;
+ writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
+
+ if (pull == NMK_GPIO_PULL_UP)
+ writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+ else if (pull == NMK_GPIO_PULL_DOWN)
+ writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
+ unsigned offset)
+{
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+}
+
+static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
+ pin_cfg_t cfg)
+{
+ static const char *afnames[] = {
+ [NMK_GPIO_ALT_GPIO] = "GPIO",
+ [NMK_GPIO_ALT_A] = "A",
+ [NMK_GPIO_ALT_B] = "B",
+ [NMK_GPIO_ALT_C] = "C"
+ };
+ static const char *pullnames[] = {
+ [NMK_GPIO_PULL_NONE] = "none",
+ [NMK_GPIO_PULL_UP] = "up",
+ [NMK_GPIO_PULL_DOWN] = "down",
+ [3] /* illegal */ = "??"
+ };
+ static const char *slpmnames[] = {
+ [NMK_GPIO_SLPM_INPUT] = "input",
+ [NMK_GPIO_SLPM_NOCHANGE] = "no-change",
+ };
+
+ int pin = PIN_NUM(cfg);
+ int pull = PIN_PULL(cfg);
+ int af = PIN_ALT(cfg);
+ int slpm = PIN_SLPM(cfg);
+
+ dev_dbg(nmk_chip->chip.dev, "pin %d: af %s, pull %s, slpm %s\n",
+ pin, afnames[af], pullnames[pull], slpmnames[slpm]);
+
+ __nmk_gpio_make_input(nmk_chip, offset);
+ __nmk_gpio_set_pull(nmk_chip, offset, pull);
+ __nmk_gpio_set_slpm(nmk_chip, offset, slpm);
+ __nmk_gpio_set_mode(nmk_chip, offset, af);
+}
+
+/**
+ * nmk_config_pin - configure a pin's mux attributes
+ * @cfg: pin confguration
+ *
+ * Configures a pin's mode (alternate function or GPIO), its pull up status,
+ * and its sleep mode based on the specified configuration. The @cfg is
+ * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These
+ * are constructed using, and can be further enhanced with, the macros in
+ * plat/pincfg.h.
+ *
+ * If a pin's mode is set to GPIO, it is configured as an input to avoid
+ * side-effects. The gpio can be manipulated later using standard GPIO API
+ * calls.
+ */
+int nmk_config_pin(pin_cfg_t cfg)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ int gpio = PIN_NUM(cfg);
+ unsigned long flags;
+
+ nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ if (!nmk_chip)
+ return -EINVAL;
+
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+ __nmk_config_pin(nmk_chip, gpio - nmk_chip->chip.base, cfg);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(nmk_config_pin);
+
+/**
+ * nmk_config_pins - configure several pins at once
+ * @cfgs: array of pin configurations
+ * @num: number of elments in the array
+ *
+ * Configures several pins using nmk_config_pin(). Refer to that function for
+ * further information.
+ */
+int nmk_config_pins(pin_cfg_t *cfgs, int num)
+{
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ int ret = nmk_config_pin(cfgs[i]);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(nmk_config_pins);
+
+/**
+ * nmk_gpio_set_slpm() - configure the sleep mode of a pin
+ * @gpio: pin number
+ * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
+ *
+ * Sets the sleep mode of a pin. If @mode is NMK_GPIO_SLPM_INPUT, the pin is
+ * changed to an input (with pullup/down enabled) in sleep and deep sleep. If
+ * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
+ * configured even when in sleep and deep sleep.
+ */
+int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+
+ nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ if (!nmk_chip)
+ return -EINVAL;
+
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+ __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+ return 0;
+}
+
+/**
+ * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
+ * @gpio: pin number
+ * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
+ *
+ * Enables/disables pull up/down on a specified pin. This only takes effect if
+ * the pin is configured as an input (either explicitly or by the alternate
+ * function).
+ *
+ * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
+ * configured as an input. Otherwise, due to the way the controller registers
+ * work, this function will change the value output on the pin.
+ */
+int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
+{
+ struct nmk_gpio_chip *nmk_chip;
+ unsigned long flags;
+
+ nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ if (!nmk_chip)
+ return -EINVAL;
+
+ spin_lock_irqsave(&nmk_chip->lock, flags);
+ __nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
+ spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+ return 0;
+}
+
/* Mode functions */
int nmk_gpio_set_mode(int gpio, int gpio_mode)
{
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- u32 afunc, bfunc, bit;
nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
if (!nmk_chip)
return -EINVAL;
- bit = 1 << (gpio - nmk_chip->chip.base);
-
spin_lock_irqsave(&nmk_chip->lock, flags);
- afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
- bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
- if (gpio_mode & NMK_GPIO_ALT_A)
- afunc |= bit;
- if (gpio_mode & NMK_GPIO_ALT_B)
- bfunc |= bit;
- writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
- writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+ __nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
return 0;
@@ -111,32 +301,41 @@ static void nmk_gpio_irq_ack(unsigned int irq)
writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
}
+enum nmk_gpio_irq_type {
+ NORMAL,
+ WAKE,
+};
+
static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
- int gpio, bool enable)
+ int gpio, enum nmk_gpio_irq_type which,
+ bool enable)
{
+ u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
+ u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
u32 bitmask = nmk_gpio_get_bitmask(gpio);
u32 reg;
/* we must individually set/clear the two edges */
if (nmk_chip->edge_rising & bitmask) {
- reg = readl(nmk_chip->addr + NMK_GPIO_RIMSC);
+ reg = readl(nmk_chip->addr + rimsc);
if (enable)
reg |= bitmask;
else
reg &= ~bitmask;
- writel(reg, nmk_chip->addr + NMK_GPIO_RIMSC);
+ writel(reg, nmk_chip->addr + rimsc);
}
if (nmk_chip->edge_falling & bitmask) {
- reg = readl(nmk_chip->addr + NMK_GPIO_FIMSC);
+ reg = readl(nmk_chip->addr + fimsc);
if (enable)
reg |= bitmask;
else
reg &= ~bitmask;
- writel(reg, nmk_chip->addr + NMK_GPIO_FIMSC);
+ writel(reg, nmk_chip->addr + fimsc);
}
}
-static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
+static int nmk_gpio_irq_modify(unsigned int irq, enum nmk_gpio_irq_type which,
+ bool enable)
{
int gpio;
struct nmk_gpio_chip *nmk_chip;
@@ -147,26 +346,35 @@ static void nmk_gpio_irq_modify(unsigned int irq, bool enable)
nmk_chip = get_irq_chip_data(irq);
bitmask = nmk_gpio_get_bitmask(gpio);
if (!nmk_chip)
- return;
+ return -EINVAL;
spin_lock_irqsave(&nmk_chip->lock, flags);
- __nmk_gpio_irq_modify(nmk_chip, gpio, enable);
+ __nmk_gpio_irq_modify(nmk_chip, gpio, which, enable);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+ return 0;
}
static void nmk_gpio_irq_mask(unsigned int irq)
{
- nmk_gpio_irq_modify(irq, false);
-};
+ nmk_gpio_irq_modify(irq, NORMAL, false);
+}
static void nmk_gpio_irq_unmask(unsigned int irq)
{
- nmk_gpio_irq_modify(irq, true);
+ nmk_gpio_irq_modify(irq, NORMAL, true);
+}
+
+static int nmk_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+{
+ return nmk_gpio_irq_modify(irq, WAKE, on);
}
static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
{
- bool enabled = !(irq_to_desc(irq)->status & IRQ_DISABLED);
+ struct irq_desc *desc = irq_to_desc(irq);
+ bool enabled = !(desc->status & IRQ_DISABLED);
+ bool wake = desc->wake_depth;
int gpio;
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
@@ -186,7 +394,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
spin_lock_irqsave(&nmk_chip->lock, flags);
if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, gpio, false);
+ __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
+
+ if (wake)
+ __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
nmk_chip->edge_rising &= ~bitmask;
if (type & IRQ_TYPE_EDGE_RISING)
@@ -197,7 +408,10 @@ static int nmk_gpio_irq_set_type(unsigned int irq, unsigned int type)
nmk_chip->edge_falling |= bitmask;
if (enabled)
- __nmk_gpio_irq_modify(nmk_chip, gpio, true);
+ __nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
+
+ if (wake)
+ __nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
spin_unlock_irqrestore(&nmk_chip->lock, flags);
@@ -210,6 +424,7 @@ static struct irq_chip nmk_gpio_irq_chip = {
.mask = nmk_gpio_irq_mask,
.unmask = nmk_gpio_irq_unmask,
.set_type = nmk_gpio_irq_set_type,
+ .set_wake = nmk_gpio_irq_set_wake,
};
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
@@ -266,16 +481,6 @@ static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
return 0;
}
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
- int val)
-{
- struct nmk_gpio_chip *nmk_chip =
- container_of(chip, struct nmk_gpio_chip, chip);
-
- writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
- return 0;
-}
-
static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
{
struct nmk_gpio_chip *nmk_chip =
@@ -298,12 +503,33 @@ static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
}
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+ nmk_gpio_set_output(chip, offset, val);
+
+ return 0;
+}
+
+static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ struct nmk_gpio_chip *nmk_chip =
+ container_of(chip, struct nmk_gpio_chip, chip);
+
+ return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
+}
+
/* This structure is replicated for each GPIO block allocated at probe time */
static struct gpio_chip nmk_gpio_template = {
.direction_input = nmk_gpio_make_input,
.get = nmk_gpio_get_input,
.direction_output = nmk_gpio_make_output,
.set = nmk_gpio_set_output,
+ .to_irq = nmk_gpio_to_irq,
.ngpio = NMK_GPIO_PER_CHIP,
.can_sleep = 0,
};
@@ -393,30 +619,12 @@ out:
return ret;
}
-static int __exit nmk_gpio_remove(struct platform_device *dev)
-{
- struct nmk_gpio_chip *nmk_chip;
- struct resource *res;
-
- res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-
- nmk_chip = platform_get_drvdata(dev);
- gpiochip_remove(&nmk_chip->chip);
- clk_disable(nmk_chip->clk);
- clk_put(nmk_chip->clk);
- kfree(nmk_chip);
- release_mem_region(res->start, resource_size(res));
- return 0;
-}
-
-
static struct platform_driver nmk_gpio_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "gpio",
},
.probe = nmk_gpio_probe,
- .remove = __exit_p(nmk_gpio_remove),
.suspend = NULL, /* to be done */
.resume = NULL,
};
@@ -426,7 +634,7 @@ static int __init nmk_gpio_init(void)
return platform_driver_register(&nmk_gpio_driver);
}
-arch_initcall(nmk_gpio_init);
+core_initcall(nmk_gpio_init);
MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
MODULE_DESCRIPTION("Nomadik GPIO Driver");
diff --git a/arch/arm/plat-nomadik/include/plat/gpio.h b/arch/arm/plat-nomadik/include/plat/gpio.h
index 4200811249ca..aba355101f49 100644
--- a/arch/arm/plat-nomadik/include/plat/gpio.h
+++ b/arch/arm/plat-nomadik/include/plat/gpio.h
@@ -55,6 +55,21 @@
#define NMK_GPIO_ALT_B 2
#define NMK_GPIO_ALT_C (NMK_GPIO_ALT_A | NMK_GPIO_ALT_B)
+/* Pull up/down values */
+enum nmk_gpio_pull {
+ NMK_GPIO_PULL_NONE,
+ NMK_GPIO_PULL_UP,
+ NMK_GPIO_PULL_DOWN,
+};
+
+/* Sleep mode */
+enum nmk_gpio_slpm {
+ NMK_GPIO_SLPM_INPUT,
+ NMK_GPIO_SLPM_NOCHANGE,
+};
+
+extern int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode);
+extern int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull);
extern int nmk_gpio_set_mode(int gpio, int gpio_mode);
extern int nmk_gpio_get_mode(int gpio);
diff --git a/arch/arm/plat-nomadik/include/plat/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h
index 42c907258b14..65704a3d4241 100644
--- a/arch/arm/plat-nomadik/include/plat/mtu.h
+++ b/arch/arm/plat-nomadik/include/plat/mtu.h
@@ -1,6 +1,12 @@
#ifndef __PLAT_MTU_H
#define __PLAT_MTU_H
+/*
+ * Guaranteed runtime conversion range in seconds for
+ * the clocksource and clockevent.
+ */
+#define MTU_MIN_RANGE 4
+
/* should be set by the platform code */
extern void __iomem *mtu_base;
diff --git a/arch/arm/plat-nomadik/include/plat/pincfg.h b/arch/arm/plat-nomadik/include/plat/pincfg.h
new file mode 100644
index 000000000000..7eed11c1038d
--- /dev/null
+++ b/arch/arm/plat-nomadik/include/plat/pincfg.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ *
+ * Based on arch/arm/mach-pxa/include/mach/mfp.h:
+ * Copyright (C) 2007 Marvell International Ltd.
+ * eric miao <eric.miao@marvell.com>
+ */
+
+#ifndef __PLAT_PINCFG_H
+#define __PLAT_PINCFG_H
+
+/*
+ * pin configurations are represented by 32-bit integers:
+ *
+ * bit 0.. 8 - Pin Number (512 Pins Maximum)
+ * bit 9..10 - Alternate Function Selection
+ * bit 11..12 - Pull up/down state
+ * bit 13 - Sleep mode behaviour
+ *
+ * to facilitate the definition, the following macros are provided
+ *
+ * PIN_CFG_DEFAULT - default config (0):
+ * pull up/down = disabled
+ * sleep mode = input
+ *
+ * PIN_CFG - default config with alternate function
+ * PIN_CFG_PULL - default config with alternate function and pull up/down
+ */
+
+typedef unsigned long pin_cfg_t;
+
+#define PIN_NUM_MASK 0x1ff
+#define PIN_NUM(x) ((x) & PIN_NUM_MASK)
+
+#define PIN_ALT_SHIFT 9
+#define PIN_ALT_MASK (0x3 << PIN_ALT_SHIFT)
+#define PIN_ALT(x) (((x) & PIN_ALT_MASK) >> PIN_ALT_SHIFT)
+#define PIN_GPIO (NMK_GPIO_ALT_GPIO << PIN_ALT_SHIFT)
+#define PIN_ALT_A (NMK_GPIO_ALT_A << PIN_ALT_SHIFT)
+#define PIN_ALT_B (NMK_GPIO_ALT_B << PIN_ALT_SHIFT)
+#define PIN_ALT_C (NMK_GPIO_ALT_C << PIN_ALT_SHIFT)
+
+#define PIN_PULL_SHIFT 11
+#define PIN_PULL_MASK (0x3 << PIN_PULL_SHIFT)
+#define PIN_PULL(x) (((x) & PIN_PULL_MASK) >> PIN_PULL_SHIFT)
+#define PIN_PULL_NONE (NMK_GPIO_PULL_NONE << PIN_PULL_SHIFT)
+#define PIN_PULL_UP (NMK_GPIO_PULL_UP << PIN_PULL_SHIFT)
+#define PIN_PULL_DOWN (NMK_GPIO_PULL_DOWN << PIN_PULL_SHIFT)
+
+#define PIN_SLPM_SHIFT 13
+#define PIN_SLPM_MASK (0x1 << PIN_SLPM_SHIFT)
+#define PIN_SLPM(x) (((x) & PIN_SLPM_MASK) >> PIN_SLPM_SHIFT)
+#define PIN_SLPM_INPUT (NMK_GPIO_SLPM_INPUT << PIN_SLPM_SHIFT)
+#define PIN_SLPM_NOCHANGE (NMK_GPIO_SLPM_NOCHANGE << PIN_SLPM_SHIFT)
+
+#define PIN_CFG_DEFAULT (PIN_PULL_NONE | PIN_SLPM_INPUT)
+
+#define PIN_CFG(num, alt) \
+ (PIN_CFG_DEFAULT |\
+ (PIN_NUM(num) | PIN_##alt))
+
+#define PIN_CFG_PULL(num, alt, pull) \
+ ((PIN_CFG_DEFAULT & ~PIN_PULL_MASK) |\
+ (PIN_NUM(num) | PIN_##alt | PIN_PULL_##pull))
+
+extern int nmk_config_pin(pin_cfg_t cfg);
+extern int nmk_config_pins(pin_cfg_t *cfgs, int num);
+
+#endif
diff --git a/arch/arm/plat-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c
index 08aaa4a7f65f..ea3ca86c5283 100644
--- a/arch/arm/plat-nomadik/timer.c
+++ b/arch/arm/plat-nomadik/timer.c
@@ -42,7 +42,6 @@ static struct clocksource nmdk_clksrc = {
.rating = 200,
.read = nmdk_read_timer_dummy,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 20,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -82,6 +81,12 @@ static void nmdk_clkevt_mode(enum clock_event_mode mode,
case CLOCK_EVT_MODE_UNUSED:
/* disable irq */
writel(0, mtu_base + MTU_IMSC);
+ /* disable timer */
+ cr = readl(mtu_base + MTU_CR(1));
+ cr &= ~MTU_CRn_ENA;
+ writel(cr, mtu_base + MTU_CR(1));
+ /* load some high default value */
+ writel(0xffffffff, mtu_base + MTU_LR(1));
break;
case CLOCK_EVT_MODE_RESUME:
break;
@@ -98,7 +103,6 @@ static int nmdk_clkevt_next(unsigned long evt, struct clock_event_device *ev)
static struct clock_event_device nmdk_clkevt = {
.name = "mtu_1",
.features = CLOCK_EVT_FEAT_ONESHOT,
- .shift = 32,
.rating = 200,
.set_mode = nmdk_clkevt_mode,
.set_next_event = nmdk_clkevt_next,
@@ -151,6 +155,7 @@ void __init nmdk_timer_init(void)
} else {
cr |= MTU_CRn_PRESCALE_1;
}
+ clocksource_calc_mult_shift(&nmdk_clksrc, rate, MTU_MIN_RANGE);
/* Timer 0 is the free running clocksource */
writel(cr, mtu_base + MTU_CR(0));
@@ -158,7 +163,6 @@ void __init nmdk_timer_init(void)
writel(0, mtu_base + MTU_BGLR(0));
writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
- nmdk_clksrc.mult = clocksource_hz2mult(rate, nmdk_clksrc.shift);
/* Now the scheduling clock is ready */
nmdk_clksrc.read = nmdk_read_timer;
@@ -175,8 +179,10 @@ void __init nmdk_timer_init(void)
} else {
cr |= MTU_CRn_PRESCALE_1;
}
+ clockevents_calc_mult_shift(&nmdk_clkevt, rate, MTU_MIN_RANGE);
+
writel(cr | MTU_CRn_ONESHOT, mtu_base + MTU_CR(1)); /* off, currently */
- nmdk_clkevt.mult = div_sc(rate, NSEC_PER_SEC, nmdk_clkevt.shift);
+
nmdk_clkevt.max_delta_ns =
clockevent_delta2ns(0xffffffff, &nmdk_clkevt);
nmdk_clkevt.min_delta_ns =
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 78b49a626d06..e2ed952df23d 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -1,6 +1,6 @@
if ARCH_OMAP
-menu "TI OMAP Implementations"
+menu "TI OMAP Common Features"
config ARCH_OMAP_OTG
bool
@@ -21,24 +21,6 @@ config ARCH_OMAP2PLUS
help
"Systems based on omap24xx, omap34xx or omap44xx"
-config ARCH_OMAP2
- bool "TI OMAP2"
- depends on ARCH_OMAP2PLUS
- select CPU_V6
-
-config ARCH_OMAP3
- bool "TI OMAP3"
- depends on ARCH_OMAP2PLUS
- select CPU_V7
- select USB_ARCH_HAS_EHCI
- select ARM_L1_CACHE_SHIFT_6
-
-config ARCH_OMAP4
- bool "TI OMAP4"
- depends on ARCH_OMAP2PLUS
- select CPU_V7
- select ARM_GIC
-
endchoice
comment "OMAP Feature Selections"
@@ -51,7 +33,7 @@ config OMAP_DEBUG_DEVICES
config OMAP_DEBUG_LEDS
bool
depends on OMAP_DEBUG_DEVICES
- default y if LEDS || LEDS_OMAP_DEBUG
+ default y if LEDS
config OMAP_RESET_CLOCKS
bool "Reset unused clocks during boot"
@@ -120,7 +102,7 @@ config OMAP_IOMMU_DEBUG
choice
prompt "System timer"
- default OMAP_MPU_TIMER
+ default OMAP_32K_TIMER if !ARCH_OMAP15XX
config OMAP_MPU_TIMER
bool "Use mpu timer"
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 98f01910c2cf..9405831b746a 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
# omap_device support (OMAP2+ only at the moment)
obj-$(CONFIG_ARCH_OMAP2) += omap_device.o
obj-$(CONFIG_ARCH_OMAP3) += omap_device.o
+obj-$(CONFIG_ARCH_OMAP4) += omap_device.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 219c01e82bc5..893a53a740d0 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -22,6 +22,7 @@
#include <linux/serial_reg.h>
#include <linux/clk.h>
#include <linux/io.h>
+#include <linux/omapfb.h>
#include <mach/hardware.h>
#include <asm/system.h>
@@ -35,6 +36,7 @@
#include <plat/mux.h>
#include <plat/fpga.h>
#include <plat/serial.h>
+#include <plat/vram.h>
#include <plat/clock.h>
@@ -81,6 +83,12 @@ const void *omap_get_var_config(u16 tag, size_t *len)
}
EXPORT_SYMBOL(omap_get_var_config);
+void __init omap_reserve(void)
+{
+ omapfb_reserve_sdram_lmb();
+ omap_vram_reserve_sdram_lmb();
+}
+
/*
* 32KHz clocksource ... always available, on pretty most chips except
* OMAP 730 and 1510. Other timers could be used as clocksources, with
@@ -309,18 +317,18 @@ static struct omap_globals omap3_globals = {
.uart1_phys = OMAP3_UART1_BASE,
.uart2_phys = OMAP3_UART2_BASE,
.uart3_phys = OMAP3_UART3_BASE,
+ .uart4_phys = OMAP3_UART4_BASE, /* Only on 3630 */
};
-void __init omap2_set_globals_343x(void)
+void __init omap2_set_globals_3xxx(void)
{
__omap2_set_globals(&omap3_globals);
}
-void __init omap2_set_globals_36xx(void)
+void __init omap3_map_io(void)
{
- omap3_globals.uart4_phys = OMAP3_UART4_BASE;
-
- __omap2_set_globals(&omap3_globals);
+ omap2_set_globals_3xxx();
+ omap34xx_map_common_io();
}
#endif
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c
index 53fcef7c5201..fc05b1022602 100644
--- a/arch/arm/plat-omap/debug-leds.c
+++ b/arch/arm/plat-omap/debug-leds.c
@@ -39,7 +39,7 @@ static struct h2p2_dbg_fpga __iomem *fpga;
static u16 led_state, hw_led_state;
-#ifdef CONFIG_LEDS_OMAP_DEBUG
+#ifdef CONFIG_OMAP_DEBUG_LEDS
#define new_led_api() 1
#else
#define new_led_api() 0
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c
index 95677d17cd1c..d1920be7833b 100644
--- a/arch/arm/plat-omap/devices.c
+++ b/arch/arm/plat-omap/devices.c
@@ -24,135 +24,13 @@
#include <plat/control.h>
#include <plat/board.h>
#include <plat/mmc.h>
-#include <plat/mux.h>
#include <mach/gpio.h>
#include <plat/menelaus.h>
#include <plat/mcbsp.h>
-#include <plat/dsp_common.h>
#include <plat/omap44xx.h>
-#if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE)
-
-static struct dsp_platform_data dsp_pdata = {
- .kdev_list = LIST_HEAD_INIT(dsp_pdata.kdev_list),
-};
-
-static struct resource omap_dsp_resources[] = {
- {
- .name = "dsp_mmu",
- .start = -1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device omap_dsp_device = {
- .name = "dsp",
- .id = -1,
- .num_resources = ARRAY_SIZE(omap_dsp_resources),
- .resource = omap_dsp_resources,
- .dev = {
- .platform_data = &dsp_pdata,
- },
-};
-
-static inline void omap_init_dsp(void)
-{
- struct resource *res;
- int irq;
-
- if (cpu_is_omap15xx())
- irq = INT_1510_DSP_MMU;
- else if (cpu_is_omap16xx())
- irq = INT_1610_DSP_MMU;
- else if (cpu_is_omap24xx())
- irq = INT_24XX_DSP_MMU;
-
- res = platform_get_resource_byname(&omap_dsp_device,
- IORESOURCE_IRQ, "dsp_mmu");
- res->start = irq;
-
- platform_device_register(&omap_dsp_device);
-}
-
-int dsp_kfunc_device_register(struct dsp_kfunc_device *kdev)
-{
- static DEFINE_MUTEX(dsp_pdata_lock);
-
- spin_lock_init(&kdev->lock);
-
- mutex_lock(&dsp_pdata_lock);
- list_add_tail(&kdev->entry, &dsp_pdata.kdev_list);
- mutex_unlock(&dsp_pdata_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(dsp_kfunc_device_register);
-
-#else
-static inline void omap_init_dsp(void) { }
-#endif /* CONFIG_OMAP_DSP */
-
/*-------------------------------------------------------------------------*/
-#if defined(CONFIG_KEYBOARD_OMAP) || defined(CONFIG_KEYBOARD_OMAP_MODULE)
-
-static void omap_init_kp(void)
-{
- /* 2430 and 34xx keypad is on TWL4030 */
- if (cpu_is_omap2430() || cpu_is_omap34xx())
- return;
- if (machine_is_omap_h2() || machine_is_omap_h3()) {
- omap_cfg_reg(F18_1610_KBC0);
- omap_cfg_reg(D20_1610_KBC1);
- omap_cfg_reg(D19_1610_KBC2);
- omap_cfg_reg(E18_1610_KBC3);
- omap_cfg_reg(C21_1610_KBC4);
-
- omap_cfg_reg(G18_1610_KBR0);
- omap_cfg_reg(F19_1610_KBR1);
- omap_cfg_reg(H14_1610_KBR2);
- omap_cfg_reg(E20_1610_KBR3);
- omap_cfg_reg(E19_1610_KBR4);
- omap_cfg_reg(N19_1610_KBR5);
- } else if (machine_is_omap_perseus2() || machine_is_omap_fsample()) {
- omap_cfg_reg(E2_7XX_KBR0);
- omap_cfg_reg(J7_7XX_KBR1);
- omap_cfg_reg(E1_7XX_KBR2);
- omap_cfg_reg(F3_7XX_KBR3);
- omap_cfg_reg(D2_7XX_KBR4);
-
- omap_cfg_reg(C2_7XX_KBC0);
- omap_cfg_reg(D3_7XX_KBC1);
- omap_cfg_reg(E4_7XX_KBC2);
- omap_cfg_reg(F4_7XX_KBC3);
- omap_cfg_reg(E3_7XX_KBC4);
- } else if (machine_is_omap_h4()) {
- omap_cfg_reg(T19_24XX_KBR0);
- omap_cfg_reg(R19_24XX_KBR1);
- omap_cfg_reg(V18_24XX_KBR2);
- omap_cfg_reg(M21_24XX_KBR3);
- omap_cfg_reg(E5__24XX_KBR4);
- if (omap_has_menelaus()) {
- omap_cfg_reg(B3__24XX_KBR5);
- omap_cfg_reg(AA4_24XX_KBC2);
- omap_cfg_reg(B13_24XX_KBC6);
- } else {
- omap_cfg_reg(M18_24XX_KBR5);
- omap_cfg_reg(H19_24XX_KBC2);
- omap_cfg_reg(N19_24XX_KBC6);
- }
- omap_cfg_reg(R20_24XX_KBC0);
- omap_cfg_reg(M14_24XX_KBC1);
- omap_cfg_reg(V17_24XX_KBC3);
- omap_cfg_reg(P21_24XX_KBC4);
- omap_cfg_reg(L14_24XX_KBC5);
- }
-}
-#else
-static inline void omap_init_kp(void) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
#if defined(CONFIG_OMAP_MCBSP) || defined(CONFIG_OMAP_MCBSP_MODULE)
static struct platform_device **omap_mcbsp_devices;
@@ -419,8 +297,6 @@ static int __init omap_init_devices(void)
/* please keep these calls, and their implementations above,
* in alphabetical order so they're easier to sort through.
*/
- omap_init_dsp();
- omap_init_kp();
omap_init_rng();
omap_init_mcpdm();
omap_init_uwire();
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index f7f571e7987e..ec7eddf9e525 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -290,7 +290,7 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
val = dma_read(CCR(lch));
/* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
- val &= ~((3 << 19) | 0x1f);
+ val &= ~((1 << 23) | (3 << 19) | 0x1f);
val |= (dma_trigger & ~0x1f) << 14;
val |= dma_trigger & 0x1f;
@@ -304,11 +304,14 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
else
val &= ~(1 << 18);
- if (src_or_dst_synch)
+ if (src_or_dst_synch == OMAP_DMA_DST_SYNC_PREFETCH) {
+ val &= ~(1 << 24); /* dest synch */
+ val |= (1 << 23); /* Prefetch */
+ } else if (src_or_dst_synch) {
val |= 1 << 24; /* source synch */
- else
+ } else {
val &= ~(1 << 24); /* dest synch */
-
+ }
dma_write(val, CCR(lch));
}
diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
index d3eea4f47533..66bc292a8137 100644
--- a/arch/arm/plat-omap/fb.c
+++ b/arch/arm/plat-omap/fb.c
@@ -26,7 +26,7 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
#include <linux/io.h>
#include <linux/omapfb.h>
@@ -171,49 +171,78 @@ static int check_fbmem_region(int region_idx, struct omapfb_mem_region *rg,
return 0;
}
+static int valid_sdram(unsigned long addr, unsigned long size)
+{
+ struct lmb_property res;
+
+ res.base = addr;
+ res.size = size;
+ return !lmb_find(&res) && res.base == addr && res.size == size;
+}
+
+static int reserve_sdram(unsigned long addr, unsigned long size)
+{
+ if (lmb_is_region_reserved(addr, size))
+ return -EBUSY;
+ if (lmb_reserve(addr, size))
+ return -ENOMEM;
+ return 0;
+}
+
/*
* Called from map_io. We need to call to this early enough so that we
* can reserve the fixed SDRAM regions before VM could get hold of them.
*/
-void __init omapfb_reserve_sdram(void)
+void __init omapfb_reserve_sdram_lmb(void)
{
- struct bootmem_data *bdata;
- unsigned long sdram_start, sdram_size;
- unsigned long reserved;
- int i;
+ unsigned long reserved = 0;
+ int i;
if (config_invalid)
return;
- bdata = NODE_DATA(0)->bdata;
- sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
- sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
- reserved = 0;
for (i = 0; ; i++) {
- struct omapfb_mem_region rg;
+ struct omapfb_mem_region rg;
if (get_fbmem_region(i, &rg) < 0)
break;
+
if (i == OMAPFB_PLANE_NUM) {
- printk(KERN_ERR
- "Extraneous FB mem configuration entries\n");
+ pr_err("Extraneous FB mem configuration entries\n");
config_invalid = 1;
return;
}
+
/* Check if it's our memory type. */
- if (set_fbmem_region_type(&rg, OMAPFB_MEMTYPE_SDRAM,
- sdram_start, sdram_size) < 0 ||
- (rg.type != OMAPFB_MEMTYPE_SDRAM))
+ if (rg.type != OMAPFB_MEMTYPE_SDRAM)
continue;
- BUG_ON(omapfb_config.mem_desc.region[i].size);
- if (check_fbmem_region(i, &rg, sdram_start, sdram_size) < 0) {
+
+ /* Check if the region falls within SDRAM */
+ if (rg.paddr && !valid_sdram(rg.paddr, rg.size))
+ continue;
+
+ if (rg.size == 0) {
+ pr_err("Zero size for FB region %d\n", i);
config_invalid = 1;
return;
}
+
if (rg.paddr) {
- reserve_bootmem(rg.paddr, rg.size, BOOTMEM_DEFAULT);
+ if (reserve_sdram(rg.paddr, rg.size)) {
+ pr_err("Trying to use reserved memory for FB region %d\n",
+ i);
+ config_invalid = 1;
+ return;
+ }
reserved += rg.size;
}
+
+ if (omapfb_config.mem_desc.region[i].size) {
+ pr_err("FB region %d already set\n", i);
+ config_invalid = 1;
+ return;
+ }
+
omapfb_config.mem_desc.region[i] = rg;
configured_regions++;
}
@@ -359,7 +388,10 @@ static inline int omap_init_fb(void)
arch_initcall(omap_init_fb);
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
@@ -375,7 +407,10 @@ void omapfb_set_platform_data(struct omapfb_platform_data *data)
{
}
-void omapfb_reserve_sdram(void) {}
+void omapfb_reserve_sdram_lmb(void)
+{
+}
+
unsigned long omapfb_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 9b7e3545f325..7951eefe1a0e 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -390,7 +390,9 @@ static inline int gpio_valid(int gpio)
return 0;
if (cpu_is_omap7xx() && gpio < 192)
return 0;
- if (cpu_is_omap24xx() && gpio < 128)
+ if (cpu_is_omap2420() && gpio < 128)
+ return 0;
+ if (cpu_is_omap2430() && gpio < 160)
return 0;
if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
return 0;
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c
index eec2b4993c69..a5ce4f0aad35 100644
--- a/arch/arm/plat-omap/i2c.c
+++ b/arch/arm/plat-omap/i2c.c
@@ -138,6 +138,16 @@ static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id)
return platform_device_register(pdev);
}
+/*
+ * XXX This function is a temporary compatibility wrapper - only
+ * needed until the I2C driver can be converted to call
+ * omap_pm_set_max_dev_wakeup_lat() and handle a return code.
+ */
+static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t)
+{
+ omap_pm_set_max_mpu_wakeup_lat(dev, t);
+}
+
static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
{
struct resource *res;
@@ -168,7 +178,7 @@ static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id)
struct omap_i2c_bus_platform_data *pd;
pd = pdev->dev.platform_data;
- pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat;
+ pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat;
}
return platform_device_register(pdev);
diff --git a/arch/arm/plat-omap/include/plat/board.h b/arch/arm/plat-omap/include/plat/board.h
index 5cd622039da0..3cf4fa25ab3d 100644
--- a/arch/arm/plat-omap/include/plat/board.h
+++ b/arch/arm/plat-omap/include/plat/board.h
@@ -85,6 +85,14 @@ struct omap_usb_config {
* 6 == 6 wire unidirectional (or TLL)
*/
u8 pins[3];
+
+ struct platform_device *udc_device;
+ struct platform_device *ohci_device;
+ struct platform_device *otg_device;
+
+ u32 (*usb0_init)(unsigned nwires, unsigned is_device);
+ u32 (*usb1_init)(unsigned nwires);
+ u32 (*usb2_init)(unsigned nwires, unsigned alt_pingroup);
};
struct omap_lcd_config {
diff --git a/arch/arm/plat-omap/include/plat/clock.h b/arch/arm/plat-omap/include/plat/clock.h
index dfc472ca0cc4..fef4696dcf67 100644
--- a/arch/arm/plat-omap/include/plat/clock.h
+++ b/arch/arm/plat-omap/include/plat/clock.h
@@ -19,6 +19,22 @@ struct module;
struct clk;
struct clockdomain;
+/**
+ * struct clkops - some clock function pointers
+ * @enable: fn ptr that enables the current clock in hardware
+ * @disable: fn ptr that enables the current clock in hardware
+ * @find_idlest: function returning the IDLEST register for the clock's IP blk
+ * @find_companion: function returning the "companion" clk reg for the clock
+ *
+ * A "companion" clk is an accompanying clock to the one being queried
+ * that must be enabled for the IP module connected to the clock to
+ * become accessible by the hardware. Neither @find_idlest nor
+ * @find_companion should be needed; that information is IP
+ * block-specific; the hwmod code has been created to handle this, but
+ * until hwmod data is ready and drivers have been converted to use PM
+ * runtime calls in place of clk_enable()/clk_disable(), @find_idlest and
+ * @find_companion must, unfortunately, remain.
+ */
struct clkops {
int (*enable)(struct clk *);
void (*disable)(struct clk *);
@@ -30,12 +46,45 @@ struct clkops {
#ifdef CONFIG_ARCH_OMAP2PLUS
+/* struct clksel_rate.flags possibilities */
+#define RATE_IN_242X (1 << 0)
+#define RATE_IN_243X (1 << 1)
+#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
+#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
+#define RATE_IN_36XX (1 << 4)
+#define RATE_IN_4430 (1 << 5)
+
+#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
+#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
+
+/**
+ * struct clksel_rate - register bitfield values corresponding to clk divisors
+ * @val: register bitfield value (shifted to bit 0)
+ * @div: clock divisor corresponding to @val
+ * @flags: (see "struct clksel_rate.flags possibilities" above)
+ *
+ * @val should match the value of a read from struct clk.clksel_reg
+ * AND'ed with struct clk.clksel_mask, shifted right to bit 0.
+ *
+ * @div is the divisor that should be applied to the parent clock's rate
+ * to produce the current clock's rate.
+ *
+ * XXX @flags probably should be replaced with an struct omap_chip.
+ */
struct clksel_rate {
u32 val;
u8 div;
u8 flags;
};
+/**
+ * struct clksel - available parent clocks, and a pointer to their divisors
+ * @parent: struct clk * to a possible parent clock
+ * @rates: available divisors for this parent clock
+ *
+ * A struct clksel is always associated with one or more struct clks
+ * and one or more struct clksel_rates.
+ */
struct clksel {
struct clk *parent;
const struct clksel_rate *rates;
@@ -116,6 +165,60 @@ struct dpll_data {
#endif
+/* struct clk.flags possibilities */
+#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
+#define CLOCK_IDLE_CONTROL (1 << 1)
+#define CLOCK_NO_IDLE_PARENT (1 << 2)
+#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
+#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
+
+/**
+ * struct clk - OMAP struct clk
+ * @node: list_head connecting this clock into the full clock list
+ * @ops: struct clkops * for this clock
+ * @name: the name of the clock in the hardware (used in hwmod data and debug)
+ * @parent: pointer to this clock's parent struct clk
+ * @children: list_head connecting to the child clks' @sibling list_heads
+ * @sibling: list_head connecting this clk to its parent clk's @children
+ * @rate: current clock rate
+ * @enable_reg: register to write to enable the clock (see @enable_bit)
+ * @recalc: fn ptr that returns the clock's current rate
+ * @set_rate: fn ptr that can change the clock's current rate
+ * @round_rate: fn ptr that can round the clock's current rate
+ * @init: fn ptr to do clock-specific initialization
+ * @enable_bit: bitshift to write to enable/disable the clock (see @enable_reg)
+ * @usecount: number of users that have requested this clock to be enabled
+ * @fixed_div: when > 0, this clock's rate is its parent's rate / @fixed_div
+ * @flags: see "struct clk.flags possibilities" above
+ * @clksel_reg: for clksel clks, register va containing src/divisor select
+ * @clksel_mask: bitmask in @clksel_reg for the src/divisor selector
+ * @clksel: for clksel clks, pointer to struct clksel for this clock
+ * @dpll_data: for DPLLs, pointer to struct dpll_data for this clock
+ * @clkdm_name: clockdomain name that this clock is contained in
+ * @clkdm: pointer to struct clockdomain, resolved from @clkdm_name at runtime
+ * @rate_offset: bitshift for rate selection bitfield (OMAP1 only)
+ * @src_offset: bitshift for source selection bitfield (OMAP1 only)
+ *
+ * XXX @rate_offset, @src_offset should probably be removed and OMAP1
+ * clock code converted to use clksel.
+ *
+ * XXX @usecount is poorly named. It should be "enable_count" or
+ * something similar. "users" in the description refers to kernel
+ * code (core code or drivers) that have called clk_enable() and not
+ * yet called clk_disable(); the usecount of parent clocks is also
+ * incremented by the clock code when clk_enable() is called on child
+ * clocks and decremented by the clock code when clk_disable() is
+ * called on child clocks.
+ *
+ * XXX @clkdm, @usecount, @children, @sibling should be marked for
+ * internal use only.
+ *
+ * @children and @sibling are used to optimize parent-to-child clock
+ * tree traversals. (child-to-parent traversals use @parent.)
+ *
+ * XXX The notion of the clock's current rate probably needs to be
+ * separated from the clock's target rate.
+ */
struct clk {
struct list_head node;
const struct clkops *ops;
@@ -129,8 +232,8 @@ struct clk {
int (*set_rate)(struct clk *, unsigned long);
long (*round_rate)(struct clk *, unsigned long);
void (*init)(struct clk *);
- __u8 enable_bit;
- __s8 usecount;
+ u8 enable_bit;
+ s8 usecount;
u8 fixed_div;
u8 flags;
#ifdef CONFIG_ARCH_OMAP2PLUS
@@ -141,8 +244,8 @@ struct clk {
const char *clkdm_name;
struct clockdomain *clkdm;
#else
- __u8 rate_offset;
- __u8 src_offset;
+ u8 rate_offset;
+ u8 src_offset;
#endif
#if defined(CONFIG_PM_DEBUG) && defined(CONFIG_DEBUG_FS)
struct dentry *dent; /* For visible tree hierarchy */
@@ -188,23 +291,4 @@ extern const struct clkops clkops_null;
extern struct clk dummy_ck;
-/* Clock flags */
-#define ENABLE_REG_32BIT (1 << 0) /* Use 32-bit access */
-#define CLOCK_IDLE_CONTROL (1 << 1)
-#define CLOCK_NO_IDLE_PARENT (1 << 2)
-#define ENABLE_ON_INIT (1 << 3) /* Enable upon framework init */
-#define INVERT_ENABLE (1 << 4) /* 0 enables, 1 disables */
-
-/* Clksel_rate flags */
-#define RATE_IN_242X (1 << 0)
-#define RATE_IN_243X (1 << 1)
-#define RATE_IN_3XXX (1 << 2) /* rates common to all OMAP3 */
-#define RATE_IN_3430ES2 (1 << 3) /* 3430ES2 rates only */
-#define RATE_IN_36XX (1 << 4)
-#define RATE_IN_4430 (1 << 5)
-
-#define RATE_IN_24XX (RATE_IN_242X | RATE_IN_243X)
-
-#define RATE_IN_3430ES2PLUS (RATE_IN_3430ES2 | RATE_IN_36XX)
-
#endif
diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h
index d265018f5e6b..9776b41ad76f 100644
--- a/arch/arm/plat-omap/include/plat/common.h
+++ b/arch/arm/plat-omap/include/plat/common.h
@@ -34,6 +34,8 @@ struct sys_timer;
extern void omap_map_common_io(void);
extern struct sys_timer omap_timer;
+extern void omap_reserve(void);
+
/*
* IO bases for various OMAP processors
* Except the tap base, rest all the io bases
@@ -56,8 +58,7 @@ struct omap_globals {
void omap2_set_globals_242x(void);
void omap2_set_globals_243x(void);
-void omap2_set_globals_343x(void);
-void omap2_set_globals_36xx(void);
+void omap2_set_globals_3xxx(void);
void omap2_set_globals_443x(void);
/* These get called from omap2_set_globals_xxxx(), do not call these */
@@ -67,6 +68,8 @@ void omap2_set_globals_control(struct omap_globals *);
void omap2_set_globals_prcm(struct omap_globals *);
void omap2_set_globals_uart(struct omap_globals *);
+void omap3_map_io(void);
+
/**
* omap_test_timeout - busy-loop, testing a condition
* @cond: condition to test until it evaluates to true
@@ -87,4 +90,8 @@ void omap2_set_globals_uart(struct omap_globals *);
} \
})
+extern struct device *omap2_get_mpuss_device(void);
+extern struct device *omap2_get_dsp_device(void);
+extern struct device *omap2_get_l3_device(void);
+
#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/cpu.h b/arch/arm/plat-omap/include/plat/cpu.h
index 75141742300c..aa2f4f079f57 100644
--- a/arch/arm/plat-omap/include/plat/cpu.h
+++ b/arch/arm/plat-omap/include/plat/cpu.h
@@ -444,6 +444,7 @@ extern u32 omap3_features;
#define OMAP3_HAS_NEON BIT(3)
#define OMAP3_HAS_ISP BIT(4)
#define OMAP3_HAS_192MHZ_CLK BIT(5)
+#define OMAP3_HAS_IO_WAKEUP BIT(6)
#define OMAP3_HAS_FEATURE(feat,flag) \
static inline unsigned int omap3_has_ ##feat(void) \
@@ -457,5 +458,6 @@ OMAP3_HAS_FEATURE(iva, IVA)
OMAP3_HAS_FEATURE(neon, NEON)
OMAP3_HAS_FEATURE(isp, ISP)
OMAP3_HAS_FEATURE(192mhz_clk, 192MHZ_CLK)
+OMAP3_HAS_FEATURE(io_wakeup, IO_WAKEUP)
#endif
diff --git a/arch/arm/plat-omap/include/plat/dma.h b/arch/arm/plat-omap/include/plat/dma.h
index 02232ca2c37f..af3a03941add 100644
--- a/arch/arm/plat-omap/include/plat/dma.h
+++ b/arch/arm/plat-omap/include/plat/dma.h
@@ -345,6 +345,7 @@
#define OMAP_DMA_SYNC_BLOCK 0x02
#define OMAP_DMA_SYNC_PACKET 0x03
+#define OMAP_DMA_DST_SYNC_PREFETCH 0x02
#define OMAP_DMA_SRC_SYNC 0x01
#define OMAP_DMA_DST_SYNC 0x00
diff --git a/arch/arm/plat-omap/include/plat/dsp_common.h b/arch/arm/plat-omap/include/plat/dsp_common.h
deleted file mode 100644
index da97736f3efa..000000000000
--- a/arch/arm/plat-omap/include/plat/dsp_common.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
- *
- * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
- *
- * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.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, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#ifndef ASM_ARCH_DSP_COMMON_H
-#define ASM_ARCH_DSP_COMMON_H
-
-#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_OMAP_MMU_FWK)
-extern void omap_dsp_request_mpui(void);
-extern void omap_dsp_release_mpui(void);
-extern int omap_dsp_request_mem(void);
-extern int omap_dsp_release_mem(void);
-#else
-static inline int omap_dsp_request_mem(void)
-{
- return 0;
-}
-#define omap_dsp_release_mem() do {} while (0)
-#endif
-
-#endif /* ASM_ARCH_DSP_COMMON_H */
diff --git a/arch/arm/plat-omap/include/plat/iommu.h b/arch/arm/plat-omap/include/plat/iommu.h
index 0752af9d099e..33c7d41cb6a5 100644
--- a/arch/arm/plat-omap/include/plat/iommu.h
+++ b/arch/arm/plat-omap/include/plat/iommu.h
@@ -80,6 +80,7 @@ struct iommu_functions {
int (*enable)(struct iommu *obj);
void (*disable)(struct iommu *obj);
+ void (*set_twl)(struct iommu *obj, bool on);
u32 (*fault_isr)(struct iommu *obj, u32 *ra);
void (*tlb_read_cr)(struct iommu *obj, struct cr_regs *cr);
@@ -143,6 +144,7 @@ extern void iotlb_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e);
extern u32 iotlb_cr_to_virt(struct cr_regs *cr);
extern int load_iotlb_entry(struct iommu *obj, struct iotlb_entry *e);
+extern void iommu_set_twl(struct iommu *obj, bool on);
extern void flush_iotlb_page(struct iommu *obj, u32 da);
extern void flush_iotlb_range(struct iommu *obj, u32 start, u32 end);
extern void flush_iotlb_all(struct iommu *obj);
diff --git a/arch/arm/plat-omap/include/plat/mux.h b/arch/arm/plat-omap/include/plat/mux.h
index c7472a28ce24..aeba71796ad9 100644
--- a/arch/arm/plat-omap/include/plat/mux.h
+++ b/arch/arm/plat-omap/include/plat/mux.h
@@ -114,28 +114,11 @@
PU_PD_REG(NA, 0) \
},
-#define MUX_CFG_24XX(desc, reg_offset, mode, \
- pull_en, pull_mode, dbg) \
-{ \
- .name = desc, \
- .debug = dbg, \
- .mux_reg = reg_offset, \
- .mask = mode, \
- .pull_val = pull_en, \
- .pu_pd_val = pull_mode, \
-},
-
-/* 24xx/34xx mux bit defines */
-#define OMAP2_PULL_ENA (1 << 3)
-#define OMAP2_PULL_UP (1 << 4)
-#define OMAP2_ALTELECTRICALSEL (1 << 5)
-
struct pin_config {
char *name;
const unsigned int mux_reg;
unsigned char debug;
-#if defined(CONFIG_ARCH_OMAP1) || defined(CONFIG_ARCH_OMAP2)
const unsigned char mask_offset;
const unsigned char mask;
@@ -147,7 +130,6 @@ struct pin_config {
const char *pu_pd_name;
const unsigned int pu_pd_reg;
const unsigned char pu_pd_val;
-#endif
#if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS)
const char *mux_reg_name;
@@ -191,6 +173,10 @@ enum omap7xx_index {
SPI_7XX_4,
SPI_7XX_5,
SPI_7XX_6,
+
+ /* UART */
+ UART_7XX_1,
+ UART_7XX_2,
};
enum omap1xxx_index {
@@ -446,208 +432,6 @@ enum omap1xxx_index {
};
-enum omap24xx_index {
- /* 24xx I2C */
- M19_24XX_I2C1_SCL,
- L15_24XX_I2C1_SDA,
- J15_24XX_I2C2_SCL,
- H19_24XX_I2C2_SDA,
-
- /* 24xx Menelaus interrupt */
- W19_24XX_SYS_NIRQ,
-
- /* 24xx clock */
- W14_24XX_SYS_CLKOUT,
-
- /* 24xx GPMC chipselects, wait pin monitoring */
- E2_GPMC_NCS2,
- L2_GPMC_NCS7,
- L3_GPMC_WAIT0,
- N7_GPMC_WAIT1,
- M1_GPMC_WAIT2,
- P1_GPMC_WAIT3,
-
- /* 242X McBSP */
- Y15_24XX_MCBSP2_CLKX,
- R14_24XX_MCBSP2_FSX,
- W15_24XX_MCBSP2_DR,
- V15_24XX_MCBSP2_DX,
-
- /* 24xx GPIO */
- M21_242X_GPIO11,
- P21_242X_GPIO12,
- AA10_242X_GPIO13,
- AA6_242X_GPIO14,
- AA4_242X_GPIO15,
- Y11_242X_GPIO16,
- AA12_242X_GPIO17,
- AA8_242X_GPIO58,
- Y20_24XX_GPIO60,
- W4__24XX_GPIO74,
- N15_24XX_GPIO85,
- M15_24XX_GPIO92,
- P20_24XX_GPIO93,
- P18_24XX_GPIO95,
- M18_24XX_GPIO96,
- L14_24XX_GPIO97,
- J15_24XX_GPIO99,
- V14_24XX_GPIO117,
- P14_24XX_GPIO125,
-
- /* 242x DBG GPIO */
- V4_242X_GPIO49,
- W2_242X_GPIO50,
- U4_242X_GPIO51,
- V3_242X_GPIO52,
- V2_242X_GPIO53,
- V6_242X_GPIO53,
- T4_242X_GPIO54,
- Y4_242X_GPIO54,
- T3_242X_GPIO55,
- U2_242X_GPIO56,
-
- /* 24xx external DMA requests */
- AA10_242X_DMAREQ0,
- AA6_242X_DMAREQ1,
- E4_242X_DMAREQ2,
- G4_242X_DMAREQ3,
- D3_242X_DMAREQ4,
- E3_242X_DMAREQ5,
-
- /* UART3 */
- K15_24XX_UART3_TX,
- K14_24XX_UART3_RX,
-
- /* MMC/SDIO */
- G19_24XX_MMC_CLKO,
- H18_24XX_MMC_CMD,
- F20_24XX_MMC_DAT0,
- H14_24XX_MMC_DAT1,
- E19_24XX_MMC_DAT2,
- D19_24XX_MMC_DAT3,
- F19_24XX_MMC_DAT_DIR0,
- E20_24XX_MMC_DAT_DIR1,
- F18_24XX_MMC_DAT_DIR2,
- E18_24XX_MMC_DAT_DIR3,
- G18_24XX_MMC_CMD_DIR,
- H15_24XX_MMC_CLKI,
-
- /* Full speed USB */
- J20_24XX_USB0_PUEN,
- J19_24XX_USB0_VP,
- K20_24XX_USB0_VM,
- J18_24XX_USB0_RCV,
- K19_24XX_USB0_TXEN,
- J14_24XX_USB0_SE0,
- K18_24XX_USB0_DAT,
-
- N14_24XX_USB1_SE0,
- W12_24XX_USB1_SE0,
- P15_24XX_USB1_DAT,
- R13_24XX_USB1_DAT,
- W20_24XX_USB1_TXEN,
- P13_24XX_USB1_TXEN,
- V19_24XX_USB1_RCV,
- V12_24XX_USB1_RCV,
-
- AA10_24XX_USB2_SE0,
- Y11_24XX_USB2_DAT,
- AA12_24XX_USB2_TXEN,
- AA6_24XX_USB2_RCV,
- AA4_24XX_USB2_TLLSE0,
-
- /* Keypad GPIO*/
- T19_24XX_KBR0,
- R19_24XX_KBR1,
- V18_24XX_KBR2,
- M21_24XX_KBR3,
- E5__24XX_KBR4,
- M18_24XX_KBR5,
- R20_24XX_KBC0,
- M14_24XX_KBC1,
- H19_24XX_KBC2,
- V17_24XX_KBC3,
- P21_24XX_KBC4,
- L14_24XX_KBC5,
- N19_24XX_KBC6,
-
- /* 24xx Menelaus Keypad GPIO */
- B3__24XX_KBR5,
- AA4_24XX_KBC2,
- B13_24XX_KBC6,
-
- /* 2430 USB */
- AD9_2430_USB0_PUEN,
- Y11_2430_USB0_VP,
- AD7_2430_USB0_VM,
- AE7_2430_USB0_RCV,
- AD4_2430_USB0_TXEN,
- AF9_2430_USB0_SE0,
- AE6_2430_USB0_DAT,
- AD24_2430_USB1_SE0,
- AB24_2430_USB1_RCV,
- Y25_2430_USB1_TXEN,
- AA26_2430_USB1_DAT,
-
- /* 2430 HS-USB */
- AD9_2430_USB0HS_DATA3,
- Y11_2430_USB0HS_DATA4,
- AD7_2430_USB0HS_DATA5,
- AE7_2430_USB0HS_DATA6,
- AD4_2430_USB0HS_DATA2,
- AF9_2430_USB0HS_DATA0,
- AE6_2430_USB0HS_DATA1,
- AE8_2430_USB0HS_CLK,
- AD8_2430_USB0HS_DIR,
- AE5_2430_USB0HS_STP,
- AE9_2430_USB0HS_NXT,
- AC7_2430_USB0HS_DATA7,
-
- /* 2430 McBSP */
- AD6_2430_MCBSP_CLKS,
-
- AB2_2430_MCBSP1_CLKR,
- AD5_2430_MCBSP1_FSR,
- AA1_2430_MCBSP1_DX,
- AF3_2430_MCBSP1_DR,
- AB3_2430_MCBSP1_FSX,
- Y9_2430_MCBSP1_CLKX,
-
- AC10_2430_MCBSP2_FSX,
- AD16_2430_MCBSP2_CLX,
- AE13_2430_MCBSP2_DX,
- AD13_2430_MCBSP2_DR,
- AC10_2430_MCBSP2_FSX_OFF,
- AD16_2430_MCBSP2_CLX_OFF,
- AE13_2430_MCBSP2_DX_OFF,
- AD13_2430_MCBSP2_DR_OFF,
-
- AC9_2430_MCBSP3_CLKX,
- AE4_2430_MCBSP3_FSX,
- AE2_2430_MCBSP3_DR,
- AF4_2430_MCBSP3_DX,
-
- N3_2430_MCBSP4_CLKX,
- AD23_2430_MCBSP4_DR,
- AB25_2430_MCBSP4_DX,
- AC25_2430_MCBSP4_FSX,
-
- AE16_2430_MCBSP5_CLKX,
- AF12_2430_MCBSP5_FSX,
- K7_2430_MCBSP5_DX,
- M1_2430_MCBSP5_DR,
-
- /* 2430 McSPI*/
- Y18_2430_MCSPI1_CLK,
- AD15_2430_MCSPI1_SIMO,
- AE17_2430_MCSPI1_SOMI,
- U1_2430_MCSPI1_CS0,
-
- /* Touchscreen GPIO */
- AF19_2430_GPIO_85,
-
-};
-
struct omap_mux_cfg {
struct pin_config *pins;
unsigned long size;
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 3ee41d711492..728fbb9dd549 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -1,8 +1,8 @@
/*
* omap-pm.h - OMAP power management interface
*
- * Copyright (C) 2008-2009 Texas Instruments, Inc.
- * Copyright (C) 2008-2009 Nokia Corporation
+ * Copyright (C) 2008-2010 Texas Instruments, Inc.
+ * Copyright (C) 2008-2010 Nokia Corporation
* Paul Walmsley
*
* Interface developed by (in alphabetical order): Karthik Dasu, Jouni
@@ -16,6 +16,7 @@
#include <linux/device.h>
#include <linux/cpufreq.h>
+#include <linux/clk.h>
#include "powerdomain.h"
@@ -89,7 +90,7 @@ void omap_pm_if_exit(void);
* @t: maximum MPU wakeup latency in microseconds
*
* Request that the maximum interrupt latency for the MPU to be no
- * greater than 't' microseconds. "Interrupt latency" in this case is
+ * greater than @t microseconds. "Interrupt latency" in this case is
* defined as the elapsed time from the occurrence of a hardware or
* timer interrupt to the time when the device driver's interrupt
* service routine has been entered by the MPU.
@@ -105,15 +106,19 @@ void omap_pm_if_exit(void);
* elapsed from when a device driver enables a hardware device with
* clk_enable(), to when the device is ready for register access or
* other use. To control this device wakeup latency, use
- * set_max_dev_wakeup_lat()
+ * omap_pm_set_max_dev_wakeup_lat()
*
- * Multiple calls to set_max_mpu_wakeup_lat() will replace the
+ * Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
* previous t value. To remove the latency target for the MPU, call
* with t = -1.
*
- * No return value.
+ * XXX This constraint will be deprecated soon in favor of the more
+ * general omap_pm_set_max_dev_wakeup_lat()
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
*/
-void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
/**
@@ -123,8 +128,8 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
* @r: minimum throughput (in KiB/s)
*
* Request that the minimum data throughput on the OCP interconnect
- * attached to device 'dev' interconnect agent 'tbus_id' be no less
- * than 'r' KiB/s.
+ * attached to device @dev interconnect agent @tbus_id be no less
+ * than @r KiB/s.
*
* It is expected that the OMAP PM or bus code will use this
* information to set the interconnect clock to run at the lowest
@@ -138,40 +143,44 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
* code will also need to add an minimum L3 interconnect speed
* constraint,
*
- * Multiple calls to set_min_bus_tput() will replace the previous rate
- * value for this device. To remove the interconnect throughput
- * restriction for this device, call with r = 0.
+ * Multiple calls to omap_pm_set_min_bus_tput() will replace the
+ * previous rate value for this device. To remove the interconnect
+ * throughput restriction for this device, call with r = 0.
*
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
*/
-void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
/**
* omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @dev: struct device *
+ * @req_dev: struct device * requesting the constraint, or NULL if none
+ * @dev: struct device * to set the constraint one
* @t: maximum device wakeup latency in microseconds
*
- * Request that the maximum amount of time necessary for a device to
- * become accessible after its clocks are enabled should be no greater
- * than 't' microseconds. Specifically, this represents the time from
- * when a device driver enables device clocks with clk_enable(), to
- * when the register reads and writes on the device will succeed.
- * This function should be called before clk_disable() is called,
- * since the power state transition decision may be made during
- * clk_disable().
+ * Request that the maximum amount of time necessary for a device @dev
+ * to become accessible after its clocks are enabled should be no
+ * greater than @t microseconds. Specifically, this represents the
+ * time from when a device driver enables device clocks with
+ * clk_enable(), to when the register reads and writes on the device
+ * will succeed. This function should be called before clk_disable()
+ * is called, since the power state transition decision may be made
+ * during clk_disable().
*
* It is intended that underlying PM code will use this information to
* determine what power state to put the powerdomain enclosing this
* device into.
*
- * Multiple calls to set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device. To remove the wakeup
- * latency restriction for this device, call with t = -1.
+ * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
+ * previous wakeup latency values for this device. To remove the
+ * wakeup latency restriction for this device, call with t = -1.
*
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
*/
-void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t);
/**
@@ -198,10 +207,71 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t);
* value for this device. To remove the maximum DMA latency for this
* device, call with t = -1.
*
- * No return value.
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
*/
-void omap_pm_set_max_sdma_lat(struct device *dev, long t);
+int omap_pm_set_max_sdma_lat(struct device *dev, long t);
+
+/**
+ * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
+ * @dev: struct device * requesting the constraint
+ * @clk: struct clk * to set the minimum rate constraint on
+ * @r: minimum rate in Hz
+ *
+ * Request that the minimum clock rate on the device @dev's clk @clk
+ * be no less than @r Hz.
+ *
+ * It is expected that the OMAP PM code will use this information to
+ * find an OPP or clock setting that will satisfy this clock rate
+ * constraint, along with any other applicable system constraints on
+ * the clock rate or corresponding voltage, etc.
+ *
+ * omap_pm_set_min_clk_rate() differs from the clock code's
+ * clk_set_rate() in that it considers other constraints before taking
+ * any hardware action, and may change a system OPP rather than just a
+ * clock rate. clk_set_rate() is intended to be a low-level
+ * interface.
+ *
+ * omap_pm_set_min_clk_rate() is easily open to abuse. A better API
+ * would be something like "omap_pm_set_min_dev_performance()";
+ * however, there is no easily-generalizable concept of performance
+ * that applies to all devices. Only a device (and possibly the
+ * device subsystem) has both the subsystem-specific knowledge, and
+ * the hardware IP block-specific knowledge, to translate a constraint
+ * on "touchscreen sampling accuracy" or "number of pixels or polygons
+ * rendered per second" to a clock rate. This translation can be
+ * dependent on the hardware IP block's revision, or firmware version,
+ * and the driver is the only code on the system that has this
+ * information and can know how to translate that into a clock rate.
+ *
+ * The intended use-case for this function is for userspace or other
+ * kernel code to communicate a particular performance requirement to
+ * a subsystem; then for the subsystem to communicate that requirement
+ * to something that is meaningful to the device driver; then for the
+ * device driver to convert that requirement to a clock rate, and to
+ * then call omap_pm_set_min_clk_rate().
+ *
+ * Users of this function (such as device drivers) should not simply
+ * call this function with some high clock rate to ensure "high
+ * performance." Rather, the device driver should take a performance
+ * constraint from its subsystem, such as "render at least X polygons
+ * per second," and use some formula or table to convert that into a
+ * clock rate constraint given the hardware type and hardware
+ * revision. Device drivers or subsystems should not assume that they
+ * know how to make a power/performance tradeoff - some device use
+ * cases may tolerate a lower-fidelity device function for lower power
+ * consumption; others may demand a higher-fidelity device function,
+ * no matter what the power consumption.
+ *
+ * Multiple calls to omap_pm_set_min_clk_rate() will replace the
+ * previous rate value for the device @dev. To remove the minimum clock
+ * rate constraint for the device, call with r = 0.
+ *
+ * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
+ * is not satisfiable, or 0 upon success.
+ */
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
/*
* DSP Bridge-specific constraints
diff --git a/arch/arm/plat-omap/include/plat/omap_device.h b/arch/arm/plat-omap/include/plat/omap_device.h
index 3694b622c4ac..25cd9ac3b095 100644
--- a/arch/arm/plat-omap/include/plat/omap_device.h
+++ b/arch/arm/plat-omap/include/plat/omap_device.h
@@ -101,6 +101,8 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
int omap_device_register(struct omap_device *od);
int omap_early_device_register(struct omap_device *od);
+void __iomem *omap_device_get_rt_va(struct omap_device *od);
+
/* OMAP PM interface */
int omap_device_align_pm_lat(struct platform_device *pdev,
u32 new_wakeup_lat_limit);
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 0eccc09ac4a9..a4e508dfaba2 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -1,7 +1,7 @@
/*
* omap_hwmod macros, structures
*
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
* Paul Walmsley
*
* Created in collaboration with (alphabetical order): Benoît Cousson,
@@ -419,7 +419,7 @@ struct omap_hwmod_class {
* @slaves: ptr to array of OCP ifs that this hwmod can respond on
* @dev_attr: arbitrary device attributes that can be passed to the driver
* @_sysc_cache: internal-use hwmod flags
- * @_rt_va: cached register target start address (internal use)
+ * @_mpu_rt_va: cached register target start address (internal use)
* @_mpu_port_index: cached MPU register target slave ID (internal use)
* @msuspendmux_reg_id: CONTROL_MSUSPENDMUX register ID (1-6)
* @msuspendmux_shift: CONTROL_MSUSPENDMUX register bit shift
@@ -460,7 +460,7 @@ struct omap_hwmod {
struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
void *dev_attr;
u32 _sysc_cache;
- void __iomem *_rt_va;
+ void __iomem *_mpu_rt_va;
struct list_head node;
u16 flags;
u8 _mpu_port_index;
@@ -482,11 +482,14 @@ int omap_hwmod_init(struct omap_hwmod **ohs);
int omap_hwmod_register(struct omap_hwmod *oh);
int omap_hwmod_unregister(struct omap_hwmod *oh);
struct omap_hwmod *omap_hwmod_lookup(const char *name);
-int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh));
-int omap_hwmod_late_init(void);
+int omap_hwmod_for_each(int (*fn)(struct omap_hwmod *oh, void *data),
+ void *data);
+int omap_hwmod_late_init(u8 skip_setup_idle);
int omap_hwmod_enable(struct omap_hwmod *oh);
+int _omap_hwmod_enable(struct omap_hwmod *oh);
int omap_hwmod_idle(struct omap_hwmod *oh);
+int _omap_hwmod_idle(struct omap_hwmod *oh);
int omap_hwmod_shutdown(struct omap_hwmod *oh);
int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
@@ -504,6 +507,7 @@ int omap_hwmod_count_resources(struct omap_hwmod *oh);
int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res);
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
+void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
struct omap_hwmod *init_oh);
diff --git a/arch/arm/plat-omap/include/plat/smp.h b/arch/arm/plat-omap/include/plat/smp.h
index 8983d54c4fd2..6a3ff65c0303 100644
--- a/arch/arm/plat-omap/include/plat/smp.h
+++ b/arch/arm/plat-omap/include/plat/smp.h
@@ -30,6 +30,7 @@
extern void omap_secondary_startup(void);
extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
extern void omap_auxcoreboot_addr(u32 cpu_addr);
+extern u32 omap_read_auxcoreboot0(void);
/*
* We use Soft IRQ1 as the IPI
diff --git a/arch/arm/plat-omap/include/plat/uncompress.h b/arch/arm/plat-omap/include/plat/uncompress.h
index bbedd71943f6..ddf723be48dc 100644
--- a/arch/arm/plat-omap/include/plat/uncompress.h
+++ b/arch/arm/plat-omap/include/plat/uncompress.h
@@ -25,6 +25,8 @@
#include <plat/serial.h>
+#define MDR1_MODE_MASK 0x07
+
static volatile u8 *uart_base;
static int uart_shift;
@@ -42,6 +44,10 @@ static void putc(int c)
if (!uart_base)
return;
+ /* Check for UART 16x mode */
+ if ((uart_base[UART_OMAP_MDR1 << uart_shift] & MDR1_MODE_MASK) != 0)
+ return;
+
while (!(uart_base[UART_LSR << uart_shift] & UART_LSR_THRE))
barrier();
uart_base[UART_TX << uart_shift] = c;
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index 98eef5360e6d..2a9427c8cc48 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -81,7 +81,34 @@ extern void usb_ohci_init(const struct ohci_hcd_omap_platform_data *pdata);
#endif
-void omap_usb_init(struct omap_usb_config *pdata);
+
+/*
+ * FIXME correct answer depends on hmc_mode,
+ * as does (on omap1) any nonzero value for config->otg port number
+ */
+#ifdef CONFIG_USB_GADGET_OMAP
+#define is_usb0_device(config) 1
+#else
+#define is_usb0_device(config) 0
+#endif
+
+void omap_otg_init(struct omap_usb_config *config);
+
+#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
+void omap1_usb_init(struct omap_usb_config *pdata);
+#else
+static inline void omap1_usb_init(struct omap_usb_config *pdata)
+{
+}
+#endif
+
+#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP_OTG_MODULE)
+void omap2_usbfs_init(struct omap_usb_config *pdata);
+#else
+static inline omap2_usbfs_init(struct omap_usb_config *pdata)
+{
+}
+#endif
/*-------------------------------------------------------------------------*/
@@ -192,4 +219,24 @@ void omap_usb_init(struct omap_usb_config *pdata);
# define USB0PUENACTLOI (1 << 16)
# define USBSTANDBYCTRL (1 << 15)
+#if defined(CONFIG_ARCH_OMAP1) && defined(CONFIG_USB)
+u32 omap1_usb0_init(unsigned nwires, unsigned is_device);
+u32 omap1_usb1_init(unsigned nwires);
+u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup);
+#else
+static inline u32 omap1_usb0_init(unsigned nwires, unsigned is_device)
+{
+ return 0;
+}
+static inline u32 omap1_usb1_init(unsigned nwires)
+{
+ return 0;
+
+}
+static inline u32 omap1_usb2_init(unsigned nwires, unsigned alt_pingroup)
+{
+ return 0;
+}
+#endif
+
#endif /* __ASM_ARCH_OMAP_USB_H */
diff --git a/arch/arm/plat-omap/include/plat/vram.h b/arch/arm/plat-omap/include/plat/vram.h
index edd4987758a6..70e1272232f0 100644
--- a/arch/arm/plat-omap/include/plat/vram.h
+++ b/arch/arm/plat-omap/include/plat/vram.h
@@ -38,7 +38,7 @@ extern void omap_vram_get_info(unsigned long *vram, unsigned long *free_vram,
extern void omap_vram_set_sdram_vram(u32 size, u32 start);
extern void omap_vram_set_sram_vram(u32 size, u32 start);
-extern void omap_vram_reserve_sdram(void);
+extern void omap_vram_reserve_sdram_lmb(void);
extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
@@ -48,7 +48,7 @@ extern unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
static inline void omap_vram_set_sdram_vram(u32 size, u32 start) { }
static inline void omap_vram_set_sram_vram(u32 size, u32 start) { }
-static inline void omap_vram_reserve_sdram(void) { }
+static inline void omap_vram_reserve_sdram_lmb(void) { }
static inline unsigned long omap_vram_reserve_sram(unsigned long sram_pstart,
unsigned long sram_vstart,
unsigned long sram_size,
diff --git a/arch/arm/plat-omap/iommu.c b/arch/arm/plat-omap/iommu.c
index bc094dbacee6..a202a2ce6e3d 100644
--- a/arch/arm/plat-omap/iommu.c
+++ b/arch/arm/plat-omap/iommu.c
@@ -370,6 +370,23 @@ void flush_iotlb_all(struct iommu *obj)
}
EXPORT_SYMBOL_GPL(flush_iotlb_all);
+/**
+ * iommu_set_twl - enable/disable table walking logic
+ * @obj: target iommu
+ * @on: enable/disable
+ *
+ * Function used to enable/disable TWL. If one wants to work
+ * exclusively with locked TLB entries and receive notifications
+ * for TLB miss then call this function to disable TWL.
+ */
+void iommu_set_twl(struct iommu *obj, bool on)
+{
+ clk_enable(obj->clk);
+ arch_iommu->set_twl(obj, on);
+ clk_disable(obj->clk);
+}
+EXPORT_SYMBOL_GPL(iommu_set_twl);
+
#if defined(CONFIG_OMAP_IOMMU_DEBUG_MODULE)
ssize_t iommu_dump_ctx(struct iommu *obj, char *buf, ssize_t bytes)
@@ -653,7 +670,7 @@ void iopgtable_lookup_entry(struct iommu *obj, u32 da, u32 **ppgd, u32 **ppte)
if (!*iopgd)
goto out;
- if (*iopgd & IOPGD_TABLE)
+ if (iopgd_is_table(*iopgd))
iopte = iopte_offset(iopgd, da);
out:
*ppgd = iopgd;
@@ -670,7 +687,7 @@ static size_t iopgtable_clear_entry_core(struct iommu *obj, u32 da)
if (!*iopgd)
return 0;
- if (*iopgd & IOPGD_TABLE) {
+ if (iopgd_is_table(*iopgd)) {
int i;
u32 *iopte = iopte_offset(iopgd, da);
@@ -745,7 +762,7 @@ static void iopgtable_clear_entry_all(struct iommu *obj)
if (!*iopgd)
continue;
- if (*iopgd & IOPGD_TABLE)
+ if (iopgd_is_table(*iopgd))
iopte_free(iopte_offset(iopgd, 0));
*iopgd = 0;
@@ -783,9 +800,11 @@ static irqreturn_t iommu_fault_handler(int irq, void *data)
if (!stat)
return IRQ_HANDLED;
+ iommu_disable(obj);
+
iopgd = iopgd_offset(obj, da);
- if (!(*iopgd & IOPGD_TABLE)) {
+ if (!iopgd_is_table(*iopgd)) {
dev_err(obj->dev, "%s: da:%08x pgd:%p *pgd:%08x\n", __func__,
da, iopgd, *iopgd);
return IRQ_NONE;
diff --git a/arch/arm/plat-omap/iopgtable.h b/arch/arm/plat-omap/iopgtable.h
index ab23b6a140fd..c3e93bb0911f 100644
--- a/arch/arm/plat-omap/iopgtable.h
+++ b/arch/arm/plat-omap/iopgtable.h
@@ -63,6 +63,8 @@
#define IOPGD_SECTION (2 << 0)
#define IOPGD_SUPER (1 << 18 | 2 << 0)
+#define iopgd_is_table(x) (((x) & 3) == IOPGD_TABLE)
+
#define IOPTE_SMALL (2 << 0)
#define IOPTE_LARGE (1 << 0)
@@ -70,12 +72,12 @@
#define iopgd_index(da) (((da) >> IOPGD_SHIFT) & (PTRS_PER_IOPGD - 1))
#define iopgd_offset(obj, da) ((obj)->iopgd + iopgd_index(da))
-#define iopte_paddr(iopgd) (*iopgd & ~((1 << 10) - 1))
-#define iopte_vaddr(iopgd) ((u32 *)phys_to_virt(iopte_paddr(iopgd)))
+#define iopgd_page_paddr(iopgd) (*iopgd & ~((1 << 10) - 1))
+#define iopgd_page_vaddr(iopgd) ((u32 *)phys_to_virt(iopgd_page_paddr(iopgd)))
/* to find an entry in the second-level page table. */
#define iopte_index(da) (((da) >> IOPTE_SHIFT) & (PTRS_PER_IOPTE - 1))
-#define iopte_offset(iopgd, da) (iopte_vaddr(iopgd) + iopte_index(da))
+#define iopte_offset(iopgd, da) (iopgd_page_vaddr(iopgd) + iopte_index(da))
static inline u32 iotlb_init_entry(struct iotlb_entry *e, u32 da, u32 pa,
u32 flags)
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
index 06703635ace1..0d4aa0d5876c 100644
--- a/arch/arm/plat-omap/mux.c
+++ b/arch/arm/plat-omap/mux.c
@@ -54,7 +54,7 @@ int __init_or_module omap_cfg_reg(const unsigned long index)
{
struct pin_config *reg;
- if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
+ if (!cpu_class_is_omap1()) {
printk(KERN_ERR "mux: Broken omap_cfg_reg(%lu) entry\n",
index);
WARN_ON(1);
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index 186bca82cfab..e129ce80c53b 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -34,11 +34,11 @@ struct omap_opp *l3_opps;
* Device-driver-originated constraints (via board-*.c files)
*/
-void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
+int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
{
if (!dev || t < -1) {
- WARN_ON(1);
- return;
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
};
if (t == -1)
@@ -58,14 +58,16 @@ void omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
*
* TI CDP code can call constraint_set here.
*/
+
+ return 0;
}
-void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
+int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
agent_id != OCP_TARGET_AGENT)) {
- WARN_ON(1);
- return;
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
};
if (r == 0)
@@ -83,13 +85,16 @@ void omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
*
* TI CDP code can call constraint_set here on the VDD2 OPP.
*/
+
+ return 0;
}
-void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
+int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
+ long t)
{
- if (!dev || t < -1) {
- WARN_ON(1);
- return;
+ if (!req_dev || !dev || t < -1) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
};
if (t == -1)
@@ -111,13 +116,15 @@ void omap_pm_set_max_dev_wakeup_lat(struct device *dev, long t)
*
* TI CDP code can call constraint_set here.
*/
+
+ return 0;
}
-void omap_pm_set_max_sdma_lat(struct device *dev, long t)
+int omap_pm_set_max_sdma_lat(struct device *dev, long t)
{
if (!dev || t < -1) {
- WARN_ON(1);
- return;
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
};
if (t == -1)
@@ -139,8 +146,36 @@ void omap_pm_set_max_sdma_lat(struct device *dev, long t)
* TI CDP code can call constraint_set here.
*/
+ return 0;
}
+int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
+{
+ if (!dev || !c || r < 0) {
+ WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
+ return -EINVAL;
+ }
+
+ if (r == 0)
+ pr_debug("OMAP PM: remove min clk rate constraint: "
+ "dev %s\n", dev_name(dev));
+ else
+ pr_debug("OMAP PM: add min clk rate constraint: "
+ "dev %s, rate = %ld Hz\n", dev_name(dev), r);
+
+ /*
+ * Code in a real implementation should keep track of these
+ * constraints on the clock, and determine the highest minimum
+ * clock rate. It should iterate over each OPP and determine
+ * whether the OPP will result in a clock rate that would
+ * satisfy this constraint (and any other PM constraint in effect
+ * at that time). Once it finds the lowest-voltage OPP that
+ * meets those conditions, it should switch to it, or return
+ * an error if the code is not capable of doing so.
+ */
+
+ return 0;
+}
/*
* DSP Bridge-specific constraints
diff --git a/arch/arm/plat-omap/omap_device.c b/arch/arm/plat-omap/omap_device.c
index f899603051ac..ea0d659fcb1c 100644
--- a/arch/arm/plat-omap/omap_device.c
+++ b/arch/arm/plat-omap/omap_device.c
@@ -1,7 +1,7 @@
/*
* omap_device implementation
*
- * Copyright (C) 2009 Nokia Corporation
+ * Copyright (C) 2009-2010 Nokia Corporation
* Paul Walmsley, Kevin Hilman
*
* Developed in collaboration with (alphabetical order): Benoit
@@ -90,8 +90,11 @@
#define USE_WAKEUP_LAT 0
#define IGNORE_WAKEUP_LAT 1
-
-#define OMAP_DEVICE_MAGIC 0xf00dcafe
+/*
+ * OMAP_DEVICE_MAGIC: used to determine whether a struct omap_device
+ * obtained via container_of() is in fact a struct omap_device
+ */
+#define OMAP_DEVICE_MAGIC 0xf00dcafe
/* Private functions */
@@ -359,7 +362,7 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
struct omap_device *od;
char *pdev_name2;
struct resource *res = NULL;
- int res_count;
+ int i, res_count;
struct omap_hwmod **hwmods;
if (!ohs || oh_cnt == 0 || !pdev_name)
@@ -416,6 +419,9 @@ struct omap_device *omap_device_build_ss(const char *pdev_name, int pdev_id,
else
ret = omap_device_register(od);
+ for (i = 0; i < oh_cnt; i++)
+ hwmods[i]->od = od;
+
if (ret)
goto odbs_exit4;
@@ -652,6 +658,25 @@ struct powerdomain *omap_device_get_pwrdm(struct omap_device *od)
return omap_hwmod_get_pwrdm(od->hwmods[0]);
}
+/**
+ * omap_device_get_mpu_rt_va - return the MPU's virtual addr for the hwmod base
+ * @od: struct omap_device *
+ *
+ * Return the MPU's virtual address for the base of the hwmod, from
+ * the ioremap() that the hwmod code does. Only valid if there is one
+ * hwmod associated with this device. Returns NULL if there are zero
+ * or more than one hwmods associated with this omap_device;
+ * otherwise, passes along the return value from
+ * omap_hwmod_get_mpu_rt_va().
+ */
+void __iomem *omap_device_get_rt_va(struct omap_device *od)
+{
+ if (od->hwmods_cnt != 1)
+ return NULL;
+
+ return omap_hwmod_get_mpu_rt_va(od->hwmods[0]);
+}
+
/*
* Public functions intended for use in omap_device_pm_latency
* .activate_func and .deactivate_func function pointers
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
index d3bf17cd36f3..f3570884883e 100644
--- a/arch/arm/plat-omap/usb.c
+++ b/arch/arm/plat-omap/usb.c
@@ -22,524 +22,13 @@
#include <linux/module.h>
#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/errno.h>
#include <linux/init.h>
#include <linux/platform_device.h>
-#include <linux/usb/otg.h>
#include <linux/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <mach/hardware.h>
-
-#include <plat/control.h>
-#include <plat/mux.h>
#include <plat/usb.h>
#include <plat/board.h>
-#ifdef CONFIG_ARCH_OMAP1
-
-#define INT_USB_IRQ_GEN IH2_BASE + 20
-#define INT_USB_IRQ_NISO IH2_BASE + 30
-#define INT_USB_IRQ_ISO IH2_BASE + 29
-#define INT_USB_IRQ_HGEN INT_USB_HHC_1
-#define INT_USB_IRQ_OTG IH2_BASE + 8
-
-#else
-
-#define INT_USB_IRQ_GEN INT_24XX_USB_IRQ_GEN
-#define INT_USB_IRQ_NISO INT_24XX_USB_IRQ_NISO
-#define INT_USB_IRQ_ISO INT_24XX_USB_IRQ_ISO
-#define INT_USB_IRQ_HGEN INT_24XX_USB_IRQ_HGEN
-#define INT_USB_IRQ_OTG INT_24XX_USB_IRQ_OTG
-
-#endif
-
-
-/* These routines should handle the standard chip-specific modes
- * for usb0/1/2 ports, covering basic mux and transceiver setup.
- *
- * Some board-*.c files will need to set up additional mux options,
- * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
- */
-
-/* TESTED ON:
- * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
- * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
- * - 5912 OSK UDC, with *nonstandard* A-to-A cable
- * - 1510 Innovator UDC with bundled usb0 cable
- * - 1510 Innovator OHCI with bundled usb1/usb2 cable
- * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
- * - 1710 custom development board using alternate pin group
- * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
- */
-
-/*-------------------------------------------------------------------------*/
-
-#if defined(CONFIG_ARCH_OMAP_OTG) || defined(CONFIG_ARCH_OMAP15XX)
-
-static void omap2_usb_devconf_clear(u8 port, u32 mask)
-{
- u32 r;
-
- r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- r &= ~USBTXWRMODEI(port, mask);
- omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
-}
-
-static void omap2_usb_devconf_set(u8 port, u32 mask)
-{
- u32 r;
-
- r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- r |= USBTXWRMODEI(port, mask);
- omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
-}
-
-static void omap2_usb2_disable_5pinbitll(void)
-{
- u32 r;
-
- r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- r &= ~(USBTXWRMODEI(2, USB_BIDIR_TLL) | USBT2TLL5PI);
- omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
-}
-
-static void omap2_usb2_enable_5pinunitll(void)
-{
- u32 r;
-
- r = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- r |= USBTXWRMODEI(2, USB_UNIDIR_TLL) | USBT2TLL5PI;
- omap_ctrl_writel(r, OMAP2_CONTROL_DEVCONF0);
-}
-
-static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
-{
- u32 syscon1 = 0;
-
- if (cpu_is_omap24xx())
- omap2_usb_devconf_clear(0, USB_BIDIR_TLL);
-
- if (nwires == 0) {
- if (cpu_class_is_omap1() && !cpu_is_omap15xx()) {
- u32 l;
-
- /* pulldown D+/D- */
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l &= ~(3 << 1);
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
- return 0;
- }
-
- if (is_device) {
- if (cpu_is_omap24xx())
- omap_cfg_reg(J20_24XX_USB0_PUEN);
- else if (cpu_is_omap7xx()) {
- omap_cfg_reg(AA17_7XX_USB_DM);
- omap_cfg_reg(W16_7XX_USB_PU_EN);
- omap_cfg_reg(W17_7XX_USB_VBUSI);
- omap_cfg_reg(W18_7XX_USB_DMCK_OUT);
- omap_cfg_reg(W19_7XX_USB_DCRST);
- } else
- omap_cfg_reg(W4_USB_PUEN);
- }
-
- /* internal transceiver (unavailable on 17xx, 24xx) */
- if (!cpu_class_is_omap2() && nwires == 2) {
- u32 l;
-
- // omap_cfg_reg(P9_USB_DP);
- // omap_cfg_reg(R8_USB_DM);
-
- if (cpu_is_omap15xx()) {
- /* This works on 1510-Innovator */
- return 0;
- }
-
- /* NOTES:
- * - peripheral should configure VBUS detection!
- * - only peripherals may use the internal D+/D- pulldowns
- * - OTG support on this port not yet written
- */
-
- /* Don't do this for omap7xx -- it causes USB to not work correctly */
- if (!cpu_is_omap7xx()) {
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l &= ~(7 << 4);
- if (!is_device)
- l |= (3 << 1);
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
-
- return 3 << 16;
- }
-
- /* alternate pin config, external transceiver */
- if (cpu_is_omap15xx()) {
- printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
- return 0;
- }
-
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(K18_24XX_USB0_DAT);
- omap_cfg_reg(K19_24XX_USB0_TXEN);
- omap_cfg_reg(J14_24XX_USB0_SE0);
- if (nwires != 3)
- omap_cfg_reg(J18_24XX_USB0_RCV);
- } else {
- omap_cfg_reg(V6_USB0_TXD);
- omap_cfg_reg(W9_USB0_TXEN);
- omap_cfg_reg(W5_USB0_SE0);
- if (nwires != 3)
- omap_cfg_reg(Y5_USB0_RCV);
- }
-
- /* NOTE: SPEED and SUSP aren't configured here. OTG hosts
- * may be able to use I2C requests to set those bits along
- * with VBUS switching and overcurrent detection.
- */
-
- if (cpu_class_is_omap1() && nwires != 6) {
- u32 l;
-
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l &= ~CONF_USB2_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
-
- switch (nwires) {
- case 3:
- syscon1 = 2;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(0, USB_BIDIR);
- break;
- case 4:
- syscon1 = 1;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(0, USB_BIDIR);
- break;
- case 6:
- syscon1 = 3;
- if (cpu_is_omap24xx()) {
- omap_cfg_reg(J19_24XX_USB0_VP);
- omap_cfg_reg(K20_24XX_USB0_VM);
- omap2_usb_devconf_set(0, USB_UNIDIR);
- } else {
- u32 l;
-
- omap_cfg_reg(AA9_USB0_VP);
- omap_cfg_reg(R9_USB0_VM);
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l |= CONF_USB2_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
- break;
- default:
- printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
- 0, nwires);
- }
- return syscon1 << 16;
-}
-
-static u32 __init omap_usb1_init(unsigned nwires)
-{
- u32 syscon1 = 0;
-
- if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) {
- u32 l;
-
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l &= ~CONF_USB1_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
- if (cpu_is_omap24xx())
- omap2_usb_devconf_clear(1, USB_BIDIR_TLL);
-
- if (nwires == 0)
- return 0;
-
- /* external transceiver */
- if (cpu_class_is_omap1()) {
- omap_cfg_reg(USB1_TXD);
- omap_cfg_reg(USB1_TXEN);
- if (nwires != 3)
- omap_cfg_reg(USB1_RCV);
- }
-
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(USB1_SEO);
- omap_cfg_reg(USB1_SPEED);
- // SUSP
- } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
- omap_cfg_reg(W13_1610_USB1_SE0);
- omap_cfg_reg(R13_1610_USB1_SPEED);
- // SUSP
- } else if (cpu_is_omap1710()) {
- omap_cfg_reg(R13_1710_USB1_SE0);
- // SUSP
- } else if (cpu_is_omap24xx()) {
- /* NOTE: board-specific code must set up pin muxing for usb1,
- * since each signal could come out on either of two balls.
- */
- } else {
- pr_debug("usb%d cpu unrecognized\n", 1);
- return 0;
- }
-
- switch (nwires) {
- case 2:
- if (!cpu_is_omap24xx())
- goto bad;
- /* NOTE: board-specific code must override this setting if
- * this TLL link is not using DP/DM
- */
- syscon1 = 1;
- omap2_usb_devconf_set(1, USB_BIDIR_TLL);
- break;
- case 3:
- syscon1 = 2;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(1, USB_BIDIR);
- break;
- case 4:
- syscon1 = 1;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(1, USB_BIDIR);
- break;
- case 6:
- if (cpu_is_omap24xx())
- goto bad;
- syscon1 = 3;
- omap_cfg_reg(USB1_VP);
- omap_cfg_reg(USB1_VM);
- if (!cpu_is_omap15xx()) {
- u32 l;
-
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l |= CONF_USB1_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
- break;
- default:
-bad:
- printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
- 1, nwires);
- }
- return syscon1 << 20;
-}
-
-static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
-{
- u32 syscon1 = 0;
-
- if (cpu_is_omap24xx()) {
- omap2_usb2_disable_5pinbitll();
- alt_pingroup = 0;
- }
-
- /* NOTE omap1 erratum: must leave USB2_UNI_R set if usb0 in use */
- if (alt_pingroup || nwires == 0)
- return 0;
-
- if (cpu_class_is_omap1() && !cpu_is_omap15xx() && nwires != 6) {
- u32 l;
-
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l &= ~CONF_USB2_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
-
- /* external transceiver */
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(USB2_TXD);
- omap_cfg_reg(USB2_TXEN);
- omap_cfg_reg(USB2_SEO);
- if (nwires != 3)
- omap_cfg_reg(USB2_RCV);
- /* there is no USB2_SPEED */
- } else if (cpu_is_omap16xx()) {
- omap_cfg_reg(V6_USB2_TXD);
- omap_cfg_reg(W9_USB2_TXEN);
- omap_cfg_reg(W5_USB2_SE0);
- if (nwires != 3)
- omap_cfg_reg(Y5_USB2_RCV);
- // FIXME omap_cfg_reg(USB2_SPEED);
- } else if (cpu_is_omap24xx()) {
- omap_cfg_reg(Y11_24XX_USB2_DAT);
- omap_cfg_reg(AA10_24XX_USB2_SE0);
- if (nwires > 2)
- omap_cfg_reg(AA12_24XX_USB2_TXEN);
- if (nwires > 3)
- omap_cfg_reg(AA6_24XX_USB2_RCV);
- } else {
- pr_debug("usb%d cpu unrecognized\n", 1);
- return 0;
- }
- // if (cpu_class_is_omap1()) omap_cfg_reg(USB2_SUSP);
-
- switch (nwires) {
- case 2:
- if (!cpu_is_omap24xx())
- goto bad;
- /* NOTE: board-specific code must override this setting if
- * this TLL link is not using DP/DM
- */
- syscon1 = 1;
- omap2_usb_devconf_set(2, USB_BIDIR_TLL);
- break;
- case 3:
- syscon1 = 2;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(2, USB_BIDIR);
- break;
- case 4:
- syscon1 = 1;
- if (cpu_is_omap24xx())
- omap2_usb_devconf_set(2, USB_BIDIR);
- break;
- case 5:
- if (!cpu_is_omap24xx())
- goto bad;
- omap_cfg_reg(AA4_24XX_USB2_TLLSE0);
- /* NOTE: board-specific code must override this setting if
- * this TLL link is not using DP/DM. Something must also
- * set up OTG_SYSCON2.HMC_TLL{ATTACH,SPEED}
- */
- syscon1 = 3;
- omap2_usb2_enable_5pinunitll();
- break;
- case 6:
- if (cpu_is_omap24xx())
- goto bad;
- syscon1 = 3;
- if (cpu_is_omap15xx()) {
- omap_cfg_reg(USB2_VP);
- omap_cfg_reg(USB2_VM);
- } else {
- u32 l;
-
- omap_cfg_reg(AA9_USB2_VP);
- omap_cfg_reg(R9_USB2_VM);
- l = omap_readl(USB_TRANSCEIVER_CTRL);
- l |= CONF_USB2_UNI_R;
- omap_writel(l, USB_TRANSCEIVER_CTRL);
- }
- break;
- default:
-bad:
- printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
- 2, nwires);
- }
- return syscon1 << 24;
-}
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_USB_GADGET_OMAP
-
-static struct resource udc_resources[] = {
- /* order is significant! */
- { /* registers */
- .start = UDC_BASE,
- .end = UDC_BASE + 0xff,
- .flags = IORESOURCE_MEM,
- }, { /* general IRQ */
- .start = INT_USB_IRQ_GEN,
- .flags = IORESOURCE_IRQ,
- }, { /* PIO IRQ */
- .start = INT_USB_IRQ_NISO,
- .flags = IORESOURCE_IRQ,
- }, { /* SOF IRQ */
- .start = INT_USB_IRQ_ISO,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static u64 udc_dmamask = ~(u32)0;
-
-static struct platform_device udc_device = {
- .name = "omap_udc",
- .id = -1,
- .dev = {
- .dma_mask = &udc_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(udc_resources),
- .resource = udc_resources,
-};
-
-#endif
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-
-/* The dmamask must be set for OHCI to work */
-static u64 ohci_dmamask = ~(u32)0;
-
-static struct resource ohci_resources[] = {
- {
- .start = OMAP_OHCI_BASE,
- .end = OMAP_OHCI_BASE + 0xff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = INT_USB_IRQ_HGEN,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ohci_device = {
- .name = "ohci",
- .id = -1,
- .dev = {
- .dma_mask = &ohci_dmamask,
- .coherent_dma_mask = 0xffffffff,
- },
- .num_resources = ARRAY_SIZE(ohci_resources),
- .resource = ohci_resources,
-};
-
-#endif
-
-#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
-
-static struct resource otg_resources[] = {
- /* order is significant! */
- {
- .start = OTG_BASE,
- .end = OTG_BASE + 0xff,
- .flags = IORESOURCE_MEM,
- }, {
- .start = INT_USB_IRQ_OTG,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device otg_device = {
- .name = "omap_otg",
- .id = -1,
- .num_resources = ARRAY_SIZE(otg_resources),
- .resource = otg_resources,
-};
-
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-// FIXME correct answer depends on hmc_mode,
-// as does (on omap1) any nonzero value for config->otg port number
-#ifdef CONFIG_USB_GADGET_OMAP
-#define is_usb0_device(config) 1
-#else
-#define is_usb0_device(config) 0
-#endif
-
-/*-------------------------------------------------------------------------*/
-
#ifdef CONFIG_ARCH_OMAP_OTG
void __init
@@ -560,9 +49,9 @@ omap_otg_init(struct omap_usb_config *config)
/* pin muxing and transceiver pinouts */
if (config->pins[0] > 2) /* alt pingroup 2 */
alt_pingroup = 1;
- syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
- syscon |= omap_usb1_init(config->pins[1]);
- syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
+ syscon |= config->usb0_init(config->pins[0], is_usb0_device(config));
+ syscon |= config->usb1_init(config->pins[1]);
+ syscon |= config->usb2_init(config->pins[2], alt_pingroup);
pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1));
omap_writel(syscon, OTG_SYSCON_1);
@@ -610,15 +99,11 @@ omap_otg_init(struct omap_usb_config *config)
#ifdef CONFIG_USB_GADGET_OMAP
if (config->otg || config->register_dev) {
+ struct platform_device *udc_device = config->udc_device;
+
syscon &= ~DEV_IDLE_EN;
- udc_device.dev.platform_data = config;
- /* IRQ numbers for omap7xx */
- if(cpu_is_omap7xx()) {
- udc_resources[1].start = INT_7XX_USB_GENI;
- udc_resources[2].start = INT_7XX_USB_NON_ISO;
- udc_resources[3].start = INT_7XX_USB_ISO;
- }
- status = platform_device_register(&udc_device);
+ udc_device->dev.platform_data = config;
+ status = platform_device_register(udc_device);
if (status)
pr_debug("can't register UDC device, %d\n", status);
}
@@ -626,11 +111,11 @@ omap_otg_init(struct omap_usb_config *config)
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
if (config->otg || config->register_host) {
+ struct platform_device *ohci_device = config->ohci_device;
+
syscon &= ~HST_IDLE_EN;
- ohci_device.dev.platform_data = config;
- if (cpu_is_omap7xx())
- ohci_resources[1].start = INT_7XX_USB_HHC_1;
- status = platform_device_register(&ohci_device);
+ ohci_device->dev.platform_data = config;
+ status = platform_device_register(ohci_device);
if (status)
pr_debug("can't register OHCI device, %d\n", status);
}
@@ -638,11 +123,11 @@ omap_otg_init(struct omap_usb_config *config)
#ifdef CONFIG_USB_OTG
if (config->otg) {
+ struct platform_device *otg_device = config->otg_device;
+
syscon &= ~OTG_IDLE_EN;
- otg_device.dev.platform_data = config;
- if (cpu_is_omap7xx())
- otg_resources[1].start = INT_7XX_USB_OTG;
- status = platform_device_register(&otg_device);
+ otg_device->dev.platform_data = config;
+ status = platform_device_register(otg_device);
if (status)
pr_debug("can't register OTG device, %d\n", status);
}
@@ -654,102 +139,5 @@ omap_otg_init(struct omap_usb_config *config)
}
#else
-static inline void omap_otg_init(struct omap_usb_config *config) {}
-#endif
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_ARCH_OMAP15XX
-
-/* ULPD_DPLL_CTRL */
-#define DPLL_IOB (1 << 13)
-#define DPLL_PLL_ENABLE (1 << 4)
-#define DPLL_LOCK (1 << 0)
-
-/* ULPD_APLL_CTRL */
-#define APLL_NDPLL_SWITCH (1 << 0)
-
-
-static void __init omap_1510_usb_init(struct omap_usb_config *config)
-{
- unsigned int val;
- u16 w;
-
- omap_usb0_init(config->pins[0], is_usb0_device(config));
- omap_usb1_init(config->pins[1]);
- omap_usb2_init(config->pins[2], 0);
-
- val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
- val |= (config->hmc_mode << 1);
- omap_writel(val, MOD_CONF_CTRL_0);
-
- printk("USB: hmc %d", config->hmc_mode);
- if (config->pins[0])
- printk(", usb0 %d wires%s", config->pins[0],
- is_usb0_device(config) ? " (dev)" : "");
- if (config->pins[1])
- printk(", usb1 %d wires", config->pins[1]);
- if (config->pins[2])
- printk(", usb2 %d wires", config->pins[2]);
- printk("\n");
-
- /* use DPLL for 48 MHz function clock */
- pr_debug("APLL %04x DPLL %04x REQ %04x\n", omap_readw(ULPD_APLL_CTRL),
- omap_readw(ULPD_DPLL_CTRL), omap_readw(ULPD_SOFT_REQ));
-
- w = omap_readw(ULPD_APLL_CTRL);
- w &= ~APLL_NDPLL_SWITCH;
- omap_writew(w, ULPD_APLL_CTRL);
-
- w = omap_readw(ULPD_DPLL_CTRL);
- w |= DPLL_IOB | DPLL_PLL_ENABLE;
- omap_writew(w, ULPD_DPLL_CTRL);
-
- w = omap_readw(ULPD_SOFT_REQ);
- w |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
- omap_writew(w, ULPD_SOFT_REQ);
-
- while (!(omap_readw(ULPD_DPLL_CTRL) & DPLL_LOCK))
- cpu_relax();
-
-#ifdef CONFIG_USB_GADGET_OMAP
- if (config->register_dev) {
- int status;
-
- udc_device.dev.platform_data = config;
- status = platform_device_register(&udc_device);
- if (status)
- pr_debug("can't register UDC device, %d\n", status);
- /* udc driver gates 48MHz by D+ pullup */
- }
-#endif
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
- if (config->register_host) {
- int status;
-
- ohci_device.dev.platform_data = config;
- status = platform_device_register(&ohci_device);
- if (status)
- pr_debug("can't register OHCI device, %d\n", status);
- /* hcd explicitly gates 48MHz */
- }
-#endif
-}
-
-#else
-static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
+void omap_otg_init(struct omap_usb_config *config) {}
#endif
-
-/*-------------------------------------------------------------------------*/
-
-void __init omap_usb_init(struct omap_usb_config *pdata)
-{
- if (cpu_is_omap7xx() || cpu_is_omap16xx() || cpu_is_omap24xx())
- omap_otg_init(pdata);
- else if (cpu_is_omap15xx())
- omap_1510_usb_init(pdata);
- else
- printk(KERN_ERR "USB: No init for your chip yet\n");
-}
-
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 2753fb3e4f73..15ef1e4026cf 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -160,6 +160,11 @@ config S3C_DEV_HSMMC2
help
Compile in platform device definitions for HSMMC channel 2
+config S3C_DEV_HSMMC3
+ bool
+ help
+ Compile in platform device definitions for HSMMC channel 3
+
config S3C_DEV_HWMON
bool
help
@@ -216,6 +221,11 @@ config SAMSUNG_DEV_ADC
help
Compile in platform device definition for ADC controller
+config SAMSUNG_DEV_IDE
+ bool
+ help
+ Compile in platform device definitions for IDE
+
config S3C64XX_DEV_SPI
bool
help
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index b1d82cc5e716..75b91b43db49 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -30,9 +30,12 @@ obj-$(CONFIG_S3C_ADC) += adc.o
# devices
+obj-y += platformdata.o
+
obj-$(CONFIG_S3C_DEV_HSMMC) += dev-hsmmc.o
obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o
obj-$(CONFIG_S3C_DEV_HSMMC2) += dev-hsmmc2.o
+obj-$(CONFIG_S3C_DEV_HSMMC3) += dev-hsmmc3.o
obj-$(CONFIG_S3C_DEV_HWMON) += dev-hwmon.o
obj-y += dev-i2c0.o
obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o
@@ -47,6 +50,7 @@ obj-$(CONFIG_S3C_DEV_ONENAND) += dev-onenand.o
obj-$(CONFIG_S3C_DEV_RTC) += dev-rtc.o
obj-$(CONFIG_SAMSUNG_DEV_ADC) += dev-adc.o
+obj-$(CONFIG_SAMSUNG_DEV_IDE) += dev-ide.o
obj-$(CONFIG_SAMSUNG_DEV_TS) += dev-ts.o
# DMA support
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
new file mode 100644
index 000000000000..57bd394123cd
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -0,0 +1,72 @@
+/* linux/arch/arm/plat-samsung/dev-hsmmc3.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Copyright (c) 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Based on arch/arm/plat-samsung/dev-hsmmc1.c
+ *
+ * Samsung device definition for hsmmc device 3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mmc/host.h>
+
+#include <mach/map.h>
+#include <plat/sdhci.h>
+#include <plat/devs.h>
+
+#define S3C_SZ_HSMMC (0x1000)
+
+static struct resource s3c_hsmmc3_resource[] = {
+ [0] = {
+ .start = S3C_PA_HSMMC3,
+ .end = S3C_PA_HSMMC3 + S3C_SZ_HSMMC - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_MMC3,
+ .end = IRQ_MMC3,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 s3c_device_hsmmc3_dmamask = 0xffffffffUL;
+
+struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata = {
+ .max_width = 4,
+ .host_caps = (MMC_CAP_4_BIT_DATA |
+ MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED),
+};
+
+struct platform_device s3c_device_hsmmc3 = {
+ .name = "s3c-sdhci",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(s3c_hsmmc3_resource),
+ .resource = s3c_hsmmc3_resource,
+ .dev = {
+ .dma_mask = &s3c_device_hsmmc3_dmamask,
+ .coherent_dma_mask = 0xffffffffUL,
+ .platform_data = &s3c_hsmmc3_def_platdata,
+ },
+};
+
+void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
+{
+ struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
+
+ set->max_width = pd->max_width;
+
+ if (pd->cfg_gpio)
+ set->cfg_gpio = pd->cfg_gpio;
+ if (pd->cfg_card)
+ set->cfg_card = pd->cfg_card;
+}
diff --git a/arch/arm/plat-samsung/dev-ide.c b/arch/arm/plat-samsung/dev-ide.c
new file mode 100644
index 000000000000..b497982795a7
--- /dev/null
+++ b/arch/arm/plat-samsung/dev-ide.c
@@ -0,0 +1,44 @@
+/* linux/arch/arm/plat-samsung/dev-ide.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA device definition.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <mach/map.h>
+#include <plat/ata.h>
+#include <plat/devs.h>
+
+static struct resource s3c_cfcon_resource[] = {
+ [0] = {
+ .start = SAMSUNG_PA_CFCON,
+ .end = SAMSUNG_PA_CFCON + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_CFCON,
+ .end = IRQ_CFCON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device s3c_device_cfcon = {
+ .id = 0,
+ .num_resources = ARRAY_SIZE(s3c_cfcon_resource),
+ .resource = s3c_cfcon_resource,
+};
+
+void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata)
+{
+ s3c_set_platdata(pdata, sizeof(struct s3c_ide_platdata),
+ &s3c_device_cfcon);
+}
diff --git a/arch/arm/plat-samsung/dev-wdt.c b/arch/arm/plat-samsung/dev-wdt.c
index 5efca87cddbd..019b5b8cf14c 100644
--- a/arch/arm/plat-samsung/dev-wdt.c
+++ b/arch/arm/plat-samsung/dev-wdt.c
@@ -21,7 +21,7 @@
static struct resource s3c_wdt_resource[] = {
[0] = {
.start = S3C_PA_WDT,
- .end = S3C_PA_WDT + SZ_1M - 1,
+ .end = S3C_PA_WDT + SZ_1K,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/plat-samsung/include/plat/adc-core.h b/arch/arm/plat-samsung/include/plat/adc-core.h
new file mode 100644
index 000000000000..a281568d5856
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/adc-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/adc-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * Samsung ADC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ADC_CORE_H
+#define __ASM_PLAT_ADC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_adc_setname(char *name)
+{
+#ifdef CONFIG_SAMSUNG_DEV_ADC
+ s3c_device_adc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_ADC_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata-core.h b/arch/arm/plat-samsung/include/plat/ata-core.h
new file mode 100644
index 000000000000..f5a4ec7141b1
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata-core.h
@@ -0,0 +1,28 @@
+/* linux/arch/arm/plat-samsung/include/plat/ata-core.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ATA_CORE_H
+#define __ASM_PLAT_ATA_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+*/
+
+/* re-define device name depending on support. */
+static inline void s3c_cfcon_setname(char *name)
+{
+#ifdef CONFIG_SAMSUNG_DEV_IDE
+ s3c_device_cfcon.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_ATA_CORE_H */
diff --git a/arch/arm/plat-samsung/include/plat/ata.h b/arch/arm/plat-samsung/include/plat/ata.h
new file mode 100644
index 000000000000..2a3855a8372a
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/ata.h
@@ -0,0 +1,36 @@
+/* linux/arch/arm/plat-samsung/include/plat/ata.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA platform_device info
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_ATA_H
+#define __ASM_PLAT_ATA_H __FILE__
+
+/**
+ * struct s3c_ide_platdata - S3C IDE driver platform data.
+ * @setup_gpio: Setup the external GPIO pins to the right state for data
+ * transfer in true-ide mode.
+ */
+struct s3c_ide_platdata {
+ void (*setup_gpio)(void);
+};
+
+/*
+ * s3c_ide_set_platdata() - Setup the platform specifc data for IDE driver.
+ * @pdata: Platform data for IDE driver.
+ */
+extern void s3c_ide_set_platdata(struct s3c_ide_platdata *pdata);
+
+/* architecture-specific IDE configuration */
+extern void s3c64xx_ide_setup_gpio(void);
+extern void s5pc100_ide_setup_gpio(void);
+extern void s5pv210_ide_setup_gpio(void);
+
+#endif /*__ASM_PLAT_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h
index e6144e4b9118..097d0e458ab9 100644
--- a/arch/arm/plat-samsung/include/plat/devs.h
+++ b/arch/arm/plat-samsung/include/plat/devs.h
@@ -54,6 +54,8 @@ extern struct platform_device s3c_device_hwmon;
extern struct platform_device s3c_device_hsmmc0;
extern struct platform_device s3c_device_hsmmc1;
extern struct platform_device s3c_device_hsmmc2;
+extern struct platform_device s3c_device_hsmmc3;
+extern struct platform_device s3c_device_cfcon;
extern struct platform_device s3c_device_spi0;
extern struct platform_device s3c_device_spi1;
@@ -108,3 +110,15 @@ extern struct platform_device s3c_device_camif;
extern struct platform_device s3c_device_ac97;
#endif
+
+/**
+ * s3c_set_platdata() - helper for setting platform data
+ * @pd: The default platform data for this device.
+ * @pdsize: The size of the platform data.
+ * @pdev: Pointer to the device to fill in.
+ *
+ * This helper replaces a number of calls that copy and then set the
+ * platform data of the device.
+ */
+extern void *s3c_set_platdata(void *pd, size_t pdsize,
+ struct platform_device *pdev);
diff --git a/arch/arm/plat-samsung/include/plat/regs-ata.h b/arch/arm/plat-samsung/include/plat/regs-ata.h
new file mode 100644
index 000000000000..f5df92fdae26
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/regs-ata.h
@@ -0,0 +1,56 @@
+/* linux/arch/arm/plat-samsung/include/plat/regs-ata.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung CF-ATA register definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_REGS_ATA_H
+#define __ASM_PLAT_REGS_ATA_H __FILE__
+
+#define S3C_CFATA_REG(x) (x)
+
+#define S3C_CFATA_MUX S3C_CFATA_REG(0x0)
+
+#define S3C_ATA_CTRL S3C_CFATA_REG(0x0)
+#define S3C_ATA_STATUS S3C_CFATA_REG(0x4)
+#define S3C_ATA_CMD S3C_CFATA_REG(0x8)
+#define S3C_ATA_SWRST S3C_CFATA_REG(0xc)
+#define S3C_ATA_IRQ S3C_CFATA_REG(0x10)
+#define S3C_ATA_IRQ_MSK S3C_CFATA_REG(0x14)
+#define S3C_ATA_CFG S3C_CFATA_REG(0x18)
+
+#define S3C_ATA_MDMA_TIME S3C_CFATA_REG(0x28)
+#define S3C_ATA_PIO_TIME S3C_CFATA_REG(0x2c)
+#define S3C_ATA_UDMA_TIME S3C_CFATA_REG(0x30)
+#define S3C_ATA_XFR_NUM S3C_CFATA_REG(0x34)
+#define S3C_ATA_XFR_CNT S3C_CFATA_REG(0x38)
+#define S3C_ATA_TBUF_START S3C_CFATA_REG(0x3c)
+#define S3C_ATA_TBUF_SIZE S3C_CFATA_REG(0x40)
+#define S3C_ATA_SBUF_START S3C_CFATA_REG(0x44)
+#define S3C_ATA_SBUF_SIZE S3C_CFATA_REG(0x48)
+#define S3C_ATA_CADR_TBUF S3C_CFATA_REG(0x4c)
+#define S3C_ATA_CADR_SBUF S3C_CFATA_REG(0x50)
+#define S3C_ATA_PIO_DTR S3C_CFATA_REG(0x54)
+#define S3C_ATA_PIO_FED S3C_CFATA_REG(0x58)
+#define S3C_ATA_PIO_SCR S3C_CFATA_REG(0x5c)
+#define S3C_ATA_PIO_LLR S3C_CFATA_REG(0x60)
+#define S3C_ATA_PIO_LMR S3C_CFATA_REG(0x64)
+#define S3C_ATA_PIO_LHR S3C_CFATA_REG(0x68)
+#define S3C_ATA_PIO_DVR S3C_CFATA_REG(0x6c)
+#define S3C_ATA_PIO_CSD S3C_CFATA_REG(0x70)
+#define S3C_ATA_PIO_DAD S3C_CFATA_REG(0x74)
+#define S3C_ATA_PIO_READY S3C_CFATA_REG(0x78)
+#define S3C_ATA_PIO_RDATA S3C_CFATA_REG(0x7c)
+
+#define S3C_CFATA_MUX_TRUEIDE 0x01
+
+#define S3C_ATA_CFG_SWAP 0x40
+#define S3C_ATA_CFG_IORDYEN 0x02
+
+#endif /* __ASM_PLAT_REGS_ATA_H */
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 016674fa20dd..c52c6f0d8eb2 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -58,6 +58,7 @@ struct s3c_sdhci_platdata {
extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
+extern void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd);
/* Default platform data, exported so that per-cpu initialisation can
* set the correct one when there are more than one cpu type selected.
@@ -66,6 +67,7 @@ extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
+extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata;
/* Helper function availablity */
@@ -78,6 +80,7 @@ extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
+extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
/* S3C6400 SDHCI setup */
@@ -266,10 +269,22 @@ static inline void s5pv210_default_sdhci2(void)
static inline void s5pv210_default_sdhci2(void) { }
#endif /* CONFIG_S3C_DEV_HSMMC2 */
+#ifdef CONFIG_S3C_DEV_HSMMC3
+static inline void s5pv210_default_sdhci3(void)
+{
+ s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
+ s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
+ s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
+}
+#else
+static inline void s5pv210_default_sdhci3(void) { }
+#endif /* CONFIG_S3C_DEV_HSMMC3 */
+
#else
static inline void s5pv210_default_sdhci0(void) { }
static inline void s5pv210_default_sdhci1(void) { }
static inline void s5pv210_default_sdhci2(void) { }
+static inline void s5pv210_default_sdhci3(void) { }
#endif /* CONFIG_S5PC100_SETUP_SDHCI */
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
new file mode 100644
index 000000000000..7cf2e1e3b20f
--- /dev/null
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -0,0 +1,37 @@
+/* linux/arch/arm/plat-samsung/platformdata.c
+ *
+ * Copyright 2010 Ben Dooks <ben-linux <at> fluff.org>
+ *
+ * Helper for platform data setting
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+
+#include <plat/devs.h>
+
+void __init *s3c_set_platdata(void *pd, size_t pdsize,
+ struct platform_device *pdev)
+{
+ void *npd;
+
+ if (!pd) {
+ /* too early to use dev_name(), may not be registered */
+ printk(KERN_ERR "%s: no platform data supplied\n", pdev->name);
+ return NULL;
+ }
+
+ npd = kmemdup(pd, pdsize, GFP_KERNEL);
+ if (!npd) {
+ printk(KERN_ERR "%s: cannot clone platform data\n", pdev->name);
+ return NULL;
+ }
+
+ pdev->dev.platform_data = npd;
+ return npd;
+}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 8f10d24ae625..48cbdcb6bbd4 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Sat May 1 10:36:42 2010
+# Last update: Mon Jul 12 21:10:14 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -1994,7 +1994,7 @@ spark MACH_SPARK SPARK 2002
benzina MACH_BENZINA BENZINA 2003
blaze MACH_BLAZE BLAZE 2004
linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005
-htckovsky MACH_HTCVENUS HTCVENUS 2006
+htckovsky MACH_HTCKOVSKY HTCKOVSKY 2006
sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007
hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008
sapphira MACH_SAPPHIRA SAPPHIRA 2009
@@ -2609,7 +2609,7 @@ fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
lexikon MACH_LEXIKON LEXIKON 2622
mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
icontrol MACH_ICONTROL ICONTROL 2624
-sheevad MACH_SHEEVAD SHEEVAD 2625
+gplugd MACH_SHEEVAD SHEEVAD 2625
qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626
qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
bee MACH_BEE BEE 2628
@@ -2804,3 +2804,149 @@ teton_bga MACH_TETON_BGA TETON_BGA 2816
snapper9g45 MACH_SNAPPER9G45 SNAPPER9G45 2817
tam3517 MACH_TAM3517 TAM3517 2818
pdc100 MACH_PDC100 PDC100 2819
+eukrea_cpuimx25sd MACH_EUKREA_CPUIMX25 EUKREA_CPUIMX25 2820
+eukrea_cpuimx35sd MACH_EUKREA_CPUIMX35 EUKREA_CPUIMX35 2821
+eukrea_cpuimx51sd MACH_EUKREA_CPUIMX51SD EUKREA_CPUIMX51SD 2822
+eukrea_cpuimx51 MACH_EUKREA_CPUIMX51 EUKREA_CPUIMX51 2823
+p565 MACH_P565 P565 2824
+acer_a4 MACH_ACER_A4 ACER_A4 2825
+davinci_dm368_bip MACH_DAVINCI_DM368_BIP DAVINCI_DM368_BIP 2826
+eshare MACH_ESHARE ESHARE 2827
+hw_omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
+wlbargn MACH_WLBARGN WLBARGN 2829
+bm170 MACH_BM170 BM170 2830
+netspace_mini_v2 MACH_NETSPACE_MINI_V2 NETSPACE_MINI_V2 2831
+netspace_plug_v2 MACH_NETSPACE_PLUG_V2 NETSPACE_PLUG_V2 2832
+siemens_l1 MACH_SIEMENS_L1 SIEMENS_L1 2833
+elv_lcu1 MACH_ELV_LCU1 ELV_LCU1 2834
+mcu1 MACH_MCU1 MCU1 2835
+omap3_tao3530 MACH_OMAP3_TAO3530 OMAP3_TAO3530 2836
+omap3_pcutouch MACH_OMAP3_PCUTOUCH OMAP3_PCUTOUCH 2837
+smdkc210 MACH_SMDKC210 SMDKC210 2838
+omap3_braillo MACH_OMAP3_BRAILLO OMAP3_BRAILLO 2839
+spyplug MACH_SPYPLUG SPYPLUG 2840
+ginger MACH_GINGER GINGER 2841
+tny_t3530 MACH_TNY_T3530 TNY_T3530 2842
+pca102 MACH_PCA102 PCA102 2843
+spade MACH_SPADE SPADE 2844
+mxc25_topaz MACH_MXC25_TOPAZ MXC25_TOPAZ 2845
+t5325 MACH_T5325 T5325 2846
+gw2361 MACH_GW2361 GW2361 2847
+elog MACH_ELOG ELOG 2848
+income MACH_INCOME INCOME 2849
+bcm589x MACH_BCM589X BCM589X 2850
+etna MACH_ETNA ETNA 2851
+hawks MACH_HAWKS HAWKS 2852
+meson MACH_MESON MESON 2853
+xsbase255 MACH_XSBASE255 XSBASE255 2854
+pvm2030 MACH_PVM2030 PVM2030 2855
+mioa502 MACH_MIOA502 MIOA502 2856
+vvbox_sdorig2 MACH_VVBOX_SDORIG2 VVBOX_SDORIG2 2857
+vvbox_sdlite2 MACH_VVBOX_SDLITE2 VVBOX_SDLITE2 2858
+vvbox_sdpro4 MACH_VVBOX_SDPRO4 VVBOX_SDPRO4 2859
+htc_spv_m700 MACH_HTC_SPV_M700 HTC_SPV_M700 2860
+mx257sx MACH_MX257SX MX257SX 2861
+goni MACH_GONI GONI 2862
+msm8x55_svlte_ffa MACH_MSM8X55_SVLTE_FFA MSM8X55_SVLTE_FFA 2863
+msm8x55_svlte_surf MACH_MSM8X55_SVLTE_SURF MSM8X55_SVLTE_SURF 2864
+quickstep MACH_QUICKSTEP QUICKSTEP 2865
+dmw96 MACH_DMW96 DMW96 2866
+hammerhead MACH_HAMMERHEAD HAMMERHEAD 2867
+trident MACH_TRIDENT TRIDENT 2868
+lightning MACH_LIGHTNING LIGHTNING 2869
+iconnect MACH_ICONNECT ICONNECT 2870
+autobot MACH_AUTOBOT AUTOBOT 2871
+coconut MACH_COCONUT COCONUT 2872
+durian MACH_DURIAN DURIAN 2873
+cayenne MACH_CAYENNE CAYENNE 2874
+fuji MACH_FUJI FUJI 2875
+synology_6282 MACH_SYNOLOGY_6282 SYNOLOGY_6282 2876
+em1sy MACH_EM1SY EM1SY 2877
+m502 MACH_M502 M502 2878
+matrix518 MACH_MATRIX518 MATRIX518 2879
+tiny_gurnard MACH_TINY_GURNARD TINY_GURNARD 2880
+spear1310 MACH_SPEAR1310 SPEAR1310 2881
+bv07 MACH_BV07 BV07 2882
+mxt_td61 MACH_MXT_TD61 MXT_TD61 2883
+openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
+devixp MACH_DEVIXP DEVIXP 2885
+miccpt MACH_MICCPT MICCPT 2886
+mic256 MACH_MIC256 MIC256 2887
+as1167 MACH_AS1167 AS1167 2888
+omap3_ibiza MACH_OMAP3_IBIZA OMAP3_IBIZA 2889
+u5500 MACH_U5500 U5500 2890
+davinci_picto MACH_DAVINCI_PICTO DAVINCI_PICTO 2891
+mecha MACH_MECHA MECHA 2892
+bubba3 MACH_BUBBA3 BUBBA3 2893
+pupitre MACH_PUPITRE PUPITRE 2894
+tegra_harmony MACH_TEGRA_HARMONY TEGRA_HARMONY 2895
+tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896
+tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897
+simplenet MACH_SIMPLENET SIMPLENET 2898
+ec4350tbm MACH_EC4350TBM EC4350TBM 2899
+pec_tc MACH_PEC_TC PEC_TC 2900
+pec_hc2 MACH_PEC_HC2 PEC_HC2 2901
+esl_mobilis_a MACH_ESL_MOBILIS_A ESL_MOBILIS_A 2902
+esl_mobilis_b MACH_ESL_MOBILIS_B ESL_MOBILIS_B 2903
+esl_wave_a MACH_ESL_WAVE_A ESL_WAVE_A 2904
+esl_wave_b MACH_ESL_WAVE_B ESL_WAVE_B 2905
+unisense_mmm MACH_UNISENSE_MMM UNISENSE_MMM 2906
+blueshark MACH_BLUESHARK BLUESHARK 2907
+e10 MACH_E10 E10 2908
+app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909
+pov15hd MACH_POV15HD POV15HD 2910
+stella MACH_STELLA STELLA 2911
+linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
+netwalker MACH_NETWALKER NETWALKER 2914
+acsx106 MACH_ACSX106 ACSX106 2915
+atlas5_c1 MACH_ATLAS5_C1 ATLAS5_C1 2916
+nsb3ast MACH_NSB3AST NSB3AST 2917
+gnet_slc MACH_GNET_SLC GNET_SLC 2918
+af4000 MACH_AF4000 AF4000 2919
+ark9431 MACH_ARK9431 ARK9431 2920
+fs_s5pc100 MACH_FS_S5PC100 FS_S5PC100 2921
+omap3505nova8 MACH_OMAP3505NOVA8 OMAP3505NOVA8 2922
+omap3621_edp1 MACH_OMAP3621_EDP1 OMAP3621_EDP1 2923
+oratisaes MACH_ORATISAES ORATISAES 2924
+smdkv310 MACH_SMDKV310 SMDKV310 2925
+siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926
+ventana MACH_VENTANA VENTANA 2927
+wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
+ec4350sdb MACH_EC4350SDB EC4350SDB 2929
+mimas MACH_MIMAS MIMAS 2930
+titan MACH_TITAN TITAN 2931
+craneboard MACH_CRANEBOARD CRANEBOARD 2932
+es2440 MACH_ES2440 ES2440 2933
+najay_a9263 MACH_NAJAY_A9263 NAJAY_A9263 2934
+htctornado MACH_HTCTORNADO HTCTORNADO 2935
+dimm_mx257 MACH_DIMM_MX257 DIMM_MX257 2936
+jigen301 MACH_JIGEN JIGEN 2937
+smdk6450 MACH_SMDK6450 SMDK6450 2938
+meno_qng MACH_MENO_QNG MENO_QNG 2939
+ns2416 MACH_NS2416 NS2416 2940
+rpc353 MACH_RPC353 RPC353 2941
+tq6410 MACH_TQ6410 TQ6410 2942
+sky6410 MACH_SKY6410 SKY6410 2943
+dynasty MACH_DYNASTY DYNASTY 2944
+vivo MACH_VIVO VIVO 2945
+bury_bl7582 MACH_BURY_BL7582 BURY_BL7582 2946
+bury_bps5270 MACH_BURY_BPS5270 BURY_BPS5270 2947
+basi MACH_BASI BASI 2948
+tn200 MACH_TN200 TN200 2949
+c2mmi MACH_C2MMI C2MMI 2950
+meson_6236m MACH_MESON_6236M MESON_6236M 2951
+meson_8626m MACH_MESON_8626M MESON_8626M 2952
+tube MACH_TUBE TUBE 2953
+messina MACH_MESSINA MESSINA 2954
+mx50_arm2 MACH_MX50_ARM2 MX50_ARM2 2955
+cetus9263 MACH_CETUS9263 CETUS9263 2956
+brownstone MACH_BROWNSTONE BROWNSTONE 2957
+vmx25 MACH_VMX25 VMX25 2958
+vmx51 MACH_VMX51 VMX51 2959
+abacus MACH_ABACUS ABACUS 2960
+cm4745 MACH_CM4745 CM4745 2961
+oratislink MACH_ORATISLINK ORATISLINK 2962
+davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963
+netviz MACH_NETVIZ NETVIZ 2964
+flexibity MACH_FLEXIBITY FLEXIBITY 2965
+wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 315a540c7ce5..8063a322c790 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -15,6 +15,7 @@
#include <linux/sched.h>
#include <linux/init.h>
+#include <asm/cputype.h>
#include <asm/thread_notify.h>
#include <asm/vfp.h>
@@ -549,10 +550,13 @@ static int __init vfp_init(void)
/*
* Check for the presence of the Advanced SIMD
* load/store instructions, integer and single
- * precision floating point operations.
+ * precision floating point operations. Only check
+ * for NEON if the hardware has the MVFR registers.
*/
- if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
- elf_hwcap |= HWCAP_NEON;
+ if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+ if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+ elf_hwcap |= HWCAP_NEON;
+ }
#endif
}
return 0;
diff --git a/arch/avr32/include/asm/ioctls.h b/arch/avr32/include/asm/ioctls.h
index 0cf2c0a4502b..e6ac0b661076 100644
--- a/arch/avr32/include/asm/ioctls.h
+++ b/arch/avr32/include/asm/ioctls.h
@@ -54,6 +54,9 @@
#define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */
#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */
+#define TIOCGRS485 0x542E
+#define TIOCSRS485 0x542F
+
#define FIONCLEX 0x5450
#define FIOCLEX 0x5451
#define FIOASYNC 0x5452
diff --git a/arch/avr32/mach-at32ap/include/mach/board.h b/arch/avr32/mach-at32ap/include/mach/board.h
index c7f25bb1d068..61740201b311 100644
--- a/arch/avr32/mach-at32ap/include/mach/board.h
+++ b/arch/avr32/mach-at32ap/include/mach/board.h
@@ -5,6 +5,7 @@
#define __ASM_ARCH_BOARD_H
#include <linux/types.h>
+#include <linux/serial.h>
#define GPIO_PIN_NONE (-1)
@@ -35,6 +36,7 @@ struct atmel_uart_data {
short use_dma_tx; /* use transmit DMA? */
short use_dma_rx; /* use receive DMA? */
void __iomem *regs; /* virtual base address, if any */
+ struct serial_rs485 rs485; /* rs485 settings */
};
void at32_map_usart(unsigned int hw_id, unsigned int line, int flags);
struct platform_device *at32_add_device_usart(unsigned int id);
diff --git a/arch/blackfin/include/asm/elf.h b/arch/blackfin/include/asm/elf.h
index 117713adea7f..e6c6812a9abd 100644
--- a/arch/blackfin/include/asm/elf.h
+++ b/arch/blackfin/include/asm/elf.h
@@ -119,6 +119,7 @@ do { \
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
memcpy((char *) &pr_reg, (char *)regs, \
sizeof(struct pt_regs));
+#define ELF_CORE_COPY_FPREGS(...) 0 /* Blackfin has no FPU */
/* This yields a mask that user programs can use to figure out what
instruction set this cpu supports. */
diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
index 8b18b5359210..620834097632 100644
--- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
+++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h
@@ -1738,85 +1738,4 @@
#define nAFEXIT 0x0
#define SECSTAT 0xe0 /* Secure Status */
-/* Bit masks for NFC_CTL */
-
-#define WR_DLY 0xf /* Write Strobe Delay */
-#define RD_DLY 0xf0 /* Read Strobe Delay */
-#define NWIDTH 0x100 /* NAND Data Width */
-#define nNWIDTH 0x0
-#define PG_SIZE 0x200 /* Page Size */
-#define nPG_SIZE 0x0
-
-/* Bit masks for NFC_STAT */
-
-#define NBUSY 0x1 /* Not Busy */
-#define nNBUSY 0x0
-#define WB_FULL 0x2 /* Write Buffer Full */
-#define nWB_FULL 0x0
-#define PG_WR_STAT 0x4 /* Page Write Pending */
-#define nPG_WR_STAT 0x0
-#define PG_RD_STAT 0x8 /* Page Read Pending */
-#define nPG_RD_STAT 0x0
-#define WB_EMPTY 0x10 /* Write Buffer Empty */
-#define nWB_EMPTY 0x0
-
-/* Bit masks for NFC_IRQSTAT */
-
-#define NBUSYIRQ 0x1 /* Not Busy IRQ */
-#define nNBUSYIRQ 0x0
-#define WB_OVF 0x2 /* Write Buffer Overflow */
-#define nWB_OVF 0x0
-#define WB_EDGE 0x4 /* Write Buffer Edge Detect */
-#define nWB_EDGE 0x0
-#define RD_RDY 0x8 /* Read Data Ready */
-#define nRD_RDY 0x0
-#define WR_DONE 0x10 /* Page Write Done */
-#define nWR_DONE 0x0
-
-/* Bit masks for NFC_IRQMASK */
-
-#define MASK_BUSYIRQ 0x1 /* Mask Not Busy IRQ */
-#define nMASK_BUSYIRQ 0x0
-#define MASK_WBOVF 0x2 /* Mask Write Buffer Overflow */
-#define nMASK_WBOVF 0x0
-#define MASK_WBEMPTY 0x4 /* Mask Write Buffer Empty */
-#define nMASK_WBEMPTY 0x0
-#define MASK_RDRDY 0x8 /* Mask Read Data Ready */
-#define nMASK_RDRDY 0x0
-#define MASK_WRDONE 0x10 /* Mask Write Done */
-#define nMASK_WRDONE 0x0
-
-/* Bit masks for NFC_RST */
-
-#define ECC_RST 0x1 /* ECC (and NFC counters) Reset */
-#define nECC_RST 0x0
-
-/* Bit masks for NFC_PGCTL */
-
-#define PG_RD_START 0x1 /* Page Read Start */
-#define nPG_RD_START 0x0
-#define PG_WR_START 0x2 /* Page Write Start */
-#define nPG_WR_START 0x0
-
-/* Bit masks for NFC_ECC0 */
-
-#define ECC0 0x7ff /* Parity Calculation Result0 */
-
-/* Bit masks for NFC_ECC1 */
-
-#define ECC1 0x7ff /* Parity Calculation Result1 */
-
-/* Bit masks for NFC_ECC2 */
-
-#define ECC2 0x7ff /* Parity Calculation Result2 */
-
-/* Bit masks for NFC_ECC3 */
-
-#define ECC3 0x7ff /* Parity Calculation Result3 */
-
-/* Bit masks for NFC_COUNT */
-
-#define ECCCNT 0x3ff /* Transfer Count */
-
-
#endif /* _DEF_BF52X_H */
diff --git a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
index 0ed06c2366fe..54143441af5e 100644
--- a/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
+++ b/arch/blackfin/mach-bf548/include/mach/defBF54x_base.h
@@ -2044,66 +2044,6 @@
#define RESET_WDOG 0x4000 /* SW Reset Generated By Watchdog Timer */
#define RESET_SOFTWARE 0x8000 /* SW Reset Occurred Since Last Read Of SWRST */
-/* Bit masks for NFC_CTL */
-
-#define WR_DLY 0xf /* Write Strobe Delay */
-#define RD_DLY 0xf0 /* Read Strobe Delay */
-#define NWIDTH 0x100 /* NAND Data Width */
-#define PG_SIZE 0x200 /* Page Size */
-
-/* Bit masks for NFC_STAT */
-
-#define NBUSY 0x1 /* Not Busy */
-#define WB_FULL 0x2 /* Write Buffer Full */
-#define PG_WR_STAT 0x4 /* Page Write Pending */
-#define PG_RD_STAT 0x8 /* Page Read Pending */
-#define WB_EMPTY 0x10 /* Write Buffer Empty */
-
-/* Bit masks for NFC_IRQSTAT */
-
-#define NBUSYIRQ 0x1 /* Not Busy IRQ */
-#define WB_OVF 0x2 /* Write Buffer Overflow */
-#define WB_EDGE 0x4 /* Write Buffer Edge Detect */
-#define RD_RDY 0x8 /* Read Data Ready */
-#define WR_DONE 0x10 /* Page Write Done */
-
-/* Bit masks for NFC_IRQMASK */
-
-#define MASK_BUSYIRQ 0x1 /* Mask Not Busy IRQ */
-#define MASK_WBOVF 0x2 /* Mask Write Buffer Overflow */
-#define MASK_WBEMPTY 0x4 /* Mask Write Buffer Empty */
-#define MASK_RDRDY 0x8 /* Mask Read Data Ready */
-#define MASK_WRDONE 0x10 /* Mask Write Done */
-
-/* Bit masks for NFC_RST */
-
-#define ECC_RST 0x1 /* ECC (and NFC counters) Reset */
-
-/* Bit masks for NFC_PGCTL */
-
-#define PG_RD_START 0x1 /* Page Read Start */
-#define PG_WR_START 0x2 /* Page Write Start */
-
-/* Bit masks for NFC_ECC0 */
-
-#define ECC0 0x7ff /* Parity Calculation Result0 */
-
-/* Bit masks for NFC_ECC1 */
-
-#define ECC1 0x7ff /* Parity Calculation Result1 */
-
-/* Bit masks for NFC_ECC2 */
-
-#define ECC2 0x7ff /* Parity Calculation Result2 */
-
-/* Bit masks for NFC_ECC3 */
-
-#define ECC3 0x7ff /* Parity Calculation Result3 */
-
-/* Bit masks for NFC_COUNT */
-
-#define ECCCNT 0x3ff /* Transfer Count */
-
/* Bit masks for EPPIx_STATUS */
#define CFIFO_ERR 0x1 /* Chroma FIFO Error */
diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig
index 312b12094a1d..c5fe20553dad 100644
--- a/arch/ia64/configs/bigsur_defconfig
+++ b/arch/ia64/configs/bigsur_defconfig
@@ -1,1358 +1,118 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Mon Feb 27 16:10:42 2006
-#
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_CPUSETS is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS 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_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLUB=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
-# CONFIG_IA64_GENERIC is not set
-CONFIG_IA64_DIG=y
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_HP_SIM is not set
-CONFIG_ITANIUM=y
-# CONFIG_MCKINLEY is not set
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-CONFIG_IA64_PAGE_SIZE_16KB=y
-# CONFIG_IA64_PAGE_SIZE_64KB is not set
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_IA64_BRL_EMU=y
-CONFIG_IA64_L1_CACHE_SHIFT=6
-# CONFIG_IA64_CYCLONE is not set
-CONFIG_IOSAPIC=y
-CONFIG_FORCE_MAX_ZONEORDER=17
-CONFIG_SMP=y
-CONFIG_NR_CPUS=2
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_SCHED_SMT is not set
-CONFIG_PREEMPT=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-# CONFIG_VIRTUAL_MEM_MAP is not set
-# CONFIG_IA64_MCA_RECOVERY is not set
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-
-#
-# Firmware Drivers
-#
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-
-#
-# Power management and ACPI
-#
-CONFIG_PM=y
-CONFIG_PM_LEGACY=y
-# CONFIG_PM_DEBUG is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_SYSTEM=y
-# CONFIG_ACPI_CONTAINER is not set
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_DEBUG is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_AGP_I460=m
+CONFIG_AGP=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_AUTOFS_FS=m
+CONFIG_BINFMT_MISC=m
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_DM=m
CONFIG_BLK_DEV_GENERIC=m
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_IDECD=m
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_PIIX=m
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
+CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID10=m
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=m
+CONFIG_CIFS=m
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_STATS=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
+CONFIG_DM_SNAPSHOT=m
CONFIG_DM_ZERO=m
-# CONFIG_DM_MULTIPATH is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_SPI is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=y
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_EFI_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
CONFIG_DRM=m
-# CONFIG_DRM_TDFX is not set
CONFIG_DRM_R128=m
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_MGA is not set
-# CONFIG_DRM_SIS is not set
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HPET is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_FSCPOS is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-# CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-# CONFIG_SND_SEQUENCER_OSS is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-CONFIG_SND_CS4281=m
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_OHCI_HCD is not set
-CONFIG_USB_UHCI_HCD=m
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS)
-#
-
-#
-# File systems
-#
+CONFIG_DUMMY=y
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_XFS_RT is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_HUGETLBFS=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C=y
+CONFIG_IA64_DIG=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IDE=m
+CONFIG_INET=y
CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_INPUT_EVDEV=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID1=m
+CONFIG_MD=y
+CONFIG_MII=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-CONFIG_CIFS_STATS=y
-# CONFIG_CIFS_STATS2 is not set
-CONFIG_CIFS_XATTR=y
-CONFIG_CIFS_POSIX=y
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
CONFIG_NLS_UTF8=m
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-
-#
-# Instrumentation Support
-#
-CONFIG_PROFILING=y
+CONFIG_NR_CPUS=2
CONFIG_OPROFILE=y
-# CONFIG_KPROBES is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_IA64_GRANULE_16MB is not set
-CONFIG_IA64_GRANULE_64MB=y
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-CONFIG_SYSVIPC_COMPAT=y
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_PREEMPT=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROFILING=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SGI_PARTITION=y
+CONFIG_SMP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SOUND=m
+CONFIG_SYSVIPC=y
+CONFIG_TMPFS=y
+CONFIG_UDF_FS=m
+CONFIG_UNIX=y
+CONFIG_USB_ACM=m
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB=m
+CONFIG_USB_MON=m
+CONFIG_USB_PRINTER=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_UHCI_HCD=m
+CONFIG_VFAT_FS=y
+# CONFIG_VIRTUAL_MEM_MAP is not set
+CONFIG_XFS_FS=y
+CONFIG_XFS_POSIX_ACL=y
+CONFIG_XFS_QUOTA=y
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig
index 6a4cc506fb5f..01ba5305e98c 100644
--- a/arch/ia64/configs/generic_defconfig
+++ b/arch/ia64/configs/generic_defconfig
@@ -1,1455 +1,133 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc7
-# Mon Dec 8 08:12:07 2008
-#
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_CGROUPS=y
-# CONFIG_CGROUP_DEBUG is not set
-# CONFIG_CGROUP_NS is not set
-# CONFIG_CGROUP_FREEZER is not set
-# CONFIG_CGROUP_DEVICE is not set
-CONFIG_CPUSETS=y
-# CONFIG_GROUP_SCHED is not set
-# CONFIG_CGROUP_CPUACCT is not set
-# CONFIG_RESOURCE_COUNTERS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_PROC_PID_CPUSET=y
-# CONFIG_RELAY is not set
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-CONFIG_BLOCK_COMPAT=y
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_FREEZER is not set
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_ZONE_DMA=y
-CONFIG_QUICKLIST=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_IOMMU_HELPER=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_DMI=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_IA64_UNCACHED_ALLOCATOR=y
-CONFIG_AUDIT_ARCH=y
-# CONFIG_PARAVIRT_GUEST is not set
-CONFIG_IA64_GENERIC=y
-# CONFIG_IA64_DIG is not set
-# CONFIG_IA64_DIG_VTD is not set
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_SGI_UV is not set
-# CONFIG_IA64_HP_SIM is not set
-# CONFIG_IA64_XEN_GUEST is not set
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-# CONFIG_IA64_PAGE_SIZE_16KB is not set
-CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-CONFIG_HZ=250
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-# CONFIG_SCHED_HRTICK is not set
-CONFIG_IA64_L1_CACHE_SHIFT=7
-CONFIG_IA64_CYCLONE=y
-CONFIG_IOSAPIC=y
-CONFIG_FORCE_MAX_ZONEORDER=17
-# CONFIG_VIRT_CPU_ACCOUNTING is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=4096
-CONFIG_HOTPLUG_CPU=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
-# CONFIG_SCHED_SMT is not set
-# CONFIG_PERMIT_BSP_REMOVE is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_FLATMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM_MANUAL=y
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_NEED_MULTIPLE_NODES=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_MIGRATION=y
-CONFIG_RESOURCES_64BIT=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_NR_QUICK=1
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
-CONFIG_NUMA=y
-CONFIG_NODES_SHIFT=10
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
-CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
-CONFIG_HAVE_ARCH_NODEDATA_EXTENSION=y
-CONFIG_COMPAT_FOR_U64_ALIGNMENT=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-# CONFIG_IA64_MC_ERR_INJECT is not set
-CONFIG_SGI_SN=y
-# CONFIG_IA64_ESI is not set
-# CONFIG_IA64_HP_AML_NFW is not set
-
-#
-# SN Devices
-#
-CONFIG_SGI_IOC3=m
-CONFIG_KEXEC=y
-CONFIG_CRASH_DUMP=y
-
-#
-# Firmware Drivers
-#
-# CONFIG_FIRMWARE_MEMMAP is not set
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_DMIID=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-
-#
-# Power management and ACPI options
-#
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_ACPI=y
-CONFIG_ACPI_PROCFS=y
-CONFIG_ACPI_PROCFS_POWER=y
-CONFIG_ACPI_SYSFS_POWER=y
-CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_BUTTON=m
-CONFIG_ACPI_FAN=m
+CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_DOCK=y
+CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_HOTPLUG_CPU=y
-CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_NUMA=y
-# CONFIG_ACPI_CUSTOM_DSDT is not set
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-# CONFIG_ACPI_PCI_SLOT is not set
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_CONTAINER=m
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS is not set
-CONFIG_ARCH_SUPPORTS_MSI=y
-CONFIG_PCI_MSI=y
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
-CONFIG_HOTPLUG_PCI=m
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_ACPI=m
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_HOTPLUG_PCI_SGI is not set
-# CONFIG_PCCARD is not set
-CONFIG_DMAR=y
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_ACPI_PROCFS=y
+CONFIG_AGP_HP_ZX1=m
+CONFIG_AGP_I460=m
+CONFIG_AGP=m
+CONFIG_AGP_SGI_TIOCA=m
CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_LRO=m
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-CONFIG_WIRELESS=y
-# CONFIG_CFG80211 is not set
-CONFIG_WIRELESS_OLD_REGULATORY=y
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-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_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-CONFIG_CONNECTOR=y
-CONFIG_PROC_EVENTS=y
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG_MESSAGES is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_ATA_PIIX=y
+CONFIG_ATA=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_AUTOFS_FS=m
+CONFIG_BINFMT_MISC=m
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-CONFIG_SGI_IOC4=y
-# CONFIG_TIFM_CORE is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-CONFIG_SGI_XP=m
-# CONFIG_HP_ILO is not set
-# CONFIG_C2PORT is not set
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
-
-#
-# Please see Documentation/ide/ide.txt for help/info on IDE drives
-#
-CONFIG_IDE_TIMINGS=y
-CONFIG_IDE_ATAPI=y
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_IDE_GD=y
-CONFIG_IDE_GD_ATA=y
-# CONFIG_IDE_GD_ATAPI is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEDMA_SFF=y
-
-#
-# PCI IDE chipsets support
-#
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_DM=m
CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SGIIOC4=y
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-CONFIG_BLK_DEV_IDEDMA=y
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-CONFIG_SCSI_NETLINK=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
+CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SGIIOC4=y
CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CGROUPS=y
CONFIG_CHR_DEV_SG=m
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-CONFIG_SCSI_SAS_ATTRS=y
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_STEX is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-CONFIG_SCSI_SYM53C8XX_MMIO=y
-# CONFIG_SCSI_IPR is not set
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_ATA=y
-CONFIG_ATA_NONSTANDARD=y
-CONFIG_ATA_ACPI=y
-CONFIG_SATA_PMP=y
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_SIL24 is not set
-CONFIG_ATA_SFF=y
-# CONFIG_SATA_SVW is not set
-CONFIG_ATA_PIIX=y
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-CONFIG_SATA_VITESSE=y
-# CONFIG_SATA_INIC162X is not set
-# CONFIG_PATA_ACPI is not set
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_SCH is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CIFS=m
+CONFIG_CONNECTOR=y
+CONFIG_CPUSETS=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRC_T10DIF=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_UEVENT is not set
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=m
-CONFIG_FUSION_SAS=y
-CONFIG_FUSION_MAX_SGE=128
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LOGGING is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-# CONFIG_NET_SB1000 is not set
-# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_ULI526X is not set
-# CONFIG_HP100 is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-CONFIG_EEPRO100=m
-CONFIG_E100=m
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-# CONFIG_ATL2 is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-CONFIG_E1000=y
-# CONFIG_E1000E is not set
-# CONFIG_IP1000 is not set
-CONFIG_IGB=y
-# CONFIG_IGB_LRO is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_VIA_VELOCITY is not set
-CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E is not set
-# CONFIG_JME is not set
-CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NIU is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_TEHUTI is not set
-# CONFIG_BNX2X is not set
-# CONFIG_QLGE is not set
-# CONFIG_SFC is not set
-# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-CONFIG_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_FM801 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_SYNCLINK_GT is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-# CONFIG_NOZOMI is not set
-CONFIG_SGI_SNSC=y
-CONFIG_SGI_TIOCX=y
-CONFIG_SGI_MBCS=m
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_PNP=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_SGI_L1_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_SERIAL_SGI_IOC4=y
-# CONFIG_SERIAL_SGI_IOC3 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_EFI_RTC=y
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_HPET=y
-CONFIG_HPET_MMAP=y
-# CONFIG_HANGCHECK_TIMER is not set
-CONFIG_MMTIMER=y
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-# CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=y
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_BATTERY_DS2760 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_I5K_AMB is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-CONFIG_THERMAL=m
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_AGP_HP_ZX1=m
-CONFIG_AGP_SGI_TIOCA=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_ZERO=m
CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
+CONFIG_DRM_MGA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_SOUND=m
-CONFIG_SOUND_OSS_CORE=y
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_PCM_OSS_PLUGINS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-CONFIG_SND_VERBOSE_PRINTK=y
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_VMASTER=y
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_DRIVERS=y
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-# CONFIG_SND_AC97_POWER_SAVE is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_OXYGEN is not set
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-CONFIG_SND_CS46XX_NEW_DSP=y
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-CONFIG_SND_EMU10K1=m
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-CONFIG_SND_FM801=m
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=m
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-CONFIG_HID_A4TECH=m
-CONFIG_HID_APPLE=m
-CONFIG_HID_BELKIN=m
-CONFIG_HID_BRIGHT=m
-CONFIG_HID_CHERRY=m
-CONFIG_HID_CHICONY=m
-CONFIG_HID_CYPRESS=m
-CONFIG_HID_DELL=m
-CONFIG_HID_EZKEY=m
+CONFIG_DRM_TDFX=m
+CONFIG_DUMMY=m
+CONFIG_E1000=y
+CONFIG_E100=m
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SAS=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION=y
+CONFIG_GAMEPORT=m
CONFIG_HID_GYRATION=m
-CONFIG_HID_LOGITECH=m
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
CONFIG_HID_PANTHERLORD=m
-# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=m
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SONY=m
CONFIG_HID_SUNPLUS=m
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
-CONFIG_USB_SUPPORT=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-CONFIG_USB_MON=y
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=m
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# Enable Host or Gadget support to see Inventra options
-#
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
-#
-
-#
-# see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_UWB is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HPET=y
+CONFIG_HUGETLBFS=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_IA64_CYCLONE=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_IA64_PAGE_SIZE_64KB=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IDE=y
+CONFIG_IGB=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKCONFIG=y
+CONFIG_INET=y
+CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND=m
-# CONFIG_INFINIBAND_USER_MAD is not set
-# CONFIG_INFINIBAND_USER_ACCESS is not set
-CONFIG_INFINIBAND_ADDR_TRANS=y
CONFIG_INFINIBAND_MTHCA=m
-CONFIG_INFINIBAND_MTHCA_DEBUG=y
-# CONFIG_INFINIBAND_IPATH is not set
-# CONFIG_INFINIBAND_AMSO1100 is not set
-# CONFIG_MLX4_INFINIBAND is not set
-# CONFIG_INFINIBAND_NES is not set
-CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_CM is not set
-CONFIG_INFINIBAND_IPOIB_DEBUG=y
-# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set
-# CONFIG_INFINIBAND_SRP is not set
-# CONFIG_INFINIBAND_ISER is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
-# CONFIG_STAGING is not set
-CONFIG_STAGING_EXCLUDE_BUILD=y
-
-#
-# HP Simulator drivers
-#
-# CONFIG_HP_SIMETH is not set
-# CONFIG_HP_SIMSERIAL is not set
-# CONFIG_HP_SIMSCSI is not set
-CONFIG_MSPEC=m
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_IP_MULTICAST=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_VMCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KEXEC=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MCKINLEY=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MSPEC=m
+CONFIG_NETCONSOLE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET_TULIP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_XPRT_RDMA=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp437"
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
@@ -1465,15 +143,14 @@ 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_874=m
CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=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 is not set
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
@@ -1481,194 +158,79 @@ CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=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_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=2048
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-CONFIG_DEBUG_MEMORY_INIT=y
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_NTFS_FS=m
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+# CONFIG_PNP_DEBUG_MESSAGES is not set
+CONFIG_POSIX_MQUEUE=y
+CONFIG_PROC_KCORE=y
+CONFIG_RAW_DRIVER=m
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS=y
+CONFIG_SATA_VITESSE=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_SGI_IOC4=y
+CONFIG_SERIAL_SGI_L1_CONSOLE=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SGI_IOC4=y
+CONFIG_SGI_MBCS=m
+CONFIG_SGI_PARTITION=y
+CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SGI_XP=m
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_FM801=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_VIRMIDI=m
+CONFIG_SOUND=m
+CONFIG_SYN_COOKIES=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-CONFIG_SYSVIPC_COMPAT=y
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=m
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_HASH=m
-CONFIG_CRYPTO_RNG=m
-CONFIG_CRYPTO_MANAGER=m
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_HW=y
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_HAVE_KVM=y
-CONFIG_VIRTUALIZATION=y
-# CONFIG_KVM is not set
-# CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTIO_BALLOON is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC_T10DIF=y
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_IRQ_PER_CPU=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SYSVIPC=y
+CONFIG_TIGON3=y
+CONFIG_TMPFS=y
+CONFIG_TULIP=m
+CONFIG_UDF_FS=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_UNIX=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB=m
+CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_UHCI_HCD=m
+CONFIG_VFAT_FS=y
+CONFIG_XFS_FS=y
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig
index 2dc185b0f9a3..18989a084143 100644
--- a/arch/ia64/configs/gensparse_defconfig
+++ b/arch/ia64/configs/gensparse_defconfig
@@ -1,1267 +1,110 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Thu Mar 2 16:39:10 2006
-#
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_CPUSETS is not set
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-# CONFIG_KALLSYMS_EXTRA_PASS 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_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLUB=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
-CONFIG_IA64_GENERIC=y
-# CONFIG_IA64_DIG is not set
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_HP_SIM is not set
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-CONFIG_IA64_PAGE_SIZE_16KB=y
-# CONFIG_IA64_PAGE_SIZE_64KB is not set
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_IA64_L1_CACHE_SHIFT=7
-CONFIG_IA64_CYCLONE=y
-CONFIG_IOSAPIC=y
-# CONFIG_IA64_SGI_SN_XP is not set
-CONFIG_FORCE_MAX_ZONEORDER=17
-CONFIG_SMP=y
-CONFIG_NR_CPUS=512
-CONFIG_IA64_NR_NODES=256
-CONFIG_HOTPLUG_CPU=y
-# CONFIG_SCHED_SMT is not set
-# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_FLATMEM_MANUAL is not set
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-CONFIG_SPARSEMEM_MANUAL=y
-CONFIG_SPARSEMEM=y
-CONFIG_NEED_MULTIPLE_NODES=y
-CONFIG_HAVE_MEMORY_PRESENT=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPARSEMEM_EXTREME=y
-# CONFIG_MEMORY_HOTPLUG is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_MIGRATION=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
-CONFIG_NUMA=y
-CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-CONFIG_SGI_SN=y
-
-#
-# Firmware Drivers
-#
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-
-#
-# Power management and ACPI
-#
-CONFIG_PM=y
-CONFIG_PM_LEGACY=y
-# CONFIG_PM_DEBUG is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_FAN=m
CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_HOTPLUG_CPU=y
-CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_NUMA=y
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_CONTAINER=m
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_DEBUG is not set
-
-#
-# PCI Hotplug Support
-#
-CONFIG_HOTPLUG_PCI=m
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_ACPI=m
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_HOTPLUG_PCI_SGI is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_AGP_HP_ZX1=m
+CONFIG_AGP_I460=m
+CONFIG_AGP=m
+CONFIG_AGP_SGI_TIOCA=m
CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_BINFMT_MISC=m
+CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_DM=m
CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-CONFIG_BLK_DEV_SGIIOC4=y
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
+CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SGIIOC4=y
CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-CONFIG_SCSI_SATA=y
-# CONFIG_SCSI_SATA_AHCI is not set
-# CONFIG_SCSI_SATA_SVW is not set
-# CONFIG_SCSI_ATA_PIIX is not set
-# CONFIG_SCSI_SATA_MV is not set
-# CONFIG_SCSI_SATA_NV is not set
-# CONFIG_SCSI_PDC_ADMA is not set
-# CONFIG_SCSI_SATA_QSTOR is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIL24 is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_ULI is not set
-# CONFIG_SCSI_SATA_VIA is not set
-CONFIG_SCSI_SATA_VITESSE=y
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-CONFIG_MD_RAID5=m
-CONFIG_MD_RAID6=m
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=m
+CONFIG_CHR_DEV_ST=m
+CONFIG_CIFS=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
-# CONFIG_DM_MULTIPATH_EMC is not set
-
-#
-# Fusion MPT device support
-#
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=m
-# CONFIG_FUSION_SAS is not set
-CONFIG_FUSION_MAX_SGE=128
-# CONFIG_FUSION_CTL is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_ULI526X is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=m
-CONFIG_E100=m
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-CONFIG_E1000=y
-# CONFIG_E1000_NAPI is not set
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-CONFIG_NETCONSOLE=y
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_RX is not set
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-CONFIG_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_FM801 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_SYNCLINK_GT is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_STALDRV is not set
-CONFIG_SGI_SNSC=y
-CONFIG_SGI_TIOCX=y
-CONFIG_SGI_MBCS=m
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_ACPI=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_SERIAL_SGI_L1_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_SERIAL_SGI_IOC4=y
-CONFIG_SERIAL_SGI_IOC3=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_EFI_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
-CONFIG_AGP_HP_ZX1=m
-CONFIG_AGP_SGI_TIOCA=m
+CONFIG_DM_SNAPSHOT=m
+CONFIG_DM_ZERO=m
CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
+CONFIG_DRM_MGA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_HPET=y
-# CONFIG_HPET_RTC_IRQ is not set
-CONFIG_HPET_MMAP=y
-# CONFIG_HANGCHECK_TIMER is not set
-CONFIG_MMTIMER=y
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-CONFIG_SND_HWDEP=m
-CONFIG_SND_RAWMIDI=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PRINTK=y
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_MPU401_UART=m
-CONFIG_SND_OPL3_LIB=m
-CONFIG_SND_AC97_CODEC=m
-CONFIG_SND_AC97_BUS=m
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_MTPAV=m
-CONFIG_SND_SERIAL_U16550=m
-CONFIG_SND_MPU401=m
-
-#
-# PCI devices
-#
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-CONFIG_SND_CS4281=m
-CONFIG_SND_CS46XX=m
-CONFIG_SND_CS46XX_NEW_DSP=y
-CONFIG_SND_EMU10K1=m
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-CONFIG_SND_FM801=m
-# CONFIG_SND_FM801_TEA575X is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=m
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETKIT is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-CONFIG_INFINIBAND=m
-# CONFIG_INFINIBAND_USER_MAD is not set
-# CONFIG_INFINIBAND_USER_ACCESS is not set
-CONFIG_INFINIBAND_MTHCA=m
-# CONFIG_INFINIBAND_MTHCA_DEBUG is not set
-CONFIG_INFINIBAND_IPOIB=m
-# CONFIG_INFINIBAND_IPOIB_DEBUG is not set
-# CONFIG_INFINIBAND_SRP is not set
-
-#
-# SN Devices
-#
-CONFIG_SGI_IOC4=y
-CONFIG_SGI_IOC3=y
-
-#
-# EDAC - error detection and reporting (RAS)
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
+CONFIG_DRM_TDFX=m
+CONFIG_DUMMY=m
+CONFIG_E1000=y
+CONFIG_E100=m
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=y
-CONFIG_XFS_EXPORT=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_FUSION_FC=m
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION=y
+CONFIG_GAMEPORT=m
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HPET=y
+CONFIG_HUGETLBFS=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_IA64_CYCLONE=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IDE_GENERIC=y
+CONFIG_IDE=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKCONFIG=y
+CONFIG_INET=y
+CONFIG_INFINIBAND_IPOIB=m
+CONFIG_INFINIBAND=m
+CONFIG_INFINIBAND_MTHCA=m
CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_IP_MULTICAST=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_KALLSYMS_ALL=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MCKINLEY=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_NETCONSOLE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET_TULIP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-CONFIG_NFS_DIRECTIO=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp437"
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
@@ -1277,15 +120,14 @@ 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_874=m
CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=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 is not set
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
@@ -1293,100 +135,77 @@ CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=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_NLS_UTF8=m
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-
-#
-# HP Simulator drivers
-#
-# CONFIG_HP_SIMETH is not set
-# CONFIG_HP_SIMSERIAL is not set
-# CONFIG_HP_SIMSCSI is not set
-
-#
-# Instrumentation Support
-#
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-CONFIG_SYSVIPC_COMPAT=y
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_NR_CPUS=512
+CONFIG_NTFS_FS=m
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_PROC_KCORE=y
+CONFIG_RAW_DRIVER=m
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS=y
+CONFIG_SCSI_FC_ATTRS=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_SERIAL_SGI_IOC3=y
+CONFIG_SERIAL_SGI_IOC4=y
+CONFIG_SERIAL_SGI_L1_CONSOLE=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SGI_IOC3=y
+CONFIG_SGI_IOC4=y
+CONFIG_SGI_MBCS=m
+CONFIG_SGI_PARTITION=y
+CONFIG_SGI_SNSC=y
+CONFIG_SGI_TIOCX=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMP=y
+CONFIG_SND_CS4281=m
+CONFIG_SND_CS46XX=m
+CONFIG_SND_DUMMY=m
+CONFIG_SND_EMU10K1=m
+CONFIG_SND_FM801=m
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_MPU401=m
+CONFIG_SND_MTPAV=m
+CONFIG_SND_PCM_OSS=m
+CONFIG_SND_SEQ_DUMMY=m
+CONFIG_SND_SEQUENCER=m
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SERIAL_U16550=m
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_VIRMIDI=m
+CONFIG_SOUND=m
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SYN_COOKIES=y
+CONFIG_SYSVIPC=y
+CONFIG_TIGON3=y
+CONFIG_TMPFS=y
+CONFIG_TULIP=m
+CONFIG_UDF_FS=m
+CONFIG_UNIX=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB=m
+CONFIG_USB_MON=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_UHCI_HCD=m
+CONFIG_VFAT_FS=y
+CONFIG_XFS_FS=y
diff --git a/arch/ia64/configs/sim_defconfig b/arch/ia64/configs/sim_defconfig
index 21a23cdfd41c..585222b368c3 100644
--- a/arch/ia64/configs/sim_defconfig
+++ b/arch/ia64/configs/sim_defconfig
@@ -1,723 +1,57 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc5
-# Mon Feb 27 16:13:41 2006
-#
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_CPUSETS is not set
-CONFIG_INITRAMFS_SOURCE=""
+CONFIG_BINFMT_MISC=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_SD=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS 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_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-CONFIG_SLUB=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_DMA_IS_DMA32=y
-# CONFIG_IA64_GENERIC is not set
-# CONFIG_IA64_DIG is not set
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_EXT2_FS=y
+# CONFIG_EXT3_FS_XATTR is not set
+CONFIG_EXT3_FS=y
+CONFIG_HP_SIMETH=y
+CONFIG_HP_SIMSCSI=y
+CONFIG_HP_SIMSERIAL_CONSOLE=y
+CONFIG_HP_SIMSERIAL=y
+CONFIG_HUGETLBFS=y
CONFIG_IA64_HP_SIM=y
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-# CONFIG_IA64_PAGE_SIZE_16KB is not set
CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_IA64_L1_CACHE_SHIFT=7
-# CONFIG_IA64_CYCLONE is not set
-CONFIG_FORCE_MAX_ZONEORDER=17
-CONFIG_SMP=y
-CONFIG_NR_CPUS=64
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_SCHED_SMT is not set
-CONFIG_PREEMPT=y
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-# CONFIG_VIRTUAL_MEM_MAP is not set
-# CONFIG_IA64_MCA_RECOVERY is not set
-# CONFIG_PERFMON is not set
CONFIG_IA64_PALINFO=m
-
-#
-# Firmware Drivers
-#
-CONFIG_EFI_VARS=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management and ACPI
-#
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_UNIX is not set
-# CONFIG_NET_KEY is not set
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKCONFIG=y
CONFIG_INET=y
+CONFIG_INOTIFY=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_BIC=y
# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-# CONFIG_STANDALONE is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_MCKINLEY=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_NET=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD=y
+CONFIG_NFS_FS=y
+CONFIG_NR_CPUS=64
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PREEMPT=y
+CONFIG_PROC_KCORE=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI Transport Attributes
-#
+CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_SPI_ATTRS=y
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# Network device support
-#
-# CONFIG_NETDEVICES is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# PHY device support
-#
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
+CONFIG_SCSI=y
# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-CONFIG_EFI_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_AGP is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-# CONFIG_TELCLOCK is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
+CONFIG_SMP=y
+# CONFIG_STANDALONE is not set
+CONFIG_SYSVIPC=y
# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB_ARCH_HAS_HCD is not set
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# InfiniBand support
-#
-
-#
-# EDAC - error detection and reporting (RAS)
-#
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_FS_XATTR is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_INOTIFY=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-# CONFIG_TMPFS is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-CONFIG_NFS_DIRECTIO=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-
-#
-# HP Simulator drivers
-#
-CONFIG_HP_SIMETH=y
-CONFIG_HP_SIMSERIAL=y
-CONFIG_HP_SIMSERIAL_CONSOLE=y
-CONFIG_HP_SIMSCSI=y
-
-#
-# Instrumentation Support
-#
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_MAGIC_SYSRQ is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_DEBUG_PREEMPT=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_DEBUG_FS is not set
-# CONFIG_DEBUG_VM is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_IA64_GRANULE_16MB is not set
-CONFIG_IA64_GRANULE_64MB=y
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-CONFIG_SYSVIPC_COMPAT=y
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Hardware crypto devices
-#
diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig
index c5a5ea9d54ae..498618ea00ea 100644
--- a/arch/ia64/configs/tiger_defconfig
+++ b/arch/ia64/configs/tiger_defconfig
@@ -1,1134 +1,113 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.22
-# Thu Jul 19 13:54:47 2007
-#
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-# CONFIG_CPUSETS is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLUB=y
-# CONFIG_SLUB is not set
-# CONFIG_SLOB is not set
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_KMOD=y
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_BSG is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_ZONE_DMA=y
-CONFIG_QUICKLIST=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_DMI=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_AUDIT_ARCH=y
-# CONFIG_IA64_GENERIC is not set
-CONFIG_IA64_DIG=y
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_HP_SIM is not set
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-# CONFIG_IA64_PAGE_SIZE_16KB is not set
-CONFIG_IA64_PAGE_SIZE_64KB=y
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_IA64_L1_CACHE_SHIFT=7
-CONFIG_IA64_CYCLONE=y
-CONFIG_IOSAPIC=y
-CONFIG_FORCE_MAX_ZONEORDER=17
-CONFIG_SMP=y
-CONFIG_NR_CPUS=16
-CONFIG_HOTPLUG_CPU=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-# CONFIG_SCHED_SMT is not set
-CONFIG_PERMIT_BSP_REMOVE=y
-CONFIG_FORCE_CPEI_RETARGET=y
-# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_NR_QUICK=1
-CONFIG_VIRT_TO_BUS=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-# CONFIG_IA64_MC_ERR_INJECT is not set
-# CONFIG_IA64_ESI is not set
-CONFIG_KEXEC=y
-# CONFIG_CRASH_DUMP is not set
-
-#
-# Firmware Drivers
-#
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_DMIID=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-
-# CONFIG_DMAR is not set
-
-#
-# Power management and ACPI
-#
-CONFIG_PM=y
-CONFIG_PM_LEGACY=y
-# CONFIG_PM_DEBUG is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
-CONFIG_ACPI_PROCFS=y
CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_FAN=m
-# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_HOTPLUG_CPU=y
-CONFIG_ACPI_THERMAL=m
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_CONTAINER=m
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS is not set
-CONFIG_ARCH_SUPPORTS_MSI=y
-# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_DEBUG is not set
-CONFIG_HOTPLUG_PCI=m
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_ACPI=m
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_ACPI_PROCFS=y
+CONFIG_AGP_I460=m
+CONFIG_AGP=m
CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=m
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_DM=m
CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_ONLYDISK is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-CONFIG_SCSI_NETLINK=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
+CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-CONFIG_SCSI_SYM53C8XX_MMIO=y
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_ATA is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CIFS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
+CONFIG_DM_SNAPSHOT=m
CONFIG_DM_ZERO=m
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-
-#
-# Fusion MPT device support
-#
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=y
-# CONFIG_FUSION_SAS is not set
-CONFIG_FUSION_MAX_SGE=128
-CONFIG_FUSION_CTL=y
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-# CONFIG_ARCNET is not set
-# CONFIG_PHYLIB is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_ULI526X is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-CONFIG_EEPRO100=m
-CONFIG_E100=m
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-CONFIG_E1000=y
-# CONFIG_E1000_NAPI is not set
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_VIA_VELOCITY is not set
-CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-CONFIG_NETCONSOLE=y
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-CONFIG_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_FM801 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_MOXA_SMARTIO_NEW is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_SYNCLINK_GT is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_PNP=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_EFI_RTC=y
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-CONFIG_AGP=m
-CONFIG_AGP_I460=m
CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
+CONFIG_DRM_MGA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_HPET=y
-# CONFIG_HPET_RTC_IRQ is not set
-CONFIG_HPET_MMAP=y
-# CONFIG_HANGCHECK_TIMER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-# CONFIG_I2C is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-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_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_PERSIST is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=y
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Userspace I/O
-#
-# CONFIG_UIO is not set
-# CONFIG_MSPEC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
+CONFIG_DRM_TDFX=m
+CONFIG_DUMMY=m
+CONFIG_E1000=y
+CONFIG_E100=m
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS=y
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_EXT3_FS=y
+CONFIG_FORCE_CPEI_RETARGET=y
+CONFIG_FUSION_CTL=y
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION=y
+CONFIG_GAMEPORT=m
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HPET=y
+CONFIG_HUGETLBFS=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_IA64_CYCLONE=y
+CONFIG_IA64_DIG=y
+CONFIG_IA64_GRANULE_16MB=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_IA64_PAGE_SIZE_64KB=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IDE=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKCONFIG=y
+CONFIG_INET=y
CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_IP_MULTICAST=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KEXEC=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MCKINLEY=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_NETCONSOLE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET_TULIP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-CONFIG_NFS_DIRECTIO=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_NFSD_TCP=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_BIND34 is not set
-CONFIG_RPCSEC_GSS_KRB5=y
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp437"
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
@@ -1144,15 +123,14 @@ 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_874=m
CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=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 is not set
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
@@ -1160,120 +138,50 @@ CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=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_NLS_UTF8=m
-
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_ITU_T is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_IRQ_PER_CPU=y
-
-#
-# Instrumentation Support
-#
-# CONFIG_PROFILING is not set
-# CONFIG_KPROBES is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_LIST is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_FAULT_INJECTION is not set
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_MANAGER=m
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=m
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-CONFIG_CRYPTO_HW=y
+CONFIG_NR_CPUS=16
+CONFIG_NTFS_FS=m
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+CONFIG_PERMIT_BSP_REMOVE=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_PROC_KCORE=y
+CONFIG_RAW_DRIVER=m
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_SYSVIPC=y
+CONFIG_TIGON3=y
+CONFIG_TMPFS=y
+CONFIG_TULIP=m
+CONFIG_UDF_FS=m
+CONFIG_UNIX=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB=y
+CONFIG_VFAT_FS=y
+CONFIG_XFS_FS=y
diff --git a/arch/ia64/configs/xen_domu_defconfig b/arch/ia64/configs/xen_domu_defconfig
index c67eafc4bb38..5f6d284723a4 100644
--- a/arch/ia64/configs/xen_domu_defconfig
+++ b/arch/ia64/configs/xen_domu_defconfig
@@ -1,1374 +1,121 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc1
-# Fri Jan 16 11:49:59 2009
-#
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# General setup
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_AUDIT is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=20
-CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
-# CONFIG_GROUP_SCHED is not set
-
-#
-# Control Group support
-#
-# CONFIG_CGROUPS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-# CONFIG_RELAY is not set
-CONFIG_NAMESPACES=y
-# CONFIG_UTS_NS is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_HOTPLUG=y
-CONFIG_PRINTK=y
-CONFIG_BUG=y
-CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
-CONFIG_BASE_FULL=y
-CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
-CONFIG_EPOLL=y
-CONFIG_SIGNALFD=y
-CONFIG_TIMERFD=y
-CONFIG_EVENTFD=y
-CONFIG_SHMEM=y
-CONFIG_AIO=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=y
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
-# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
-CONFIG_HAVE_OPROFILE=y
-# CONFIG_KPROBES is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-CONFIG_HAVE_ARCH_TRACEHOOK=y
-CONFIG_HAVE_DMA_ATTRS=y
-CONFIG_USE_GENERIC_SMP_HELPERS=y
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
-CONFIG_SLABINFO=y
-CONFIG_RT_MUTEXES=y
-CONFIG_BASE_SMALL=0
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-CONFIG_STOP_MACHINE=y
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_INTEGRITY is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
-CONFIG_FREEZER=y
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_ZONE_DMA=y
-CONFIG_QUICKLIST=y
-CONFIG_MMU=y
-CONFIG_SWIOTLB=y
-CONFIG_IOMMU_HELPER=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_HAVE_SETUP_PER_CPU_AREA=y
-CONFIG_DMI=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-CONFIG_AUDIT_ARCH=y
-CONFIG_PARAVIRT_GUEST=y
-CONFIG_PARAVIRT=y
-CONFIG_XEN=y
-CONFIG_XEN_XENCOMM=y
-CONFIG_NO_IDLE_HZ=y
-# CONFIG_IA64_GENERIC is not set
-# CONFIG_IA64_DIG is not set
-# CONFIG_IA64_DIG_VTD is not set
-# CONFIG_IA64_HP_ZX1 is not set
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_SGI_UV is not set
-# CONFIG_IA64_HP_SIM is not set
-CONFIG_IA64_XEN_GUEST=y
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-CONFIG_IA64_PAGE_SIZE_16KB=y
-# CONFIG_IA64_PAGE_SIZE_64KB is not set
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-CONFIG_HZ=250
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-# CONFIG_SCHED_HRTICK is not set
-CONFIG_IA64_L1_CACHE_SHIFT=7
-CONFIG_IA64_CYCLONE=y
-CONFIG_IOSAPIC=y
-CONFIG_FORCE_MAX_ZONEORDER=17
-# CONFIG_VIRT_CPU_ACCOUNTING is not set
-CONFIG_SMP=y
-CONFIG_NR_CPUS=16
-CONFIG_HOTPLUG_CPU=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
-# CONFIG_SCHED_SMT is not set
-CONFIG_PERMIT_BSP_REMOVE=y
-CONFIG_FORCE_CPEI_RETARGET=y
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
-CONFIG_PAGEFLAGS_EXTENDED=y
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_MIGRATION=y
-CONFIG_PHYS_ADDR_T_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_BOUNCE=y
-CONFIG_NR_QUICK=1
-CONFIG_VIRT_TO_BUS=y
-CONFIG_UNEVICTABLE_LRU=y
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-# CONFIG_IA64_MC_ERR_INJECT is not set
-# CONFIG_IA64_ESI is not set
-# CONFIG_IA64_HP_AML_NFW is not set
-CONFIG_KEXEC=y
-# CONFIG_CRASH_DUMP is not set
-
-#
-# Firmware Drivers
-#
-# CONFIG_FIRMWARE_MEMMAP is not set
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_DMIID=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_BINFMT_MISC=m
-
-#
-# Power management and ACPI options
-#
-CONFIG_PM=y
-# CONFIG_PM_DEBUG is not set
-CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND=y
-CONFIG_SUSPEND_FREEZER=y
-CONFIG_ACPI=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_PROCFS=y
-CONFIG_ACPI_PROCFS_POWER=y
-CONFIG_ACPI_SYSFS_POWER=y
-CONFIG_ACPI_PROC_EVENT=y
CONFIG_ACPI_BUTTON=m
+CONFIG_ACPI_CONTAINER=m
CONFIG_ACPI_FAN=m
-# CONFIG_ACPI_DOCK is not set
CONFIG_ACPI_PROCESSOR=m
-CONFIG_ACPI_HOTPLUG_CPU=y
-CONFIG_ACPI_THERMAL=m
-# CONFIG_ACPI_CUSTOM_DSDT is not set
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-# CONFIG_ACPI_PCI_SLOT is not set
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_CONTAINER=m
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCIEPORTBUS is not set
-CONFIG_ARCH_SUPPORTS_MSI=y
-# CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCI_STUB is not set
-CONFIG_HOTPLUG_PCI=m
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_ACPI=m
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_PCCARD is not set
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NET_NS is not set
-CONFIG_COMPAT_NET_DEV_OPS=y
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
+CONFIG_ACPI_PROCFS=y
+CONFIG_AGP=m
CONFIG_ARPD=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-# CONFIG_INET_LRO is not set
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_IP_DCCP is not set
-# CONFIG_IP_SCTP is not set
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_SCHED is not set
-# CONFIG_DCB is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
-# CONFIG_WIRELESS is not set
-# CONFIG_WIMAX is not set
-# CONFIG_RFKILL is not set
-# CONFIG_NET_9P is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-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_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
-# CONFIG_MTD is not set
-# CONFIG_PARPORT is not set
-CONFIG_PNP=y
-CONFIG_PNP_DEBUG_MESSAGES=y
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-CONFIG_BLK_DEV_LOOP=m
+CONFIG_AUTOFS4_FS=y
+CONFIG_AUTOFS_FS=y
+CONFIG_BINFMT_MISC=m
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_BLK_DEV_CMD64X=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_XIP is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-CONFIG_XEN_BLKDEV_FRONTEND=y
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_MISC_DEVICES=y
-# CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-# CONFIG_ICS932S401 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_C2PORT is not set
-CONFIG_HAVE_IDE=y
-CONFIG_IDE=y
-
-#
-# Please see Documentation/ide/ide.txt for help/info on IDE drives
-#
-CONFIG_IDE_TIMINGS=y
-CONFIG_IDE_ATAPI=y
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_IDE_GD=y
-CONFIG_IDE_GD_ATA=y
-# CONFIG_IDE_GD_ATAPI is not set
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_PROC_FS=y
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEDMA_SFF=y
-
-#
-# PCI IDE chipsets support
-#
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_PCIBUS_ORDER=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_DM=m
CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_LOOP=m
+CONFIG_BLK_DEV_MD=m
+CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_PIIX=y
-# CONFIG_BLK_DEV_IT8172 is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-CONFIG_BLK_DEV_IDEDMA=y
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_TGT is not set
-CONFIG_SCSI_NETLINK=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
+CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-CONFIG_SCSI_WAIT_SCAN=m
-
-#
-# SCSI Transports
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_SCSI_CXGB3_ISCSI is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_LIBFC is not set
-# CONFIG_FCOE is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_STEX is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-CONFIG_SCSI_SYM53C8XX_MMIO=y
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_DH is not set
-# CONFIG_ATA is not set
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-# CONFIG_MD_RAID10 is not set
-# CONFIG_MD_RAID456 is not set
-CONFIG_MD_MULTIPATH=m
-# CONFIG_MD_FAULTY is not set
-CONFIG_BLK_DEV_DM=m
-# CONFIG_DM_DEBUG is not set
+CONFIG_CHR_DEV_ST=m
+CONFIG_CIFS=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_PCBC=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
+CONFIG_DM_SNAPSHOT=m
CONFIG_DM_ZERO=m
-# CONFIG_DM_MULTIPATH is not set
-# CONFIG_DM_DELAY is not set
-# CONFIG_DM_UEVENT is not set
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=y
-# CONFIG_FUSION_SAS is not set
-CONFIG_FUSION_MAX_SGE=128
-CONFIG_FUSION_CTL=y
-# CONFIG_FUSION_LOGGING is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# Enable only one of the two stacks, unless you know what you are doing
-#
-# CONFIG_FIREWIRE is not set
-# CONFIG_IEEE1394 is not set
-# CONFIG_I2O is not set
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_VETH is not set
-# CONFIG_NET_SB1000 is not set
-# CONFIG_ARCNET is not set
-CONFIG_PHYLIB=y
-
-#
-# MII PHY device drivers
-#
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_LXT_PHY is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_VITESSE_PHY is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_BROADCOM_PHY is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_STE10XP is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_FIXED_PHY is not set
-# CONFIG_MDIO_BITBANG is not set
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=m
-# CONFIG_TULIP_MWI is not set
-# CONFIG_TULIP_MMIO is not set
-# CONFIG_TULIP_NAPI is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_ULI526X is not set
-# CONFIG_HP100 is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-CONFIG_E100=m
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_R6040 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SMSC9420 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-# CONFIG_ATL2 is not set
-CONFIG_NETDEV_1000=y
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-CONFIG_E1000=y
-# CONFIG_E1000E is not set
-# CONFIG_IP1000 is not set
-# CONFIG_IGB is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_VIA_VELOCITY is not set
-CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1E is not set
-# CONFIG_JME is not set
-CONFIG_NETDEV_10000=y
-# CONFIG_CHELSIO_T1 is not set
-CONFIG_CHELSIO_T3_DEPENDS=y
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_ENIC is not set
-# CONFIG_IXGBE is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NIU is not set
-# CONFIG_MLX4_EN is not set
-# CONFIG_MLX4_CORE is not set
-# CONFIG_TEHUTI is not set
-# CONFIG_BNX2X is not set
-# CONFIG_QLGE is not set
-# CONFIG_SFC is not set
-# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
-
-#
-# Enable WiMAX (Networking options) to see the WiMAX drivers
-#
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_WAN is not set
-CONFIG_XEN_NETDEV_FRONTEND=y
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-CONFIG_NETCONSOLE=y
-# CONFIG_NETCONSOLE_DYNAMIC is not set
-CONFIG_NETPOLL=y
-# CONFIG_NETPOLL_TRAP is not set
-CONFIG_NET_POLL_CONTROLLER=y
-# CONFIG_ISDN is not set
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_POLLDEV is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=y
-CONFIG_MOUSE_PS2_ALPS=y
-CONFIG_MOUSE_PS2_LOGIPS2PP=y
-CONFIG_MOUSE_PS2_SYNAPTICS=y
-CONFIG_MOUSE_PS2_LIFEBOOK=y
-CONFIG_MOUSE_PS2_TRACKPOINT=y
-# CONFIG_MOUSE_PS2_ELANTECH is not set
-# CONFIG_MOUSE_PS2_TOUCHKIT is not set
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_BCM5974 is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-CONFIG_SERIO_LIBPS2=y
-# CONFIG_SERIO_RAW is not set
-CONFIG_GAMEPORT=m
-# CONFIG_GAMEPORT_NS558 is not set
-# CONFIG_GAMEPORT_L4 is not set
-# CONFIG_GAMEPORT_EMU10K1 is not set
-# CONFIG_GAMEPORT_FM801 is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_CONSOLE_TRANSLATIONS=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_SYNCLINK_GT is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-# CONFIG_NOZOMI is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_PNP=y
-CONFIG_SERIAL_8250_NR_UARTS=6
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-CONFIG_HVC_DRIVER=y
-CONFIG_HVC_IRQ=y
-CONFIG_HVC_XEN=y
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_EFI_RTC=y
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-CONFIG_RAW_DRIVER=m
-CONFIG_MAX_RAW_DEVS=256
-CONFIG_HPET=y
-CONFIG_HPET_MMAP=y
-# CONFIG_HANGCHECK_TIMER is not set
-# CONFIG_TCG_TPM is not set
-CONFIG_DEVPORT=y
-CONFIG_I2C=m
-CONFIG_I2C_BOARDINFO=y
-# CONFIG_I2C_CHARDEV is not set
-CONFIG_I2C_HELPER_AUTO=y
-CONFIG_I2C_ALGOBIT=m
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# PC SMBus host controller drivers
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-
-#
-# I2C system bus drivers (mostly embedded / system-on-chip)
-#
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
-
-#
-# External I2C/SMBus adapter drivers
-#
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_TINY_USB is not set
-
-#
-# Graphics adapter I2C/DDC channel drivers
-#
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Other I2C/SMBus bus drivers
-#
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-# CONFIG_W1 is not set
-CONFIG_POWER_SUPPLY=y
-# CONFIG_POWER_SUPPLY_DEBUG is not set
-# CONFIG_PDA_POWER is not set
-# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-CONFIG_HWMON=y
-# CONFIG_HWMON_VID is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7473 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_I5K_AMB is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_HWMON_DEBUG_CHIP is not set
-CONFIG_THERMAL=m
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_WATCHDOG is not set
-CONFIG_SSB_POSSIBLE=y
-
-#
-# Sonics Silicon Backplane
-#
-# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_REGULATOR is not set
-
-#
-# Multimedia devices
-#
-
-#
-# Multimedia core support
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
-
-#
-# Multimedia drivers
-#
-CONFIG_DAB=y
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-CONFIG_AGP=m
CONFIG_DRM=m
-CONFIG_DRM_TDFX=m
+CONFIG_DRM_MGA=m
CONFIG_DRM_R128=m
CONFIG_DRM_RADEON=m
-CONFIG_DRM_MGA=m
CONFIG_DRM_SIS=m
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-
-#
-# Display device support
-#
-# CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_SOUND is not set
-CONFIG_HID_SUPPORT=y
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-# CONFIG_HIDRAW is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_HID_PID is not set
-# CONFIG_USB_HIDDEV is not set
-
-#
-# Special HID drivers
-#
-CONFIG_HID_COMPAT=y
-CONFIG_HID_A4TECH=y
-CONFIG_HID_APPLE=y
-CONFIG_HID_BELKIN=y
-CONFIG_HID_CHERRY=y
-CONFIG_HID_CHICONY=y
-CONFIG_HID_CYPRESS=y
-CONFIG_HID_EZKEY=y
+CONFIG_DRM_TDFX=m
+CONFIG_DUMMY=m
+CONFIG_E1000=y
+CONFIG_E100=m
+CONFIG_EFI_PARTITION=y
+CONFIG_EFI_RTC=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_FORCE_CPEI_RETARGET=y
+CONFIG_FUSION_CTL=y
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION=y
+CONFIG_GAMEPORT=m
CONFIG_HID_GYRATION=y
-CONFIG_HID_LOGITECH=y
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-CONFIG_HID_MICROSOFT=y
-CONFIG_HID_MONTEREY=y
CONFIG_HID_NTRIG=y
CONFIG_HID_PANTHERLORD=y
-# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
CONFIG_HID_SUNPLUS=y
-# CONFIG_GREENASIA_FF is not set
CONFIG_HID_TOPSEED=y
-# CONFIG_THRUSTMASTER_FF is not set
-# CONFIG_ZEROPLUS_FF is not set
-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_DEBUG is not set
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_DEVICE_CLASS=y
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_C67X00_HCD is not set
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=y
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_HWA_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_TMC is not set
-
-#
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
-#
-
-#
-# see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
-# CONFIG_USB_GADGET is not set
-
-#
-# OTG and related infrastructure
-#
-# CONFIG_UWB is not set
-# CONFIG_MMC is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_NEW_LEDS is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_INFINIBAND is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_UIO is not set
-CONFIG_XEN_BALLOON=y
-CONFIG_XEN_SCRUB_PAGES=y
-CONFIG_XENFS=y
-CONFIG_XEN_COMPAT_XENFS=y
-# CONFIG_STAGING is not set
-# CONFIG_MSPEC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT2_FS_XIP is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-# CONFIG_EXT4_FS is not set
-CONFIG_JBD=y
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_FILE_LOCKING=y
-CONFIG_XFS_FS=y
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_BTRFS_FS is not set
-CONFIG_DNOTIFY=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=m
+CONFIG_HOTPLUG_PCI=m
+CONFIG_HPET=y
+CONFIG_HUGETLBFS=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_IA64_CYCLONE=y
+CONFIG_IA64_GRANULE_16MB=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IA64_XEN_GUEST=y
+CONFIG_IDE=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_IKCONFIG=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET=y
CONFIG_INOTIFY=y
-CONFIG_INOTIFY_USER=y
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_AUTOFS4_FS=y
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_IP_MULTICAST=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=m
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_RW is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_PROC_PAGE_MONITOR=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-# CONFIG_CONFIGFS_FS is not set
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_SQUASHFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KEXEC=y
+CONFIG_LOG_BUF_SHIFT=20
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MCKINLEY=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_MULTIPATH=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_NETCONSOLE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NET_PCI=y
+CONFIG_NET_TULIP=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V4=y
CONFIG_NFS_FS=m
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-CONFIG_NFSD_V4=y
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=m
-CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_REGISTER_V4 is not set
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="cp437"
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=m
CONFIG_NLS_CODEPAGE_775=m
@@ -1384,15 +131,14 @@ 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_874=m
CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_936=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 is not set
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=m
CONFIG_NLS_ISO8859_3=m
@@ -1400,200 +146,54 @@ CONFIG_NLS_ISO8859_4=m
CONFIG_NLS_ISO8859_5=m
CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_8=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_NLS_UTF8=m
-# CONFIG_DLM is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_FRAME_WARN=2048
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
-CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
-CONFIG_SCHED_DEBUG=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-CONFIG_DEBUG_MEMORY_INIT=y
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-# CONFIG_RCU_TORTURE_TEST is not set
+CONFIG_NR_CPUS=16
+CONFIG_NTFS_FS=m
+CONFIG_PACKET=y
+CONFIG_PARAVIRT_GUEST=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+CONFIG_PERMIT_BSP_REMOVE=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_PROC_KCORE=y
+CONFIG_RAW_DRIVER=m
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-
-#
-# Tracers
-#
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_BOOT_TRACER is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
-# CONFIG_SAMPLES is not set
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
-# CONFIG_IA64_PRINT_HAZARDS is not set
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-CONFIG_CRYPTO=y
-
-#
-# Crypto core or helper
-#
-# CONFIG_CRYPTO_FIPS is not set
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_ALGAPI2=y
-CONFIG_CRYPTO_AEAD2=y
-CONFIG_CRYPTO_BLKCIPHER=m
-CONFIG_CRYPTO_BLKCIPHER2=y
-CONFIG_CRYPTO_HASH=y
-CONFIG_CRYPTO_HASH2=y
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CRYPTO_MANAGER=m
-CONFIG_CRYPTO_MANAGER2=y
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Authenticated Encryption with Associated Data
-#
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_SEQIV is not set
-
-#
-# Block modes
-#
-CONFIG_CRYPTO_CBC=m
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-CONFIG_CRYPTO_ECB=m
-# CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_XTS is not set
-
-#
-# Hash modes
-#
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-
-#
-# Digest
-#
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_WP512 is not set
-
-#
-# Ciphers
-#
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-
-#
-# Compression
-#
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_LZO is not set
-
-#
-# Random Number Generation
-#
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRYPTO_HW=y
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
-CONFIG_HAVE_KVM=y
-CONFIG_VIRTUALIZATION=y
-# CONFIG_KVM is not set
-# CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTIO_BALLOON is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CRC_ITU_T=m
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_HAS_DMA=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_IRQ_PER_CPU=y
-# CONFIG_IOMMU_API is not set
+CONFIG_REISERFS_FS_POSIX_ACL=y
+CONFIG_REISERFS_FS_SECURITY=y
+CONFIG_REISERFS_FS_XATTR=y
+CONFIG_REISERFS_FS=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=6
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_SMB_FS=m
+CONFIG_SMB_NLS_DEFAULT=y
+CONFIG_SMP=y
+CONFIG_SYN_COOKIES=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_SYSVIPC=y
+CONFIG_TIGON3=y
+CONFIG_TMPFS=y
+CONFIG_TULIP=m
+CONFIG_UDF_FS=m
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_UNIX=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_STORAGE=m
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB=y
+CONFIG_VFAT_FS=y
+CONFIG_XFS_FS=y
diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig
index 3cec65b534c2..de0b68e0d48e 100644
--- a/arch/ia64/configs/zx1_defconfig
+++ b/arch/ia64/configs/zx1_defconfig
@@ -1,1460 +1,85 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.21-rc3
-# Thu Mar 8 11:04:20 2007
-#
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_LOCALVERSION_AUTO=y
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_IPC_NS is not set
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_CPUSETS is not set
-CONFIG_SYSFS_DEPRECATED=y
-# CONFIG_RELAY is not set
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SYSCTL=y
-# CONFIG_EMBEDDED is not set
-CONFIG_SYSCTL_SYSCALL=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS 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_SHMEM=y
-CONFIG_SLUB=y
-CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
-CONFIG_BASE_SMALL=0
-# CONFIG_SLOB is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
-CONFIG_STOP_MACHINE=y
-
-#
-# Block layer
-#
-CONFIG_BLOCK=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_DEFAULT_AS=y
-# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-# CONFIG_DEFAULT_NOOP is not set
-CONFIG_DEFAULT_IOSCHED="anticipatory"
-
-#
-# Processor type and features
-#
-CONFIG_IA64=y
-CONFIG_64BIT=y
-CONFIG_ZONE_DMA=y
-CONFIG_MMU=y
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
-CONFIG_GENERIC_FIND_NEXT_BIT=y
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_TIME=y
-CONFIG_DMI=y
-CONFIG_EFI=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
-CONFIG_AUDIT_ARCH=y
-# CONFIG_IA64_GENERIC is not set
-# CONFIG_IA64_DIG is not set
-CONFIG_IA64_HP_ZX1=y
-# CONFIG_IA64_HP_ZX1_SWIOTLB is not set
-# CONFIG_IA64_SGI_SN2 is not set
-# CONFIG_IA64_HP_SIM is not set
-# CONFIG_ITANIUM is not set
-CONFIG_MCKINLEY=y
-# CONFIG_IA64_PAGE_SIZE_4KB is not set
-# CONFIG_IA64_PAGE_SIZE_8KB is not set
-CONFIG_IA64_PAGE_SIZE_16KB=y
-# CONFIG_IA64_PAGE_SIZE_64KB is not set
-CONFIG_PGTABLE_3=y
-# CONFIG_PGTABLE_4 is not set
-# CONFIG_HZ_100 is not set
-CONFIG_HZ_250=y
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_1000 is not set
-CONFIG_HZ=250
-CONFIG_IA64_L1_CACHE_SHIFT=7
-# CONFIG_IA64_CYCLONE is not set
-CONFIG_IOSAPIC=y
-CONFIG_FORCE_MAX_ZONEORDER=17
-CONFIG_SMP=y
-CONFIG_NR_CPUS=16
-CONFIG_HOTPLUG_CPU=y
-CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
-# CONFIG_SCHED_SMT is not set
-# CONFIG_PERMIT_BSP_REMOVE is not set
-# CONFIG_PREEMPT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-CONFIG_FLATMEM_MANUAL=y
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-CONFIG_FLATMEM=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_RESOURCES_64BIT=y
-CONFIG_ZONE_DMA_FLAG=1
-CONFIG_ARCH_SELECT_MEMORY_MODEL=y
-CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
-CONFIG_ARCH_FLATMEM_ENABLE=y
-CONFIG_ARCH_SPARSEMEM_ENABLE=y
-CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
-CONFIG_ARCH_POPULATES_NODE_MAP=y
-CONFIG_VIRTUAL_MEM_MAP=y
-CONFIG_HOLES_IN_ZONE=y
-CONFIG_IA64_MCA_RECOVERY=y
-CONFIG_PERFMON=y
-CONFIG_IA64_PALINFO=y
-# CONFIG_IA64_ESI is not set
-# CONFIG_KEXEC is not set
-CONFIG_CRASH_DUMP=y
-
-#
-# Firmware Drivers
-#
-CONFIG_EFI_VARS=y
-CONFIG_EFI_PCDP=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-
-#
-# Power management and ACPI
-#
-CONFIG_PM=y
-CONFIG_PM_LEGACY=y
-# CONFIG_PM_DEBUG is not set
-# CONFIG_PM_SYSFS_DEPRECATED is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
CONFIG_ACPI_PROCFS=y
-CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_FAN=y
-# CONFIG_ACPI_DOCK is not set
-CONFIG_ACPI_PROCESSOR=y
-CONFIG_ACPI_HOTPLUG_CPU=y
-CONFIG_ACPI_THERMAL=y
-CONFIG_ACPI_BLACKLIST_YEAR=0
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_SYSTEM=y
-CONFIG_ACPI_CONTAINER=y
-
-#
-# CPU Frequency scaling
-#
-# CONFIG_CPU_FREQ is not set
-
-#
-# Bus options (PCI, PCMCIA)
-#
-CONFIG_PCI=y
-CONFIG_PCI_DOMAINS=y
-# CONFIG_PCIEPORTBUS is not set
-# CONFIG_PCI_MSI is not set
-# CONFIG_PCI_DEBUG is not set
-
-#
-# PCI Hotplug Support
-#
-CONFIG_HOTPLUG_PCI=y
-# CONFIG_HOTPLUG_PCI_FAKE is not set
-CONFIG_HOTPLUG_PCI_ACPI=y
-# CONFIG_HOTPLUG_PCI_ACPI_IBM is not set
-# CONFIG_HOTPLUG_PCI_CPCI is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-# CONFIG_PCCARD is not set
-
-#
-# Networking
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_NETDEBUG is not set
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_UNIX=y
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_INET_XFRM_MODE_TRANSPORT=y
-CONFIG_INET_XFRM_MODE_TUNNEL=y
-CONFIG_INET_XFRM_MODE_BEET=y
-CONFIG_INET_DIAG=y
-CONFIG_INET_TCP_DIAG=y
-# CONFIG_TCP_CONG_ADVANCED is not set
-CONFIG_TCP_CONG_CUBIC=y
-CONFIG_DEFAULT_TCP_CONG="cubic"
-# CONFIG_TCP_MD5SIG is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_NETWORK_SECMARK is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# Core Netfilter Configuration
-#
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NF_CONNTRACK_ENABLED is not set
-# CONFIG_NETFILTER_XTABLES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-
-#
-# DCCP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_DCCP is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-
-#
-# TIPC Configuration (EXPERIMENTAL)
-#
-# CONFIG_TIPC is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_TCPPROBE is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-# CONFIG_IEEE80211 is not set
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_SYS_HYPERVISOR is not set
-
-#
-# Connector - unified userspace <-> kernelspace linker
-#
-# CONFIG_CONNECTOR is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play support
-#
-CONFIG_PNP=y
-# CONFIG_PNP_DEBUG is not set
-
-#
-# Protocols
-#
-CONFIG_PNPACPI=y
-
-#
-# Block devices
-#
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_AGP_HP_ZX1=y
+CONFIG_AGP=y
+CONFIG_AUTOFS_FS=y
+CONFIG_BINFMT_MISC=y
+CONFIG_BLK_DEV_CMD64X=y
+CONFIG_BLK_DEV_GENERIC=y
+CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_INITRD=y
CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=16
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_ATA_OVER_ETH is not set
-
-#
-# Misc devices
-#
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_TIFM_CORE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_IDE_MAX_HWIFS=4
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_IDE_GENERIC is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-# CONFIG_IDEDMA_PCI_AUTO is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-CONFIG_BLK_DEV_CMD64X=y
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_IDE_ARM is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_RAID_ATTRS is not set
-CONFIG_SCSI=y
-# CONFIG_SCSI_TGT is not set
-CONFIG_SCSI_NETLINK=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_CHR_DEV_OSST=y
-CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
+CONFIG_BLK_DEV_SR=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_CHR_DEV_OSST=y
CONFIG_CHR_DEV_SG=y
-# CONFIG_CHR_DEV_SCH is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-# CONFIG_SCSI_SCAN_ASYNC is not set
-
-#
-# SCSI Transports
-#
-CONFIG_SCSI_SPI_ATTRS=y
-CONFIG_SCSI_FC_ATTRS=y
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_ISCSI_TCP is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_STEX is not set
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1
-CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16
-CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64
-CONFIG_SCSI_SYM53C8XX_MMIO=y
-CONFIG_SCSI_QLOGIC_1280=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_LPFC is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_SRP is not set
-
-#
-# Serial ATA (prod) and Parallel ATA (experimental) drivers
-#
-# CONFIG_ATA is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_FC=y
-# CONFIG_FUSION_SAS is not set
-CONFIG_FUSION_MAX_SGE=128
-CONFIG_FUSION_CTL=m
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
+CONFIG_CHR_DEV_ST=y
+CONFIG_CRASH_DUMP=y
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DRM_RADEON=y
+CONFIG_DRM=y
CONFIG_DUMMY=y
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_NET_SB1000 is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# PHY device support
-#
-# CONFIG_PHYLIB is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_CASSINI is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-CONFIG_NET_TULIP=y
-# CONFIG_DE2104X is not set
-CONFIG_TULIP=y
-CONFIG_TULIP_MWI=y
-CONFIG_TULIP_MMIO=y
-CONFIG_TULIP_NAPI=y
-CONFIG_TULIP_NAPI_HW_MITIGATION=y
-# CONFIG_DE4X5 is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_DM9102 is not set
-# CONFIG_ULI526X is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-CONFIG_E100=y
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_SC92031 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
CONFIG_E1000=y
-# CONFIG_E1000_NAPI is not set
-# CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_VIA_VELOCITY is not set
-CONFIG_TIGON3=y
-# CONFIG_BNX2 is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_ATL1 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NETXEN_NIC is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-# CONFIG_INPUT_FF_MEMLESS is not set
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=y
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Hardware I/O ports
-#
-CONFIG_SERIO=y
-# CONFIG_SERIO_I8042 is not set
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_PCIPS2 is not set
-# CONFIG_SERIO_RAW is not set
-# CONFIG_GAMEPORT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_VT_HW_CONSOLE_BINDING is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_PCI=y
-CONFIG_SERIAL_8250_PNP=y
-CONFIG_SERIAL_8250_NR_UARTS=8
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_RSA is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_JSM is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_E100=y
+CONFIG_EFI_PARTITION=y
CONFIG_EFI_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-CONFIG_AGP=y
-CONFIG_AGP_HP_ZX1=y
-CONFIG_DRM=y
-# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_R128 is not set
-CONFIG_DRM_RADEON=y
-# CONFIG_DRM_MGA is not set
-# CONFIG_DRM_SIS is not set
-# CONFIG_DRM_VIA is not set
-# CONFIG_DRM_SAVAGE is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HPET is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# TPM devices
-#
-# CONFIG_TCG_TPM is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_ALGOPCF=y
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PASEMI is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Hardware Monitoring support
-#
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_SM501 is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=y
-CONFIG_VIDEO_V4L1=y
-CONFIG_VIDEO_V4L1_COMPAT=y
-CONFIG_VIDEO_V4L2=y
-
-#
-# Video Capture Adapters
-#
-
-#
-# Video Capture Adapters
-#
-# CONFIG_VIDEO_ADV_DEBUG is not set
-CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CPIA2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-
-#
-# V4L USB devices
-#
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_QUICKCAM_MESSENGER is not set
-# CONFIG_USB_ET61X251 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-# CONFIG_USB_W9968CF is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_ZC0301 is not set
-# CONFIG_USB_PWC is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_USB_DSBR is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# Graphics support
-#
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_FB=y
-# CONFIG_FIRMWARE_EDID is not set
-CONFIG_FB_DDC=y
-CONFIG_FB_CFB_FILLRECT=y
-CONFIG_FB_CFB_COPYAREA=y
-CONFIG_FB_CFB_IMAGEBLIT=y
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_MACMODES is not set
-CONFIG_FB_BACKLIGHT=y
-CONFIG_FB_MODE_HELPERS=y
-# CONFIG_FB_TILEBLITTING is not set
-
-#
-# Frambuffer hardware drivers
-#
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-CONFIG_FB_RADEON=y
-CONFIG_FB_RADEON_I2C=y
-CONFIG_FB_RADEON_BACKLIGHT=y
-CONFIG_FB_RADEON_DEBUG=y
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_VGACON_SOFT_SCROLLBACK is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_HWDEP=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_SEQUENCER=y
-# CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_PCM_OSS_PLUGINS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_DYNAMIC_MINORS is not set
-CONFIG_SND_SUPPORT_OLD_API=y
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_MPU401_UART=y
-CONFIG_SND_OPL3_LIB=y
-CONFIG_SND_AC97_CODEC=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# PCI devices
-#
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-CONFIG_SND_FM801=y
-# CONFIG_SND_FM801_TEA575X_BOOL is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-
-#
-# USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# SoC audio support
-#
-# CONFIG_SND_SOC is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-CONFIG_AC97_BUS=y
-
-#
-# HID Devices
-#
-CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
-
-#
-# USB support
-#
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EHCI_BIG_ENDIAN_MMIO is not set
-# CONFIG_USB_ISP116X_HCD is not set
-CONFIG_USB_OHCI_HCD=y
-# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
-# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=y
-# CONFIG_USB_SL811_HCD is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
-#
-
-#
-# may also be needed; see USB_STORAGE Help for more information
-#
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_LIBUSUAL is not set
-
-#
-# USB Input Devices
-#
-CONFIG_USB_HID=y
-# CONFIG_USB_HIDINPUT_POWERBOOK is not set
-# CONFIG_HID_FF is not set
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_ACECAD is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_TOUCHSCREEN is not set
-# CONFIG_USB_YEALINK is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-# CONFIG_USB_ATI_REMOTE2 is not set
-# CONFIG_USB_KEYSPAN_REMOTE is not set
-# CONFIG_USB_APPLETOUCH is not set
-# CONFIG_USB_GTCO is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-
-#
-# USB Network Adapters
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET_MII is not set
-# CONFIG_USB_USBNET is not set
-CONFIG_USB_MON=y
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGET is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_IOWARRIOR is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# LED devices
-#
-# CONFIG_NEW_LEDS is not set
-
-#
-# LED drivers
-#
-
-#
-# LED Triggers
-#
-
-#
-# InfiniBand support
-#
-# CONFIG_INFINIBAND is not set
-
-#
-# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
-#
-
-#
-# Real Time Clock
-#
-# CONFIG_RTC_CLASS is not set
-
-#
-# DMA Engine support
-#
-# CONFIG_DMA_ENGINE is not set
-
-#
-# DMA Clients
-#
-
-#
-# DMA Devices
-#
-
-#
-# Auxiliary Display support
-#
-
-#
-# Virtualization
-#
-# CONFIG_MSPEC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
+CONFIG_EFI_VARS=y
+CONFIG_EXPERIMENTAL=y
CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_INOTIFY is not set
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FUSE_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
+CONFIG_FB_RADEON_DEBUG=y
+CONFIG_FB_RADEON=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FUSION_CTL=m
+CONFIG_FUSION_FC=y
+CONFIG_FUSION_SPI=y
+CONFIG_FUSION=y
+CONFIG_HOTPLUG_CPU=y
+CONFIG_HOTPLUG_PCI_ACPI=y
+CONFIG_HOTPLUG_PCI=y
+CONFIG_HUGETLBFS=y
+# CONFIG_HWMON is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C_CHARDEV=y
+CONFIG_IA64_HP_ZX1=y
+CONFIG_IA64_MCA_RECOVERY=y
+CONFIG_IA64_PALINFO=y
+CONFIG_IA64_PRINT_HAZARDS=y
+CONFIG_IDE=y
+CONFIG_INET=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_JOYDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_IP_MULTICAST=y
+# CONFIG_IPV6 is not set
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
+CONFIG_KPROBES=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_MCKINLEY=y
+CONFIG_MODULES=y
CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_PROC_VMCORE=y
-CONFIG_PROC_SYSCTL=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-CONFIG_HUGETLBFS=y
-CONFIG_HUGETLB_PAGE=y
-CONFIG_RAMFS=y
-# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NETFILTER=y
+CONFIG_NET_PCI=y
+CONFIG_NET_TULIP=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
-CONFIG_NFS_COMMON=y
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=y
-CONFIG_RPCSEC_GSS_KRB5=y
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_9P_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_KARMA_PARTITION is not set
-CONFIG_EFI_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_1251=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_737=y
CONFIG_NLS_CODEPAGE_775=y
@@ -1470,15 +95,14 @@ CONFIG_NLS_CODEPAGE_864=y
CONFIG_NLS_CODEPAGE_865=y
CONFIG_NLS_CODEPAGE_866=y
CONFIG_NLS_CODEPAGE_869=y
-CONFIG_NLS_CODEPAGE_936=y
-CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_874=y
CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_936=y
CONFIG_NLS_CODEPAGE_949=y
-CONFIG_NLS_CODEPAGE_874=y
-CONFIG_NLS_ISO8859_8=y
-# CONFIG_NLS_CODEPAGE_1250 is not set
-CONFIG_NLS_CODEPAGE_1251=y
-# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_2=y
CONFIG_NLS_ISO8859_3=y
@@ -1486,125 +110,52 @@ CONFIG_NLS_ISO8859_4=y
CONFIG_NLS_ISO8859_5=y
CONFIG_NLS_ISO8859_6=y
CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_8=y
CONFIG_NLS_ISO8859_9=y
-CONFIG_NLS_ISO8859_13=y
-CONFIG_NLS_ISO8859_14=y
-CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_KOI8_R=y
CONFIG_NLS_KOI8_U=y
CONFIG_NLS_UTF8=y
-
-#
-# Distributed Lock Manager
-#
-# CONFIG_DLM is not set
-
-#
-# Library routines
-#
-CONFIG_BITREVERSE=y
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_PLIST=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_PENDING_IRQ=y
-CONFIG_IRQ_PER_CPU=y
-
-#
-# Instrumentation Support
-#
-# CONFIG_PROFILING is not set
-CONFIG_KPROBES=y
-
-#
-# Kernel hacking
-#
-# CONFIG_PRINTK_TIME is not set
-CONFIG_ENABLE_MUST_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_DEBUG_FS is not set
-# CONFIG_HEADERS_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SHIRQ is not set
-CONFIG_LOG_BUF_SHIFT=17
-CONFIG_DETECT_SOFTLOCKUP=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_TIMER_STATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_LIST is not set
-CONFIG_FORCED_INLINING=y
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_LKDTM is not set
-# CONFIG_FAULT_INJECTION is not set
-CONFIG_IA64_GRANULE_16MB=y
-# CONFIG_IA64_GRANULE_64MB is not set
-CONFIG_IA64_PRINT_HAZARDS=y
-# CONFIG_DISABLE_VHPT is not set
-# CONFIG_IA64_DEBUG_CMPXCHG is not set
-# CONFIG_IA64_DEBUG_IRQ is not set
-CONFIG_SYSVIPC_COMPAT=y
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_MANAGER=y
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_MD4 is not set
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-CONFIG_CRYPTO_ECB=m
-CONFIG_CRYPTO_CBC=y
-CONFIG_CRYPTO_PCBC=m
-# CONFIG_CRYPTO_LRW is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Hardware crypto devices
-#
+CONFIG_NR_CPUS=16
+CONFIG_PACKET=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_PERFMON=y
+CONFIG_PROC_KCORE=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_QLOGIC_1280=y
+CONFIG_SCSI_SYM53C8XX_2=y
+CONFIG_SCSI=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_NR_UARTS=8
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+CONFIG_SMP=y
+CONFIG_SND_FM801=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_SEQUENCER_OSS=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND=y
+CONFIG_SOUND=y
+CONFIG_SYSVIPC=y
+CONFIG_TIGON3=y
+CONFIG_TMPFS=y
+CONFIG_TULIP_MMIO=y
+CONFIG_TULIP_MWI=y
+CONFIG_TULIP_NAPI_HW_MITIGATION=y
+CONFIG_TULIP_NAPI=y
+CONFIG_TULIP=y
+CONFIG_UDF_FS=y
+CONFIG_UNIX=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB=y
+CONFIG_VFAT_FS=y
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index ab985f785c14..744329072f33 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -1696,8 +1696,8 @@ pfm_poll(struct file *filp, poll_table * wait)
return mask;
}
-static int
-pfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long
+pfm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
DPRINT(("pfm_ioctl called\n"));
return -EINVAL;
@@ -2174,15 +2174,15 @@ pfm_no_open(struct inode *irrelevant, struct file *dontcare)
static const struct file_operations pfm_file_ops = {
- .llseek = no_llseek,
- .read = pfm_read,
- .write = pfm_write,
- .poll = pfm_poll,
- .ioctl = pfm_ioctl,
- .open = pfm_no_open, /* special open code to disallow open via /proc */
- .fasync = pfm_fasync,
- .release = pfm_close,
- .flush = pfm_flush
+ .llseek = no_llseek,
+ .read = pfm_read,
+ .write = pfm_write,
+ .poll = pfm_poll,
+ .unlocked_ioctl = pfm_ioctl,
+ .open = pfm_no_open, /* special open code to disallow open via /proc */
+ .fasync = pfm_fasync,
+ .release = pfm_close,
+ .flush = pfm_flush
};
static int
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index e07218a2577f..5a4d044dcb1c 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -6,204 +6,209 @@
#include <asm-generic/vmlinux.lds.h>
-#define IVT_TEXT \
- VMLINUX_SYMBOL(__start_ivt_text) = .; \
- *(.text..ivt) \
- VMLINUX_SYMBOL(__end_ivt_text) = .;
-
OUTPUT_FORMAT("elf64-ia64-little")
OUTPUT_ARCH(ia64)
ENTRY(phys_start)
jiffies = jiffies_64;
+
PHDRS {
- code PT_LOAD;
- percpu PT_LOAD;
- data PT_LOAD;
- note PT_NOTE;
- unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
+ code PT_LOAD;
+ percpu PT_LOAD;
+ data PT_LOAD;
+ note PT_NOTE;
+ unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
}
-SECTIONS
-{
- /* unwind exit sections must be discarded before the rest of the
- sections get included. */
- /DISCARD/ : {
- *(.IA_64.unwind.exit.text)
- *(.IA_64.unwind_info.exit.text)
- *(.comment)
- *(.note)
- }
-
- v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
- phys_start = _start - LOAD_OFFSET;
-
- code : { } :code
- . = KERNEL_START;
-
- _text = .;
- _stext = .;
-
- .text : AT(ADDR(.text) - LOAD_OFFSET)
- {
- IVT_TEXT
- TEXT_TEXT
- SCHED_TEXT
- LOCK_TEXT
- KPROBES_TEXT
- *(.gnu.linkonce.t*)
- }
- .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
- { *(.text2) }
-#ifdef CONFIG_SMP
- .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET)
- { *(.text..lock) }
-#endif
- _etext = .;
- /* Read-only data */
+SECTIONS {
+ /*
+ * unwind exit sections must be discarded before
+ * the rest of the sections get included.
+ */
+ /DISCARD/ : {
+ *(.IA_64.unwind.exit.text)
+ *(.IA_64.unwind_info.exit.text)
+ *(.comment)
+ *(.note)
+ }
- NOTES :code :note /* put .notes in text and mark in PT_NOTE */
- code_continues : {} :code /* switch back to regular program... */
+ v = PAGE_OFFSET; /* this symbol is here to make debugging easier... */
+ phys_start = _start - LOAD_OFFSET;
+
+ code : {
+ } :code
+ . = KERNEL_START;
+
+ _text = .;
+ _stext = .;
+
+ .text : AT(ADDR(.text) - LOAD_OFFSET) {
+ __start_ivt_text = .;
+ *(.text..ivt)
+ __end_ivt_text = .;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ KPROBES_TEXT
+ *(.gnu.linkonce.t*)
+ }
- EXCEPTION_TABLE(16)
+ .text2 : AT(ADDR(.text2) - LOAD_OFFSET) {
+ *(.text2)
+ }
- /* MCA table */
- . = ALIGN(16);
- __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET)
- {
- __start___mca_table = .;
- *(__mca_table)
- __stop___mca_table = .;
+#ifdef CONFIG_SMP
+ .text..lock : AT(ADDR(.text..lock) - LOAD_OFFSET) {
+ *(.text..lock)
+ }
+#endif
+ _etext = .;
+
+ /*
+ * Read-only data
+ */
+ NOTES :code :note /* put .notes in text and mark in PT_NOTE */
+ code_continues : {
+ } : code /* switch back to regular program... */
+
+ EXCEPTION_TABLE(16)
+
+ /* MCA table */
+ . = ALIGN(16);
+ __mca_table : AT(ADDR(__mca_table) - LOAD_OFFSET) {
+ __start___mca_table = .;
+ *(__mca_table)
+ __stop___mca_table = .;
}
- .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET)
- {
- __start___phys_stack_reg_patchlist = .;
- *(.data..patch.phys_stack_reg)
- __end___phys_stack_reg_patchlist = .;
+ .data..patch.phys_stack_reg : AT(ADDR(.data..patch.phys_stack_reg) - LOAD_OFFSET) {
+ __start___phys_stack_reg_patchlist = .;
+ *(.data..patch.phys_stack_reg)
+ __end___phys_stack_reg_patchlist = .;
}
- /* Global data */
- _data = .;
+ /*
+ * Global data
+ */
+ _data = .;
- /* Unwind info & table: */
- . = ALIGN(8);
- .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET)
- { *(.IA_64.unwind_info*) }
- .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET)
- {
- __start_unwind = .;
- *(.IA_64.unwind*)
- __end_unwind = .;
+ /* Unwind info & table: */
+ . = ALIGN(8);
+ .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET) {
+ *(.IA_64.unwind_info*)
+ }
+ .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET) {
+ __start_unwind = .;
+ *(.IA_64.unwind*)
+ __end_unwind = .;
} :code :unwind
- code_continues2 : {} : code
+ code_continues2 : {
+ } : code
- RODATA
+ RODATA
- .opd : AT(ADDR(.opd) - LOAD_OFFSET)
- { *(.opd) }
-
- /* Initialization code and data: */
+ .opd : AT(ADDR(.opd) - LOAD_OFFSET) {
+ *(.opd)
+ }
- . = ALIGN(PAGE_SIZE);
- __init_begin = .;
+ /*
+ * Initialization code and data:
+ */
+ . = ALIGN(PAGE_SIZE);
+ __init_begin = .;
- INIT_TEXT_SECTION(PAGE_SIZE)
- INIT_DATA_SECTION(16)
+ INIT_TEXT_SECTION(PAGE_SIZE)
+ INIT_DATA_SECTION(16)
- .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET)
- {
- __start___vtop_patchlist = .;
- *(.data..patch.vtop)
- __end___vtop_patchlist = .;
+ .data..patch.vtop : AT(ADDR(.data..patch.vtop) - LOAD_OFFSET) {
+ __start___vtop_patchlist = .;
+ *(.data..patch.vtop)
+ __end___vtop_patchlist = .;
}
- .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET)
- {
- __start___rse_patchlist = .;
- *(.data..patch.rse)
- __end___rse_patchlist = .;
+ .data..patch.rse : AT(ADDR(.data..patch.rse) - LOAD_OFFSET) {
+ __start___rse_patchlist = .;
+ *(.data..patch.rse)
+ __end___rse_patchlist = .;
}
- .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET)
- {
- __start___mckinley_e9_bundles = .;
- *(.data..patch.mckinley_e9)
- __end___mckinley_e9_bundles = .;
+ .data..patch.mckinley_e9 : AT(ADDR(.data..patch.mckinley_e9) - LOAD_OFFSET) {
+ __start___mckinley_e9_bundles = .;
+ *(.data..patch.mckinley_e9)
+ __end___mckinley_e9_bundles = .;
}
#if defined(CONFIG_PARAVIRT)
- . = ALIGN(16);
- .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET)
- {
- __start_paravirt_bundles = .;
- *(.paravirt_bundles)
- __stop_paravirt_bundles = .;
- }
- . = ALIGN(16);
- .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET)
- {
- __start_paravirt_insts = .;
- *(.paravirt_insts)
- __stop_paravirt_insts = .;
- }
- . = ALIGN(16);
- .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET)
- {
- __start_paravirt_branches = .;
- *(.paravirt_branches)
- __stop_paravirt_branches = .;
+ . = ALIGN(16);
+ .paravirt_bundles : AT(ADDR(.paravirt_bundles) - LOAD_OFFSET) {
+ __start_paravirt_bundles = .;
+ *(.paravirt_bundles)
+ __stop_paravirt_bundles = .;
+ }
+ . = ALIGN(16);
+ .paravirt_insts : AT(ADDR(.paravirt_insts) - LOAD_OFFSET) {
+ __start_paravirt_insts = .;
+ *(.paravirt_insts)
+ __stop_paravirt_insts = .;
+ }
+ . = ALIGN(16);
+ .paravirt_branches : AT(ADDR(.paravirt_branches) - LOAD_OFFSET) {
+ __start_paravirt_branches = .;
+ *(.paravirt_branches)
+ __stop_paravirt_branches = .;
}
#endif
#if defined(CONFIG_IA64_GENERIC)
- /* Machine Vector */
- . = ALIGN(16);
- .machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
- {
- machvec_start = .;
- *(.machvec)
- machvec_end = .;
+ /* Machine Vector */
+ . = ALIGN(16);
+ .machvec : AT(ADDR(.machvec) - LOAD_OFFSET) {
+ machvec_start = .;
+ *(.machvec)
+ machvec_end = .;
}
#endif
#ifdef CONFIG_SMP
- . = ALIGN(PERCPU_PAGE_SIZE);
- __cpu0_per_cpu = .;
- . = . + PERCPU_PAGE_SIZE; /* cpu0 per-cpu space */
+ . = ALIGN(PERCPU_PAGE_SIZE);
+ __cpu0_per_cpu = .;
+ . = . + PERCPU_PAGE_SIZE; /* cpu0 per-cpu space */
#endif
- . = ALIGN(PAGE_SIZE);
- __init_end = .;
+ . = ALIGN(PAGE_SIZE);
+ __init_end = .;
- .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET)
- {
- PAGE_ALIGNED_DATA(PAGE_SIZE)
- . = ALIGN(PAGE_SIZE);
- __start_gate_section = .;
- *(.data..gate)
- __stop_gate_section = .;
+ .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
+ PAGE_ALIGNED_DATA(PAGE_SIZE)
+ . = ALIGN(PAGE_SIZE);
+ __start_gate_section = .;
+ *(.data..gate)
+ __stop_gate_section = .;
#ifdef CONFIG_XEN
- . = ALIGN(PAGE_SIZE);
- __xen_start_gate_section = .;
- *(.data..gate.xen)
- __xen_stop_gate_section = .;
+ . = ALIGN(PAGE_SIZE);
+ __xen_start_gate_section = .;
+ *(.data..gate.xen)
+ __xen_stop_gate_section = .;
#endif
}
- . = ALIGN(PAGE_SIZE); /* make sure the gate page doesn't expose
- * kernel data
- */
-
- /* Per-cpu data: */
- . = ALIGN(PERCPU_PAGE_SIZE);
- PERCPU_VADDR(PERCPU_ADDR, :percpu)
- __phys_per_cpu_start = __per_cpu_load;
- . = __phys_per_cpu_start + PERCPU_PAGE_SIZE; /* ensure percpu data fits
- * into percpu page size
- */
-
- data : { } :data
- .data : AT(ADDR(.data) - LOAD_OFFSET)
- {
+ /*
+ * make sure the gate page doesn't expose
+ * kernel data
+ */
+ . = ALIGN(PAGE_SIZE);
+
+ /* Per-cpu data: */
+ . = ALIGN(PERCPU_PAGE_SIZE);
+ PERCPU_VADDR(PERCPU_ADDR, :percpu)
+ __phys_per_cpu_start = __per_cpu_load;
+ /*
+ * ensure percpu data fits
+ * into percpu page size
+ */
+ . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;
+
+ data : {
+ } :data
+ .data : AT(ADDR(.data) - LOAD_OFFSET) {
INIT_TASK_DATA(PAGE_SIZE)
CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
READ_MOSTLY_DATA(SMP_CACHE_BYTES)
@@ -213,26 +218,37 @@ SECTIONS
CONSTRUCTORS
}
- . = ALIGN(16); /* gp must be 16-byte aligned for exc. table */
- .got : AT(ADDR(.got) - LOAD_OFFSET)
- { *(.got.plt) *(.got) }
- __gp = ADDR(.got) + 0x200000;
- /* We want the small data sections together, so single-instruction offsets
- can access them all, and initialized data all before uninitialized, so
- we can shorten the on-disk segment size. */
- .sdata : AT(ADDR(.sdata) - LOAD_OFFSET)
- { *(.sdata) *(.sdata1) *(.srdata) }
- _edata = .;
+ . = ALIGN(16); /* gp must be 16-byte aligned for exc. table */
+ .got : AT(ADDR(.got) - LOAD_OFFSET) {
+ *(.got.plt)
+ *(.got)
+ }
+ __gp = ADDR(.got) + 0x200000;
+
+ /*
+ * We want the small data sections together,
+ * so single-instruction offsets can access
+ * them all, and initialized data all before
+ * uninitialized, so we can shorten the
+ * on-disk segment size.
+ */
+ .sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {
+ *(.sdata)
+ *(.sdata1)
+ *(.srdata)
+ }
+ _edata = .;
- BSS_SECTION(0, 0, 0)
+ BSS_SECTION(0, 0, 0)
- _end = .;
+ _end = .;
- code : { } :code
+ code : {
+ } :code
- STABS_DEBUG
- DWARF_DEBUG
+ STABS_DEBUG
+ DWARF_DEBUG
- /* Default discards */
- DISCARDS
+ /* Default discards */
+ DISCARDS
}
diff --git a/arch/m68k/include/asm/ide.h b/arch/m68k/include/asm/ide.h
index 3958726664ba..492fee8a1ab2 100644
--- a/arch/m68k/include/asm/ide.h
+++ b/arch/m68k/include/asm/ide.h
@@ -1,6 +1,4 @@
/*
- * linux/include/asm-m68k/ide.h
- *
* Copyright (C) 1994-1996 Linus Torvalds & authors
*/
@@ -34,6 +32,8 @@
#include <asm/io.h>
#include <asm/irq.h>
+#ifdef CONFIG_MMU
+
/*
* Get rid of defs from io.h - ide has its private and conflicting versions
* Since so far no single m68k platform uses ISA/PCI I/O space for IDE, we
@@ -53,5 +53,14 @@
#define __ide_mm_outsw(port, addr, n) raw_outsw((u16 *)port, addr, n)
#define __ide_mm_outsl(port, addr, n) raw_outsl((u32 *)port, addr, n)
+#else
+
+#define __ide_mm_insw(port, addr, n) io_insw((unsigned int)port, addr, n)
+#define __ide_mm_insl(port, addr, n) io_insl((unsigned int)port, addr, n)
+#define __ide_mm_outsw(port, addr, n) io_outsw((unsigned int)port, addr, n)
+#define __ide_mm_outsl(port, addr, n) io_outsl((unsigned int)port, addr, n)
+
+#endif /* CONFIG_MMU */
+
#endif /* __KERNEL__ */
#endif /* _M68K_IDE_H */
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 1c16b1baf8db..c247de02bc7e 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -332,6 +332,15 @@ static struct mac_model mac_data_table[] = {
.scc_type = MAC_SCC_II,
.nubus_type = MAC_NUBUS,
.floppy_type = MAC_FLOPPY_SWIM_ADDR2,
+ }, {
+ .ident = MAC_MODEL_CCLII,
+ .name = "Color Classic II",
+ .adb_type = MAC_ADB_CUDA,
+ .via_type = MAC_VIA_IIci,
+ .scsi_type = MAC_SCSI_OLD,
+ .scc_type = MAC_SCC_II,
+ .nubus_type = MAC_NUBUS,
+ .floppy_type = MAC_FLOPPY_SWIM_ADDR2,
},
/*
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index 0f118ca156d9..e023fc6b37e5 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -91,7 +91,7 @@ static void cuda_write_pram(int offset, __u8 data)
#define cuda_write_pram NULL
#endif
-#if 0 /* def CONFIG_ADB_PMU68K */
+#ifdef CONFIG_ADB_PMU68K
static long pmu_read_time(void)
{
struct adb_request req;
@@ -102,8 +102,8 @@ static long pmu_read_time(void)
while (!req.complete)
pmu_poll();
- time = (req.reply[0] << 24) | (req.reply[1] << 16)
- | (req.reply[2] << 8) | req.reply[3];
+ time = (req.reply[1] << 24) | (req.reply[2] << 16)
+ | (req.reply[3] << 8) | req.reply[4];
return time - RTC_OFFSET;
}
diff --git a/arch/m68k/sun3/leds.c b/arch/m68k/sun3/leds.c
index a3e948463982..aad2e0a0682e 100644
--- a/arch/m68k/sun3/leds.c
+++ b/arch/m68k/sun3/leds.c
@@ -7,7 +7,7 @@ void sun3_leds(unsigned char byte)
unsigned char dfc;
GET_DFC(dfc);
- SET_DFC(FC_CONTROL);
- SET_CONTROL_BYTE(AC_LEDS,byte);
+ SET_DFC(FC_CONTROL);
+ SET_CONTROL_BYTE(AC_LEDS, byte);
SET_DFC(dfc);
}
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 76818f926539..ad6c2768e85e 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -223,6 +223,36 @@ config TASK_SIZE
hex "Size of user task space" if TASK_SIZE_BOOL
default "0x80000000"
+choice
+ prompt "Page size"
+ default MICROBLAZE_4K_PAGES
+ depends on ADVANCED_OPTIONS && !MMU
+ help
+ Select the kernel logical page size. Increasing the page size
+ will reduce software overhead at each page boundary, allow
+ hardware prefetch mechanisms to be more effective, and allow
+ larger dma transfers increasing IO efficiency and reducing
+ overhead. However the utilization of memory will increase.
+ For example, each cached file will using a multiple of the
+ page size to hold its contents and the difference between the
+ end of file and the end of page is wasted.
+
+ If unsure, choose 4K_PAGES.
+
+config MICROBLAZE_4K_PAGES
+ bool "4k page size"
+
+config MICROBLAZE_8K_PAGES
+ bool "8k page size"
+
+config MICROBLAZE_16K_PAGES
+ bool "16k page size"
+
+config MICROBLAZE_32K_PAGES
+ bool "32k page size"
+
+endchoice
+
endmenu
source "mm/Kconfig"
diff --git a/arch/microblaze/include/asm/cacheflush.h b/arch/microblaze/include/asm/cacheflush.h
index a6edd356cd08..34d15e9a8a7f 100644
--- a/arch/microblaze/include/asm/cacheflush.h
+++ b/arch/microblaze/include/asm/cacheflush.h
@@ -17,6 +17,7 @@
/* Somebody depends on this; sigh... */
#include <linux/mm.h>
+#include <linux/io.h>
/* Look at Documentation/cachetlb.txt */
@@ -60,7 +61,6 @@ void microblaze_cache_init(void);
#define invalidate_icache() mbc->iin();
#define invalidate_icache_range(start, end) mbc->iinr(start, end);
-
#define flush_icache_user_range(vma, pg, adr, len) flush_icache();
#define flush_icache_page(vma, pg) do { } while (0)
@@ -72,9 +72,15 @@ void microblaze_cache_init(void);
#define flush_dcache() mbc->dfl();
#define flush_dcache_range(start, end) mbc->dflr(start, end);
-#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
-/* D-cache aliasing problem can't happen - cache is between MMU and ram */
-#define flush_dcache_page(page) do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+/* MS: We have to implement it because of rootfs-jffs2 issue on WB */
+#define flush_dcache_page(page) \
+do { \
+ unsigned long addr = (unsigned long) page_address(page); /* virtual */ \
+ addr = (u32)virt_to_phys((void *)addr); \
+ flush_dcache_range((unsigned) (addr), (unsigned) (addr) + PAGE_SIZE); \
+} while(0);
+
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
@@ -97,8 +103,10 @@ void microblaze_cache_init(void);
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
+ u32 addr = virt_to_phys(dst); \
+ invalidate_icache_range((unsigned) (addr), (unsigned) (addr) + (len));\
memcpy((dst), (src), (len)); \
- flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
+ flush_dcache_range((unsigned) (addr), (unsigned) (addr) + (len));\
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
diff --git a/arch/microblaze/include/asm/dma-mapping.h b/arch/microblaze/include/asm/dma-mapping.h
index 18b3731c8509..507389580709 100644
--- a/arch/microblaze/include/asm/dma-mapping.h
+++ b/arch/microblaze/include/asm/dma-mapping.h
@@ -79,12 +79,6 @@ static inline int dma_supported(struct device *dev, u64 mask)
return ops->dma_supported(dev, mask);
}
-#ifdef CONFIG_PCI
-/* We have our own implementation of pci_set_dma_mask() */
-#define HAVE_ARCH_PCI_SET_DMA_MASK
-
-#endif
-
static inline int dma_set_mask(struct device *dev, u64 dma_mask)
{
struct dma_map_ops *ops = get_dma_ops(dev);
diff --git a/arch/microblaze/include/asm/elf.h b/arch/microblaze/include/asm/elf.h
index 7d4acf2b278e..732caf1be741 100644
--- a/arch/microblaze/include/asm/elf.h
+++ b/arch/microblaze/include/asm/elf.h
@@ -77,7 +77,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define ELF_DATA ELFDATA2MSB
#endif
-#define ELF_EXEC_PAGESIZE 4096
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
#define ELF_CORE_COPY_REGS(_dest, _regs) \
diff --git a/arch/microblaze/include/asm/exceptions.h b/arch/microblaze/include/asm/exceptions.h
index 4c7b5d037c88..fa0e36657fdd 100644
--- a/arch/microblaze/include/asm/exceptions.h
+++ b/arch/microblaze/include/asm/exceptions.h
@@ -14,6 +14,11 @@
#define _ASM_MICROBLAZE_EXCEPTIONS_H
#ifdef __KERNEL__
+
+#ifndef CONFIG_MMU
+#define EX_HANDLER_STACK_SIZ (4*19)
+#endif
+
#ifndef __ASSEMBLY__
/* Macros to enable and disable HW exceptions in the MSR */
diff --git a/arch/microblaze/include/asm/page.h b/arch/microblaze/include/asm/page.h
index 464ff32bee3d..c12c6dfafd9f 100644
--- a/arch/microblaze/include/asm/page.h
+++ b/arch/microblaze/include/asm/page.h
@@ -23,8 +23,16 @@
#ifdef __KERNEL__
/* PAGE_SHIFT determines the page size */
-#define PAGE_SHIFT (12)
-#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#if defined(CONFIG_MICROBLAZE_32K_PAGES)
+#define PAGE_SHIFT 15
+#elif defined(CONFIG_MICROBLAZE_16K_PAGES)
+#define PAGE_SHIFT 14
+#elif defined(CONFIG_MICROBLAZE_8K_PAGES)
+#define PAGE_SHIFT 13
+#else
+#define PAGE_SHIFT 12
+#endif
+#define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
#define LOAD_OFFSET ASM_CONST((CONFIG_KERNEL_START-CONFIG_KERNEL_BASE_ADDR))
diff --git a/arch/microblaze/include/asm/setup.h b/arch/microblaze/include/asm/setup.h
index 7f31394985e0..782b5c89248e 100644
--- a/arch/microblaze/include/asm/setup.h
+++ b/arch/microblaze/include/asm/setup.h
@@ -28,8 +28,6 @@ void disable_early_printk(void);
void heartbeat(void);
void setup_heartbeat(void);
-unsigned long long sched_clock(void);
-
# ifdef CONFIG_MMU
extern void mmu_reset(void);
extern void early_console_reg_tlb_alloc(unsigned int addr);
diff --git a/arch/microblaze/include/asm/system.h b/arch/microblaze/include/asm/system.h
index 48c4f0335e3f..4f8eaea21f88 100644
--- a/arch/microblaze/include/asm/system.h
+++ b/arch/microblaze/include/asm/system.h
@@ -45,7 +45,6 @@ extern struct task_struct *_switch_to(struct thread_info *prev,
#define smp_rmb() rmb()
#define smp_wmb() wmb()
-void show_trace(struct task_struct *task, unsigned long *stack);
void __bad_xchg(volatile void *ptr, int size);
static inline unsigned long __xchg(unsigned long x, volatile void *ptr,
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index 26460d15b338..d840f4a2d3c9 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -359,7 +359,7 @@ extern long __user_bad(void);
__copy_tofrom_user((__force void __user *)(to), \
(void __user *)(from), (n))
#define __copy_from_user_inatomic(to, from, n) \
- copy_from_user((to), (from), (n))
+ __copy_from_user((to), (from), (n))
static inline long copy_from_user(void *to,
const void __user *from, unsigned long n)
@@ -373,7 +373,7 @@ static inline long copy_from_user(void *to,
#define __copy_to_user(to, from, n) \
__copy_tofrom_user((void __user *)(to), \
(__force const void __user *)(from), (n))
-#define __copy_to_user_inatomic(to, from, n) copy_to_user((to), (from), (n))
+#define __copy_to_user_inatomic(to, from, n) __copy_to_user((to), (from), (n))
static inline long copy_to_user(void __user *to,
const void *from, unsigned long n)
diff --git a/arch/microblaze/include/asm/unwind.h b/arch/microblaze/include/asm/unwind.h
new file mode 100644
index 000000000000..d248b7de4b13
--- /dev/null
+++ b/arch/microblaze/include/asm/unwind.h
@@ -0,0 +1,29 @@
+/*
+ * Backtrace support for Microblaze
+ *
+ * Copyright (C) 2010 Digital Design Corporation
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __MICROBLAZE_UNWIND_H
+#define __MICROBLAZE_UNWIND_H
+
+struct stack_trace;
+
+struct trap_handler_info {
+ unsigned long start_addr;
+ unsigned long end_addr;
+ const char *trap_name;
+};
+extern struct trap_handler_info microblaze_trap_handlers;
+
+extern const char _hw_exception_handler;
+extern const char ex_handler_unhandled;
+
+void microblaze_unwind(struct task_struct *task, struct stack_trace *trace);
+
+#endif /* __MICROBLAZE_UNWIND_H */
+
diff --git a/arch/microblaze/kernel/Makefile b/arch/microblaze/kernel/Makefile
index e51bc1520825..d66ddef53c07 100644
--- a/arch/microblaze/kernel/Makefile
+++ b/arch/microblaze/kernel/Makefile
@@ -17,7 +17,7 @@ extra-y := head.o vmlinux.lds
obj-y += dma.o exceptions.o \
hw_exception_handler.o init_task.o intc.o irq.o of_device.o \
of_platform.o process.o prom.o prom_parse.o ptrace.o \
- setup.o signal.o sys_microblaze.o timer.o traps.o reset.o
+ reset.o setup.o signal.o sys_microblaze.o timer.o traps.o unwind.o
obj-y += cpu/
diff --git a/arch/microblaze/kernel/cpu/mb.c b/arch/microblaze/kernel/cpu/mb.c
index 4216eb1eaa32..7086e3564281 100644
--- a/arch/microblaze/kernel/cpu/mb.c
+++ b/arch/microblaze/kernel/cpu/mb.c
@@ -126,6 +126,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
cpuinfo.pvr_user1,
cpuinfo.pvr_user2);
+ count += seq_printf(m, "Page size:\t%lu\n", PAGE_SIZE);
return 0;
}
diff --git a/arch/microblaze/kernel/entry-nommu.S b/arch/microblaze/kernel/entry-nommu.S
index 8cc18cd2cce6..ca84368570b6 100644
--- a/arch/microblaze/kernel/entry-nommu.S
+++ b/arch/microblaze/kernel/entry-nommu.S
@@ -588,3 +588,31 @@ sys_rt_sigsuspend_wrapper:
#include "syscall_table.S"
syscall_table_size=(.-sys_call_table)
+
+type_SYSCALL:
+ .ascii "SYSCALL\0"
+type_IRQ:
+ .ascii "IRQ\0"
+type_IRQ_PREEMPT:
+ .ascii "IRQ (PREEMPTED)\0"
+type_SYSCALL_PREEMPT:
+ .ascii " SYSCALL (PREEMPTED)\0"
+
+ /*
+ * Trap decoding for stack unwinder
+ * Tuples are (start addr, end addr, string)
+ * If return address lies on [start addr, end addr],
+ * unwinder displays 'string'
+ */
+
+ .align 4
+.global microblaze_trap_handlers
+microblaze_trap_handlers:
+ /* Exact matches come first */
+ .word ret_to_user ; .word ret_to_user ; .word type_SYSCALL
+ .word ret_from_intr; .word ret_from_intr ; .word type_IRQ
+ /* Fuzzy matches go here */
+ .word ret_from_intr; .word no_intr_resched; .word type_IRQ_PREEMPT
+ .word work_pending ; .word no_work_pending; .word type_SYSCALL_PREEMPT
+ /* End of table */
+ .word 0 ; .word 0 ; .word 0
diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
index c0ede25c5b99..7a19d8910e3b 100644
--- a/arch/microblaze/kernel/entry.S
+++ b/arch/microblaze/kernel/entry.S
@@ -476,13 +476,13 @@ C_ENTRY(sys_vfork):
C_ENTRY(sys_clone):
bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
- lwi r6, r1, PTO+PT_R1; /* If so, use paret's stack ptr */
-1: la r7, r1, PTO; /* Arg 2: parent context */
- add r8, r0, r0; /* Arg 3: (unused) */
- add r9, r0, r0; /* Arg 4: (unused) */
- add r10, r0, r0; /* Arg 5: (unused) */
- brid do_fork /* Do real work (tail-call) */
- nop;
+ lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */
+1: add r10, r0, r9; /* Arg 6: (child_tidptr) */
+ add r9, r0, r8; /* Arg 5: (parent_tidptr) */
+ add r8, r0, r7; /* Arg 4: (stack_size) */
+ la r7, r1, PTO; /* Arg 3: pt_regs */
+ brid do_fork /* Do real work (tail-call) */
+ nop
C_ENTRY(sys_execve):
la r8, r1, PTO; /* add user context as 4th arg */
@@ -1127,3 +1127,30 @@ ENTRY(_break)
syscall_table_size=(.-sys_call_table)
+type_SYSCALL:
+ .ascii "SYSCALL\0"
+type_IRQ:
+ .ascii "IRQ\0"
+type_IRQ_PREEMPT:
+ .ascii "IRQ (PREEMPTED)\0"
+type_SYSCALL_PREEMPT:
+ .ascii " SYSCALL (PREEMPTED)\0"
+
+ /*
+ * Trap decoding for stack unwinder
+ * Tuples are (start addr, end addr, string)
+ * If return address lies on [start addr, end addr],
+ * unwinder displays 'string'
+ */
+
+ .align 4
+.global microblaze_trap_handlers
+microblaze_trap_handlers:
+ /* Exact matches come first */
+ .word ret_from_trap; .word ret_from_trap ; .word type_SYSCALL
+ .word ret_from_irq ; .word ret_from_irq ; .word type_IRQ
+ /* Fuzzy matches go here */
+ .word ret_from_irq ; .word no_intr_resched ; .word type_IRQ_PREEMPT
+ .word ret_from_trap; .word TRAP_return ; .word type_SYSCALL_PREEMPT
+ /* End of table */
+ .word 0 ; .word 0 ; .word 0
diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
index 1bf739888260..42434008209e 100644
--- a/arch/microblaze/kernel/head.S
+++ b/arch/microblaze/kernel/head.S
@@ -43,10 +43,10 @@
.global empty_zero_page
.align 12
empty_zero_page:
- .space 4096
+ .space PAGE_SIZE
.global swapper_pg_dir
swapper_pg_dir:
- .space 4096
+ .space PAGE_SIZE
#endif /* CONFIG_MMU */
diff --git a/arch/microblaze/kernel/hw_exception_handler.S b/arch/microblaze/kernel/hw_exception_handler.S
index 995a2123635b..781195438ee6 100644
--- a/arch/microblaze/kernel/hw_exception_handler.S
+++ b/arch/microblaze/kernel/hw_exception_handler.S
@@ -78,9 +78,6 @@
#include <asm/asm-offsets.h>
/* Helpful Macros */
-#ifndef CONFIG_MMU
-#define EX_HANDLER_STACK_SIZ (4*19)
-#endif
#define NUM_TO_REG(num) r ## num
#ifdef CONFIG_MMU
@@ -988,6 +985,7 @@ ex_unaligned_fixup:
.end _unaligned_data_exception
#endif /* CONFIG_MMU */
+.global ex_handler_unhandled
ex_handler_unhandled:
/* FIXME add handle function for unhandled exception - dump register */
bri 0
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index 8f120aca123d..598f1fd61c89 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -37,6 +37,7 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
{
unsigned int irq;
struct pt_regs *old_regs = set_irq_regs(regs);
+ trace_hardirqs_off();
irq_enter();
irq = get_irq(regs);
@@ -53,6 +54,7 @@ next_irq:
irq_exit();
set_irq_regs(old_regs);
+ trace_hardirqs_on();
}
int show_interrupts(struct seq_file *p, void *v)
diff --git a/arch/microblaze/kernel/misc.S b/arch/microblaze/kernel/misc.S
index 0fb5fc6c1fc2..206da3da361f 100644
--- a/arch/microblaze/kernel/misc.S
+++ b/arch/microblaze/kernel/misc.S
@@ -76,7 +76,7 @@ early_console_reg_tlb_alloc:
* the UARTs nice and early. We use a 4k real==virtual mapping.
*/
ori r4, r0, MICROBLAZE_TLB_SIZE - 1
- mts rtlbx, r4 /* TLB slot 2 */
+ mts rtlbx, r4 /* TLB slot 63 */
or r4,r5,r0
andi r4,r4,0xfffff000
diff --git a/arch/microblaze/kernel/process.c b/arch/microblaze/kernel/process.c
index 09bed44dfcd3..ba7c4b16ed35 100644
--- a/arch/microblaze/kernel/process.c
+++ b/arch/microblaze/kernel/process.c
@@ -76,8 +76,11 @@ __setup("hlt", hlt_setup);
void default_idle(void)
{
if (likely(hlt_counter)) {
- while (!need_resched())
- cpu_relax();
+ local_irq_disable();
+ stop_critical_timings();
+ cpu_relax();
+ start_critical_timings();
+ local_irq_enable();
} else {
clear_thread_flag(TIF_POLLING_NRFLAG);
smp_mb__after_clear_bit();
diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
index a4a7770c6140..dc03ffc8174a 100644
--- a/arch/microblaze/kernel/ptrace.c
+++ b/arch/microblaze/kernel/ptrace.c
@@ -38,6 +38,8 @@
#include <asm/processor.h>
#include <linux/uaccess.h>
#include <asm/asm-offsets.h>
+#include <asm/cacheflush.h>
+#include <asm/io.h>
/* Returns the address where the register at REG_OFFS in P is stashed away. */
static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
@@ -101,8 +103,21 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
if (request == PTRACE_PEEKUSR)
val = *reg_addr;
- else
+ else {
+#if 1
*reg_addr = data;
+#else
+ /* MS potential problem on WB system
+ * Be aware that reg_addr is virtual address
+ * virt_to_phys conversion is necessary.
+ * This could be sensible solution.
+ */
+ u32 paddr = virt_to_phys((u32)reg_addr);
+ invalidate_icache_range(paddr, paddr + 4);
+ *reg_addr = data;
+ flush_dcache_range(paddr, paddr + 4);
+#endif
+ }
} else
rval = -EIO;
diff --git a/arch/microblaze/kernel/stacktrace.c b/arch/microblaze/kernel/stacktrace.c
index 123692f22647..84bc6686102c 100644
--- a/arch/microblaze/kernel/stacktrace.c
+++ b/arch/microblaze/kernel/stacktrace.c
@@ -14,52 +14,18 @@
#include <linux/thread_info.h>
#include <linux/ptrace.h>
#include <linux/module.h>
+#include <asm/unwind.h>
-/* FIXME initial support */
void save_stack_trace(struct stack_trace *trace)
{
- unsigned long *sp;
- unsigned long addr;
- asm("addik %0, r1, 0" : "=r" (sp));
-
- while (!kstack_end(sp)) {
- addr = *sp++;
- if (__kernel_text_address(addr)) {
- if (trace->skip > 0)
- trace->skip--;
- else
- trace->entries[trace->nr_entries++] = addr;
-
- if (trace->nr_entries >= trace->max_entries)
- break;
- }
- }
+ /* Exclude our helper functions from the trace*/
+ trace->skip += 2;
+ microblaze_unwind(NULL, trace);
}
EXPORT_SYMBOL_GPL(save_stack_trace);
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
- unsigned int *sp;
- unsigned long addr;
-
- struct thread_info *ti = task_thread_info(tsk);
-
- if (tsk == current)
- asm("addik %0, r1, 0" : "=r" (sp));
- else
- sp = (unsigned int *)ti->cpu_context.r1;
-
- while (!kstack_end(sp)) {
- addr = *sp++;
- if (__kernel_text_address(addr)) {
- if (trace->skip > 0)
- trace->skip--;
- else
- trace->entries[trace->nr_entries++] = addr;
-
- if (trace->nr_entries >= trace->max_entries)
- break;
- }
- }
+ microblaze_unwind(tsk, trace);
}
EXPORT_SYMBOL_GPL(save_stack_trace_tsk);
diff --git a/arch/microblaze/kernel/timer.c b/arch/microblaze/kernel/timer.c
index ed61b2f17719..7dc2e12ce4cb 100644
--- a/arch/microblaze/kernel/timer.c
+++ b/arch/microblaze/kernel/timer.c
@@ -28,6 +28,7 @@
#include <asm/prom.h>
#include <asm/irq.h>
#include <asm/system.h>
+#include <linux/cnt32_to_63.h>
#ifdef CONFIG_SELFMOD_TIMER
#include <asm/selfmod.h>
@@ -135,7 +136,7 @@ static void microblaze_timer_set_mode(enum clock_event_mode mode,
static struct clock_event_device clockevent_microblaze_timer = {
.name = "microblaze_clockevent",
.features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
- .shift = 24,
+ .shift = 2,
.rating = 300,
.set_next_event = microblaze_timer_set_next_event,
.set_mode = microblaze_timer_set_mode,
@@ -195,7 +196,7 @@ static cycle_t microblaze_cc_read(const struct cyclecounter *cc)
static struct cyclecounter microblaze_cc = {
.read = microblaze_cc_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24,
+ .shift = 2,
};
int __init init_microblaze_timecounter(void)
@@ -213,7 +214,7 @@ static struct clocksource clocksource_microblaze = {
.rating = 300,
.read = microblaze_read,
.mask = CLOCKSOURCE_MASK(32),
- .shift = 24, /* I can shift it */
+ .shift = 2, /* I can shift it */
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -235,6 +236,12 @@ static int __init microblaze_clocksource_init(void)
return 0;
}
+/*
+ * We have to protect accesses before timer initialization
+ * and return 0 for sched_clock function below.
+ */
+static int timer_initialized;
+
void __init time_init(void)
{
u32 irq, i = 0;
@@ -289,4 +296,15 @@ void __init time_init(void)
#endif
microblaze_clocksource_init();
microblaze_clockevent_init();
+ timer_initialized = 1;
+}
+
+unsigned long long notrace sched_clock(void)
+{
+ if (timer_initialized) {
+ struct clocksource *cs = &clocksource_microblaze;
+ cycle_t cyc = cnt32_to_63(cs->read(NULL));
+ return clocksource_cyc2ns(cyc, cs->mult, cs->shift);
+ }
+ return 0;
}
diff --git a/arch/microblaze/kernel/traps.c b/arch/microblaze/kernel/traps.c
index 75e49202a5ed..ba034d421ec2 100644
--- a/arch/microblaze/kernel/traps.c
+++ b/arch/microblaze/kernel/traps.c
@@ -16,13 +16,14 @@
#include <asm/exceptions.h>
#include <asm/system.h>
+#include <asm/unwind.h>
void trap_init(void)
{
__enable_hw_exceptions();
}
-static unsigned long kstack_depth_to_print = 24;
+static unsigned long kstack_depth_to_print; /* 0 == entire stack */
static int __init kstack_setup(char *s)
{
@@ -30,31 +31,47 @@ static int __init kstack_setup(char *s)
}
__setup("kstack=", kstack_setup);
-void show_trace(struct task_struct *task, unsigned long *stack)
+void show_stack(struct task_struct *task, unsigned long *sp)
{
- unsigned long addr;
-
- if (!stack)
- stack = (unsigned long *)&stack;
+ unsigned long words_to_show;
+ u32 fp = (u32) sp;
+
+ if (fp == 0) {
+ if (task) {
+ fp = ((struct thread_info *)
+ (task->stack))->cpu_context.r1;
+ } else {
+ /* Pick up caller of dump_stack() */
+ fp = (u32)&sp - 8;
+ }
+ }
- printk(KERN_NOTICE "Call Trace: ");
-#ifdef CONFIG_KALLSYMS
- printk(KERN_NOTICE "\n");
-#endif
- while (!kstack_end(stack)) {
- addr = *stack++;
- /*
- * If the address is either in the text segment of the
- * kernel, or in the region which contains vmalloc'ed
- * memory, it *may* be the address of a calling
- * routine; if so, print it so that someone tracing
- * down the cause of the crash will be able to figure
- * out the call path that was taken.
- */
- if (kernel_text_address(addr))
- print_ip_sym(addr);
+ words_to_show = (THREAD_SIZE - (fp & (THREAD_SIZE - 1))) >> 2;
+ if (kstack_depth_to_print && (words_to_show > kstack_depth_to_print))
+ words_to_show = kstack_depth_to_print;
+
+ pr_info("Kernel Stack:\n");
+
+ /*
+ * Make the first line an 'odd' size if necessary to get
+ * remaining lines to start at an address multiple of 0x10
+ */
+ if (fp & 0xF) {
+ unsigned long line1_words = (0x10 - (fp & 0xF)) >> 2;
+ if (line1_words < words_to_show) {
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32,
+ 4, (void *)fp, line1_words << 2, 0);
+ fp += line1_words << 2;
+ words_to_show -= line1_words;
+ }
}
- printk(KERN_NOTICE "\n");
+ print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, (void *)fp,
+ words_to_show << 2, 0);
+ printk(KERN_INFO "\n\n");
+
+ pr_info("Call Trace:\n");
+ microblaze_unwind(task, NULL);
+ pr_info("\n");
if (!task)
task = current;
@@ -62,34 +79,6 @@ void show_trace(struct task_struct *task, unsigned long *stack)
debug_show_held_locks(task);
}
-void show_stack(struct task_struct *task, unsigned long *sp)
-{
- unsigned long *stack;
- int i;
-
- if (sp == NULL) {
- if (task)
- sp = (unsigned long *) ((struct thread_info *)
- (task->stack))->cpu_context.r1;
- else
- sp = (unsigned long *)&sp;
- }
-
- stack = sp;
-
- printk(KERN_INFO "\nStack:\n ");
-
- for (i = 0; i < kstack_depth_to_print; i++) {
- if (kstack_end(sp))
- break;
- if (i && ((i % 8) == 0))
- printk("\n ");
- printk("%08lx ", *sp++);
- }
- printk("\n");
- show_trace(task, stack);
-}
-
void dump_stack(void)
{
show_stack(NULL, NULL);
diff --git a/arch/microblaze/kernel/unwind.c b/arch/microblaze/kernel/unwind.c
new file mode 100644
index 000000000000..fefac5c33586
--- /dev/null
+++ b/arch/microblaze/kernel/unwind.c
@@ -0,0 +1,318 @@
+/*
+ * Backtrace support for Microblaze
+ *
+ * Copyright (C) 2010 Digital Design Corporation
+ *
+ * Based on arch/sh/kernel/cpu/sh5/unwind.c code which is:
+ * Copyright (C) 2004 Paul Mundt
+ * Copyright (C) 2004 Richard Curnow
+ *
+ * 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.
+ */
+
+/* #define DEBUG 1 */
+#include <linux/kallsyms.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/stacktrace.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <asm/sections.h>
+#include <asm/exceptions.h>
+#include <asm/unwind.h>
+
+struct stack_trace;
+
+/*
+ * On Microblaze, finding the previous stack frame is a little tricky.
+ * At this writing (3/2010), Microblaze does not support CONFIG_FRAME_POINTERS,
+ * and even if it did, gcc (4.1.2) does not store the frame pointer at
+ * a consistent offset within each frame. To determine frame size, it is
+ * necessary to search for the assembly instruction that creates or reclaims
+ * the frame and extract the size from it.
+ *
+ * Microblaze stores the stack pointer in r1, and creates a frame via
+ *
+ * addik r1, r1, -FRAME_SIZE
+ *
+ * The frame is reclaimed via
+ *
+ * addik r1, r1, FRAME_SIZE
+ *
+ * Frame creation occurs at or near the top of a function.
+ * Depending on the compiler, reclaim may occur at the end, or before
+ * a mid-function return.
+ *
+ * A stack frame is usually not created in a leaf function.
+ *
+ */
+
+/**
+ * get_frame_size - Extract the stack adjustment from an
+ * "addik r1, r1, adjust" instruction
+ * @instr : Microblaze instruction
+ *
+ * Return - Number of stack bytes the instruction reserves or reclaims
+ */
+inline long get_frame_size(unsigned long instr)
+{
+ return abs((s16)(instr & 0xFFFF));
+}
+
+/**
+ * find_frame_creation - Search backward to find the instruction that creates
+ * the stack frame (hopefully, for the same function the
+ * initial PC is in).
+ * @pc : Program counter at which to begin the search
+ *
+ * Return - PC at which stack frame creation occurs
+ * NULL if this cannot be found, i.e. a leaf function
+ */
+static unsigned long *find_frame_creation(unsigned long *pc)
+{
+ int i;
+
+ /* NOTE: Distance to search is arbitrary
+ * 250 works well for most things,
+ * 750 picks up things like tcp_recvmsg(),
+ * 1000 needed for fat_fill_super()
+ */
+ for (i = 0; i < 1000; i++, pc--) {
+ unsigned long instr;
+ s16 frame_size;
+
+ if (!kernel_text_address((unsigned long) pc))
+ return NULL;
+
+ instr = *pc;
+
+ /* addik r1, r1, foo ? */
+ if ((instr & 0xFFFF0000) != 0x30210000)
+ continue; /* No */
+
+ frame_size = get_frame_size(instr);
+ if ((frame_size < 8) || (frame_size & 3)) {
+ pr_debug(" Invalid frame size %d at 0x%p\n",
+ frame_size, pc);
+ return NULL;
+ }
+
+ pr_debug(" Found frame creation at 0x%p, size %d\n", pc,
+ frame_size);
+ return pc;
+ }
+
+ return NULL;
+}
+
+/**
+ * lookup_prev_stack_frame - Find the stack frame of the previous function.
+ * @fp : Frame (stack) pointer for current function
+ * @pc : Program counter within current function
+ * @leaf_return : r15 value within current function. If the current function
+ * is a leaf, this is the caller's return address.
+ * @pprev_fp : On exit, set to frame (stack) pointer for previous function
+ * @pprev_pc : On exit, set to current function caller's return address
+ *
+ * Return - 0 on success, -EINVAL if the previous frame cannot be found
+ */
+static int lookup_prev_stack_frame(unsigned long fp, unsigned long pc,
+ unsigned long leaf_return,
+ unsigned long *pprev_fp,
+ unsigned long *pprev_pc)
+{
+ unsigned long *prologue = NULL;
+
+ /* _switch_to is a special leaf function */
+ if (pc != (unsigned long) &_switch_to)
+ prologue = find_frame_creation((unsigned long *)pc);
+
+ if (prologue) {
+ long frame_size = get_frame_size(*prologue);
+
+ *pprev_fp = fp + frame_size;
+ *pprev_pc = *(unsigned long *)fp;
+ } else {
+ if (!leaf_return)
+ return -EINVAL;
+ *pprev_pc = leaf_return;
+ *pprev_fp = fp;
+ }
+
+ /* NOTE: don't check kernel_text_address here, to allow display
+ * of userland return address
+ */
+ return (!*pprev_pc || (*pprev_pc & 3)) ? -EINVAL : 0;
+}
+
+static void microblaze_unwind_inner(struct task_struct *task,
+ unsigned long pc, unsigned long fp,
+ unsigned long leaf_return,
+ struct stack_trace *trace);
+
+/**
+ * unwind_trap - Unwind through a system trap, that stored previous state
+ * on the stack.
+ */
+#ifdef CONFIG_MMU
+static inline void unwind_trap(struct task_struct *task, unsigned long pc,
+ unsigned long fp, struct stack_trace *trace)
+{
+ /* To be implemented */
+}
+#else
+static inline void unwind_trap(struct task_struct *task, unsigned long pc,
+ unsigned long fp, struct stack_trace *trace)
+{
+ const struct pt_regs *regs = (const struct pt_regs *) fp;
+ microblaze_unwind_inner(task, regs->pc, regs->r1, regs->r15, trace);
+}
+#endif
+
+/**
+ * microblaze_unwind_inner - Unwind the stack from the specified point
+ * @task : Task whose stack we are to unwind (may be NULL)
+ * @pc : Program counter from which we start unwinding
+ * @fp : Frame (stack) pointer from which we start unwinding
+ * @leaf_return : Value of r15 at pc. If the function is a leaf, this is
+ * the caller's return address.
+ * @trace : Where to store stack backtrace (PC values).
+ * NULL == print backtrace to kernel log
+ */
+void microblaze_unwind_inner(struct task_struct *task,
+ unsigned long pc, unsigned long fp,
+ unsigned long leaf_return,
+ struct stack_trace *trace)
+{
+ int ofs = 0;
+
+ pr_debug(" Unwinding with PC=%p, FP=%p\n", (void *)pc, (void *)fp);
+ if (!pc || !fp || (pc & 3) || (fp & 3)) {
+ pr_debug(" Invalid state for unwind, aborting\n");
+ return;
+ }
+ for (; pc != 0;) {
+ unsigned long next_fp, next_pc = 0;
+ unsigned long return_to = pc + 2 * sizeof(unsigned long);
+ const struct trap_handler_info *handler =
+ &microblaze_trap_handlers;
+
+ /* Is previous function the HW exception handler? */
+ if ((return_to >= (unsigned long)&_hw_exception_handler)
+ &&(return_to < (unsigned long)&ex_handler_unhandled)) {
+ /*
+ * HW exception handler doesn't save all registers,
+ * so we open-code a special case of unwind_trap()
+ */
+#ifndef CONFIG_MMU
+ const struct pt_regs *regs =
+ (const struct pt_regs *) fp;
+#endif
+ pr_info("HW EXCEPTION\n");
+#ifndef CONFIG_MMU
+ microblaze_unwind_inner(task, regs->r17 - 4,
+ fp + EX_HANDLER_STACK_SIZ,
+ regs->r15, trace);
+#endif
+ return;
+ }
+
+ /* Is previous function a trap handler? */
+ for (; handler->start_addr; ++handler) {
+ if ((return_to >= handler->start_addr)
+ && (return_to <= handler->end_addr)) {
+ if (!trace)
+ pr_info("%s\n", handler->trap_name);
+ unwind_trap(task, pc, fp, trace);
+ return;
+ }
+ }
+ pc -= ofs;
+
+ if (trace) {
+#ifdef CONFIG_STACKTRACE
+ if (trace->skip > 0)
+ trace->skip--;
+ else
+ trace->entries[trace->nr_entries++] = pc;
+
+ if (trace->nr_entries >= trace->max_entries)
+ break;
+#endif
+ } else {
+ /* Have we reached userland? */
+ if (unlikely(pc == task_pt_regs(task)->pc)) {
+ pr_info("[<%p>] PID %lu [%s]\n",
+ (void *) pc,
+ (unsigned long) task->pid,
+ task->comm);
+ break;
+ } else
+ print_ip_sym(pc);
+ }
+
+ /* Stop when we reach anything not part of the kernel */
+ if (!kernel_text_address(pc))
+ break;
+
+ if (lookup_prev_stack_frame(fp, pc, leaf_return, &next_fp,
+ &next_pc) == 0) {
+ ofs = sizeof(unsigned long);
+ pc = next_pc & ~3;
+ fp = next_fp;
+ leaf_return = 0;
+ } else {
+ pr_debug(" Failed to find previous stack frame\n");
+ break;
+ }
+
+ pr_debug(" Next PC=%p, next FP=%p\n",
+ (void *)next_pc, (void *)next_fp);
+ }
+}
+
+/**
+ * microblaze_unwind - Stack unwinder for Microblaze (external entry point)
+ * @task : Task whose stack we are to unwind (NULL == current)
+ * @trace : Where to store stack backtrace (PC values).
+ * NULL == print backtrace to kernel log
+ */
+void microblaze_unwind(struct task_struct *task, struct stack_trace *trace)
+{
+ if (task) {
+ if (task == current) {
+ const struct pt_regs *regs = task_pt_regs(task);
+ microblaze_unwind_inner(task, regs->pc, regs->r1,
+ regs->r15, trace);
+ } else {
+ struct thread_info *thread_info =
+ (struct thread_info *)(task->stack);
+ const struct cpu_context *cpu_context =
+ &thread_info->cpu_context;
+
+ microblaze_unwind_inner(task,
+ (unsigned long) &_switch_to,
+ cpu_context->r1,
+ cpu_context->r15, trace);
+ }
+ } else {
+ unsigned long pc, fp;
+
+ __asm__ __volatile__ ("or %0, r1, r0" : "=r" (fp));
+
+ __asm__ __volatile__ (
+ "brlid %0, 0f;"
+ "nop;"
+ "0:"
+ : "=r" (pc)
+ );
+
+ /* Since we are not a leaf function, use leaf_return = 0 */
+ microblaze_unwind_inner(current, pc, fp, 0, trace);
+ }
+}
+
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
index db72d7124602..b0de1a6b5513 100644
--- a/arch/microblaze/kernel/vmlinux.lds.S
+++ b/arch/microblaze/kernel/vmlinux.lds.S
@@ -55,7 +55,7 @@ SECTIONS {
*/
.sdata2 : AT(ADDR(.sdata2) - LOAD_OFFSET) {
_ssrw = .;
- . = ALIGN(4096); /* page aligned when MMU used - origin 0x8 */
+ . = ALIGN(PAGE_SIZE); /* page aligned when MMU used */
*(.sdata2)
. = ALIGN(8);
_essrw = .;
@@ -70,7 +70,7 @@ SECTIONS {
/* Reserve some low RAM for r0 based memory references */
. = ALIGN(0x4) ;
r0_ram = . ;
- . = . + 4096; /* a page should be enough */
+ . = . + PAGE_SIZE; /* a page should be enough */
/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
. = ALIGN(8);
@@ -120,7 +120,7 @@ SECTIONS {
__init_end_before_initramfs = .;
- .init.ramfs ALIGN(4096) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
+ .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
__initramfs_start = .;
*(.init.ramfs)
__initramfs_end = .;
@@ -132,11 +132,11 @@ SECTIONS {
* so that __init_end == __bss_start. This will make image.elf
* consistent with the image.bin
*/
- /* . = ALIGN(4096); */
+ /* . = ALIGN(PAGE_SIZE); */
}
__init_end = .;
- .bss ALIGN (4096) : AT(ADDR(.bss) - LOAD_OFFSET) {
+ .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) {
/* page aligned when MMU used */
__bss_start = . ;
*(.bss*)
@@ -145,7 +145,7 @@ SECTIONS {
__bss_stop = . ;
_ebss = . ;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
_end = .;
DISCARDS
diff --git a/arch/microblaze/mm/fault.c b/arch/microblaze/mm/fault.c
index bab922993185..b224c650a18d 100644
--- a/arch/microblaze/mm/fault.c
+++ b/arch/microblaze/mm/fault.c
@@ -226,7 +226,6 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
-survive:
fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
index cca3579d4268..573b97e7c14b 100644
--- a/arch/microblaze/mm/init.c
+++ b/arch/microblaze/mm/init.c
@@ -134,13 +134,8 @@ void __init setup_memory(void)
* for 4GB of memory, using 4kB pages), plus 1 page
* (in case the address isn't page-aligned).
*/
-#ifndef CONFIG_MMU
- map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(TOPHYS((u32)klimit)),
- min_low_pfn, max_low_pfn);
-#else
- map_size = init_bootmem_node(&contig_page_data,
+ map_size = init_bootmem_node(NODE_DATA(0),
PFN_UP(TOPHYS((u32)klimit)), min_low_pfn, max_low_pfn);
-#endif
lmb_reserve(PFN_UP(TOPHYS((u32)klimit)) << PAGE_SHIFT, map_size);
/* free bootmem is whole main memory */
diff --git a/arch/mips/Kbuild b/arch/mips/Kbuild
new file mode 100644
index 000000000000..e322d65f33a4
--- /dev/null
+++ b/arch/mips/Kbuild
@@ -0,0 +1,15 @@
+# Fail on warnings - also for files referenced in subdirs
+# -Werror can be disabled for specific files using:
+# CFLAGS_<file.o> := -Wno-error
+subdir-ccflags-y := -Werror
+
+# platform specific definitions
+include arch/mips/Kbuild.platforms
+obj-y := $(platform-y)
+
+# mips object files
+# The object files are linked as core-y files would be linked
+
+obj-y += kernel/
+obj-y += mm/
+obj-y += math-emu/
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
new file mode 100644
index 000000000000..ea3b96cf2673
--- /dev/null
+++ b/arch/mips/Kbuild.platforms
@@ -0,0 +1,31 @@
+# All platforms listed in alphabetic order
+
+platforms += alchemy
+platforms += ar7
+platforms += bcm47xx
+platforms += bcm63xx
+platforms += cavium-octeon
+platforms += cobalt
+platforms += dec
+platforms += emma
+platforms += jazz
+platforms += lasat
+platforms += loongson
+platforms += mipssim
+platforms += mti-malta
+platforms += pmc-sierra
+platforms += pnx833x
+platforms += pnx8550
+platforms += powertv
+platforms += rb532
+platforms += sgi-ip22
+platforms += sgi-ip27
+platforms += sgi-ip32
+platforms += sibyte
+platforms += sni
+platforms += txx9
+platforms += vr41xx
+platforms += wrppmc
+
+# include the platform specific files
+include $(patsubst %, $(srctree)/arch/mips/%/Platform, $(platforms))
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 0b9c01add0a0..9296cbf3f1f5 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -130,26 +130,6 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap
cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap
cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap
cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap
-# only gcc >= 4.4 have the loongson-specific support
-cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
-cflags-$(CONFIG_CPU_LOONGSON2E) += \
- $(call cc-option,-march=loongson2e,-march=r4600)
-cflags-$(CONFIG_CPU_LOONGSON2F) += \
- $(call cc-option,-march=loongson2f,-march=r4600)
-# enable the workarounds for loongson2f
-ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
- ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
- $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
- else
- cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
- endif
- ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
- $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
- else
- cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
- endif
-endif
-
cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
-Wa,-mips32 -Wa,--trap
cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
@@ -209,455 +189,7 @@ endif
#
# Board-dependent options and extra files
#
-
-#
-# Texas Instruments AR7
-#
-core-$(CONFIG_AR7) += arch/mips/ar7/
-cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7
-load-$(CONFIG_AR7) += 0xffffffff94100000
-
-#
-# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
-#
-core-$(CONFIG_MACH_JAZZ) += arch/mips/jazz/
-cflags-$(CONFIG_MACH_JAZZ) += -I$(srctree)/arch/mips/include/asm/mach-jazz
-load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
-
-#
-# Common Alchemy Au1x00 stuff
-#
-core-$(CONFIG_SOC_AU1X00) += arch/mips/alchemy/common/
-
-#
-# AMD Alchemy Pb1000 eval board
-#
-core-$(CONFIG_MIPS_PB1000) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1100 eval board
-#
-core-$(CONFIG_MIPS_PB1100) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1500 eval board
-#
-core-$(CONFIG_MIPS_PB1500) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1550 eval board
-#
-core-$(CONFIG_MIPS_PB1550) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
-
-#
-# AMD Alchemy Pb1200 eval board
-#
-core-$(CONFIG_MIPS_PB1200) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1000 eval board
-#
-core-$(CONFIG_MIPS_DB1000) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1100 eval board
-#
-core-$(CONFIG_MIPS_DB1100) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1500 eval board
-#
-core-$(CONFIG_MIPS_DB1500) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1550 eval board
-#
-core-$(CONFIG_MIPS_DB1550) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1200 eval board
-#
-core-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
-
-#
-# AMD Alchemy Bosporus eval board
-#
-core-$(CONFIG_MIPS_BOSPORUS) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
-
-#
-# AMD Alchemy Mirage eval board
-#
-core-$(CONFIG_MIPS_MIRAGE) += arch/mips/alchemy/devboards/
-cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
-
-#
-# 4G-Systems eval board
-#
-libs-$(CONFIG_MIPS_MTX1) += arch/mips/alchemy/mtx-1/
-load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
-
-#
-# MyCable eval board
-#
-libs-$(CONFIG_MIPS_XXS1500) += arch/mips/alchemy/xxs1500/
-load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
-
-# must be last for Alchemy systems for GPIO to work properly
-cflags-$(CONFIG_SOC_AU1X00) += -I$(srctree)/arch/mips/include/asm/mach-au1x00
-
-
-#
-# Cobalt Server
-#
-core-$(CONFIG_MIPS_COBALT) += arch/mips/cobalt/
-cflags-$(CONFIG_MIPS_COBALT) += -I$(srctree)/arch/mips/include/asm/mach-cobalt
-load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
-
-#
-# DECstation family
-#
-core-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/
-cflags-$(CONFIG_MACH_DECSTATION)+= -I$(srctree)/arch/mips/include/asm/mach-dec
-libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
-load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
-
-#
-# Wind River PPMC Board (4KC + GT64120)
-#
-core-$(CONFIG_WR_PPMC) += arch/mips/gt64120/wrppmc/
-cflags-$(CONFIG_WR_PPMC) += -I$(srctree)/arch/mips/include/asm/mach-wrppmc
-load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
-
-#
-# Loongson family
-#
-core-$(CONFIG_MACH_LOONGSON) += arch/mips/loongson/
-cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson \
- -mno-branch-likely
-load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
-load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
-
-#
-# MIPS Malta board
-#
-core-$(CONFIG_MIPS_MALTA) += arch/mips/mti-malta/
-cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
-load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
-all-$(CONFIG_MIPS_MALTA) := $(COMPRESSION_FNAME).bin
-
-#
-# MIPS SIM
-#
-core-$(CONFIG_MIPS_SIM) += arch/mips/mipssim/
-cflags-$(CONFIG_MIPS_SIM) += -I$(srctree)/arch/mips/include/asm/mach-mipssim
-load-$(CONFIG_MIPS_SIM) += 0x80100000
-
-#
-# PMC-Sierra MSP SOCs
-#
-core-$(CONFIG_PMC_MSP) += arch/mips/pmc-sierra/msp71xx/
-cflags-$(CONFIG_PMC_MSP) += -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \
- -mno-branch-likely
-load-$(CONFIG_PMC_MSP) += 0xffffffff80100000
-
-#
-# PMC-Sierra Yosemite
-#
-core-$(CONFIG_PMC_YOSEMITE) += arch/mips/pmc-sierra/yosemite/
-cflags-$(CONFIG_PMC_YOSEMITE) += -I$(srctree)/arch/mips/include/asm/mach-yosemite
-load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000
-
-#
-# LASAT platforms
-#
-core-$(CONFIG_LASAT) += arch/mips/lasat/
-cflags-$(CONFIG_LASAT) += -I$(srctree)/arch/mips/include/asm/mach-lasat
-load-$(CONFIG_LASAT) += 0xffffffff80000000
-
-#
-# Common VR41xx
-#
-core-$(CONFIG_MACH_VR41XX) += arch/mips/vr41xx/common/
-cflags-$(CONFIG_MACH_VR41XX) += -I$(srctree)/arch/mips/include/asm/mach-vr41xx
-
-#
-# ZAO Networks Capcella (VR4131)
-#
-load-$(CONFIG_ZAO_CAPCELLA) += 0xffffffff80000000
-
-#
-# Victor MP-C303/304 (VR4122)
-#
-load-$(CONFIG_VICTOR_MPC30X) += 0xffffffff80001000
-
-#
-# IBM WorkPad z50 (VR4121)
-#
-core-$(CONFIG_IBM_WORKPAD) += arch/mips/vr41xx/ibm-workpad/
-load-$(CONFIG_IBM_WORKPAD) += 0xffffffff80004000
-
-#
-# CASIO CASSIPEIA E-55/65 (VR4111)
-#
-core-$(CONFIG_CASIO_E55) += arch/mips/vr41xx/casio-e55/
-load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
-
-#
-# TANBAC VR4131 multichip module(TB0225) and TANBAC VR4131DIMM(TB0229) (VR4131)
-#
-load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
-
-# NXP STB225
-core-$(CONFIG_SOC_PNX833X) += arch/mips/nxp/pnx833x/common/
-cflags-$(CONFIG_SOC_PNX833X) += -Iarch/mips/include/asm/mach-pnx833x
-libs-$(CONFIG_NXP_STB220) += arch/mips/nxp/pnx833x/stb22x/
-load-$(CONFIG_NXP_STB220) += 0xffffffff80001000
-libs-$(CONFIG_NXP_STB225) += arch/mips/nxp/pnx833x/stb22x/
-load-$(CONFIG_NXP_STB225) += 0xffffffff80001000
-
-#
-# Common NXP PNX8550
-#
-core-$(CONFIG_SOC_PNX8550) += arch/mips/nxp/pnx8550/common/
-cflags-$(CONFIG_SOC_PNX8550) += -I$(srctree)/arch/mips/include/asm/mach-pnx8550
-
-#
-# NXP PNX8550 JBS board
-#
-libs-$(CONFIG_PNX8550_JBS) += arch/mips/nxp/pnx8550/jbs/
-#cflags-$(CONFIG_PNX8550_JBS) += -I$(srctree)/arch/mips/include/asm/mach-pnx8550
-load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
-
-# NXP PNX8550 STB810 board
-#
-libs-$(CONFIG_PNX8550_STB810) += arch/mips/nxp/pnx8550/stb810/
-load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000
-
-#
-# Common NEC EMMAXXX
-#
-core-$(CONFIG_SOC_EMMA2RH) += arch/mips/emma/common/
-cflags-$(CONFIG_SOC_EMMA2RH) += -I$(srctree)/arch/mips/include/asm/mach-emma2rh
-
-#
-# NEC EMMA2RH Mark-eins
-#
-core-$(CONFIG_NEC_MARKEINS) += arch/mips/emma/markeins/
-load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000
-
-#
-# Cisco PowerTV Platform
-#
-core-$(CONFIG_POWERTV) += arch/mips/powertv/
-cflags-$(CONFIG_POWERTV) += -I$(srctree)/arch/mips/include/asm/mach-powertv
-load-$(CONFIG_POWERTV) += 0xffffffff90800000
-
-#
-# SGI IP22 (Indy/Indigo2)
-#
-# Set the load address to >= 0xffffffff88069000 if you want to leave space for
-# symmon, 0xffffffff80002000 for production kernels. Note that the value must
-# be aligned to a multiple of the kernel stack size or the handling of the
-# current variable will break so for 64-bit kernels we have to raise the start
-# address by 8kb.
-#
-core-$(CONFIG_SGI_IP22) += arch/mips/sgi-ip22/
-cflags-$(CONFIG_SGI_IP22) += -I$(srctree)/arch/mips/include/asm/mach-ip22
-ifdef CONFIG_32BIT
-load-$(CONFIG_SGI_IP22) += 0xffffffff88002000
-endif
-ifdef CONFIG_64BIT
-load-$(CONFIG_SGI_IP22) += 0xffffffff88004000
-endif
-
-#
-# SGI-IP27 (Origin200/2000)
-#
-# Set the load address to >= 0xc000000000300000 if you want to leave space for
-# symmon, 0xc00000000001c000 for production kernels. Note that the value must
-# be 16kb aligned or the handling of the current variable will break.
-#
-ifdef CONFIG_SGI_IP27
-core-$(CONFIG_SGI_IP27) += arch/mips/sgi-ip27/
-cflags-$(CONFIG_SGI_IP27) += -I$(srctree)/arch/mips/include/asm/mach-ip27
-ifdef CONFIG_MAPPED_KERNEL
-load-$(CONFIG_SGI_IP27) += 0xc00000004001c000
-OBJCOPYFLAGS := --change-addresses=0x3fffffff80000000
-dataoffset-$(CONFIG_SGI_IP27) += 0x01000000
-else
-load-$(CONFIG_SGI_IP27) += 0xa80000000001c000
-OBJCOPYFLAGS := --change-addresses=0x57ffffff80000000
-endif
-endif
-
-#
-# SGI IP28 (Indigo2 R10k)
-#
-# Set the load address to >= 0xa800000020080000 if you want to leave space for
-# symmon, 0xa800000020004000 for production kernels ? Note that the value must
-# be 16kb aligned or the handling of the current variable will break.
-# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
-#
-ifdef CONFIG_SGI_IP28
- ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
- $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
- endif
-endif
-core-$(CONFIG_SGI_IP28) += arch/mips/sgi-ip22/
-cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
-load-$(CONFIG_SGI_IP28) += 0xa800000020004000
-
-#
-# SGI-IP32 (O2)
-#
-# Set the load address to >= 80069000 if you want to leave space for symmon,
-# 0xffffffff80004000 for production kernels. Note that the value must be aligned to
-# a multiple of the kernel stack size or the handling of the current variable
-# will break.
-#
-core-$(CONFIG_SGI_IP32) += arch/mips/sgi-ip32/
-cflags-$(CONFIG_SGI_IP32) += -I$(srctree)/arch/mips/include/asm/mach-ip32
-load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
-
-#
-# Sibyte SB1250/BCM1480 SOC
-#
-# This is a LIB so that it links at the end, and initcalls are later
-# the sequence; but it is built as an object so that modules don't get
-# removed (as happens, even if they have __initcall/module_init)
-#
-core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/sb1250/
-core-$(CONFIG_SIBYTE_BCM112X) += arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM112X) += -I$(srctree)/arch/mips/include/asm/mach-sibyte \
- -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
-
-core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/sb1250/
-core-$(CONFIG_SIBYTE_SB1250) += arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_SB1250) += -I$(srctree)/arch/mips/include/asm/mach-sibyte \
- -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
-
-core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/bcm1480/
-core-$(CONFIG_SIBYTE_BCM1x55) += arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM1x55) += -I$(srctree)/arch/mips/include/asm/mach-sibyte \
- -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
-
-core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/bcm1480/
-core-$(CONFIG_SIBYTE_BCM1x80) += arch/mips/sibyte/common/
-cflags-$(CONFIG_SIBYTE_BCM1x80) += -I$(srctree)/arch/mips/include/asm/mach-sibyte \
- -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
-
-#
-# Sibyte BCM91120x (Carmel) board
-# Sibyte BCM91120C (CRhine) board
-# Sibyte BCM91125C (CRhone) board
-# Sibyte BCM91125E (Rhone) board
-# Sibyte SWARM board
-# Sibyte BCM91x80 (BigSur) board
-#
-core-$(CONFIG_SIBYTE_CARMEL) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_CRHINE) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CRHINE) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_CRHONE) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_CRHONE) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_RHONE) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_SENTOSA) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_SWARM) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
-core-$(CONFIG_SIBYTE_BIGSUR) += arch/mips/sibyte/swarm/
-load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
-
-#
-# Broadcom BCM47XX boards
-#
-core-$(CONFIG_BCM47XX) += arch/mips/bcm47xx/
-cflags-$(CONFIG_BCM47XX) += -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
-load-$(CONFIG_BCM47XX) := 0xffffffff80001000
-
-#
-# Broadcom BCM63XX boards
-#
-core-$(CONFIG_BCM63XX) += arch/mips/bcm63xx/
-cflags-$(CONFIG_BCM63XX) += -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
-load-$(CONFIG_BCM63XX) := 0xffffffff80010000
-
-#
-# SNI RM
-#
-core-$(CONFIG_SNI_RM) += arch/mips/sni/
-cflags-$(CONFIG_SNI_RM) += -I$(srctree)/arch/mips/include/asm/mach-rm
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-load-$(CONFIG_SNI_RM) += 0xffffffff80600000
-else
-load-$(CONFIG_SNI_RM) += 0xffffffff80030000
-endif
-all-$(CONFIG_SNI_RM) := $(COMPRESSION_FNAME).ecoff
-
-#
-# Common TXx9
-#
-core-$(CONFIG_MACH_TX39XX) += arch/mips/txx9/generic/
-cflags-$(CONFIG_MACH_TX39XX) += -I$(srctree)/arch/mips/include/asm/mach-tx39xx
-load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000
-core-$(CONFIG_MACH_TX49XX) += arch/mips/txx9/generic/
-cflags-$(CONFIG_MACH_TX49XX) += -I$(srctree)/arch/mips/include/asm/mach-tx49xx
-load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
-
-#
-# Toshiba JMR-TX3927 board
-#
-core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/
-
-#
-# Routerboard 532 board
-#
-core-$(CONFIG_MIKROTIK_RB532) += arch/mips/rb532/
-cflags-$(CONFIG_MIKROTIK_RB532) += -I$(srctree)/arch/mips/include/asm/mach-rc32434
-load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000
-
-#
-# Toshiba RBTX49XX boards
-#
-core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/
-core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/
-core-$(CONFIG_TOSHIBA_RBTX4939) += arch/mips/txx9/rbtx4939/
-
-#
-# Cavium Octeon
-#
-core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/
-cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
-core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/executive/
-ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
-load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
-else
-load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
-endif
+include $(srctree)/arch/mips/Kbuild.platforms
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
@@ -706,7 +238,8 @@ head-y := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
libs-y += arch/mips/lib/
-core-y += arch/mips/kernel/ arch/mips/mm/ arch/mips/math-emu/
+# See arch/mips/Kbuild for content of core part of the kernel
+core-y += arch/mips/
drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/
@@ -733,35 +266,19 @@ vmlinux.32: vmlinux
vmlinux.64: vmlinux
$(OBJCOPY) -O $(64bit-bfd) $(OBJCOPYFLAGS) $< $@
-makeboot =$(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) $(1)
-makezboot =$(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
- VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $(1)
-
all: $(all-y)
-vmlinuz: vmlinux FORCE
- +@$(call makezboot,$@)
+# boot
+vmlinux.bin vmlinux.ecoff vmlinux.srec: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot VMLINUX=$(vmlinux-32) arch/mips/boot/$@
-vmlinuz.bin: vmlinux
- +@$(call makezboot,$@)
+# boot/compressed
+vmlinuz vmlinuz.bin vmlinuz.ecoff vmlinuz.srec: $(vmlinux-32) FORCE
+ $(Q)$(MAKE) $(build)=arch/mips/boot/compressed \
+ VMLINUX_LOAD_ADDRESS=$(load-y) 32bit-bfd=$(32bit-bfd) $@
-vmlinuz.ecoff: vmlinux
- +@$(call makezboot,$@)
-vmlinuz.srec: vmlinux
- +@$(call makezboot,$@)
-
-vmlinux.bin: $(vmlinux-32)
- +@$(call makeboot,$@)
-
-vmlinux.ecoff: $(vmlinux-32)
- +@$(call makeboot,$@)
-
-vmlinux.srec: $(vmlinux-32)
- +@$(call makeboot,$@)
-
-CLEAN_FILES += vmlinux.ecoff \
- vmlinux.srec
+CLEAN_FILES += vmlinux.32 vmlinux.64
archprepare:
ifdef CONFIG_MIPS32_N32
@@ -780,9 +297,9 @@ install:
$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)
archclean:
- @$(MAKE) $(clean)=arch/mips/boot
- @$(MAKE) $(clean)=arch/mips/boot/compressed
- @$(MAKE) $(clean)=arch/mips/lasat
+ $(Q)$(MAKE) $(clean)=arch/mips/boot
+ $(Q)$(MAKE) $(clean)=arch/mips/boot/compressed
+ $(Q)$(MAKE) $(clean)=arch/mips/lasat
define archhelp
echo ' install - install kernel into $(INSTALL_PATH)'
@@ -796,11 +313,3 @@ define archhelp
echo
echo ' These will be default as apropriate for a configured platform.'
endef
-
-CLEAN_FILES += vmlinux.32 \
- vmlinux.64 \
- vmlinux.ecoff \
- vmlinuz \
- vmlinuz.ecoff \
- vmlinuz.bin \
- vmlinuz.srec
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform
new file mode 100644
index 000000000000..495cc9a2a3b1
--- /dev/null
+++ b/arch/mips/alchemy/Platform
@@ -0,0 +1,109 @@
+#
+# Core Alchemy code
+#
+platform-$(CONFIG_MACH_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
+#
+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/
+cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
+
+#
+# AMD Alchemy Db1200 eval board
+#
+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
+#
+platform-$(CONFIG_MIPS_MIRAGE) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
+
+#
+# 4G-Systems eval board
+#
+platform-$(CONFIG_MIPS_MTX1) += alchemy/mtx-1/
+load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
+
+#
+# MyCable eval board
+#
+platform-$(CONFIG_MIPS_XXS1500) += alchemy/xxs1500/
+load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
+
+
+# boards can specify their own <gpio.h> in one of their include dirs.
+# If they do, placing this line here at the end will make sure the
+# compiler picks the board one. If they don't, it will make sure
+# the alchemy generic gpio header is picked up.
+
+cflags-$(CONFIG_MACH_ALCHEMY) += -I$(srctree)/arch/mips/include/asm/mach-au1x00
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index 06c0e65a54b5..27811fe341d6 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -18,5 +18,3 @@ ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
endif
obj-$(CONFIG_PCI) += pci.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c
index 460c6285c1bb..af0fe41055af 100644
--- a/arch/mips/alchemy/common/clocks.c
+++ b/arch/mips/alchemy/common/clocks.c
@@ -89,11 +89,7 @@ unsigned long au1xxx_calc_clock(void)
* over backwards trying to determine the frequency.
*/
if (au1xxx_cpu_has_pll_wo())
-#ifdef CONFIG_SOC_AU1000_FREQUENCY
- cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
-#else
cpu_speed = 396000000;
-#endif
else
cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index ecbd37f9ee87..826449c817c3 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -16,5 +16,3 @@ obj-$(CONFIG_MIPS_DB1500) += db1x00/
obj-$(CONFIG_MIPS_DB1550) += db1x00/
obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c
index 3cb95a98ab31..3fa34c3abc04 100644
--- a/arch/mips/alchemy/devboards/db1200/platform.c
+++ b/arch/mips/alchemy/devboards/db1200/platform.c
@@ -216,14 +216,14 @@ static struct resource db1200_ide_res[] = {
}
};
-static u64 ide_dmamask = DMA_32BIT_MASK;
+static u64 ide_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1200_ide_dev = {
.name = "au1200-ide",
.id = 0,
.dev = {
.dma_mask = &ide_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(db1200_ide_res),
.resource = db1200_ide_res,
@@ -385,12 +385,12 @@ static struct au1550_spi_info db1200_spi_platdata = {
.activate_cs = db1200_spi_cs_en,
};
-static u64 spi_dmamask = DMA_32BIT_MASK;
+static u64 spi_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1200_spi_dev = {
.dev = {
.dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_32BIT_MASK,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1200_spi_platdata,
},
.name = "au1550-spi",
diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
index 2ea9b02ef09f..18c1bd53e4c0 100644
--- a/arch/mips/alchemy/devboards/pb1200/Makefile
+++ b/arch/mips/alchemy/devboards/pb1200/Makefile
@@ -3,5 +3,3 @@
#
obj-y := board_setup.o platform.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/mtx-1/Makefile b/arch/mips/alchemy/mtx-1/Makefile
index 4a53815b3c6c..81b540ceaf88 100644
--- a/arch/mips/alchemy/mtx-1/Makefile
+++ b/arch/mips/alchemy/mtx-1/Makefile
@@ -6,7 +6,4 @@
# Makefile for 4G Systems MTX-1 board.
#
-lib-y := init.o board_setup.o
-obj-y := platform.o
-
-EXTRA_CFLAGS += -Werror
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
index 4dc81d794cb8..91defcf4f335 100644
--- a/arch/mips/alchemy/xxs1500/Makefile
+++ b/arch/mips/alchemy/xxs1500/Makefile
@@ -5,6 +5,4 @@
# Makefile for MyCable XXS1500 board.
#
-lib-y := init.o board_setup.o platform.o
-
-EXTRA_CFLAGS += -Werror
+obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/ar7/Makefile b/arch/mips/ar7/Makefile
index 26bc5da18997..7435e44b3964 100644
--- a/arch/mips/ar7/Makefile
+++ b/arch/mips/ar7/Makefile
@@ -8,4 +8,3 @@ obj-y := \
platform.o \
gpio.o \
clock.o
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/ar7/Platform b/arch/mips/ar7/Platform
new file mode 100644
index 000000000000..0bf85c416c6c
--- /dev/null
+++ b/arch/mips/ar7/Platform
@@ -0,0 +1,6 @@
+#
+# Texas Instruments AR7
+#
+platform-$(CONFIG_AR7) += ar7/
+cflags-$(CONFIG_AR7) += -I$(srctree)/arch/mips/include/asm/mach-ar7
+load-$(CONFIG_AR7) += 0xffffffff94100000
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 8f31d1d59683..0da5b2b8dd88 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -292,40 +292,28 @@ static struct platform_device cpmac_high = {
.num_resources = ARRAY_SIZE(cpmac_high_res),
};
-static inline unsigned char char2hex(char h)
+static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
{
- switch (h) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- return h - '0';
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- return h - 'A' + 10;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return h - 'a' + 10;
- default:
- return 0;
- }
-}
-
-static void cpmac_get_mac(int instance, unsigned char *dev_addr)
-{
- int i;
- char name[5], default_mac[ETH_ALEN], *mac;
+ char name[5], *mac;
- mac = NULL;
sprintf(name, "mac%c", 'a' + instance);
mac = prom_getenv(name);
- if (!mac) {
+ if (!mac && instance) {
sprintf(name, "mac%c", 'a');
mac = prom_getenv(name);
}
- if (!mac) {
- random_ether_addr(default_mac);
- mac = default_mac;
- }
- for (i = 0; i < 6; i++)
- dev_addr[i] = (char2hex(mac[i * 3]) << 4) +
- char2hex(mac[i * 3 + 1]);
+
+ if (mac) {
+ if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ &dev_addr[0], &dev_addr[1],
+ &dev_addr[2], &dev_addr[3],
+ &dev_addr[4], &dev_addr[5]) != 6) {
+ pr_warning("cannot parse mac address, "
+ "using random address\n");
+ random_ether_addr(dev_addr);
+ }
+ } else
+ random_ether_addr(dev_addr);
}
/*****************************************************************************
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform
new file mode 100644
index 000000000000..874b7ca4cd11
--- /dev/null
+++ b/arch/mips/bcm47xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM47XX boards
+#
+platform-$(CONFIG_BCM47XX) += bcm47xx/
+cflags-$(CONFIG_BCM47XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
+load-$(CONFIG_BCM47XX) := 0xffffffff80001000
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 00064b660809..6dfdc69928ac 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -3,5 +3,3 @@ obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/bcm63xx/Platform b/arch/mips/bcm63xx/Platform
new file mode 100644
index 000000000000..5f86b2fff6de
--- /dev/null
+++ b/arch/mips/bcm63xx/Platform
@@ -0,0 +1,7 @@
+#
+# Broadcom BCM63XX boards
+#
+platform-$(CONFIG_BCM63XX) += bcm63xx/
+cflags-$(CONFIG_BCM63XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-bcm63xx/
+load-$(CONFIG_BCM63XX) := 0xffffffff80010000
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index e39a08edcaaa..85bcb5adc7cb 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -11,35 +11,32 @@
# Some DECstations need all possible sections of an ECOFF executable
#
ifdef CONFIG_MACH_DECSTATION
- E2EFLAGS = -a
-else
- E2EFLAGS =
+ e2eflag := -a
endif
#
# Drop some uninteresting sections in the kernel.
# This is only relevant for ELF kernels but doesn't hurt a.out
#
-drop-sections = .reginfo .mdebug .comment .note .pdr .options .MIPS.options
-strip-flags = $(addprefix --remove-section=,$(drop-sections))
-
-VMLINUX = vmlinux
-
-all: vmlinux.ecoff vmlinux.srec
-
-vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX)
- $(obj)/elf2ecoff $(VMLINUX) $(obj)/vmlinux.ecoff $(E2EFLAGS)
-
-$(obj)/elf2ecoff: $(obj)/elf2ecoff.c
- $(HOSTCC) -o $@ $^
-
-vmlinux.bin: $(VMLINUX)
- $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $(obj)/vmlinux.bin
-
-vmlinux.srec: $(VMLINUX)
- $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $(obj)/vmlinux.srec
-
-clean-files += elf2ecoff \
- vmlinux.bin \
- vmlinux.ecoff \
- vmlinux.srec
+drop-sections := .reginfo .mdebug .comment .note .pdr .options .MIPS.options
+strip-flags := $(addprefix --remove-section=,$(drop-sections))
+
+hostprogs-y := elf2ecoff
+
+targets := vmlinux.ecoff
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $(obj)/elf2ecoff $(VMLINUX) $@ $(e2eflag)
+$(obj)/vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) FORCE
+ $(call if_changed,ecoff)
+
+targets += vmlinux.bin
+quiet_cmd_bin = OBJCOPY $@
+ cmd_bin = $(OBJCOPY) -O binary $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.bin: $(VMLINUX) FORCE
+ $(call if_changed,bin)
+
+targets += vmlinux.srec
+quiet_cmd_srec = OBJCOPY $@
+ cmd_srec = $(OBJCOPY) -S -O srec $(strip-flags) $(VMLINUX) $@
+$(obj)/vmlinux.srec: $(VMLINUX) FORCE
+ $(call if_changed,srec)
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 790ddd397620..74a52d799346 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -33,15 +33,19 @@ KBUILD_AFLAGS := $(LINUXINCLUDE) $(KBUILD_AFLAGS) -D__ASSEMBLY__ \
-DBOOT_HEAP_SIZE=$(BOOT_HEAP_SIZE) \
-DKERNEL_ENTRY=0x$(shell $(NM) $(objtree)/$(KBUILD_IMAGE) 2>/dev/null | grep " kernel_entry" | cut -f1 -d \ )
-obj-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
+targets := head.o decompress.o dbg.o uart-16550.o uart-alchemy.o
+
+# decompressor objects (linked with vmlinuz)
+vmlinuzobjs-y := $(obj)/head.o $(obj)/decompress.o $(obj)/dbg.o
ifdef CONFIG_DEBUG_ZBOOT
-obj-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
-obj-$(CONFIG_MACH_ALCHEMY) += $(obj)/uart-alchemy.o
+vmlinuzobjs-$(CONFIG_SYS_SUPPORTS_ZBOOT_UART16550) += $(obj)/uart-16550.o
+vmlinuzobjs-$(CONFIG_MACH_ALCHEMY) += $(obj)/uart-alchemy.o
endif
+targets += vmlinux.bin
OBJCOPYFLAGS_vmlinux.bin := $(OBJCOPYFLAGS) -O binary -R .comment -S
-$(obj)/vmlinux.bin: $(KBUILD_IMAGE)
+$(obj)/vmlinux.bin: $(KBUILD_IMAGE) FORCE
$(call if_changed,objcopy)
suffix_$(CONFIG_KERNEL_GZIP) = gz
@@ -52,30 +56,31 @@ tool_$(CONFIG_KERNEL_GZIP) = gzip
tool_$(CONFIG_KERNEL_BZIP2) = bzip2
tool_$(CONFIG_KERNEL_LZMA) = lzma
tool_$(CONFIG_KERNEL_LZO) = lzo
-$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin
+
+targets += vmlinux.gz vmlinux.bz2 vmlinux.lzma vmlinux.lzo
+$(obj)/vmlinux.$(suffix_y): $(obj)/vmlinux.bin FORCE
$(call if_changed,$(tool_y))
-$(obj)/piggy.o: $(obj)/vmlinux.$(suffix_y) $(obj)/dummy.o
- $(Q)$(OBJCOPY) $(OBJCOPYFLAGS) \
- --add-section=.image=$< \
- --set-section-flags=.image=contents,alloc,load,readonly,data \
- $(obj)/dummy.o $@
+targets += piggy.o
+OBJCOPYFLAGS_piggy.o := --add-section=.image=$(obj)/vmlinux.$(suffix_y) \
+ --set-section-flags=.image=contents,alloc,load,readonly,data
+$(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.$(suffix_y) FORCE
+ $(call if_changed,objcopy)
LDFLAGS_vmlinuz := $(LDFLAGS) -Ttext $(VMLINUZ_LOAD_ADDRESS) -T
-vmlinuz: $(src)/ld.script $(obj-y) $(obj)/piggy.o
- $(call if_changed,ld)
+vmlinuz: $(src)/ld.script $(vmlinuzobjs-y) $(obj)/piggy.o
+ $(call cmd,ld)
$(Q)$(OBJCOPY) $(OBJCOPYFLAGS) $@
#
# Some DECstations need all possible sections of an ECOFF executable
#
ifdef CONFIG_MACH_DECSTATION
- E2EFLAGS = -a
-else
- E2EFLAGS =
+ e2eflag := -a
endif
# elf2ecoff can only handle 32bit image
+hostprogs-y := ../elf2ecoff
ifdef CONFIG_32BIT
VMLINUZ = vmlinuz
@@ -83,23 +88,22 @@ else
VMLINUZ = vmlinuz.32
endif
+quiet_cmd_32 = OBJCOPY $@
+ cmd_32 = $(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
vmlinuz.32: vmlinuz
- $(Q)$(OBJCOPY) -O $(32bit-bfd) $(OBJCOPYFLAGS) $< $@
+ $(call cmd,32)
+quiet_cmd_ecoff = ECOFF $@
+ cmd_ecoff = $< $(VMLINUZ) $@ $(e2eflag)
vmlinuz.ecoff: $(obj)/../elf2ecoff $(VMLINUZ)
- $(Q)$(obj)/../elf2ecoff $(VMLINUZ) vmlinuz.ecoff $(E2EFLAGS)
-
-$(obj)/../elf2ecoff: $(src)/../elf2ecoff.c
- $(Q)$(HOSTCC) -o $@ $^
+ $(call cmd,ecoff)
OBJCOPYFLAGS_vmlinuz.bin := $(OBJCOPYFLAGS) -O binary
vmlinuz.bin: vmlinuz
- $(call if_changed,objcopy)
+ $(call cmd,objcopy)
OBJCOPYFLAGS_vmlinuz.srec := $(OBJCOPYFLAGS) -S -O srec
vmlinuz.srec: vmlinuz
- $(call if_changed,objcopy)
+ $(call cmd,objcopy)
-clean:
-clean-files += *.o \
- vmlinu*
+clean-files := $(objtree)/vmlinuz.*
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 3e9876317e61..19eb0434269f 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -12,7 +12,6 @@
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
+obj-y += executive/
obj-$(CONFIG_SMP) += smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cavium-octeon/Platform b/arch/mips/cavium-octeon/Platform
new file mode 100644
index 000000000000..1e43ccf1a792
--- /dev/null
+++ b/arch/mips/cavium-octeon/Platform
@@ -0,0 +1,11 @@
+#
+# Cavium Octeon
+#
+platform-$(CONFIG_CPU_CAVIUM_OCTEON) += cavium-octeon/
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += \
+ -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
+ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
+else
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
+endif
diff --git a/arch/mips/cavium-octeon/cpu.c b/arch/mips/cavium-octeon/cpu.c
index b6df5387e855..0ad070cd9fb9 100644
--- a/arch/mips/cavium-octeon/cpu.c
+++ b/arch/mips/cavium-octeon/cpu.c
@@ -41,12 +41,8 @@ static int cnmips_cu2_call(struct notifier_block *nfb, unsigned long action,
return NOTIFY_OK; /* Let default notifier send signals */
}
-static struct notifier_block cnmips_cu2_notifier = {
- .notifier_call = cnmips_cu2_call,
-};
-
static int cnmips_cu2_setup(void)
{
- return register_cu2_notifier(&cnmips_cu2_notifier);
+ return cu2_notifier(cnmips_cu2_call);
}
early_initcall(cnmips_cu2_setup);
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
index 83eac37a1ff9..638adab02842 100644
--- a/arch/mips/cavium-octeon/serial.c
+++ b/arch/mips/cavium-octeon/serial.c
@@ -18,11 +18,7 @@
#include <asm/octeon/octeon.h>
-#ifdef CONFIG_GDB_CONSOLE
-#define DEBUG_UART 0
-#else
#define DEBUG_UART 1
-#endif
unsigned int octeon_serial_in(struct uart_port *up, int offset)
{
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index d1b5ffaf0281..8c81a5c5bbab 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -578,9 +578,6 @@ void __init prom_init(void)
}
if (strstr(arcs_cmdline, "console=") == NULL) {
-#ifdef CONFIG_GDB_CONSOLE
- strcat(arcs_cmdline, " console=gdb");
-#else
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
strcat(arcs_cmdline, " console=ttyS0,115200");
#else
@@ -589,7 +586,6 @@ void __init prom_init(void)
else
strcat(arcs_cmdline, " console=ttyS0,115200");
#endif
-#endif
}
if (octeon_is_simulation()) {
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile
index 237926288d6d..61a334ac43ac 100644
--- a/arch/mips/cobalt/Makefile
+++ b/arch/mips/cobalt/Makefile
@@ -7,5 +7,3 @@ obj-y := buttons.o irq.o lcd.o led.o reset.o rtc.o serial.o setup.o time.o
obj-$(CONFIG_PCI) += pci.o
obj-$(CONFIG_EARLY_PRINTK) += console.o
obj-$(CONFIG_MTD_PHYSMAP) += mtd.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/cobalt/Platform b/arch/mips/cobalt/Platform
new file mode 100644
index 000000000000..34123efd6dfe
--- /dev/null
+++ b/arch/mips/cobalt/Platform
@@ -0,0 +1,6 @@
+#
+# Cobalt Server
+#
+platform-$(CONFIG_MIPS_COBALT) += cobalt/
+cflags-$(CONFIG_MIPS_COBALT) += -I$(srctree)/arch/mips/include/asm/mach-cobalt
+load-$(CONFIG_MIPS_COBALT) += 0xffffffff80080000
diff --git a/arch/mips/configs/powertv_defconfig b/arch/mips/configs/powertv_defconfig
index 7291633d81cc..af0ab73bfce8 100644
--- a/arch/mips/configs/powertv_defconfig
+++ b/arch/mips/configs/powertv_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.31-rc5
-# Fri Aug 28 14:49:33 2009
+# Linux kernel version: 2.6.35-rc3
+# Thu Jul 1 11:03:28 2010
#
CONFIG_MIPS=y
@@ -11,11 +11,12 @@ CONFIG_MIPS=y
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_AR7 is not set
# CONFIG_BCM47XX is not set
+# CONFIG_BCM63XX is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_LASAT is not set
-# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MACH_LOONGSON is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SIM is not set
# CONFIG_NEC_MARKEINS is not set
@@ -50,7 +51,6 @@ CONFIG_POWERTV=y
# CONFIG_MIN_RUNTIME_RESOURCES is not set
# CONFIG_BOOTLOADER_DRIVER is not set
CONFIG_BOOTLOADER_FAMILY="R2"
-CONFIG_CSRC_POWERTV=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
@@ -65,9 +65,9 @@ CONFIG_SCHED_OMIT_FRAME_POINTER=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_CEVT_R4K_LIB=y
CONFIG_CEVT_R4K=y
+CONFIG_CSRC_POWERTV=y
CONFIG_DMA_NONCOHERENT=y
-CONFIG_DMA_NEED_PCI_MAP_STATE=y
-# CONFIG_EARLY_PRINTK is not set
+CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
# CONFIG_NO_IOPORT is not set
CONFIG_CPU_BIG_ENDIAN=y
@@ -79,7 +79,8 @@ CONFIG_MIPS_L1_CACHE_SHIFT=5
#
# CPU selection
#
-# CONFIG_CPU_LOONGSON2 is not set
+# CONFIG_CPU_LOONGSON2E is not set
+# CONFIG_CPU_LOONGSON2F is not set
# CONFIG_CPU_MIPS32_R1 is not set
CONFIG_CPU_MIPS32_R2=y
# CONFIG_CPU_MIPS64_R1 is not set
@@ -122,7 +123,7 @@ CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
-CONFIG_CPU_HAS_LLSC=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
CONFIG_CPU_MIPSR2_IRQ_VI=y
CONFIG_CPU_MIPSR2_IRQ_EI=y
CONFIG_CPU_HAS_SYNC=y
@@ -144,8 +145,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
-CONFIG_HAVE_MLOCK=y
-CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+# CONFIG_KSM is not set
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
@@ -177,6 +177,7 @@ CONFIG_EXPERIMENTAL=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE="mips-linux-"
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
# CONFIG_SWAP is not set
@@ -190,19 +191,15 @@ CONFIG_SYSVIPC_SYSCTL=y
#
# RCU Subsystem
#
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
# CONFIG_IKCONFIG is not set
CONFIG_LOG_BUF_SHIFT=16
-CONFIG_GROUP_SCHED=y
-CONFIG_FAIR_GROUP_SCHED=y
-# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_USER_SCHED=y
-# CONFIG_CGROUP_SCHED is not set
-# CONFIG_CGROUPS is not set
# CONFIG_SYSFS_DEPRECATED_V2 is not set
CONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
@@ -211,6 +208,7 @@ CONFIG_INITRAMFS_SOURCE=""
# CONFIG_RD_GZIP is not set
# CONFIG_RD_BZIP2 is not set
# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
@@ -234,18 +232,16 @@ CONFIG_SHMEM=y
CONFIG_AIO=y
#
-# Performance Counters
+# Kernel Performance Events And Counters
#
# CONFIG_VM_EVENT_COUNTERS is not set
CONFIG_PCI_QUIRKS=y
# CONFIG_SLUB_DEBUG is not set
-# CONFIG_STRIP_ASM_SYMS is not set
CONFIG_COMPAT_BRK=y
# CONFIG_SLAB is not set
CONFIG_SLUB=y
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
#
@@ -253,7 +249,7 @@ CONFIG_HAVE_OPROFILE=y
#
# CONFIG_GCOV_KERNEL is not set
# CONFIG_SLOW_WORK is not set
-# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_RT_MUTEXES=y
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
@@ -271,15 +267,41 @@ CONFIG_LBDAF=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
# CONFIG_IOSCHED_DEADLINE is not set
# CONFIG_IOSCHED_CFQ is not set
-# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
# CONFIG_DEFAULT_CFQ is not set
CONFIG_DEFAULT_NOOP=y
CONFIG_DEFAULT_IOSCHED="noop"
-# CONFIG_PROBE_INITRD_HEADER is not set
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
# CONFIG_FREEZER is not set
#
@@ -289,7 +311,6 @@ CONFIG_HW_HAS_PCI=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
-# CONFIG_PCI_LEGACY is not set
# CONFIG_PCI_DEBUG is not set
# CONFIG_PCI_STUB is not set
# CONFIG_PCI_IOV is not set
@@ -318,7 +339,6 @@ CONFIG_NET=y
# Networking options
#
CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
@@ -390,12 +410,26 @@ CONFIG_NETFILTER_ADVANCED=y
# CONFIG_NETFILTER_NETLINK_LOG is not set
# CONFIG_NF_CONNTRACK is not set
CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+# CONFIG_NETFILTER_XT_MARK is not set
+
+#
+# Xtables targets
+#
# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
# CONFIG_NETFILTER_XT_TARGET_MARK is not set
# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TEE is not set
# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+
+#
+# Xtables matches
+#
# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
@@ -465,10 +499,13 @@ CONFIG_IP6_NF_FILTER=y
# CONFIG_IP6_NF_RAW is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
CONFIG_STP=y
CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
@@ -526,10 +563,21 @@ CONFIG_NET_SCH_FIFO=y
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-# CONFIG_WIRELESS is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
#
# Device Drivers
@@ -539,6 +587,7 @@ CONFIG_NET_SCH_FIFO=y
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_FW_LOADER=y
@@ -550,9 +599,9 @@ CONFIG_EXTRA_FIRMWARE=""
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_TESTS is not set
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AR7_PARTS is not set
@@ -568,6 +617,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
+# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
#
@@ -611,11 +661,16 @@ CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+# CONFIG_MTD_NAND_DENALI is not set
+CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xFF108018
CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_RICOH is not set
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_CAFE is not set
# CONFIG_MTD_NAND_NANDSIM is not set
@@ -641,6 +696,10 @@ CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
@@ -658,6 +717,7 @@ CONFIG_HAVE_IDE=y
#
# SCSI device support
#
+CONFIG_SCSI_MOD=y
# CONFIG_RAID_ATTRS is not set
CONFIG_SCSI=y
CONFIG_SCSI_DMA=y
@@ -693,64 +753,95 @@ CONFIG_SCSI_WAIT_SCAN=m
# CONFIG_SCSI_OSD_INITIATOR is not set
CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_AHCI_PLATFORM is not set
+# CONFIG_SATA_INIC162X is not set
# CONFIG_SATA_SIL24 is not set
CONFIG_ATA_SFF=y
-# CONFIG_SATA_SVW is not set
+
+#
+# SFF controllers with custom DMA interface
+#
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
# CONFIG_ATA_PIIX is not set
# CONFIG_SATA_MV is not set
# CONFIG_SATA_NV is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_SATA_QSTOR is not set
# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_SX4 is not set
# CONFIG_SATA_SIL is not set
# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_SVW is not set
# CONFIG_SATA_ULI is not set
# CONFIG_SATA_VIA is not set
# CONFIG_SATA_VITESSE is not set
-# CONFIG_SATA_INIC162X is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
# CONFIG_PATA_ALI is not set
# CONFIG_PATA_AMD is not set
# CONFIG_PATA_ARTOP is not set
# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_ATP867X is not set
# CONFIG_PATA_CMD64X is not set
# CONFIG_PATA_CS5520 is not set
# CONFIG_PATA_CS5530 is not set
# CONFIG_PATA_CYPRESS is not set
# CONFIG_PATA_EFAR is not set
-# CONFIG_ATA_GENERIC is not set
# CONFIG_PATA_HPT366 is not set
# CONFIG_PATA_HPT37X is not set
# CONFIG_PATA_HPT3X2N is not set
# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_IT821X is not set
# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_NETCELL is not set
# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OLDPIIX is not set
# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_PDC_OLD is not set
# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_RDC is not set
# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SCH is not set
# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_PDC2027X is not set
# CONFIG_PATA_SIL680 is not set
# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_TRIFLEX is not set
# CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
# CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_SCH is not set
+# CONFIG_PATA_RZ1000 is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_LEGACY is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -763,7 +854,7 @@ CONFIG_ATA_SFF=y
#
#
-# See the help texts for more information.
+# The newer stack is recommended.
#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
@@ -787,6 +878,7 @@ CONFIG_MII=y
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_ETHOC is not set
+# CONFIG_SMSC911X is not set
# CONFIG_DNET is not set
# CONFIG_NET_TULIP is not set
# CONFIG_HP100 is not set
@@ -800,6 +892,7 @@ CONFIG_MII=y
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
# CONFIG_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
@@ -829,6 +922,8 @@ CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
@@ -841,16 +936,12 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
+# CONFIG_QLCNIC is not set
# CONFIG_QLGE is not set
# CONFIG_SFC is not set
# CONFIG_BE2NET is not set
# CONFIG_TR is not set
-
-#
-# Wireless LAN
-#
-# CONFIG_WLAN_PRE80211 is not set
-# CONFIG_WLAN_80211 is not set
+# CONFIG_WLAN is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -864,6 +955,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_USB_PEGASUS is not set
CONFIG_USB_RTL8150=y
# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -873,6 +965,7 @@ CONFIG_USB_RTL8150=y
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
@@ -882,6 +975,7 @@ CONFIG_USB_RTL8150=y
CONFIG_INPUT=y
# CONFIG_INPUT_FF_MEMLESS is not set
# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
#
# Userland interfaces
@@ -913,6 +1007,7 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_VT is not set
# CONFIG_DEVKMEM is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
# CONFIG_NOZOMI is not set
#
@@ -924,6 +1019,9 @@ CONFIG_INPUT_EVDEV=y
# Non-8250 serial port support
#
# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
@@ -934,6 +1032,7 @@ CONFIG_UNIX98_PTYS=y
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
# CONFIG_I2C is not set
# CONFIG_SPI is not set
@@ -945,7 +1044,6 @@ CONFIG_DEVPORT=y
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
@@ -953,20 +1051,14 @@ CONFIG_SSB_POSSIBLE=y
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
-
-#
-# Multifunction device drivers
-#
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_SUPPORT is not set
# CONFIG_REGULATOR is not set
# CONFIG_MEDIA_SUPPORT is not set
#
# Graphics support
#
+# CONFIG_VGA_ARB is not set
# CONFIG_DRM is not set
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
@@ -980,7 +1072,6 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
-# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
#
@@ -993,31 +1084,43 @@ CONFIG_USB_HIDDEV=y
#
# Special HID drivers
#
+# CONFIG_HID_3M_PCT is not set
# CONFIG_HID_A4TECH is not set
# CONFIG_HID_APPLE is not set
# CONFIG_HID_BELKIN is not set
+# CONFIG_HID_CANDO is not set
# CONFIG_HID_CHERRY is not set
# CONFIG_HID_CHICONY is not set
# CONFIG_HID_CYPRESS is not set
# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EGALAX is not set
# CONFIG_HID_EZKEY is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
# CONFIG_HID_LOGITECH is not set
# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MOSART is not set
# CONFIG_HID_MONTEREY is not set
# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
# CONFIG_HID_PANTHERLORD is not set
# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_KONE is not set
# CONFIG_HID_SAMSUNG is not set
# CONFIG_HID_SONY is not set
+# CONFIG_HID_STANTUM is not set
# CONFIG_HID_SUNPLUS is not set
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
# CONFIG_HID_TOPSEED is not set
# CONFIG_HID_THRUSTMASTER is not set
# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1032,7 +1135,6 @@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
# CONFIG_USB_OTG_WHITELIST is not set
# CONFIG_USB_OTG_BLACKLIST_HUB is not set
# CONFIG_USB_MON is not set
@@ -1050,6 +1152,7 @@ CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_OXU210HP_HCD is not set
# CONFIG_USB_ISP116X_HCD is not set
# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
CONFIG_USB_OHCI_HCD=y
# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
@@ -1133,6 +1236,7 @@ CONFIG_USB_SERIAL_CP210X=y
# CONFIG_USB_SERIAL_NAVMAN is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_OTI6858 is not set
+# CONFIG_USB_SERIAL_QCAUX is not set
# CONFIG_USB_SERIAL_QUALCOMM is not set
# CONFIG_USB_SERIAL_SPCP8X5 is not set
# CONFIG_USB_SERIAL_HP4X is not set
@@ -1146,6 +1250,8 @@ CONFIG_USB_SERIAL_CP210X=y
# CONFIG_USB_SERIAL_OPTION is not set
# CONFIG_USB_SERIAL_OMNINET is not set
# CONFIG_USB_SERIAL_OPTICON is not set
+# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
+# CONFIG_USB_SERIAL_ZIO is not set
# CONFIG_USB_SERIAL_DEBUG is not set
#
@@ -1158,7 +1264,6 @@ CONFIG_USB_SERIAL_CP210X=y
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_LEGOTOWER is not set
# CONFIG_USB_LCD is not set
-# CONFIG_USB_BERRY_CHARGE is not set
# CONFIG_USB_LED is not set
# CONFIG_USB_CYPRESS_CY7C63 is not set
# CONFIG_USB_CYTHERM is not set
@@ -1171,7 +1276,6 @@ CONFIG_USB_SERIAL_CP210X=y
# CONFIG_USB_IOWARRIOR is not set
# CONFIG_USB_TEST is not set
# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_VST is not set
# CONFIG_USB_GADGET is not set
#
@@ -1189,10 +1293,6 @@ CONFIG_RTC_LIB=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
-
-#
-# TI VLYNQ
-#
# CONFIG_STAGING is not set
#
@@ -1214,6 +1314,7 @@ CONFIG_JBD=y
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
CONFIG_FILE_LOCKING=y
CONFIG_FSNOTIFY=y
# CONFIG_DNOTIFY is not set
@@ -1274,6 +1375,7 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_LOGFS is not set
CONFIG_CRAMFS=y
# CONFIG_SQUASHFS is not set
# CONFIG_VXFS_FS is not set
@@ -1284,7 +1386,6 @@ CONFIG_CRAMFS=y
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
-# CONFIG_NILFS2_FS is not set
CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
@@ -1299,6 +1400,7 @@ CONFIG_SUNRPC=y
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
# CONFIG_CODA_FS is not set
@@ -1360,6 +1462,7 @@ CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
@@ -1393,15 +1496,25 @@ CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
# CONFIG_PAGE_POISONING is not set
+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_TRACING_SUPPORT=y
CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
@@ -1410,19 +1523,22 @@ CONFIG_FTRACE=y
CONFIG_BRANCH_PROFILE_NONE=y
# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
# CONFIG_KMEMTRACE is not set
# CONFIG_WORKQUEUE_TRACER is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
+# CONFIG_EARLY_PRINTK is not set
CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10.0.1.1:255.255.255.0:zeus:eth0: root=/dev/nfs nfsroot=/nfsroot/cramfs,wsize=512,rsize=512,tcp nokgdb console=ttyUSB0,115200 memsize=252M"
+CONFIG_CMDLINE=""
# CONFIG_CMDLINE_OVERRIDE is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_RUNTIME_DEBUG is not set
+# CONFIG_SPINLOCK_TEST is not set
#
# Security options
@@ -1430,13 +1546,16 @@ CONFIG_CMDLINE="rw dhash_entries=1024 ihash_entries=1024 ip=10.0.1.3:10.0.1.1:10
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
-# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
@@ -1479,11 +1598,13 @@ CONFIG_CRYPTO_CBC=y
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
index c530208ee154..9eb2f9c036aa 100644
--- a/arch/mips/dec/Makefile
+++ b/arch/mips/dec/Makefile
@@ -8,5 +8,3 @@ obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
obj-$(CONFIG_PROM_CONSOLE) += promcon.o
obj-$(CONFIG_TC) += tc.o
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/dec/Platform b/arch/mips/dec/Platform
new file mode 100644
index 000000000000..3adbcbd95db1
--- /dev/null
+++ b/arch/mips/dec/Platform
@@ -0,0 +1,8 @@
+#
+# DECstation family
+#
+platform-$(CONFIG_MACH_DECSTATION) = dec/
+cflags-$(CONFIG_MACH_DECSTATION) += \
+ -I$(srctree)/arch/mips/include/asm/mach-dec
+libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
+load-$(CONFIG_MACH_DECSTATION) += 0xffffffff80040000
diff --git a/arch/mips/dec/promcon.c b/arch/mips/dec/promcon.c
index 9f0972f5a702..c239c25b79ff 100644
--- a/arch/mips/dec/promcon.c
+++ b/arch/mips/dec/promcon.c
@@ -33,8 +33,7 @@ static int __init prom_console_setup(struct console *co, char *options)
return 0;
}
-static struct console sercons =
-{
+static struct console sercons = {
.name = "ttyS",
.write = prom_console_write,
.setup = prom_console_setup,
diff --git a/arch/mips/emma/Makefile b/arch/mips/emma/Makefile
new file mode 100644
index 000000000000..4254a31edb09
--- /dev/null
+++ b/arch/mips/emma/Makefile
@@ -0,0 +1,6 @@
+obj-$(CONFIG_SOC_EMMA2RH) += common/
+
+#
+# NEC EMMA2RH Mark-eins
+#
+obj-$(CONFIG_NEC_MARKEINS) += markeins/
diff --git a/arch/mips/emma/Platform b/arch/mips/emma/Platform
new file mode 100644
index 000000000000..0282f7f99b88
--- /dev/null
+++ b/arch/mips/emma/Platform
@@ -0,0 +1,4 @@
+platform-$(CONFIG_SOC_EMMA2RH) += emma/
+cflags-$(CONFIG_SOC_EMMA2RH) += \
+ -I$(srctree)/arch/mips/include/asm/mach-emma2rh
+load-$(CONFIG_NEC_MARKEINS) += 0xffffffff88100000
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 9504b7ee0b7c..3a96799eb65f 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -301,7 +301,7 @@ void __init arch_init_irq(void)
/* setup cascade interrupts */
setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_SW_CASCADE, &irq_cascade);
setup_irq(EMMA2RH_IRQ_BASE + EMMA2RH_GPIO_CASCADE, &irq_cascade);
- setup_irq(CPU_IRQ_BASE + CPU_EMMA2RH_CASCADE, &irq_cascade);
+ setup_irq(MIPS_CPU_IRQ_BASE + 2, &irq_cascade);
}
asmlinkage void plat_irq_dispatch(void)
@@ -309,13 +309,13 @@ asmlinkage void plat_irq_dispatch(void)
unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
if (pending & STATUSF_IP7)
- do_IRQ(CPU_IRQ_BASE + 7);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
else if (pending & STATUSF_IP2)
emma2rh_irq_dispatch();
else if (pending & STATUSF_IP1)
- do_IRQ(CPU_IRQ_BASE + 1);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 1);
else if (pending & STATUSF_IP0)
- do_IRQ(CPU_IRQ_BASE + 0);
+ do_IRQ(MIPS_CPU_IRQ_BASE + 0);
else
spurious_interrupt();
}
diff --git a/arch/mips/include/asm/arch_hweight.h b/arch/mips/include/asm/arch_hweight.h
new file mode 100644
index 000000000000..712a7445ee93
--- /dev/null
+++ b/arch/mips/include/asm/arch_hweight.h
@@ -0,0 +1,38 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef _ASM_ARCH_HWEIGHT_H
+#define _ASM_ARCH_HWEIGHT_H
+
+#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_hweight32(unsigned int w)
+{
+ return __builtin_popcount(w);
+}
+
+static inline unsigned int __arch_hweight16(unsigned int w)
+{
+ return __builtin_popcount(w & 0xffff);
+}
+
+static inline unsigned int __arch_hweight8(unsigned int w)
+{
+ return __builtin_popcount(w & 0xff);
+}
+
+static inline unsigned long __arch_hweight64(__u64 w)
+{
+ return __builtin_popcountll(w);
+}
+
+#else
+#include <asm-generic/bitops/arch_hweight.h>
+#endif
+
+#endif /* _ASM_ARCH_HWEIGHT_H */
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index 9255cfbee459..b0ce7ca2851f 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -700,7 +700,10 @@ static inline int ffs(int word)
#ifdef __KERNEL__
#include <asm-generic/bitops/sched.h>
-#include <asm-generic/bitops/hweight.h>
+
+#include <asm/arch_hweight.h>
+#include <asm-generic/bitops/const_hweight.h>
+
#include <asm-generic/bitops/ext2-non-atomic.h>
#include <asm-generic/bitops/ext2-atomic.h>
#include <asm-generic/bitops/minix.h>
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
index 6b04c98b7fad..2cb2f0c2c4f8 100644
--- a/arch/mips/include/asm/cop2.h
+++ b/arch/mips/include/asm/cop2.h
@@ -9,6 +9,8 @@
#ifndef __ASM_COP2_H
#define __ASM_COP2_H
+#include <linux/notifier.h>
+
enum cu2_ops {
CU2_EXCEPTION,
CU2_LWC2_OP,
@@ -20,4 +22,14 @@ enum cu2_ops {
extern int register_cu2_notifier(struct notifier_block *nb);
extern int cu2_notifier_call_chain(unsigned long val, void *v);
+#define cu2_notifier(fn, pri) \
+({ \
+ static struct notifier_block fn##_nb __cpuinitdata = { \
+ .notifier_call = fn, \
+ .priority = pri \
+ }; \
+ \
+ register_cu2_notifier(&fn##_nb); \
+})
+
#endif /* __ASM_COP2_H */
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index ac73cede3a0a..ca400f7c3f59 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -159,7 +159,8 @@
/*
* MIPS32, MIPS64, VR5500, IDT32332, IDT32334 and maybe a few other
- * pre-MIPS32/MIPS53 processors have CLO, CLZ. For 64-bit kernels
+ * pre-MIPS32/MIPS53 processors have CLO, CLZ. The IDT RC64574 is 64-bit and
+ * has CLO and CLZ but not DCLO nor DCLZ. For 64-bit kernels
* cpu_has_clo_clz also indicates the availability of DCLO and DCLZ.
*/
# ifndef cpu_has_clo_clz
diff --git a/arch/mips/include/asm/emma/emma2rh.h b/arch/mips/include/asm/emma/emma2rh.h
index 2afb2fe11b30..c1449d20ef0e 100644
--- a/arch/mips/include/asm/emma/emma2rh.h
+++ b/arch/mips/include/asm/emma/emma2rh.h
@@ -99,88 +99,22 @@
#define EMMA2RH_PCI_CONFIG_BASE EMMA2RH_PCI_IO_BASE
#define EMMA2RH_PCI_CONFIG_SIZE EMMA2RH_PCI_IO_SIZE
-#define NUM_CPU_IRQ 8
#define NUM_EMMA2RH_IRQ 96
-#define CPU_EMMA2RH_CASCADE 2
-#define CPU_IRQ_BASE MIPS_CPU_IRQ_BASE
-#define EMMA2RH_IRQ_BASE (CPU_IRQ_BASE + NUM_CPU_IRQ)
+#define EMMA2RH_IRQ_BASE (MIPS_CPU_IRQ_BASE + 8)
/*
* emma2rh irq defs
*/
-#define EMMA2RH_IRQ_INT0 (0 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT1 (1 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT2 (2 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT3 (3 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT4 (4 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT5 (5 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT6 (6 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT7 (7 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT8 (8 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT9 (9 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT10 (10 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT11 (11 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT12 (12 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT13 (13 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT14 (14 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT15 (15 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT16 (16 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT17 (17 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT18 (18 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT19 (19 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT20 (20 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT21 (21 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT22 (22 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT23 (23 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT24 (24 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT25 (25 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT26 (26 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT27 (27 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT28 (28 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT29 (29 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT30 (30 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT31 (31 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT32 (32 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT33 (33 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT34 (34 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT35 (35 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT36 (36 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT37 (37 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT38 (38 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT39 (39 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT40 (40 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT41 (41 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT42 (42 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT43 (43 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT44 (44 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT45 (45 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT46 (46 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT47 (47 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT48 (48 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT49 (49 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT50 (50 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT51 (51 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT52 (52 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT53 (53 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT54 (54 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT55 (55 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT56 (56 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT57 (57 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT58 (58 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT59 (59 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT60 (60 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT61 (61 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT62 (62 + EMMA2RH_IRQ_BASE)
-#define EMMA2RH_IRQ_INT63 (63 + EMMA2RH_IRQ_BASE)
-
-#define EMMA2RH_IRQ_PFUR0 EMMA2RH_IRQ_INT49
-#define EMMA2RH_IRQ_PFUR1 EMMA2RH_IRQ_INT50
-#define EMMA2RH_IRQ_PFUR2 EMMA2RH_IRQ_INT51
-#define EMMA2RH_IRQ_PIIC0 EMMA2RH_IRQ_INT56
-#define EMMA2RH_IRQ_PIIC1 EMMA2RH_IRQ_INT57
-#define EMMA2RH_IRQ_PIIC2 EMMA2RH_IRQ_INT58
+#define EMMA2RH_IRQ_INT(n) (EMMA2RH_IRQ_BASE + (n))
+
+#define EMMA2RH_IRQ_PFUR0 EMMA2RH_IRQ_INT(49)
+#define EMMA2RH_IRQ_PFUR1 EMMA2RH_IRQ_INT(50)
+#define EMMA2RH_IRQ_PFUR2 EMMA2RH_IRQ_INT(51)
+#define EMMA2RH_IRQ_PIIC0 EMMA2RH_IRQ_INT(56)
+#define EMMA2RH_IRQ_PIIC1 EMMA2RH_IRQ_INT(57)
+#define EMMA2RH_IRQ_PIIC2 EMMA2RH_IRQ_INT(58)
/*
* EMMA2RH Register Access
diff --git a/arch/mips/include/asm/emma/markeins.h b/arch/mips/include/asm/emma/markeins.h
index 2618bf230248..bf2d229c2dae 100644
--- a/arch/mips/include/asm/emma/markeins.h
+++ b/arch/mips/include/asm/emma/markeins.h
@@ -25,44 +25,13 @@
#define NUM_EMMA2RH_IRQ_SW 32
#define NUM_EMMA2RH_IRQ_GPIO 32
-#define EMMA2RH_SW_CASCADE (EMMA2RH_IRQ_INT7 - EMMA2RH_IRQ_INT0)
-#define EMMA2RH_GPIO_CASCADE (EMMA2RH_IRQ_INT46 - EMMA2RH_IRQ_INT0)
+#define EMMA2RH_SW_CASCADE (EMMA2RH_IRQ_INT(7) - EMMA2RH_IRQ_INT(0))
+#define EMMA2RH_GPIO_CASCADE (EMMA2RH_IRQ_INT(46) - EMMA2RH_IRQ_INT(0))
#define EMMA2RH_SW_IRQ_BASE (EMMA2RH_IRQ_BASE + NUM_EMMA2RH_IRQ)
#define EMMA2RH_GPIO_IRQ_BASE (EMMA2RH_SW_IRQ_BASE + NUM_EMMA2RH_IRQ_SW)
-#define EMMA2RH_SW_IRQ_INT0 (0+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT1 (1+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT2 (2+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT3 (3+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT4 (4+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT5 (5+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT6 (6+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT7 (7+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT8 (8+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT9 (9+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT10 (10+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT11 (11+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT12 (12+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT13 (13+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT14 (14+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT15 (15+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT16 (16+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT17 (17+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT18 (18+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT19 (19+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT20 (20+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT21 (21+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT22 (22+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT23 (23+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT24 (24+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT25 (25+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT26 (26+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT27 (27+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT28 (28+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT29 (29+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT30 (30+EMMA2RH_SW_IRQ_BASE)
-#define EMMA2RH_SW_IRQ_INT31 (31+EMMA2RH_SW_IRQ_BASE)
+#define EMMA2RH_SW_IRQ_INT(n) (EMMA2RH_SW_IRQ_BASE + (n))
#define MARKEINS_PCI_IRQ_INTA EMMA2RH_GPIO_IRQ_BASE+15
#define MARKEINS_PCI_IRQ_INTB EMMA2RH_GPIO_IRQ_BASE+16
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
index bbf054042395..2a7ea90fee2a 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -77,6 +77,14 @@ static inline int read_current_timer(unsigned long *result)
return 0;
}
+#ifdef __OCTEON__
+/*
+ * All gcc versions that have OCTEON support define __OCTEON__ and have the
+ * __builtin_popcount support.
+ */
+#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
+#endif
+
static inline int octeon_has_saa(void)
{
int id;
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h
index 58796410bd6e..fc4d766641ce 100644
--- a/arch/mips/include/asm/mach-pb1x00/pb1550.h
+++ b/arch/mips/include/asm/mach-pb1x00/pb1550.h
@@ -40,14 +40,6 @@
#define SMBUS_PSC_BASE PSC2_BASE_ADDR
#define I2S_PSC_BASE PSC3_BASE_ADDR
-#if defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_BOTH_BANKS
-#elif defined(CONFIG_MTD_PB1550_BOOT) && !defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_BOOT_ONLY
-#elif !defined(CONFIG_MTD_PB1550_BOOT) && defined(CONFIG_MTD_PB1550_USER)
-#define PB1550_USER_ONLY
-#endif
-
/*
* Timing values as described in databook, * ns value stripped of
* lower 2 bits.
diff --git a/arch/mips/include/asm/mach-powertv/asic_reg_map.h b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
index 6f26cb09828e..20348e817b09 100644
--- a/arch/mips/include/asm/mach-powertv/asic_reg_map.h
+++ b/arch/mips/include/asm/mach-powertv/asic_reg_map.h
@@ -64,7 +64,7 @@ REGISTER_MAP_ELEMENT(int_level_0_1)
REGISTER_MAP_ELEMENT(int_level_0_0)
REGISTER_MAP_ELEMENT(int_docsis_en)
REGISTER_MAP_ELEMENT(mips_pll_setup)
-REGISTER_MAP_ELEMENT(usb_fs)
+REGISTER_MAP_ELEMENT(fs432x4b4_usb_ctl)
REGISTER_MAP_ELEMENT(test_bus)
REGISTER_MAP_ELEMENT(crt_spare)
REGISTER_MAP_ELEMENT(usb2_ohci_int_mask)
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h b/arch/mips/include/asm/mach-powertv/dma-coherence.h
index 5b8d5ebeb838..f76029c2406e 100644
--- a/arch/mips/include/asm/mach-powertv/dma-coherence.h
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -65,21 +65,21 @@ static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
size_t size)
{
if (is_kseg2(addr))
- return phys_to_bus(virt_to_phys_from_pte(addr));
+ return phys_to_dma(virt_to_phys_from_pte(addr));
else
- return phys_to_bus(virt_to_phys(addr));
+ return phys_to_dma(virt_to_phys(addr));
}
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
- return phys_to_bus(page_to_phys(page));
+ return phys_to_dma(page_to_phys(page));
}
static inline unsigned long plat_dma_addr_to_phys(struct device *dev,
dma_addr_t dma_addr)
{
- return bus_to_phys(dma_addr);
+ return dma_to_phys(dma_addr);
}
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr,
diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h
index e6276d5146e8..076f2eeaa575 100644
--- a/arch/mips/include/asm/mach-powertv/ioremap.h
+++ b/arch/mips/include/asm/mach-powertv/ioremap.h
@@ -10,64 +10,101 @@
#define __ASM_MACH_POWERTV_IOREMAP_H
#include <linux/types.h>
+#include <linux/log2.h>
+#include <linux/compiler.h>
-#define LOW_MEM_BOUNDARY_PHYS 0x20000000
-#define LOW_MEM_BOUNDARY_MASK (~(LOW_MEM_BOUNDARY_PHYS - 1))
+#include <asm/pgtable-bits.h>
+#include <asm/addrspace.h>
+
+/* We're going to mess with bits, so get sizes */
+#define IOR_BPC 8 /* Bits per char */
+#define IOR_PHYS_BITS (IOR_BPC * sizeof(phys_addr_t))
+#define IOR_DMA_BITS (IOR_BPC * sizeof(dma_addr_t))
/*
- * The bus addresses are different than the physical addresses that
- * the processor sees by an offset. This offset varies by ASIC
- * version. Define a variable to hold the offset and some macros to
- * make the conversion simpler. */
-extern unsigned long phys_to_bus_offset;
-
-#ifdef CONFIG_HIGHMEM
-#define MEM_GAP_PHYS 0x60000000
+ * Define the granularity of physical/DMA mapping in terms of the number
+ * of bits that defines the offset within a grain. These will be the
+ * least significant bits of the address. The rest of a physical or DMA
+ * address will be used to index into an appropriate table to find the
+ * offset to add to the address to yield the corresponding DMA or physical
+ * address, respectively.
+ */
+#define IOR_LSBITS 22 /* Bits in a grain */
+
/*
- * TODO: We will use the hard code for conversion between physical and
- * bus until the bootloader releases their device tree to us.
+ * Compute the number of most significant address bits after removing those
+ * used for the offset within a grain and then compute the number of table
+ * entries for the conversion.
*/
-#define phys_to_bus(x) (((x) < LOW_MEM_BOUNDARY_PHYS) ? \
- ((x) + phys_to_bus_offset) : (x))
-#define bus_to_phys(x) (((x) < MEM_GAP_PHYS_ADDR) ? \
- ((x) - phys_to_bus_offset) : (x))
-#else
-#define phys_to_bus(x) ((x) + phys_to_bus_offset)
-#define bus_to_phys(x) ((x) - phys_to_bus_offset)
-#endif
+#define IOR_PHYS_MSBITS (IOR_PHYS_BITS - IOR_LSBITS)
+#define IOR_NUM_PHYS_TO_DMA ((phys_addr_t) 1 << IOR_PHYS_MSBITS)
+
+#define IOR_DMA_MSBITS (IOR_DMA_BITS - IOR_LSBITS)
+#define IOR_NUM_DMA_TO_PHYS ((dma_addr_t) 1 << IOR_DMA_MSBITS)
/*
- * Determine whether the address we are given is for an ASIC device
- * Params: addr Address to check
- * Returns: Zero if the address is not for ASIC devices, non-zero
- * if it is.
+ * Define data structures used as elements in the arrays for the conversion
+ * between physical and DMA addresses. We do some slightly fancy math to
+ * compute the width of the offset element of the conversion tables so
+ * that we can have the smallest conversion tables. Next, round up the
+ * sizes to the next higher power of two, i.e. the offset element will have
+ * 8, 16, 32, 64, etc. bits. This eliminates the need to mask off any
+ * bits. Finally, we compute a shift value that puts the most significant
+ * bits of the offset into the most significant bits of the offset element.
+ * This makes it more efficient on processors without barrel shifters and
+ * easier to see the values if the conversion table is dumped in binary.
*/
-static inline int asic_is_device_addr(phys_t addr)
+#define _IOR_OFFSET_WIDTH(n) (1 << order_base_2(n))
+#define IOR_OFFSET_WIDTH(n) \
+ (_IOR_OFFSET_WIDTH(n) < 8 ? 8 : _IOR_OFFSET_WIDTH(n))
+
+#define IOR_PHYS_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_PHYS_MSBITS)
+#define IOR_PHYS_SHIFT (IOR_PHYS_BITS - IOR_PHYS_OFFSET_BITS)
+
+#define IOR_DMA_OFFSET_BITS IOR_OFFSET_WIDTH(IOR_DMA_MSBITS)
+#define IOR_DMA_SHIFT (IOR_DMA_BITS - IOR_DMA_OFFSET_BITS)
+
+struct ior_phys_to_dma {
+ dma_addr_t offset:IOR_DMA_OFFSET_BITS __packed
+ __aligned((IOR_DMA_OFFSET_BITS / IOR_BPC));
+};
+
+struct ior_dma_to_phys {
+ dma_addr_t offset:IOR_PHYS_OFFSET_BITS __packed
+ __aligned((IOR_PHYS_OFFSET_BITS / IOR_BPC));
+};
+
+extern struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+extern struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+
+static inline dma_addr_t _phys_to_dma_offset_raw(phys_addr_t phys)
{
- return !((phys_t)addr & (phys_t) LOW_MEM_BOUNDARY_MASK);
+ return (dma_addr_t)_ior_phys_to_dma[phys >> IOR_LSBITS].offset;
}
-/*
- * Determine whether the address we are given is external RAM mappable
- * into KSEG1.
- * Params: addr Address to check
- * Returns: Zero if the address is not for external RAM and
- */
-static inline int asic_is_lowmem_ram_addr(phys_t addr)
+static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma)
{
- /*
- * The RAM always starts at the following address in the processor's
- * physical address space
- */
- static const phys_t phys_ram_base = 0x10000000;
- phys_t bus_ram_base;
+ return (dma_addr_t)_ior_dma_to_phys[dma >> IOR_LSBITS].offset;
+}
- bus_ram_base = phys_to_bus_offset + phys_ram_base;
+/* These are not portable and should not be used in drivers. Drivers should
+ * be using ioremap() and friends to map physical addreses to virtual
+ * addresses and dma_map*() and friends to map virtual addresses into DMA
+ * addresses and back.
+ */
+static inline dma_addr_t phys_to_dma(phys_addr_t phys)
+{
+ return phys + (_phys_to_dma_offset_raw(phys) << IOR_PHYS_SHIFT);
+}
- return addr >= bus_ram_base &&
- addr < (bus_ram_base + (LOW_MEM_BOUNDARY_PHYS - phys_ram_base));
+static inline phys_addr_t dma_to_phys(dma_addr_t dma)
+{
+ return dma + (_dma_to_phys_offset_raw(dma) << IOR_DMA_SHIFT);
}
+extern void ioremap_add_map(dma_addr_t phys, phys_addr_t alias,
+ dma_addr_t size);
+
/*
* Allow physical addresses to be fixed up to help peripherals located
* outside the low 32-bit range -- generic pass-through version.
@@ -77,10 +114,50 @@ static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
return phys_addr;
}
-static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+/*
+ * Handle the special case of addresses the area aliased into the first
+ * 512 MiB of the processor's physical address space. These turn into either
+ * kseg0 or kseg1 addresses, depending on flags.
+ */
+static inline void __iomem *plat_ioremap(phys_t start, unsigned long size,
unsigned long flags)
{
- return NULL;
+ phys_addr_t start_offset;
+ void __iomem *result = NULL;
+
+ /* Start by checking to see whether this is an aliased address */
+ start_offset = _dma_to_phys_offset_raw(start);
+
+ /*
+ * If:
+ * o the memory is aliased into the first 512 MiB, and
+ * o the start and end are in the same RAM bank, and
+ * o we don't have a zero size or wrap around, and
+ * o we are supposed to create an uncached mapping,
+ * handle this is a kseg0 or kseg1 address
+ */
+ if (start_offset != 0) {
+ phys_addr_t last;
+ dma_addr_t dma_to_phys_offset;
+
+ last = start + size - 1;
+ dma_to_phys_offset =
+ _dma_to_phys_offset_raw(last) << IOR_DMA_SHIFT;
+
+ if (dma_to_phys_offset == start_offset &&
+ size != 0 && start <= last) {
+ phys_t adjusted_start;
+ adjusted_start = start + start_offset;
+ if (flags == _CACHE_UNCACHED)
+ result = (void __iomem *) (unsigned long)
+ CKSEG1ADDR(adjusted_start);
+ else
+ result = (void __iomem *) (unsigned long)
+ CKSEG0ADDR(adjusted_start);
+ }
+ }
+
+ return result;
}
static inline int plat_iounmap(const volatile void __iomem *addr)
diff --git a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
index 54ef1a96d7ce..786d82daf8d6 100644
--- a/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
+++ b/arch/mips/include/asm/pmc-sierra/msp71xx/msp_prom.h
@@ -124,10 +124,6 @@ extern void prom_meminit(void);
extern void prom_fixup_mem_map(unsigned long start_mem,
unsigned long end_mem);
-#ifdef CONFIG_MTD_PMC_MSP_RAMROOT
-extern bool get_ramroot(void **start, unsigned long *size);
-#endif
-
extern int get_ethernet_addr(char *ethaddr_name, char *ethernet_addr);
extern unsigned long get_deviceid(void);
extern char identify_enet(unsigned long interface_num);
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile
index 5aee0c266d18..dd9d99bfcf7a 100644
--- a/arch/mips/jazz/Makefile
+++ b/arch/mips/jazz/Makefile
@@ -3,5 +3,3 @@
#
obj-y := irq.o jazzdma.o reset.o setup.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/jazz/Platform b/arch/mips/jazz/Platform
new file mode 100644
index 000000000000..3373788acca1
--- /dev/null
+++ b/arch/mips/jazz/Platform
@@ -0,0 +1,6 @@
+#
+# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
+#
+platform-$(CONFIG_MACH_JAZZ) += jazz/
+cflags-$(CONFIG_MACH_JAZZ) += -I$(srctree)/arch/mips/include/asm/mach-jazz
+load-$(CONFIG_MACH_JAZZ) += 0xffffffff80080000
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 7a6ac501cbb5..ff5ec2e0184e 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -101,6 +101,4 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
-EXTRA_CFLAGS += -Werror
-
CPPFLAGS_vmlinux.lds := $(KBUILD_CFLAGS)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 852780868fb4..1515b673179d 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -907,11 +907,6 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
return NOTIFY_OK;
}
-static struct notifier_block default_cu2_notifier = {
- .notifier_call = default_cu2_call,
- .priority = 0x80000000, /* Run last */
-};
-
asmlinkage void do_cpu(struct pt_regs *regs)
{
unsigned int __user *epc;
@@ -1734,5 +1729,5 @@ void __init trap_init(void)
sort_extable(__start___dbe_table, __stop___dbe_table);
- register_cu2_notifier(&default_cu2_notifier);
+ cu2_notifier(default_cu2_call, 0x80000000); /* Run last */
}
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile
index 33791609fe99..9cc4e4db8b99 100644
--- a/arch/mips/lasat/Makefile
+++ b/arch/mips/lasat/Makefile
@@ -12,5 +12,3 @@ obj-$(CONFIG_PICVUE_PROC) += picvue_proc.o
clean:
make -C image clean
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/lasat/Platform b/arch/mips/lasat/Platform
new file mode 100644
index 000000000000..760252828bf1
--- /dev/null
+++ b/arch/mips/lasat/Platform
@@ -0,0 +1,7 @@
+#
+# LASAT platforms
+#
+platform-$(CONFIG_LASAT) += lasat/
+cflags-$(CONFIG_LASAT) += \
+ -I$(srctree)/arch/mips/include/asm/mach-lasat
+load-$(CONFIG_LASAT) += 0xffffffff80000000
diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform
new file mode 100644
index 000000000000..29692e5433b1
--- /dev/null
+++ b/arch/mips/loongson/Platform
@@ -0,0 +1,32 @@
+#
+# Loongson Processors' Support
+#
+
+# Only gcc >= 4.4 have Loongson specific support
+cflags-$(CONFIG_CPU_LOONGSON2) += -Wa,--trap
+cflags-$(CONFIG_CPU_LOONGSON2E) += \
+ $(call cc-option,-march=loongson2e,-march=r4600)
+cflags-$(CONFIG_CPU_LOONGSON2F) += \
+ $(call cc-option,-march=loongson2f,-march=r4600)
+# Enable the workarounds for Loongson2f
+ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
+ ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-nop,),)
+ $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-nop)
+ else
+ cflags-$(CONFIG_CPU_NOP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-nop
+ endif
+ ifeq ($(call as-option,-Wa$(comma)-mfix-loongson2f-jump,),)
+ $(error only binutils >= 2.20.2 have needed option -mfix-loongson2f-jump)
+ else
+ cflags-$(CONFIG_CPU_JUMP_WORKAROUNDS) += -Wa$(comma)-mfix-loongson2f-jump
+ endif
+endif
+
+#
+# Loongson Machines' Support
+#
+
+platform-$(CONFIG_MACH_LOONGSON) += loongson/
+cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely
+load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000
+load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000
diff --git a/arch/mips/loongson/common/cs5536/Makefile b/arch/mips/loongson/common/cs5536/Makefile
index 510d4cdc2378..f12e64007347 100644
--- a/arch/mips/loongson/common/cs5536/Makefile
+++ b/arch/mips/loongson/common/cs5536/Makefile
@@ -9,5 +9,3 @@ obj-$(CONFIG_CS5536) += cs5536_pci.o cs5536_ide.o cs5536_acc.o cs5536_ohci.o \
# Enable cs5536 mfgpt Timer
#
obj-$(CONFIG_CS5536_MFGPT) += cs5536_mfgpt.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/loongson/fuloong-2e/Makefile b/arch/mips/loongson/fuloong-2e/Makefile
index 3aba5fcc09dc..b7622720c1ad 100644
--- a/arch/mips/loongson/fuloong-2e/Makefile
+++ b/arch/mips/loongson/fuloong-2e/Makefile
@@ -3,5 +3,3 @@
#
obj-y += irq.o reset.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/math-emu/Makefile b/arch/mips/math-emu/Makefile
index d547efdeedc2..96607230d9ea 100644
--- a/arch/mips/math-emu/Makefile
+++ b/arch/mips/math-emu/Makefile
@@ -10,4 +10,3 @@ obj-y := cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/math-emu/dp_modf.c b/arch/mips/math-emu/dp_modf.c
index 25861a42c36f..a8570e5c3efc 100644
--- a/arch/mips/math-emu/dp_modf.c
+++ b/arch/mips/math-emu/dp_modf.c
@@ -29,7 +29,7 @@
/* modf function is always exact for a finite number
*/
-ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip)
+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp *ip)
{
COMPXDP;
diff --git a/arch/mips/math-emu/dp_tint.c b/arch/mips/math-emu/dp_tint.c
index 77b2b7ccf28a..24478623c117 100644
--- a/arch/mips/math-emu/dp_tint.c
+++ b/arch/mips/math-emu/dp_tint.c
@@ -69,8 +69,7 @@ int ieee754dp_tint(ieee754dp x)
round = 0;
sticky = residue != 0;
xm = 0;
- }
- else {
+ } else {
residue = xm << (64 - DP_MBITS + xe);
round = (residue >> 63) != 0;
sticky = (residue << 1) != 0;
diff --git a/arch/mips/math-emu/dp_tlong.c b/arch/mips/math-emu/dp_tlong.c
index d71113e07164..0f07ec2be3f9 100644
--- a/arch/mips/math-emu/dp_tlong.c
+++ b/arch/mips/math-emu/dp_tlong.c
@@ -71,8 +71,7 @@ s64 ieee754dp_tlong(ieee754dp x)
round = 0;
sticky = residue != 0;
xm = 0;
- }
- else {
+ } else {
/* Shifting a u64 64 times does not work,
* so we do it in two steps. Be aware that xe
* may be -1 */
diff --git a/arch/mips/math-emu/sp_modf.c b/arch/mips/math-emu/sp_modf.c
index 4b1dbac796f8..76568946b4c0 100644
--- a/arch/mips/math-emu/sp_modf.c
+++ b/arch/mips/math-emu/sp_modf.c
@@ -29,7 +29,7 @@
/* modf function is always exact for a finite number
*/
-ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip)
+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp *ip)
{
COMPXSP;
diff --git a/arch/mips/math-emu/sp_tint.c b/arch/mips/math-emu/sp_tint.c
index 1d73d2abe0b5..352dc3a5f1af 100644
--- a/arch/mips/math-emu/sp_tint.c
+++ b/arch/mips/math-emu/sp_tint.c
@@ -72,8 +72,7 @@ int ieee754sp_tint(ieee754sp x)
round = 0;
sticky = residue != 0;
xm = 0;
- }
- else {
+ } else {
/* Shifting a u32 32 times does not work,
* so we do it in two steps. Be aware that xe
* may be -1 */
diff --git a/arch/mips/math-emu/sp_tlong.c b/arch/mips/math-emu/sp_tlong.c
index 4be21aa81fbf..92cd9c511a10 100644
--- a/arch/mips/math-emu/sp_tlong.c
+++ b/arch/mips/math-emu/sp_tlong.c
@@ -71,8 +71,7 @@ s64 ieee754sp_tlong(ieee754sp x)
round = 0;
sticky = residue != 0;
xm = 0;
- }
- else {
+ } else {
residue = xm << (32 - SP_MBITS + xe);
round = (residue >> 31) != 0;
sticky = (residue << 1) != 0;
diff --git a/arch/mips/mipssim/Makefile b/arch/mips/mipssim/Makefile
index 41b96571315e..01410a3f1729 100644
--- a/arch/mips/mipssim/Makefile
+++ b/arch/mips/mipssim/Makefile
@@ -21,5 +21,3 @@ obj-y := sim_platform.o sim_setup.o sim_mem.o sim_time.o sim_int.o
obj-$(CONFIG_EARLY_PRINTK) += sim_console.o
obj-$(CONFIG_MIPS_MT_SMTC) += sim_smtc.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mipssim/Platform b/arch/mips/mipssim/Platform
new file mode 100644
index 000000000000..3df60b8a12ef
--- /dev/null
+++ b/arch/mips/mipssim/Platform
@@ -0,0 +1,6 @@
+#
+# MIPS SIM
+#
+platform-$(CONFIG_MIPS_SIM) += mipssim/
+cflags-$(CONFIG_MIPS_SIM) += -I$(srctree)/arch/mips/include/asm/mach-mipssim
+load-$(CONFIG_MIPS_SIM) += 0x80100000
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index f0e435599707..d679c772d082 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -34,5 +34,3 @@ obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
obj-$(CONFIG_RM7000_CPU_SCACHE) += sc-rm7k.o
obj-$(CONFIG_MIPS_CPU_SCACHE) += sc-mips.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index b78f7d913ca4..b4aac424b2e9 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -16,7 +16,6 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/smp.h>
-#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/module.h>
#include <asm/branch.h>
diff --git a/arch/mips/mti-malta/Makefile b/arch/mips/mti-malta/Makefile
index 32e847808df1..6079ef33b5f0 100644
--- a/arch/mips/mti-malta/Makefile
+++ b/arch/mips/mti-malta/Makefile
@@ -15,5 +15,3 @@ obj-$(CONFIG_PCI) += malta-pci.o
# FIXME FIXME FIXME
obj-$(CONFIG_MIPS_MT_SMTC) += malta-smtc.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/mti-malta/Platform b/arch/mips/mti-malta/Platform
new file mode 100644
index 000000000000..5b548b5a4fcf
--- /dev/null
+++ b/arch/mips/mti-malta/Platform
@@ -0,0 +1,7 @@
+#
+# MIPS Malta board
+#
+platform-$(CONFIG_MIPS_MALTA) += mti-malta/
+cflags-$(CONFIG_MIPS_MALTA) += -I$(srctree)/arch/mips/include/asm/mach-malta
+load-$(CONFIG_MIPS_MALTA) += 0xffffffff80100000
+all-$(CONFIG_MIPS_MALTA) := $(COMPRESSION_FNAME).bin
diff --git a/arch/mips/nxp/pnx833x/stb22x/Makefile b/arch/mips/nxp/pnx833x/stb22x/Makefile
deleted file mode 100644
index f81c5801f455..000000000000
--- a/arch/mips/nxp/pnx833x/stb22x/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-lib-y := board.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx8550/jbs/Makefile b/arch/mips/nxp/pnx8550/jbs/Makefile
deleted file mode 100644
index ad6a8ca7d8ce..000000000000
--- a/arch/mips/nxp/pnx8550/jbs/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Makefile for the NXP JBS Board.
-
-lib-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/stb810/Makefile b/arch/mips/nxp/pnx8550/stb810/Makefile
deleted file mode 100644
index ab91d72c5664..000000000000
--- a/arch/mips/nxp/pnx8550/stb810/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-
-# Makefile for the NXP STB810 Board.
-
-lib-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/pci/ops-titan-ht.c b/arch/mips/pci/ops-titan-ht.c
index 749c1922d420..57d54adc9e20 100644
--- a/arch/mips/pci/ops-titan-ht.c
+++ b/arch/mips/pci/ops-titan-ht.c
@@ -32,7 +32,7 @@
#include <asm/titan_dep.h>
static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
- int offset, u32 * val)
+ int offset, u32 *val)
{
volatile uint32_t address;
int busno;
@@ -64,7 +64,7 @@ static int titan_ht_config_read_dword(struct pci_bus *bus, unsigned int devfn,
}
static int titan_ht_config_read(struct pci_bus *bus, unsigned int devfn,
- int offset, int size, u32 * val)
+ int offset, int size, u32 *val)
{
uint32_t dword;
diff --git a/arch/mips/pmc-sierra/Platform b/arch/mips/pmc-sierra/Platform
new file mode 100644
index 000000000000..f092f2524c5f
--- /dev/null
+++ b/arch/mips/pmc-sierra/Platform
@@ -0,0 +1,14 @@
+#
+# PMC-Sierra MSP SOCs
+#
+platform-$(CONFIG_PMC_MSP) += pmc-sierra/msp71xx/
+cflags-$(CONFIG_PMC_MSP) += -I$(srctree)/arch/mips/include/asm/pmc-sierra/msp71xx \
+ -mno-branch-likely
+load-$(CONFIG_PMC_MSP) += 0xffffffff80100000
+
+#
+# PMC-Sierra Yosemite
+#
+platform-$(CONFIG_PMC_YOSEMITE) += pmc-sierra/yosemite/
+cflags-$(CONFIG_PMC_YOSEMITE) += -I$(srctree)/arch/mips/include/asm/mach-yosemite
+load-$(CONFIG_PMC_YOSEMITE) += 0xffffffff80100000
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
index 11769b55438c..c841f083a7f5 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -32,9 +32,6 @@
#include <msp_int.h>
#include <msp_regs.h>
#include <msp_regops.h>
-#ifdef CONFIG_PMCTWILED
-#include <msp_led_macros.h>
-#endif
/* For hwbutton_interrupt->initial_state */
#define HWBUTTON_HI 0x1
@@ -82,10 +79,6 @@ static void standby_on(void *data)
printk(KERN_WARNING "STANDBY switch was set to ON (not implemented)\n");
/* TODO: Put board in standby mode */
-#ifdef CONFIG_PMCTWILED
- msp_led_turn_off(MSP_LED_PWRSTANDBY_GREEN);
- msp_led_turn_on(MSP_LED_PWRSTANDBY_RED);
-#endif
}
static void standby_off(void *data)
@@ -94,10 +87,6 @@ static void standby_off(void *data)
"STANDBY switch was set to OFF (not implemented)\n");
/* TODO: Take out of standby mode */
-#ifdef CONFIG_PMCTWILED
- msp_led_turn_on(MSP_LED_PWRSTANDBY_GREEN);
- msp_led_turn_off(MSP_LED_PWRSTANDBY_RED);
-#endif
}
static struct hwbutton_interrupt softreset_sw = {
diff --git a/arch/mips/pmc-sierra/yosemite/ht-irq.c b/arch/mips/pmc-sierra/yosemite/ht-irq.c
index 5aec4057314e..86b98e98fb4f 100644
--- a/arch/mips/pmc-sierra/yosemite/ht-irq.c
+++ b/arch/mips/pmc-sierra/yosemite/ht-irq.c
@@ -35,18 +35,17 @@
*/
void __init titan_ht_pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_bus *current_bus = bus;
- struct pci_dev *devices;
- struct list_head *devices_link;
+ struct pci_bus *current_bus = bus;
+ struct pci_dev *devices;
+ struct list_head *devices_link;
list_for_each(devices_link, &(current_bus->devices)) {
- devices = pci_dev_b(devices_link);
- if (devices == NULL)
- continue;
+ devices = pci_dev_b(devices_link);
+ if (devices == NULL)
+ continue;
}
/*
* PLX and SPKT related changes go here
*/
-
}
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c
index 51021cfd04bc..25bbbf428be9 100644
--- a/arch/mips/pmc-sierra/yosemite/irq.c
+++ b/arch/mips/pmc-sierra/yosemite/irq.c
@@ -150,8 +150,4 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
rm7k_cpu_irq_init();
rm9k_cpu_irq_init();
-
-#ifdef CONFIG_GDB_CONSOLE
- register_gdb_console();
-#endif
}
diff --git a/arch/mips/pnx833x/Makefile b/arch/mips/pnx833x/Makefile
new file mode 100644
index 000000000000..02c4698cab05
--- /dev/null
+++ b/arch/mips/pnx833x/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX833X) += common/
+obj-$(CONFIG_NXP_STB220) += stb22x/
+obj-$(CONFIG_NXP_STB225) += stb22x/
diff --git a/arch/mips/pnx833x/Platform b/arch/mips/pnx833x/Platform
new file mode 100644
index 000000000000..7e6ec4dbc8dd
--- /dev/null
+++ b/arch/mips/pnx833x/Platform
@@ -0,0 +1,5 @@
+# NXP STB225
+platform-$(CONFIG_SOC_PNX833X) += pnx833x/
+cflags-$(CONFIG_SOC_PNX833X) += -Iarch/mips/include/asm/mach-pnx833x
+load-$(CONFIG_NXP_STB220) += 0xffffffff80001000
+load-$(CONFIG_NXP_STB225) += 0xffffffff80001000
diff --git a/arch/mips/nxp/pnx833x/common/Makefile b/arch/mips/pnx833x/common/Makefile
index 4a16f3b503b5..1a46dd291b16 100644
--- a/arch/mips/nxp/pnx833x/common/Makefile
+++ b/arch/mips/pnx833x/common/Makefile
@@ -1,3 +1 @@
obj-y := interrupts.o platform.o prom.o setup.o reset.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c
index 941916f8aaff..941916f8aaff 100644
--- a/arch/mips/nxp/pnx833x/common/interrupts.c
+++ b/arch/mips/pnx833x/common/interrupts.c
diff --git a/arch/mips/nxp/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c
index 01f8345a2069..c703404171c2 100644
--- a/arch/mips/nxp/pnx833x/common/platform.c
+++ b/arch/mips/pnx833x/common/platform.c
@@ -24,6 +24,7 @@
*/
#include <linux/device.h>
#include <linux/dma-mapping.h>
+#include <linux/i2c-pnx.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -33,11 +34,6 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
-#ifdef CONFIG_I2C_PNX0105
-/* Until i2c driver available in kernel.*/
-#include <linux/i2c-pnx0105.h>
-#endif
-
#include <irq.h>
#include <irq-mapping.h>
#include <pnx833x.h>
@@ -134,7 +130,6 @@ static struct platform_device pnx833x_usb_ehci_device = {
.resource = pnx833x_usb_ehci_resources,
};
-#ifdef CONFIG_I2C_PNX0105
static struct resource pnx833x_i2c0_resources[] = {
{
.start = PNX833X_I2C0_PORTS_START,
@@ -188,7 +183,7 @@ static struct platform_device pnx833x_i2c0_device = {
};
static struct platform_device pnx833x_i2c1_device = {
- .name = "i2c-pnx0105",
+ .name = "pnx-i2c",
.id = 1,
.dev = {
.platform_data = &pnx833x_i2c_dev[1],
@@ -196,7 +191,6 @@ static struct platform_device pnx833x_i2c1_device = {
.num_resources = ARRAY_SIZE(pnx833x_i2c1_resources),
.resource = pnx833x_i2c1_resources,
};
-#endif
static u64 ethernet_dmamask = DMA_BIT_MASK(32);
@@ -297,10 +291,8 @@ static struct platform_device pnx833x_flash_nand = {
static struct platform_device *pnx833x_platform_devices[] __initdata = {
&pnx833x_uart_device,
&pnx833x_usb_ehci_device,
-#ifdef CONFIG_I2C_PNX0105
&pnx833x_i2c0_device,
&pnx833x_i2c1_device,
-#endif
&pnx833x_ethernet_device,
&pnx833x_sata_device,
&pnx833x_flash_nand,
diff --git a/arch/mips/nxp/pnx833x/common/prom.c b/arch/mips/pnx833x/common/prom.c
index 29969f90a6b0..29969f90a6b0 100644
--- a/arch/mips/nxp/pnx833x/common/prom.c
+++ b/arch/mips/pnx833x/common/prom.c
diff --git a/arch/mips/nxp/pnx833x/common/reset.c b/arch/mips/pnx833x/common/reset.c
index e0ea96d29fde..e0ea96d29fde 100644
--- a/arch/mips/nxp/pnx833x/common/reset.c
+++ b/arch/mips/pnx833x/common/reset.c
diff --git a/arch/mips/nxp/pnx833x/common/setup.c b/arch/mips/pnx833x/common/setup.c
index e51fbc4b644d..e51fbc4b644d 100644
--- a/arch/mips/nxp/pnx833x/common/setup.c
+++ b/arch/mips/pnx833x/common/setup.c
diff --git a/arch/mips/pnx833x/stb22x/Makefile b/arch/mips/pnx833x/stb22x/Makefile
new file mode 100644
index 000000000000..7b580060de50
--- /dev/null
+++ b/arch/mips/pnx833x/stb22x/Makefile
@@ -0,0 +1 @@
+obj-y := board.o
diff --git a/arch/mips/nxp/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c
index 644eb7c3210f..644eb7c3210f 100644
--- a/arch/mips/nxp/pnx833x/stb22x/board.c
+++ b/arch/mips/pnx833x/stb22x/board.c
diff --git a/arch/mips/pnx8550/Makefile b/arch/mips/pnx8550/Makefile
new file mode 100644
index 000000000000..3f7e8561437b
--- /dev/null
+++ b/arch/mips/pnx8550/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SOC_PNX8550) += common/
+obj-$(CONFIG_PNX8550_JBS) += jbs/
+obj-$(CONFIG_PNX8550_STB810) += stb810/
diff --git a/arch/mips/pnx8550/Platform b/arch/mips/pnx8550/Platform
new file mode 100644
index 000000000000..0e7fbde768d5
--- /dev/null
+++ b/arch/mips/pnx8550/Platform
@@ -0,0 +1,7 @@
+platform-$(CONFIG_SOC_PNX8550) += pnx8550/
+
+cflags-$(CONFIG_SOC_PNX8550) += \
+ -I$(srctree)/arch/mips/include/asm/mach-pnx8550
+
+load-$(CONFIG_PNX8550_JBS) += 0xffffffff80060000
+load-$(CONFIG_PNX8550_STB810) += 0xffffffff80060000
diff --git a/arch/mips/nxp/pnx8550/common/Makefile b/arch/mips/pnx8550/common/Makefile
index dd9e7b1f7fd3..f8ce695dc54f 100644
--- a/arch/mips/nxp/pnx8550/common/Makefile
+++ b/arch/mips/pnx8550/common/Makefile
@@ -24,5 +24,3 @@
obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o
obj-$(CONFIG_PCI) += pci.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/nxp/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
index cfed5051dc6d..cfed5051dc6d 100644
--- a/arch/mips/nxp/pnx8550/common/int.c
+++ b/arch/mips/pnx8550/common/int.c
diff --git a/arch/mips/nxp/pnx8550/common/pci.c b/arch/mips/pnx8550/common/pci.c
index eee4f3dfc410..eee4f3dfc410 100644
--- a/arch/mips/nxp/pnx8550/common/pci.c
+++ b/arch/mips/pnx8550/common/pci.c
diff --git a/arch/mips/nxp/pnx8550/common/platform.c b/arch/mips/pnx8550/common/platform.c
index 5264cc09a27b..5264cc09a27b 100644
--- a/arch/mips/nxp/pnx8550/common/platform.c
+++ b/arch/mips/pnx8550/common/platform.c
diff --git a/arch/mips/nxp/pnx8550/common/proc.c b/arch/mips/pnx8550/common/proc.c
index 3bba5ec828e8..3bba5ec828e8 100644
--- a/arch/mips/nxp/pnx8550/common/proc.c
+++ b/arch/mips/pnx8550/common/proc.c
diff --git a/arch/mips/nxp/pnx8550/common/prom.c b/arch/mips/pnx8550/common/prom.c
index 32f70097c3c7..32f70097c3c7 100644
--- a/arch/mips/nxp/pnx8550/common/prom.c
+++ b/arch/mips/pnx8550/common/prom.c
diff --git a/arch/mips/nxp/pnx8550/common/reset.c b/arch/mips/pnx8550/common/reset.c
index fadd8744a6bc..fadd8744a6bc 100644
--- a/arch/mips/nxp/pnx8550/common/reset.c
+++ b/arch/mips/pnx8550/common/reset.c
diff --git a/arch/mips/nxp/pnx8550/common/setup.c b/arch/mips/pnx8550/common/setup.c
index 2aed50fef10f..2aed50fef10f 100644
--- a/arch/mips/nxp/pnx8550/common/setup.c
+++ b/arch/mips/pnx8550/common/setup.c
diff --git a/arch/mips/nxp/pnx8550/common/time.c b/arch/mips/pnx8550/common/time.c
index 8836c6203df0..8836c6203df0 100644
--- a/arch/mips/nxp/pnx8550/common/time.c
+++ b/arch/mips/pnx8550/common/time.c
diff --git a/arch/mips/pnx8550/jbs/Makefile b/arch/mips/pnx8550/jbs/Makefile
new file mode 100644
index 000000000000..c4dc3d53eb5c
--- /dev/null
+++ b/arch/mips/pnx8550/jbs/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP JBS Board.
+
+obj-y := init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/jbs/board_setup.c b/arch/mips/pnx8550/jbs/board_setup.c
index 57dd903ca408..57dd903ca408 100644
--- a/arch/mips/nxp/pnx8550/jbs/board_setup.c
+++ b/arch/mips/pnx8550/jbs/board_setup.c
diff --git a/arch/mips/nxp/pnx8550/jbs/init.c b/arch/mips/pnx8550/jbs/init.c
index d59b4a4e5e8b..d59b4a4e5e8b 100644
--- a/arch/mips/nxp/pnx8550/jbs/init.c
+++ b/arch/mips/pnx8550/jbs/init.c
diff --git a/arch/mips/nxp/pnx8550/jbs/irqmap.c b/arch/mips/pnx8550/jbs/irqmap.c
index 7fc89842002c..7fc89842002c 100644
--- a/arch/mips/nxp/pnx8550/jbs/irqmap.c
+++ b/arch/mips/pnx8550/jbs/irqmap.c
diff --git a/arch/mips/pnx8550/stb810/Makefile b/arch/mips/pnx8550/stb810/Makefile
new file mode 100644
index 000000000000..cb4ff022f1fb
--- /dev/null
+++ b/arch/mips/pnx8550/stb810/Makefile
@@ -0,0 +1,4 @@
+
+# Makefile for the NXP STB810 Board.
+
+obj-y := prom_init.o board_setup.o irqmap.o
diff --git a/arch/mips/nxp/pnx8550/stb810/board_setup.c b/arch/mips/pnx8550/stb810/board_setup.c
index af2a55e0b4e9..af2a55e0b4e9 100644
--- a/arch/mips/nxp/pnx8550/stb810/board_setup.c
+++ b/arch/mips/pnx8550/stb810/board_setup.c
diff --git a/arch/mips/nxp/pnx8550/stb810/irqmap.c b/arch/mips/pnx8550/stb810/irqmap.c
index 8c034963ddcd..8c034963ddcd 100644
--- a/arch/mips/nxp/pnx8550/stb810/irqmap.c
+++ b/arch/mips/pnx8550/stb810/irqmap.c
diff --git a/arch/mips/nxp/pnx8550/stb810/prom_init.c b/arch/mips/pnx8550/stb810/prom_init.c
index ca7f4ada0640..ca7f4ada0640 100644
--- a/arch/mips/nxp/pnx8550/stb810/prom_init.c
+++ b/arch/mips/pnx8550/stb810/prom_init.c
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
index 0a0d73c0564f..506c4ca9d44a 100644
--- a/arch/mips/powertv/Makefile
+++ b/arch/mips/powertv/Makefile
@@ -23,6 +23,7 @@
# under Linux.
#
-obj-y += init.o memory.o reset.o time.o powertv_setup.o asic/ pci/
+obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \
+ asic/ pci/
-EXTRA_CFLAGS += -Wall -Werror
+EXTRA_CFLAGS += -Wall
diff --git a/arch/mips/powertv/Platform b/arch/mips/powertv/Platform
new file mode 100644
index 000000000000..4eb5af1d8eea
--- /dev/null
+++ b/arch/mips/powertv/Platform
@@ -0,0 +1,7 @@
+#
+# Cisco PowerTV Platform
+#
+platform-$(CONFIG_POWERTV) += powertv/
+cflags-$(CONFIG_POWERTV) += \
+ -I$(srctree)/arch/mips/include/asm/mach-powertv
+load-$(CONFIG_POWERTV) += 0xffffffff90800000
diff --git a/arch/mips/powertv/asic/asic-calliope.c b/arch/mips/powertv/asic/asic-calliope.c
index 1ae6623444b2..0a170e0ffeaa 100644
--- a/arch/mips/powertv/asic/asic-calliope.c
+++ b/arch/mips/powertv/asic/asic-calliope.c
@@ -77,7 +77,7 @@ const struct register_map calliope_register_map __initdata = {
.int_docsis_en = {.phys = CALLIOPE_ADDR(0xA028F4)},
.mips_pll_setup = {.phys = CALLIOPE_ADDR(0x980000)},
- .usb_fs = {.phys = CALLIOPE_ADDR(0x980030)},
+ .fs432x4b4_usb_ctl = {.phys = CALLIOPE_ADDR(0x980030)},
.test_bus = {.phys = CALLIOPE_ADDR(0x9800CC)},
.crt_spare = {.phys = CALLIOPE_ADDR(0x9800d4)},
.usb2_ohci_int_mask = {.phys = CALLIOPE_ADDR(0x9A000c)},
diff --git a/arch/mips/powertv/asic/asic-cronus.c b/arch/mips/powertv/asic/asic-cronus.c
index 5bb64bfb508b..bbc0c122be5e 100644
--- a/arch/mips/powertv/asic/asic-cronus.c
+++ b/arch/mips/powertv/asic/asic-cronus.c
@@ -77,13 +77,13 @@ const struct register_map cronus_register_map __initdata = {
.int_docsis_en = {.phys = CRONUS_ADDR(0x2A28F4)},
.mips_pll_setup = {.phys = CRONUS_ADDR(0x1C0000)},
- .usb_fs = {.phys = CRONUS_ADDR(0x1C0018)},
+ .fs432x4b4_usb_ctl = {.phys = CRONUS_ADDR(0x1C0028)},
.test_bus = {.phys = CRONUS_ADDR(0x1C00CC)},
.crt_spare = {.phys = CRONUS_ADDR(0x1c00d4)},
.usb2_ohci_int_mask = {.phys = CRONUS_ADDR(0x20000C)},
.usb2_strap = {.phys = CRONUS_ADDR(0x200014)},
.ehci_hcapbase = {.phys = CRONUS_ADDR(0x21FE00)},
- .ohci_hc_revision = {.phys = CRONUS_ADDR(0x1E0000)},
+ .ohci_hc_revision = {.phys = CRONUS_ADDR(0x21fc00)},
.bcm1_bs_lmi_steer = {.phys = CRONUS_ADDR(0x2E0008)},
.usb2_control = {.phys = CRONUS_ADDR(0x2E004C)},
.usb2_stbus_obc = {.phys = CRONUS_ADDR(0x21FF00)},
diff --git a/arch/mips/powertv/asic/asic-zeus.c b/arch/mips/powertv/asic/asic-zeus.c
index 095cbe10ebb9..4a05bb096476 100644
--- a/arch/mips/powertv/asic/asic-zeus.c
+++ b/arch/mips/powertv/asic/asic-zeus.c
@@ -77,7 +77,7 @@ const struct register_map zeus_register_map __initdata = {
.int_docsis_en = {.phys = ZEUS_ADDR(0x2828F4)},
.mips_pll_setup = {.phys = ZEUS_ADDR(0x1a0000)},
- .usb_fs = {.phys = ZEUS_ADDR(0x1a0018)},
+ .fs432x4b4_usb_ctl = {.phys = ZEUS_ADDR(0x1a0018)},
.test_bus = {.phys = ZEUS_ADDR(0x1a0238)},
.crt_spare = {.phys = ZEUS_ADDR(0x1a0090)},
.usb2_ohci_int_mask = {.phys = ZEUS_ADDR(0x1e000c)},
diff --git a/arch/mips/powertv/asic/asic_devices.c b/arch/mips/powertv/asic/asic_devices.c
index 8ee77887306a..2276c18eb73b 100644
--- a/arch/mips/powertv/asic/asic_devices.c
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -80,8 +80,8 @@ static bool usb_configured;
* Don't recommend to use it directly, it is usually used by kernel internally.
* Portable code should be using interfaces such as ioremp, dma_map_single, etc.
*/
-unsigned long phys_to_bus_offset;
-EXPORT_SYMBOL(phys_to_bus_offset);
+unsigned long phys_to_dma_offset;
+EXPORT_SYMBOL(phys_to_dma_offset);
/*
*
@@ -180,9 +180,9 @@ static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3)
val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) |
(nsb<<1) | (disable_div_by_3<<5));
- asic_write(val, usb_fs);
- asic_write(val | (en_prg<<4), usb_fs);
- asic_write(val | (en_prg<<4) | pwr, usb_fs);
+ asic_write(val, fs432x4b4_usb_ctl);
+ asic_write(val | (en_prg<<4), fs432x4b4_usb_ctl);
+ asic_write(val | (en_prg<<4) | pwr, fs432x4b4_usb_ctl);
}
/*
@@ -532,10 +532,10 @@ void __init configure_platform(void)
switch (asic) {
case ASIC_ZEUS:
- phys_to_bus_offset = 0x30000000;
+ phys_to_dma_offset = 0x30000000;
break;
case ASIC_CALLIOPE:
- phys_to_bus_offset = 0x10000000;
+ phys_to_dma_offset = 0x10000000;
break;
case ASIC_CRONUSLITE:
/* Fall through */
@@ -545,10 +545,10 @@ void __init configure_platform(void)
* 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
* 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
*/
- phys_to_bus_offset = 0x10000000;
+ phys_to_dma_offset = 0x10000000;
break;
default:
- phys_to_bus_offset = 0x00000000;
+ phys_to_dma_offset = 0x00000000;
break;
}
}
@@ -602,7 +602,7 @@ void __init platform_alloc_bootmem(void)
int size = gp_resources[i].end - gp_resources[i].start + 1;
if ((gp_resources[i].start != 0) &&
((gp_resources[i].flags & IORESOURCE_MEM) != 0)) {
- reserve_bootmem(bus_to_phys(gp_resources[i].start),
+ reserve_bootmem(dma_to_phys(gp_resources[i].start),
size, 0);
total += gp_resources[i].end -
gp_resources[i].start + 1;
@@ -626,7 +626,7 @@ void __init platform_alloc_bootmem(void)
else {
gp_resources[i].start =
- phys_to_bus(virt_to_phys(mem));
+ phys_to_dma(virt_to_phys(mem));
gp_resources[i].end =
gp_resources[i].start + size - 1;
total += size;
@@ -690,7 +690,7 @@ static void __init pmem_setup_resource(void)
if (resource && pmemaddr && pmemlen) {
/* The address provided by bootloader is in kseg0. Convert to
* a bus address. */
- resource->start = phys_to_bus(pmemaddr - 0x80000000);
+ resource->start = phys_to_dma(pmemaddr - 0x80000000);
resource->end = resource->start + pmemlen - 1;
pr_info("persistent memory: start=0x%x end=0x%x\n",
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
index 0afe227f1d0a..83552288e802 100644
--- a/arch/mips/powertv/init.c
+++ b/arch/mips/powertv/init.c
@@ -117,8 +117,10 @@ void __init prom_init(void)
board_nmi_handler_setup = mips_nmi_setup;
board_ejtag_handler_setup = mips_ejtag_setup;
- if (prom_argc == 1)
+ if (prom_argc == 1) {
+ strlcat(arcs_cmdline, " ", COMMAND_LINE_SIZE);
strlcat(arcs_cmdline, prom_argv, COMMAND_LINE_SIZE);
+ }
configure_platform();
prom_meminit();
diff --git a/arch/mips/powertv/ioremap.c b/arch/mips/powertv/ioremap.c
new file mode 100644
index 000000000000..a77c6f62fe23
--- /dev/null
+++ b/arch/mips/powertv/ioremap.c
@@ -0,0 +1,136 @@
+/*
+ * ioremap.c
+ *
+ * Support for mapping between dma_addr_t values a phys_addr_t values.
+ *
+ * Copyright (C) 2005-2009 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Author: David VomLehn <dvomlehn@cisco.com>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/mach-powertv/ioremap.h>
+
+/*
+ * Define the sizes of and masks for grains in physical and DMA space. The
+ * values are the same but the types are not.
+ */
+#define IOR_PHYS_GRAIN ((phys_addr_t) 1 << IOR_LSBITS)
+#define IOR_PHYS_GRAIN_MASK (IOR_PHYS_GRAIN - 1)
+
+#define IOR_DMA_GRAIN ((dma_addr_t) 1 << IOR_LSBITS)
+#define IOR_DMA_GRAIN_MASK (IOR_DMA_GRAIN - 1)
+
+/*
+ * Values that, when accessed by an index derived from a phys_addr_t and
+ * added to phys_addr_t value, yield a DMA address
+ */
+struct ior_phys_to_dma _ior_phys_to_dma[IOR_NUM_PHYS_TO_DMA];
+EXPORT_SYMBOL(_ior_phys_to_dma);
+
+/*
+ * Values that, when accessed by an index derived from a dma_addr_t and
+ * added to that dma_addr_t value, yield a physical address
+ */
+struct ior_dma_to_phys _ior_dma_to_phys[IOR_NUM_DMA_TO_PHYS];
+EXPORT_SYMBOL(_ior_dma_to_phys);
+
+/**
+ * setup_dma_to_phys - set up conversion from DMA to physical addresses
+ * @dma_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index
+ * into the array _dma_to_phys.
+ * @delta: Value that, when added to the DMA address, will yield the
+ * physical address
+ * @s: Number of bytes in the section of memory with the given delta
+ * between DMA and physical addresses.
+ */
+static void setup_dma_to_phys(dma_addr_t dma, phys_addr_t delta, dma_addr_t s)
+{
+ int dma_idx, first_idx, last_idx;
+ phys_addr_t first, last;
+
+ /*
+ * Calculate the first and last indices, rounding the first up and
+ * the second down.
+ */
+ first = dma & ~IOR_DMA_GRAIN_MASK;
+ last = (dma + s - 1) & ~IOR_DMA_GRAIN_MASK;
+ first_idx = first >> IOR_LSBITS; /* Convert to indices */
+ last_idx = last >> IOR_LSBITS;
+
+ for (dma_idx = first_idx; dma_idx <= last_idx; dma_idx++)
+ _ior_dma_to_phys[dma_idx].offset = delta >> IOR_DMA_SHIFT;
+}
+
+/**
+ * setup_phys_to_dma - set up conversion from DMA to physical addresses
+ * @phys_idx: Top IOR_LSBITS bits of the DMA address, i.e. an index
+ * into the array _phys_to_dma.
+ * @delta: Value that, when added to the DMA address, will yield the
+ * physical address
+ * @s: Number of bytes in the section of memory with the given delta
+ * between DMA and physical addresses.
+ */
+static void setup_phys_to_dma(phys_addr_t phys, dma_addr_t delta, phys_addr_t s)
+{
+ int phys_idx, first_idx, last_idx;
+ phys_addr_t first, last;
+
+ /*
+ * Calculate the first and last indices, rounding the first up and
+ * the second down.
+ */
+ first = phys & ~IOR_PHYS_GRAIN_MASK;
+ last = (phys + s - 1) & ~IOR_PHYS_GRAIN_MASK;
+ first_idx = first >> IOR_LSBITS; /* Convert to indices */
+ last_idx = last >> IOR_LSBITS;
+
+ for (phys_idx = first_idx; phys_idx <= last_idx; phys_idx++)
+ _ior_phys_to_dma[phys_idx].offset = delta >> IOR_PHYS_SHIFT;
+}
+
+/**
+ * ioremap_add_map - add to the physical and DMA address conversion arrays
+ * @phys: Process's view of the address of the start of the memory chunk
+ * @dma: DMA address of the start of the memory chunk
+ * @size: Size, in bytes, of the chunk of memory
+ *
+ * NOTE: It might be obvious, but the assumption is that all @size bytes have
+ * the same offset between the physical address and the DMA address.
+ */
+void ioremap_add_map(phys_addr_t phys, phys_addr_t dma, phys_addr_t size)
+{
+ if (size == 0)
+ return;
+
+ if ((dma & IOR_DMA_GRAIN_MASK) != 0 ||
+ (phys & IOR_PHYS_GRAIN_MASK) != 0 ||
+ (size & IOR_PHYS_GRAIN_MASK) != 0)
+ pr_crit("Memory allocation must be in chunks of 0x%x bytes\n",
+ IOR_PHYS_GRAIN);
+
+ setup_dma_to_phys(dma, phys - dma, size);
+ setup_phys_to_dma(phys, dma - phys, size);
+}
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
index f49eb3d0358b..c463cd39c713 100644
--- a/arch/mips/powertv/memory.c
+++ b/arch/mips/powertv/memory.c
@@ -30,28 +30,140 @@
#include <asm/sections.h>
#include <asm/mips-boards/prom.h>
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/ioremap.h>
#include "init.h"
/* Memory constants */
#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes */
#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of mebibytes */
-#define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize provided */
-#define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */
-#define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for bldr */
-#define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for bldr */
-#define PHYS_MEM_START 0x10000000 /* Start of physical memory */
+#define DEFAULT_MEMSIZE MEBIBYTE(128) /* If no memsize provided */
-char __initdata cmdline[COMMAND_LINE_SIZE];
+#define BLDR_SIZE KIBIBYTE(256) /* Memory reserved for bldr */
+#define RV_SIZE MEBIBYTE(4) /* Size of reset vector */
-void __init prom_meminit(void)
+#define LOW_MEM_END 0x20000000 /* Highest low memory address */
+#define BLDR_ALIAS 0x10000000 /* Bootloader address */
+#define RV_PHYS 0x1fc00000 /* Reset vector address */
+#define LOW_RAM_END RV_PHYS /* End of real RAM in low mem */
+
+/*
+ * Very low-level conversion from processor physical address to device
+ * DMA address for the first bank of memory.
+ */
+#define PHYS_TO_DMA(paddr) ((paddr) + (CONFIG_LOW_RAM_DMA - LOW_RAM_ALIAS))
+
+unsigned long ptv_memsize;
+
+/*
+ * struct low_mem_reserved - Items in low memmory that are reserved
+ * @start: Physical address of item
+ * @size: Size, in bytes, of this item
+ * @is_aliased: True if this is RAM aliased from another location. If false,
+ * it is something other than aliased RAM and the RAM in the
+ * unaliased address is still visible outside of low memory.
+ */
+struct low_mem_reserved {
+ phys_addr_t start;
+ phys_addr_t size;
+ bool is_aliased;
+};
+
+/*
+ * Must be in ascending address order
+ */
+struct low_mem_reserved low_mem_reserved[] = {
+ {BLDR_ALIAS, BLDR_SIZE, true}, /* Bootloader RAM */
+ {RV_PHYS, RV_SIZE, false}, /* Reset vector */
+};
+
+/*
+ * struct mem_layout - layout of a piece of the system RAM
+ * @phys: Physical address of the start of this piece of RAM. This is the
+ * address at which both the processor and I/O devices see the
+ * RAM.
+ * @alias: Alias of this piece of memory in order to make it appear in
+ * the low memory part of the processor's address space. I/O
+ * devices don't see anything here.
+ * @size: Size, in bytes, of this piece of RAM
+ */
+struct mem_layout {
+ phys_addr_t phys;
+ phys_addr_t alias;
+ phys_addr_t size;
+};
+
+/*
+ * struct mem_layout_list - list descriptor for layouts of system RAM pieces
+ * @family: Specifies the family being described
+ * @n: Number of &struct mem_layout elements
+ * @layout: Pointer to the list of &mem_layout structures
+ */
+struct mem_layout_list {
+ enum family_type family;
+ size_t n;
+ struct mem_layout *layout;
+};
+
+static struct mem_layout f1500_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(256)},
+};
+
+static struct mem_layout f4500_layout[] = {
+ {0x40000000, 0x10000000, MEBIBYTE(256)},
+ {0x20000000, 0x20000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout f8500_layout[] = {
+ {0x40000000, 0x10000000, MEBIBYTE(256)},
+ {0x20000000, 0x20000000, MEBIBYTE(32)},
+ {0x30000000, 0x30000000, MEBIBYTE(32)},
+};
+
+static struct mem_layout fx600_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(256)},
+ {0x60000000, 0x60000000, MEBIBYTE(128)},
+};
+
+static struct mem_layout_list layout_list[] = {
+ {FAMILY_1500, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_1500VZE, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_1500VZF, ARRAY_SIZE(f1500_layout), f1500_layout},
+ {FAMILY_4500, ARRAY_SIZE(f4500_layout), f4500_layout},
+ {FAMILY_8500, ARRAY_SIZE(f8500_layout), f8500_layout},
+ {FAMILY_8500RNG, ARRAY_SIZE(f8500_layout), f8500_layout},
+ {FAMILY_4600, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_4600VZA, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_8600, ARRAY_SIZE(fx600_layout), fx600_layout},
+ {FAMILY_8600VZB, ARRAY_SIZE(fx600_layout), fx600_layout},
+};
+
+/* If we can't determine the layout, use this */
+static struct mem_layout default_layout[] = {
+ {0x20000000, 0x10000000, MEBIBYTE(128)},
+};
+
+/**
+ * register_non_ram - register low memory not available for RAM usage
+ */
+static __init void register_non_ram(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(low_mem_reserved); i++)
+ add_memory_region(low_mem_reserved[i].start,
+ low_mem_reserved[i].size, BOOT_MEM_RESERVED);
+}
+
+/**
+ * get_memsize - get the size of memory as a single bank
+ */
+static phys_addr_t get_memsize(void)
{
+ phys_addr_t memsize = 0;
char *memsize_str;
- unsigned long memsize = 0;
- unsigned int physend;
- char *ptr;
- int low_mem;
- int high_mem;
+ char cmdline[COMMAND_LINE_SIZE], *ptr;
/* Check the command line first for a memsize directive */
strcpy(cmdline, arcs_cmdline);
@@ -73,96 +185,156 @@ void __init prom_meminit(void)
if (memsize == 0) {
if (_prom_memsize != 0) {
memsize = _prom_memsize;
- pr_info("_prom_memsize = 0x%lx\n", memsize);
+ pr_info("_prom_memsize = 0x%x\n", memsize);
/* add in memory that the bootloader doesn't
* report */
- memsize += BOOT_MEM_SIZE;
+ memsize += BLDR_SIZE;
} else {
memsize = DEFAULT_MEMSIZE;
pr_info("Memsize not passed by bootloader, "
- "defaulting to 0x%lx\n", memsize);
+ "defaulting to 0x%x\n", memsize);
}
}
}
- physend = PFN_ALIGN(&_end) - 0x80000000;
- if (memsize > LOW_MEM_MAX) {
- low_mem = LOW_MEM_MAX;
- high_mem = memsize - low_mem;
- } else {
- low_mem = memsize;
- high_mem = 0;
+ return memsize;
+}
+
+/**
+ * register_low_ram - register an aliased section of RAM
+ * @p: Alias address of memory
+ * @n: Number of bytes in this section of memory
+ *
+ * Returns the number of bytes registered
+ *
+ */
+static __init phys_addr_t register_low_ram(phys_addr_t p, phys_addr_t n)
+{
+ phys_addr_t s;
+ int i;
+ phys_addr_t orig_n;
+
+ orig_n = n;
+
+ BUG_ON(p + n > RV_PHYS);
+
+ for (i = 0; n != 0 && i < ARRAY_SIZE(low_mem_reserved); i++) {
+ phys_addr_t start;
+ phys_addr_t size;
+
+ start = low_mem_reserved[i].start;
+ size = low_mem_reserved[i].size;
+
+ /* Handle memory before this low memory section */
+ if (p < start) {
+ phys_addr_t s;
+ s = min(n, start - p);
+ add_memory_region(p, s, BOOT_MEM_RAM);
+ p += s;
+ n -= s;
+ }
+
+ /* Handle the low memory section itself. If it's aliased,
+ * we reduce the number of byes left, but if not, the RAM
+ * is available elsewhere and we don't reduce the number of
+ * bytes remaining. */
+ if (p == start) {
+ if (low_mem_reserved[i].is_aliased) {
+ s = min(n, size);
+ n -= s;
+ p += s;
+ } else
+ p += n;
+ }
}
+ return orig_n - n;
+}
+
/*
- * TODO: We will use the hard code for memory configuration until
- * the bootloader releases their device tree to us.
+ * register_ram - register real RAM
+ * @p: Address of memory as seen by devices
+ * @alias: If the memory is seen at an additional address by the processor,
+ * this will be the address, otherwise it is the same as @p.
+ * @n: Number of bytes in this section of memory
*/
+static __init void register_ram(phys_addr_t p, phys_addr_t alias,
+ phys_addr_t n)
+{
/*
- * Add the memory reserved for use by the bootloader to the
- * memory map.
- */
- add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
- BOOT_MEM_RESERVED);
-#ifdef CONFIG_HIGHMEM_256_128
- /*
- * Add memory in low for general use by the kernel and its friends
- * (like drivers, applications, etc).
- */
- add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
- LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
- /*
- * Add the memory reserved for reset vector.
- */
- add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
- /*
- * Add the memory reserved.
- */
- add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
- /*
- * Add memory in high for general use by the kernel and its friends
- * (like drivers, applications, etc).
- *
- * 75MB is reserved for devices which are using the memory in high.
- */
- add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
- BOOT_MEM_RAM);
-#elif defined CONFIG_HIGHMEM_128_128
- /*
- * Add memory in low for general use by the kernel and its friends
- * (like drivers, applications, etc).
- */
- add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
- MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
- /*
- * Add the memory reserved.
- */
- add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
- MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
- /*
- * Add memory in high for general use by the kernel and its friends
- * (like drivers, applications, etc).
- *
- * 75MB is reserved for devices which are using the memory in high.
- */
- add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(128 - 75),
- BOOT_MEM_RAM);
-#else
- /* Add low memory regions for either:
- * - no-highmemory configuration case -OR-
- * - highmemory "HIGHMEM_LOWBANK_ONLY" case
- */
- /*
- * Add memory for general use by the kernel and its friends
- * (like drivers, applications, etc).
+ * If some or all of this memory has an alias, break it into the
+ * aliased and non-aliased portion.
*/
- add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
- low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+ if (p != alias) {
+ phys_addr_t alias_size;
+ phys_addr_t registered;
+
+ alias_size = min(n, LOW_RAM_END - alias);
+ registered = register_low_ram(alias, alias_size);
+ ioremap_add_map(alias, p, n);
+ n -= registered;
+ p += registered;
+ }
+
+#ifdef CONFIG_HIGHMEM
+ if (n != 0) {
+ add_memory_region(p, n, BOOT_MEM_RAM);
+ ioremap_add_map(p, p, n);
+ }
+#endif
+}
+
+/**
+ * register_address_space - register things in the address space
+ * @memsize: Number of bytes of RAM installed
+ *
+ * Takes the given number of bytes of RAM and registers as many of the regions,
+ * or partial regions, as it can. So, the default configuration might have
+ * two regions with 256 MiB each. If the memsize passed in on the command line
+ * is 384 MiB, it will register the first region with 256 MiB and the second
+ * with 128 MiB.
+ */
+static __init void register_address_space(phys_addr_t memsize)
+{
+ int i;
+ phys_addr_t size;
+ size_t n;
+ struct mem_layout *layout;
+ enum family_type family;
+
/*
- * Add the memory reserved for reset vector.
+ * Register all of the things that aren't available to the kernel as
+ * memory.
*/
- add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
-#endif
+ register_non_ram();
+
+ /* Find the appropriate memory description */
+ family = platform_get_family();
+
+ for (i = 0; i < ARRAY_SIZE(layout_list); i++) {
+ if (layout_list[i].family == family)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(layout_list)) {
+ n = ARRAY_SIZE(default_layout);
+ layout = default_layout;
+ } else {
+ n = layout_list[i].n;
+ layout = layout_list[i].layout;
+ }
+
+ for (i = 0; memsize != 0 && i < n; i++) {
+ size = min(memsize, layout[i].size);
+ register_ram(layout[i].phys, layout[i].alias, size);
+ memsize -= size;
+ }
+}
+
+void __init prom_meminit(void)
+{
+ ptv_memsize = get_memsize();
+ register_address_space(ptv_memsize);
}
void __init prom_free_prom_memory(void)
diff --git a/arch/mips/powertv/powertv_setup.c b/arch/mips/powertv/powertv_setup.c
index af2cae0a5ab3..3933c373a438 100644
--- a/arch/mips/powertv/powertv_setup.c
+++ b/arch/mips/powertv/powertv_setup.c
@@ -199,14 +199,8 @@ static int panic_handler(struct notifier_block *notifier_block,
my_regs.cp0_status = read_c0_status();
}
-#ifdef CONFIG_DIAGNOSTICS
- failure_report((char *) cause_string,
- have_die_regs ? &die_regs : &my_regs);
- have_die_regs = false;
-#else
pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
"zzzz... \n");
-#endif
return NOTIFY_DONE;
}
diff --git a/arch/mips/rb532/Makefile b/arch/mips/rb532/Makefile
index 8f0b6b6a1625..efdecdb6e3ea 100644
--- a/arch/mips/rb532/Makefile
+++ b/arch/mips/rb532/Makefile
@@ -3,5 +3,3 @@
#
obj-y += irq.o time.o setup.o serial.o prom.o gpio.o devices.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/rb532/Platform b/arch/mips/rb532/Platform
new file mode 100644
index 000000000000..aeec45a7cbb3
--- /dev/null
+++ b/arch/mips/rb532/Platform
@@ -0,0 +1,7 @@
+#
+# Routerboard 532
+#
+platform-$(CONFIG_MIKROTIK_RB532) += rb532/
+cflags-$(CONFIG_MIKROTIK_RB532) += \
+ -I$(srctree)/arch/mips/include/asm/mach-rc32434
+load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index 416b18f9fa72..cc538493cae1 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -9,5 +9,3 @@ obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
obj-$(CONFIG_SGI_IP22) += ip22-berr.o
obj-$(CONFIG_SGI_IP28) += ip28-berr.o
obj-$(CONFIG_EISA) += ip22-eisa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip22/Platform b/arch/mips/sgi-ip22/Platform
new file mode 100644
index 000000000000..d29cbe863ffe
--- /dev/null
+++ b/arch/mips/sgi-ip22/Platform
@@ -0,0 +1,34 @@
+#
+# SGI IP22 (Indy/Indigo2)
+#
+# Set the load address to >= 0xffffffff88069000 if you want to leave space for
+# symmon, 0xffffffff80002000 for production kernels. Note that the value must
+# be aligned to a multiple of the kernel stack size or the handling of the
+# current variable will break so for 64-bit kernels we have to raise the start
+# address by 8kb.
+#
+patform-$(CONFIG_SGI_IP22) += sgi-ip22/
+cflags-$(CONFIG_SGI_IP22) += -I$(srctree)/arch/mips/include/asm/mach-ip22
+ifdef CONFIG_32BIT
+load-$(CONFIG_SGI_IP22) += 0xffffffff88002000
+endif
+ifdef CONFIG_64BIT
+load-$(CONFIG_SGI_IP22) += 0xffffffff88004000
+endif
+
+#
+# SGI IP28 (Indigo2 R10k)
+#
+# Set the load address to >= 0xa800000020080000 if you want to leave space for
+# symmon, 0xa800000020004000 for production kernels ? Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+# Simplified: what IP22 does at 128MB+ in ksegN, IP28 does at 512MB+ in xkphys
+#
+ifdef CONFIG_SGI_IP28
+ ifeq ($(call cc-option-yn,-mr10k-cache-barrier=store), n)
+ $(error gcc doesn't support needed option -mr10k-cache-barrier=store)
+ endif
+endif
+platform-$(CONFIG_SGI_IP28) += sgi-ip22/
+cflags-$(CONFIG_SGI_IP28) += -mr10k-cache-barrier=store -I$(srctree)/arch/mips/include/asm/mach-ip28
+load-$(CONFIG_SGI_IP28) += 0xa800000020004000
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile
index 31f4931b8484..1f29e761d691 100644
--- a/arch/mips/sgi-ip27/Makefile
+++ b/arch/mips/sgi-ip27/Makefile
@@ -8,5 +8,3 @@ obj-y := ip27-berr.o ip27-irq.o ip27-init.o ip27-klconfig.o ip27-klnuma.o \
obj-$(CONFIG_EARLY_PRINTK) += ip27-console.o
obj-$(CONFIG_SMP) += ip27-smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip27/Platform b/arch/mips/sgi-ip27/Platform
new file mode 100644
index 000000000000..1fb9c2ea7c8f
--- /dev/null
+++ b/arch/mips/sgi-ip27/Platform
@@ -0,0 +1,19 @@
+#
+# SGI-IP27 (Origin200/2000)
+#
+# Set the load address to >= 0xc000000000300000 if you want to leave space for
+# symmon, 0xc00000000001c000 for production kernels. Note that the value must
+# be 16kb aligned or the handling of the current variable will break.
+#
+ifdef CONFIG_SGI_IP27
+platform-$(CONFIG_SGI_IP27) += sgi-ip27/
+cflags-$(CONFIG_SGI_IP27) += -I$(srctree)/arch/mips/include/asm/mach-ip27
+ifdef CONFIG_MAPPED_KERNEL
+load-$(CONFIG_SGI_IP27) += 0xc00000004001c000
+OBJCOPYFLAGS := --change-addresses=0x3fffffff80000000
+dataoffset-$(CONFIG_SGI_IP27) += 0x01000000
+else
+load-$(CONFIG_SGI_IP27) += 0xa80000000001c000
+OBJCOPYFLAGS := --change-addresses=0x57ffffff80000000
+endif
+endif
diff --git a/arch/mips/sgi-ip27/ip27-klconfig.c b/arch/mips/sgi-ip27/ip27-klconfig.c
index dd830b3670d1..7afe14688003 100644
--- a/arch/mips/sgi-ip27/ip27-klconfig.c
+++ b/arch/mips/sgi-ip27/ip27-klconfig.c
@@ -48,7 +48,7 @@ klinfo_t *find_first_component(lboard_t *brd, unsigned char struct_type)
return find_component(brd, (klinfo_t *)NULL, struct_type);
}
-lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
+lboard_t *find_lboard(lboard_t *start, unsigned char brd_type)
{
/* Search all boards stored on this node. */
while (start) {
@@ -60,7 +60,7 @@ lboard_t * find_lboard(lboard_t *start, unsigned char brd_type)
return (lboard_t *)NULL;
}
-lboard_t * find_lboard_class(lboard_t *start, unsigned char brd_type)
+lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_type)
{
/* Search all boards stored on this node. */
while (start) {
@@ -78,7 +78,7 @@ cnodeid_t get_cpu_cnode(cpuid_t cpu)
return CPUID_TO_COMPACT_NODEID(cpu);
}
-klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
+klcpu_t *nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
{
lboard_t *brd;
klcpu_t *acpu;
@@ -97,7 +97,7 @@ klcpu_t * nasid_slice_to_cpuinfo(nasid_t nasid, int slice)
return (klcpu_t *)NULL;
}
-klcpu_t * sn_get_cpuinfo(cpuid_t cpu)
+klcpu_t *sn_get_cpuinfo(cpuid_t cpu)
{
nasid_t nasid;
int slice;
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile
index 31c9aa1bcb40..60f0227425e7 100644
--- a/arch/mips/sgi-ip32/Makefile
+++ b/arch/mips/sgi-ip32/Makefile
@@ -5,5 +5,3 @@
obj-y += ip32-berr.o ip32-irq.o ip32-platform.o ip32-setup.o ip32-reset.o \
crime.o ip32-memory.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sgi-ip32/Platform b/arch/mips/sgi-ip32/Platform
new file mode 100644
index 000000000000..0fea556f3641
--- /dev/null
+++ b/arch/mips/sgi-ip32/Platform
@@ -0,0 +1,11 @@
+#
+# SGI-IP32 (O2)
+#
+# Set the load address to >= 80069000 if you want to leave space for symmon,
+# 0xffffffff80004000 for production kernels. Note that the value must be aligned to
+# a multiple of the kernel stack size or the handling of the current variable
+# will break.
+#
+platform-$(CONFIG_SGI_IP32) += sgi-ip32/
+cflags-$(CONFIG_SGI_IP32) += -I$(srctree)/arch/mips/include/asm/mach-ip32
+load-$(CONFIG_SGI_IP32) += 0xffffffff80004000
diff --git a/arch/mips/sibyte/Makefile b/arch/mips/sibyte/Makefile
new file mode 100644
index 000000000000..d9df7b1f753e
--- /dev/null
+++ b/arch/mips/sibyte/Makefile
@@ -0,0 +1,27 @@
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+core-$(CONFIG_SIBYTE_BCM112X) += sb1250/
+core-$(CONFIG_SIBYTE_BCM112X) += common/
+core-$(CONFIG_SIBYTE_SB1250) += sb1250/
+core-$(CONFIG_SIBYTE_SB1250) += common/
+core-$(CONFIG_SIBYTE_BCM1x55) += bcm1480/
+core-$(CONFIG_SIBYTE_BCM1x55) += common/
+core-$(CONFIG_SIBYTE_BCM1x80) += bcm1480/
+core-$(CONFIG_SIBYTE_BCM1x80) += common/
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+core-$(CONFIG_SIBYTE_CARMEL) += swarm/
+core-$(CONFIG_SIBYTE_CRHINE) += swarm/
+core-$(CONFIG_SIBYTE_CRHONE) += swarm/
+core-$(CONFIG_SIBYTE_RHONE) += swarm/
+core-$(CONFIG_SIBYTE_SENTOSA) += swarm/
+core-$(CONFIG_SIBYTE_SWARM) += swarm/
+core-$(CONFIG_SIBYTE_BIGSUR) += swarm/
diff --git a/arch/mips/sibyte/Platform b/arch/mips/sibyte/Platform
new file mode 100644
index 000000000000..911dfe39c631
--- /dev/null
+++ b/arch/mips/sibyte/Platform
@@ -0,0 +1,43 @@
+#
+# These are all rather similar so we consider them a single platform
+#
+platform-$(CONFIG_SIBYTE_BCM112X) += sibyte/
+platform-$(CONFIG_SIBYTE_SB1250) += sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x55) += sibyte/
+platform-$(CONFIG_SIBYTE_BCM1x80) += sibyte/
+
+#
+# Sibyte SB1250 / BCM1480 family of SOCs
+#
+cflags-$(CONFIG_SIBYTE_BCM112X) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+platform-$(CONFIG_SIBYTE_SB1250) += sibyte/
+cflags-$(CONFIG_SIBYTE_SB1250) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1250_112x_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x55) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+cflags-$(CONFIG_SIBYTE_BCM1x80) += \
+ -I$(srctree)/arch/mips/include/asm/mach-sibyte \
+ -DSIBYTE_HDR_FEATURES=SIBYTE_HDR_FMASK_1480_ALL
+
+#
+# Sibyte BCM91120x (Carmel) board
+# Sibyte BCM91120C (CRhine) board
+# Sibyte BCM91125C (CRhone) board
+# Sibyte BCM91125E (Rhone) board
+# Sibyte SWARM board
+# Sibyte BCM91x80 (BigSur) board
+#
+load-$(CONFIG_SIBYTE_CARMEL) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHINE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_CRHONE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_RHONE) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SENTOSA) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_SWARM) := 0xffffffff80100000
+load-$(CONFIG_SIBYTE_BIGSUR) := 0xffffffff80100000
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile
index f292f7df0cfb..cdc4c56c3e29 100644
--- a/arch/mips/sibyte/bcm1480/Makefile
+++ b/arch/mips/sibyte/bcm1480/Makefile
@@ -1,5 +1,3 @@
obj-y := setup.o irq.o time.o
obj-$(CONFIG_SMP) += smp.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/common/Makefile b/arch/mips/sibyte/common/Makefile
index 4f659837c7c6..36aa700cc40c 100644
--- a/arch/mips/sibyte/common/Makefile
+++ b/arch/mips/sibyte/common/Makefile
@@ -1,5 +1,3 @@
obj-y := cfe.o
obj-$(CONFIG_SIBYTE_CFE_CONSOLE) += cfe_console.o
obj-$(CONFIG_SIBYTE_TBPROF) += sb_tbprof.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile
index 1896f4e77a30..d3d969de407b 100644
--- a/arch/mips/sibyte/sb1250/Makefile
+++ b/arch/mips/sibyte/sb1250/Makefile
@@ -2,5 +2,3 @@ obj-y := setup.o irq.o time.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SIBYTE_BUS_WATCHER) += bus_watcher.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile
index a7dbeebe7fe6..9d3bad3200ce 100644
--- a/arch/mips/sni/Makefile
+++ b/arch/mips/sni/Makefile
@@ -4,5 +4,3 @@
obj-y += irq.o reset.o setup.o a20r.o rm200.o pcimt.o pcit.o time.o
obj-$(CONFIG_EISA) += eisa.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/sni/Platform b/arch/mips/sni/Platform
new file mode 100644
index 000000000000..2644a9d63c0f
--- /dev/null
+++ b/arch/mips/sni/Platform
@@ -0,0 +1,11 @@
+#
+# SNI RM
+#
+platform-$(CONFIG_SNI_RM) += sni/
+cflags-$(CONFIG_SNI_RM) += -I$(srctree)/arch/mips/include/asm/mach-rm
+ifdef CONFIG_CPU_LITTLE_ENDIAN
+load-$(CONFIG_SNI_RM) += 0xffffffff80600000
+else
+load-$(CONFIG_SNI_RM) += 0xffffffff80030000
+endif
+all-$(CONFIG_SNI_RM) := $(COMPRESSION_FNAME).ecoff
diff --git a/arch/mips/txx9/Makefile b/arch/mips/txx9/Makefile
new file mode 100644
index 000000000000..9beb320689b9
--- /dev/null
+++ b/arch/mips/txx9/Makefile
@@ -0,0 +1,17 @@
+#
+# Common TXx9
+#
+core-$(CONFIG_MACH_TX39XX) += arch/mips/txx9/generic/
+core-$(CONFIG_MACH_TX49XX) += arch/mips/txx9/generic/
+
+#
+# Toshiba JMR-TX3927 board
+#
+lib-$(CONFIG_TOSHIBA_JMR3927) += jmr3927/
+
+#
+# Toshiba RBTX49XX boards
+#
+lib-$(CONFIG_TOSHIBA_RBTX4927) += rbtx4927/
+lib-$(CONFIG_TOSHIBA_RBTX4938) += rbtx4938/
+lib-$(CONFIG_TOSHIBA_RBTX4939) += rbtx4939/
diff --git a/arch/mips/txx9/Platform b/arch/mips/txx9/Platform
new file mode 100644
index 000000000000..a801abbe138b
--- /dev/null
+++ b/arch/mips/txx9/Platform
@@ -0,0 +1,10 @@
+platform-$(CONFIG_MACH_TX39XX) += txx9/
+platform-$(CONFIG_MACH_TX49XX) += txx9/
+
+cflags-$(CONFIG_MACH_TX39XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-tx39xx
+cflags-$(CONFIG_MACH_TX49XX) += \
+ -I$(srctree)/arch/mips/include/asm/mach-tx49xx
+
+load-$(CONFIG_MACH_TX39XX) += 0xffffffff80050000
+load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
diff --git a/arch/mips/txx9/generic/Makefile b/arch/mips/txx9/generic/Makefile
index f2579ce054a1..1863c167e66e 100644
--- a/arch/mips/txx9/generic/Makefile
+++ b/arch/mips/txx9/generic/Makefile
@@ -11,5 +11,3 @@ obj-$(CONFIG_SOC_TX4939) += setup_tx4939.o irq_tx4939.o
obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o
obj-$(CONFIG_SPI) += spi_eeprom.o
obj-$(CONFIG_TXX9_7SEGLED) += 7segled.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/jmr3927/Makefile b/arch/mips/txx9/jmr3927/Makefile
index 20d61ac543e5..9f5d5b623839 100644
--- a/arch/mips/txx9/jmr3927/Makefile
+++ b/arch/mips/txx9/jmr3927/Makefile
@@ -3,5 +3,3 @@
#
obj-y += prom.o irq.o setup.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4927/Makefile b/arch/mips/txx9/rbtx4927/Makefile
index f3e1f597b4f1..60b24c8f7e63 100644
--- a/arch/mips/txx9/rbtx4927/Makefile
+++ b/arch/mips/txx9/rbtx4927/Makefile
@@ -1,3 +1 @@
obj-y += prom.o setup.o irq.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4938/Makefile b/arch/mips/txx9/rbtx4938/Makefile
index f3e1f597b4f1..60b24c8f7e63 100644
--- a/arch/mips/txx9/rbtx4938/Makefile
+++ b/arch/mips/txx9/rbtx4938/Makefile
@@ -1,3 +1 @@
obj-y += prom.o setup.o irq.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/txx9/rbtx4939/Makefile b/arch/mips/txx9/rbtx4939/Makefile
index 3232cd03a7d6..5c84625a3f1c 100644
--- a/arch/mips/txx9/rbtx4939/Makefile
+++ b/arch/mips/txx9/rbtx4939/Makefile
@@ -1,3 +1 @@
obj-y += irq.o setup.o prom.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/vr41xx/Platform b/arch/mips/vr41xx/Platform
new file mode 100644
index 000000000000..b6c8d5c08ddb
--- /dev/null
+++ b/arch/mips/vr41xx/Platform
@@ -0,0 +1,32 @@
+#
+# NEC VR4100 series based machines
+#
+platform-$(CONFIG_MACH_VR41XX) += vr41xx/common/
+cflags-$(CONFIG_MACH_VR41XX) += -I$(srctree)/arch/mips/include/asm/mach-vr41xx
+
+#
+# CASIO CASSIPEIA E-55/65 (VR4111)
+#
+platform-$(CONFIG_CASIO_E55) += vr41xx/casio-e55/
+load-$(CONFIG_CASIO_E55) += 0xffffffff80004000
+
+#
+# IBM WorkPad z50 (VR4121)
+#
+platform-$(CONFIG_IBM_WORKPAD) += vr41xx/ibm-workpad/
+load-$(CONFIG_IBM_WORKPAD) += 0xffffffff80004000
+
+#
+# TANBAC VR4131 multichip module(TB0225) and TANBAC VR4131DIMM(TB0229) (VR4131)
+#
+load-$(CONFIG_TANBAC_TB022X) += 0xffffffff80000000
+
+#
+# Victor MP-C303/304 (VR4122)
+#
+load-$(CONFIG_VICTOR_MPC30X) += 0xffffffff80001000
+
+#
+# ZAO Networks Capcella (VR4131)
+#
+load-$(CONFIG_ZAO_CAPCELLA) += 0xffffffff80000000
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile
index 7d5d83b8c582..d0d84ec8d63d 100644
--- a/arch/mips/vr41xx/common/Makefile
+++ b/arch/mips/vr41xx/common/Makefile
@@ -3,5 +3,3 @@
#
obj-y += bcu.o cmu.o giu.o icu.o init.o irq.o pmu.o rtc.o siu.o type.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/gt64120/wrppmc/Makefile b/arch/mips/wrppmc/Makefile
index b49d282bee8a..307cc6920ce6 100644
--- a/arch/mips/gt64120/wrppmc/Makefile
+++ b/arch/mips/wrppmc/Makefile
@@ -6,9 +6,7 @@
# Copyright 2006 Wind River System, Inc.
# Author: Rongkai.Zhan <rongkai.zhan@windriver.com>
#
-# Makefile for the Wind River MIPS 4KC PPMC Eval Board
+# Makefile for the Wind River MIPS 4Kc PPMC Eval Board
#
obj-y += irq.o pci.o reset.o serial.o setup.o time.o
-
-EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/wrppmc/Platform b/arch/mips/wrppmc/Platform
new file mode 100644
index 000000000000..e758645e9681
--- /dev/null
+++ b/arch/mips/wrppmc/Platform
@@ -0,0 +1,7 @@
+#
+# Wind River PPMC Board (4KC + GT64120)
+#
+platform-$(CONFIG_WR_PPMC) += wrppmc/
+cflags-$(CONFIG_WR_PPMC) += \
+ -I$(srctree)/arch/mips/include/asm/mach-wrppmc
+load-$(CONFIG_WR_PPMC) += 0xffffffff80100000
diff --git a/arch/mips/gt64120/wrppmc/irq.c b/arch/mips/wrppmc/irq.c
index c6e706274db4..c6e706274db4 100644
--- a/arch/mips/gt64120/wrppmc/irq.c
+++ b/arch/mips/wrppmc/irq.c
diff --git a/arch/mips/gt64120/wrppmc/pci.c b/arch/mips/wrppmc/pci.c
index d06192faeb7c..d06192faeb7c 100644
--- a/arch/mips/gt64120/wrppmc/pci.c
+++ b/arch/mips/wrppmc/pci.c
diff --git a/arch/mips/gt64120/wrppmc/reset.c b/arch/mips/wrppmc/reset.c
index cc5474b24f06..cc5474b24f06 100644
--- a/arch/mips/gt64120/wrppmc/reset.c
+++ b/arch/mips/wrppmc/reset.c
diff --git a/arch/mips/gt64120/wrppmc/serial.c b/arch/mips/wrppmc/serial.c
index 6f9d0858f596..6f9d0858f596 100644
--- a/arch/mips/gt64120/wrppmc/serial.c
+++ b/arch/mips/wrppmc/serial.c
diff --git a/arch/mips/gt64120/wrppmc/setup.c b/arch/mips/wrppmc/setup.c
index ca65c84031a7..ca65c84031a7 100644
--- a/arch/mips/gt64120/wrppmc/setup.c
+++ b/arch/mips/wrppmc/setup.c
diff --git a/arch/mips/gt64120/wrppmc/time.c b/arch/mips/wrppmc/time.c
index 668dbd5f12c5..668dbd5f12c5 100644
--- a/arch/mips/gt64120/wrppmc/time.c
+++ b/arch/mips/wrppmc/time.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 6506bf4fbff1..25b28fdc6767 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -141,6 +141,7 @@ config PPC
select GENERIC_ATOMIC64 if PPC32
select HAVE_PERF_EVENTS
select HAVE_REGS_AND_STACK_ACCESS_API
+ select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
config EARLY_PRINTK
bool
@@ -218,7 +219,7 @@ config ARCH_HIBERNATION_POSSIBLE
config ARCH_SUSPEND_POSSIBLE
def_bool y
depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \
- PPC_85xx || PPC_86xx
+ PPC_85xx || PPC_86xx || PPC_PSERIES
config PPC_DCR_NATIVE
bool
diff --git a/arch/powerpc/include/asm/abs_addr.h b/arch/powerpc/include/asm/abs_addr.h
index 98324c5a8286..c3bffc3fa1de 100644
--- a/arch/powerpc/include/asm/abs_addr.h
+++ b/arch/powerpc/include/asm/abs_addr.h
@@ -69,7 +69,7 @@ static inline unsigned long phys_to_abs(unsigned long pa)
* Legacy iSeries Hypervisor calls
*/
#define iseries_hv_addr(virtaddr) \
- (0x8000000000000000 | virt_to_abs(virtaddr))
+ (0x8000000000000000UL | virt_to_abs(virtaddr))
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_ABS_ADDR_H */
diff --git a/arch/powerpc/include/asm/asm-compat.h b/arch/powerpc/include/asm/asm-compat.h
index 2048a6aeea91..decad950f11a 100644
--- a/arch/powerpc/include/asm/asm-compat.h
+++ b/arch/powerpc/include/asm/asm-compat.h
@@ -30,6 +30,7 @@
#define PPC_STLCX stringify_in_c(stdcx.)
#define PPC_CNTLZL stringify_in_c(cntlzd)
#define PPC_LR_STKOFF 16
+#define PPC_MIN_STKFRM 112
/* Move to CR, single-entry optimized version. Only available
* on POWER4 and later.
@@ -55,6 +56,7 @@
#define PPC_CNTLZL stringify_in_c(cntlzw)
#define PPC_MTOCRF stringify_in_c(mtcrf)
#define PPC_LR_STKOFF 4
+#define PPC_MIN_STKFRM 16
#endif
diff --git a/arch/powerpc/include/asm/cpm.h b/arch/powerpc/include/asm/cpm.h
index 0835eb977ba9..e50323fe941f 100644
--- a/arch/powerpc/include/asm/cpm.h
+++ b/arch/powerpc/include/asm/cpm.h
@@ -7,6 +7,30 @@
#include <linux/of.h>
/*
+ * SPI Parameter RAM common to QE and CPM.
+ */
+struct spi_pram {
+ __be16 rbase; /* Rx Buffer descriptor base address */
+ __be16 tbase; /* Tx Buffer descriptor base address */
+ u8 rfcr; /* Rx function code */
+ u8 tfcr; /* Tx function code */
+ __be16 mrblr; /* Max receive buffer length */
+ __be32 rstate; /* Internal */
+ __be32 rdp; /* Internal */
+ __be16 rbptr; /* Internal */
+ __be16 rbc; /* Internal */
+ __be32 rxtmp; /* Internal */
+ __be32 tstate; /* Internal */
+ __be32 tdp; /* Internal */
+ __be16 tbptr; /* Internal */
+ __be16 tbc; /* Internal */
+ __be32 txtmp; /* Internal */
+ __be32 res; /* Tx temp. */
+ __be16 rpbase; /* Relocation pointer (CPM1 only) */
+ __be16 res1; /* Reserved */
+};
+
+/*
* USB Controller pram common to QE and CPM.
*/
struct usb_ctlr {
diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h
index 81b01192f440..bd07650dca56 100644
--- a/arch/powerpc/include/asm/cpm1.h
+++ b/arch/powerpc/include/asm/cpm1.h
@@ -17,6 +17,7 @@
#ifndef __CPM1__
#define __CPM1__
+#include <linux/init.h>
#include <asm/8xx_immap.h>
#include <asm/ptrace.h>
#include <asm/cpm.h>
@@ -54,7 +55,7 @@ extern cpm8xx_t __iomem *cpmp; /* Pointer to comm processor */
extern void cpm_setbrg(uint brg, uint rate);
-extern void cpm_load_patch(cpm8xx_t *cp);
+extern void __init cpm_load_patch(cpm8xx_t *cp);
extern void cpm_reset(void);
diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index b0b21134f61a..5e2e2cfcc81b 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -517,6 +517,10 @@ static inline int cpu_has_feature(unsigned long feature)
& feature);
}
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+#define HBP_NUM 1
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
#endif /* !__ASSEMBLY__ */
#endif /* __KERNEL__ */
diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h
index 5119b7db3142..de03ca58db5d 100644
--- a/arch/powerpc/include/asm/hvcall.h
+++ b/arch/powerpc/include/asm/hvcall.h
@@ -74,6 +74,7 @@
#define H_NOT_ENOUGH_RESOURCES -44
#define H_R_STATE -45
#define H_RESCINDEND -46
+#define H_MULTI_THREADS_ACTIVE -9005
/* Long Busy is a condition that can be returned by the firmware
diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h
new file mode 100644
index 000000000000..1c33ec17ca36
--- /dev/null
+++ b/arch/powerpc/include/asm/hw_breakpoint.h
@@ -0,0 +1,74 @@
+/*
+ * PowerPC BookIII S hardware breakpoint definitions
+ *
+ * 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.
+ *
+ * Copyright 2010, IBM Corporation.
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ *
+ */
+
+#ifndef _PPC_BOOK3S_64_HW_BREAKPOINT_H
+#define _PPC_BOOK3S_64_HW_BREAKPOINT_H
+
+#ifdef __KERNEL__
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+
+struct arch_hw_breakpoint {
+ bool extraneous_interrupt;
+ u8 len; /* length of the target data symbol */
+ int type;
+ unsigned long address;
+};
+
+#include <linux/kdebug.h>
+#include <asm/reg.h>
+#include <asm/system.h>
+
+struct perf_event;
+struct pmu;
+struct perf_sample_data;
+
+#define HW_BREAKPOINT_ALIGN 0x7
+/* Maximum permissible length of any HW Breakpoint */
+#define HW_BREAKPOINT_LEN 0x8
+
+extern int hw_breakpoint_slots(int type);
+extern int arch_bp_generic_fields(int type, int *gen_bp_type);
+extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
+ unsigned long val, void *data);
+int arch_install_hw_breakpoint(struct perf_event *bp);
+void arch_uninstall_hw_breakpoint(struct perf_event *bp);
+void hw_breakpoint_pmu_read(struct perf_event *bp);
+extern void flush_ptrace_hw_breakpoint(struct task_struct *tsk);
+
+extern struct pmu perf_ops_bp;
+extern void ptrace_triggered(struct perf_event *bp, int nmi,
+ struct perf_sample_data *data, struct pt_regs *regs);
+static inline void hw_breakpoint_disable(void)
+{
+ set_dabr(0);
+}
+extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs);
+
+#else /* CONFIG_HAVE_HW_BREAKPOINT */
+static inline void hw_breakpoint_disable(void) { }
+static inline void thread_change_pc(struct task_struct *tsk,
+ struct pt_regs *regs) { }
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+#endif /* __KERNEL__ */
+#endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 9f0fc9e6ce0d..2bad6e5855ad 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -266,6 +266,7 @@ struct machdep_calls {
void (*suspend_disable_irqs)(void);
void (*suspend_enable_irqs)(void);
#endif
+ int (*suspend_disable_cpu)(void);
#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
ssize_t (*cpu_probe)(const char *, size_t);
@@ -366,8 +367,5 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7)
#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s)
-void generic_suspend_disable_irqs(void);
-void generic_suspend_enable_irqs(void);
-
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_MACHDEP_H */
diff --git a/arch/powerpc/include/asm/percpu.h b/arch/powerpc/include/asm/percpu.h
index f879252b7ea6..2cedefddba37 100644
--- a/arch/powerpc/include/asm/percpu.h
+++ b/arch/powerpc/include/asm/percpu.h
@@ -1,7 +1,6 @@
#ifndef _ASM_POWERPC_PERCPU_H_
#define _ASM_POWERPC_PERCPU_H_
#ifdef __powerpc64__
-#include <linux/compiler.h>
/*
* Same as asm-generic/percpu.h, except that we store the per cpu offset
@@ -12,9 +11,7 @@
#include <asm/paca.h>
-#define __per_cpu_offset(cpu) (paca[cpu].data_offset)
#define __my_cpu_offset local_paca->data_offset
-#define per_cpu_offset(x) (__per_cpu_offset(x))
#endif /* CONFIG_SMP */
#endif /* __powerpc64__ */
diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h
index d553bbeb726c..43adc8b819ed 100644
--- a/arch/powerpc/include/asm/ppc-opcode.h
+++ b/arch/powerpc/include/asm/ppc-opcode.h
@@ -52,13 +52,17 @@
#define PPC_INST_WAIT 0x7c00007c
#define PPC_INST_TLBIVAX 0x7c000624
#define PPC_INST_TLBSRX_DOT 0x7c0006a5
+#define PPC_INST_XXLOR 0xf0000510
/* macros to insert fields into opcodes */
#define __PPC_RA(a) (((a) & 0x1f) << 16)
#define __PPC_RB(b) (((b) & 0x1f) << 11)
#define __PPC_RS(s) (((s) & 0x1f) << 21)
#define __PPC_RT(s) __PPC_RS(s)
+#define __PPC_XA(a) ((((a) & 0x1f) << 16) | (((a) & 0x20) >> 3))
+#define __PPC_XB(b) ((((b) & 0x1f) << 11) | (((b) & 0x20) >> 4))
#define __PPC_XS(s) ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
+#define __PPC_XT(s) __PPC_XS(s)
#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
#define __PPC_WC(w) (((w) & 0x3) << 21)
/*
@@ -106,9 +110,12 @@
* the 128 bit load store instructions based on that.
*/
#define VSX_XX1(s, a, b) (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b))
+#define VSX_XX3(t, a, b) (__PPC_XT(t) | __PPC_XA(a) | __PPC_XB(b))
#define STXVD2X(s, a, b) stringify_in_c(.long PPC_INST_STXVD2X | \
VSX_XX1((s), (a), (b)))
#define LXVD2X(s, a, b) stringify_in_c(.long PPC_INST_LXVD2X | \
VSX_XX1((s), (a), (b)))
+#define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \
+ VSX_XX3((t), (a), (b)))
#endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 7492fe8ad6e4..19c05b0f74be 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -209,6 +209,14 @@ struct thread_struct {
#ifdef CONFIG_PPC64
unsigned long start_tb; /* Start purr when proc switched in */
unsigned long accum_tb; /* Total accumilated purr for process */
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ struct perf_event *ptrace_bps[HBP_NUM];
+ /*
+ * Helps identify source of single-step exception and subsequent
+ * hw-breakpoint enablement
+ */
+ struct perf_event *last_hit_ubp;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif
unsigned long dabr; /* Data address breakpoint register */
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 20de73c36682..3d35f8ae377e 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -63,6 +63,14 @@ struct rtas_t {
struct device_node *dev; /* virtual address pointer */
};
+struct rtas_suspend_me_data {
+ atomic_t working; /* number of cpus accessing this struct */
+ atomic_t done;
+ int token; /* ibm,suspend-me */
+ atomic_t error;
+ struct completion *complete; /* wait on this until working == 0 */
+};
+
/* RTAS event classes */
#define RTAS_INTERNAL_ERROR 0x80000000 /* set bit 0 */
#define RTAS_EPOW_WARNING 0x40000000 /* set bit 1 */
@@ -137,6 +145,9 @@ struct rtas_t {
#define RTAS_TYPE_PMGM_CONFIG_CHANGE 0x70
#define RTAS_TYPE_PMGM_SERVICE_PROC 0x71
+/* RTAS check-exception vector offset */
+#define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500
+
struct rtas_error_log {
unsigned long version:8; /* Architectural version */
unsigned long severity:3; /* Severity level of error */
@@ -174,6 +185,8 @@ extern int rtas_set_indicator(int indicator, int index, int new_value);
extern int rtas_set_indicator_fast(int indicator, int index, int new_value);
extern void rtas_progress(char *s, unsigned short hex);
extern void rtas_initialize(void);
+extern int rtas_suspend_cpu(struct rtas_suspend_me_data *data);
+extern int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data);
struct rtc_time;
extern unsigned long rtas_get_boot_time(void);
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index 27ccb764fdab..dc779dfcf258 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h
@@ -28,16 +28,12 @@
extern unsigned long tb_ticks_per_jiffy;
extern unsigned long tb_ticks_per_usec;
extern unsigned long tb_ticks_per_sec;
-extern u64 tb_to_xs;
-extern unsigned tb_to_us;
struct rtc_time;
extern void to_tm(int tim, struct rtc_time * tm);
extern void GregorianDay(struct rtc_time *tm);
-extern time_t last_rtc_update;
extern void generic_calibrate_decr(void);
-extern void wakeup_decrementer(void);
extern void snapshot_timebase(void);
extern void set_dec_cpu6(unsigned int val);
@@ -204,9 +200,6 @@ static inline unsigned long tb_ticks_since(unsigned long tstamp)
extern u64 mulhdu(u64, u64);
#endif
-extern void smp_space_timers(unsigned int);
-
-extern unsigned mulhwu_scale_factor(unsigned, unsigned);
extern void div128_by_32(u64 dividend_high, u64 dividend_low,
unsigned divisor, struct div_result *dr);
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 32adf7280720..3033c1b30745 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -87,6 +87,9 @@ static inline int pcibus_to_node(struct pci_bus *bus)
.balance_interval = 1, \
}
+extern int __node_distance(int, int);
+#define node_distance(a, b) __node_distance(a, b)
+
extern void __init dump_numa_cpu_topology(void);
extern int sysfs_add_device_to_node(struct sys_device *dev, int nid);
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index 13c2c283e178..08679c5319b8 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -85,6 +85,7 @@ struct vdso_data {
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
+ __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
};
@@ -105,6 +106,7 @@ struct vdso_data {
__s32 wtom_clock_sec; /* Wall to monotonic clock */
__s32 wtom_clock_nsec;
struct timespec stamp_xtime; /* xtime as at tb_orig_stamp */
+ __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 dcache_block_size; /* L1 d-cache block size */
__u32 icache_block_size; /* L1 i-cache block size */
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 58d0572de6f9..01006040f59e 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -34,6 +34,7 @@ obj-y += vdso32/
obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
signal_64.o ptrace32.o \
paca.o nvram_64.o firmware.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
obj64-$(CONFIG_RELOCATABLE) += reloc_64.o
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 496cc5b3984f..1c0607ddccc0 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -194,7 +194,6 @@ int main(void)
DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
- DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
DEFINE(PACA_KVM_SVCPU, offsetof(struct paca_struct, shadow_vcpu));
@@ -342,6 +341,7 @@ int main(void)
DEFINE(WTOM_CLOCK_SEC, offsetof(struct vdso_data, wtom_clock_sec));
DEFINE(WTOM_CLOCK_NSEC, offsetof(struct vdso_data, wtom_clock_nsec));
DEFINE(STAMP_XTIME, offsetof(struct vdso_data, stamp_xtime));
+ DEFINE(STAMP_SEC_FRAC, offsetof(struct vdso_data, stamp_sec_fraction));
DEFINE(CFG_ICACHE_BLOCKSZ, offsetof(struct vdso_data, icache_block_size));
DEFINE(CFG_DCACHE_BLOCKSZ, offsetof(struct vdso_data, dcache_block_size));
DEFINE(CFG_ICACHE_LOGBLOCKSZ, offsetof(struct vdso_data, icache_log_block_size));
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3e423fbad6bc..f53029a01554 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -828,6 +828,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
/* We have a data breakpoint exception - handle it */
handle_dabr_fault:
+ bl .save_nvgprs
ld r4,_DAR(r1)
ld r5,_DSISR(r1)
addi r3,r1,STACK_FRAME_OVERHEAD
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
index beb4d78a2304..a92c79be2728 100644
--- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -205,8 +205,7 @@ next_tlb_setup:
bdnz+ next_tlb_setup
/* 7. Jump to our 1:1 mapping */
- li r6, 0
-
+ mr r6, r25
#else
#error You need to specify the mapping or not use this at all.
#endif
@@ -217,7 +216,6 @@ next_tlb_setup:
1: mflr r9
rlwimi r6,r9,0,20,31
addi r6,r6,(2f - 1b)
- add r6, r6, r25
mtspr SPRN_SRR0,r6
mtspr SPRN_SRR1,r7
rfi /* start execution out of TLB1[0] entry */
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..5ecd0401cdb1
--- /dev/null
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,364 @@
+/*
+ * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
+ * using the CPU's debug registers. Derived from
+ * "arch/x86/kernel/hw_breakpoint.c"
+ *
+ * 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.
+ *
+ * Copyright 2010 IBM Corporation
+ * Author: K.Prasad <prasad@linux.vnet.ibm.com>
+ *
+ */
+
+#include <linux/hw_breakpoint.h>
+#include <linux/notifier.h>
+#include <linux/kprobes.h>
+#include <linux/percpu.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+
+#include <asm/hw_breakpoint.h>
+#include <asm/processor.h>
+#include <asm/sstep.h>
+#include <asm/uaccess.h>
+
+/*
+ * Stores the breakpoints currently in use on each breakpoint address
+ * register for every cpu
+ */
+static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
+
+/*
+ * Returns total number of data or instruction breakpoints available.
+ */
+int hw_breakpoint_slots(int type)
+{
+ if (type == TYPE_DATA)
+ return HBP_NUM;
+ return 0; /* no instruction breakpoints available */
+}
+
+/*
+ * Install a perf counter breakpoint.
+ *
+ * We seek a free debug address register and use it for this
+ * breakpoint.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+int arch_install_hw_breakpoint(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+ *slot = bp;
+
+ /*
+ * Do not install DABR values if the instruction must be single-stepped.
+ * If so, DABR will be populated in single_step_dabr_instruction().
+ */
+ if (current->thread.last_hit_ubp != bp)
+ set_dabr(info->address | info->type | DABR_TRANSLATION);
+
+ return 0;
+}
+
+/*
+ * Uninstall the breakpoint contained in the given counter.
+ *
+ * First we search the debug address register it uses and then we disable
+ * it.
+ *
+ * Atomic: we hold the counter->ctx->lock and we only handle variables
+ * and registers local to this cpu.
+ */
+void arch_uninstall_hw_breakpoint(struct perf_event *bp)
+{
+ struct perf_event **slot = &__get_cpu_var(bp_per_reg);
+
+ if (*slot != bp) {
+ WARN_ONCE(1, "Can't find the breakpoint");
+ return;
+ }
+
+ *slot = NULL;
+ set_dabr(0);
+}
+
+/*
+ * Perform cleanup of arch-specific counters during unregistration
+ * of the perf-event
+ */
+void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+ /*
+ * If the breakpoint is unregistered between a hw_breakpoint_handler()
+ * and the single_step_dabr_instruction(), then cleanup the breakpoint
+ * restoration variables to prevent dangling pointers.
+ */
+ if (bp->ctx->task)
+ bp->ctx->task->thread.last_hit_ubp = NULL;
+}
+
+/*
+ * Check for virtual address in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct perf_event *bp)
+{
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ return is_kernel_addr(info->address);
+}
+
+int arch_bp_generic_fields(int type, int *gen_bp_type)
+{
+ switch (type) {
+ case DABR_DATA_READ:
+ *gen_bp_type = HW_BREAKPOINT_R;
+ break;
+ case DABR_DATA_WRITE:
+ *gen_bp_type = HW_BREAKPOINT_W;
+ break;
+ case (DABR_DATA_WRITE | DABR_DATA_READ):
+ *gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ * Validate the arch-specific HW Breakpoint register settings
+ */
+int arch_validate_hwbkpt_settings(struct perf_event *bp)
+{
+ int ret = -EINVAL;
+ struct arch_hw_breakpoint *info = counter_arch_bp(bp);
+
+ if (!bp)
+ return ret;
+
+ switch (bp->attr.bp_type) {
+ case HW_BREAKPOINT_R:
+ info->type = DABR_DATA_READ;
+ break;
+ case HW_BREAKPOINT_W:
+ info->type = DABR_DATA_WRITE;
+ break;
+ case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
+ info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
+ break;
+ default:
+ return ret;
+ }
+
+ info->address = bp->attr.bp_addr;
+ info->len = bp->attr.bp_len;
+
+ /*
+ * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
+ * and breakpoint addresses are aligned to nearest double-word
+ * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the
+ * 'symbolsize' should satisfy the check below.
+ */
+ if (info->len >
+ (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN)))
+ return -EINVAL;
+ return 0;
+}
+
+/*
+ * Restores the breakpoint on the debug registers.
+ * Invoke this function if it is known that the execution context is
+ * about to change to cause loss of MSR_SE settings.
+ */
+void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
+{
+ struct arch_hw_breakpoint *info;
+
+ if (likely(!tsk->thread.last_hit_ubp))
+ return;
+
+ info = counter_arch_bp(tsk->thread.last_hit_ubp);
+ regs->msr &= ~MSR_SE;
+ set_dabr(info->address | info->type | DABR_TRANSLATION);
+ tsk->thread.last_hit_ubp = NULL;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_handler(struct die_args *args)
+{
+ int rc = NOTIFY_STOP;
+ struct perf_event *bp;
+ struct pt_regs *regs = args->regs;
+ int stepped = 1;
+ struct arch_hw_breakpoint *info;
+ unsigned int instr;
+ unsigned long dar = regs->dar;
+
+ /* Disable breakpoints during exception handling */
+ set_dabr(0);
+
+ /*
+ * The counter may be concurrently released but that can only
+ * occur from a call_rcu() path. We can then safely fetch
+ * the breakpoint, use its callback, touch its counter
+ * while we are in an rcu_read_lock() path.
+ */
+ rcu_read_lock();
+
+ bp = __get_cpu_var(bp_per_reg);
+ if (!bp)
+ goto out;
+ info = counter_arch_bp(bp);
+
+ /*
+ * Return early after invoking user-callback function without restoring
+ * DABR if the breakpoint is from ptrace which always operates in
+ * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
+ * generated in do_dabr().
+ */
+ if (bp->overflow_handler == ptrace_triggered) {
+ perf_bp_event(bp, regs);
+ rc = NOTIFY_DONE;
+ goto out;
+ }
+
+ /*
+ * Verify if dar lies within the address range occupied by the symbol
+ * being watched to filter extraneous exceptions. If it doesn't,
+ * we still need to single-step the instruction, but we don't
+ * generate an event.
+ */
+ info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) &&
+ (dar - bp->attr.bp_addr < bp->attr.bp_len));
+
+ /* Do not emulate user-space instructions, instead single-step them */
+ if (user_mode(regs)) {
+ bp->ctx->task->thread.last_hit_ubp = bp;
+ regs->msr |= MSR_SE;
+ goto out;
+ }
+
+ stepped = 0;
+ instr = 0;
+ if (!__get_user_inatomic(instr, (unsigned int *) regs->nip))
+ stepped = emulate_step(regs, instr);
+
+ /*
+ * emulate_step() could not execute it. We've failed in reliably
+ * handling the hw-breakpoint. Unregister it and throw a warning
+ * message to let the user know about it.
+ */
+ if (!stepped) {
+ WARN(1, "Unable to handle hardware breakpoint. Breakpoint at "
+ "0x%lx will be disabled.", info->address);
+ perf_event_disable(bp);
+ goto out;
+ }
+ /*
+ * As a policy, the callback is invoked in a 'trigger-after-execute'
+ * fashion
+ */
+ if (!info->extraneous_interrupt)
+ perf_bp_event(bp, regs);
+
+ set_dabr(info->address | info->type | DABR_TRANSLATION);
+out:
+ rcu_read_unlock();
+ return rc;
+}
+
+/*
+ * Handle single-step exceptions following a DABR hit.
+ */
+int __kprobes single_step_dabr_instruction(struct die_args *args)
+{
+ struct pt_regs *regs = args->regs;
+ struct perf_event *bp = NULL;
+ struct arch_hw_breakpoint *bp_info;
+
+ bp = current->thread.last_hit_ubp;
+ /*
+ * Check if we are single-stepping as a result of a
+ * previous HW Breakpoint exception
+ */
+ if (!bp)
+ return NOTIFY_DONE;
+
+ bp_info = counter_arch_bp(bp);
+
+ /*
+ * We shall invoke the user-defined callback function in the single
+ * stepping handler to confirm to 'trigger-after-execute' semantics
+ */
+ if (!bp_info->extraneous_interrupt)
+ perf_bp_event(bp, regs);
+
+ set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
+ current->thread.last_hit_ubp = NULL;
+
+ /*
+ * If the process was being single-stepped by ptrace, let the
+ * other single-step actions occur (e.g. generate SIGTRAP).
+ */
+ if (test_thread_flag(TIF_SINGLESTEP))
+ return NOTIFY_DONE;
+
+ return NOTIFY_STOP;
+}
+
+/*
+ * Handle debug exception notifications.
+ */
+int __kprobes hw_breakpoint_exceptions_notify(
+ struct notifier_block *unused, unsigned long val, void *data)
+{
+ int ret = NOTIFY_DONE;
+
+ switch (val) {
+ case DIE_DABR_MATCH:
+ ret = hw_breakpoint_handler(data);
+ break;
+ case DIE_SSTEP:
+ ret = single_step_dabr_instruction(data);
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * Release the user breakpoints used by ptrace
+ */
+void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
+{
+ struct thread_struct *t = &tsk->thread;
+
+ unregister_hw_breakpoint(t->ptrace_bps[0]);
+ t->ptrace_bps[0] = NULL;
+}
+
+void hw_breakpoint_pmu_read(struct perf_event *bp)
+{
+ /* TODO */
+}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index ed31a29c4ff7..de6b70eac51d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -25,6 +25,7 @@
#include <asm/sections.h> /* _end */
#include <asm/prom.h>
#include <asm/smp.h>
+#include <asm/hw_breakpoint.h>
int default_machine_kexec_prepare(struct kimage *image)
{
@@ -165,6 +166,7 @@ static void kexec_smp_down(void *arg)
while(kexec_all_irq_disabled == 0)
cpu_relax();
mb(); /* make sure all irqs are disabled before this */
+ hw_breakpoint_disable();
/*
* Now every CPU has IRQs off, we can clear out any pending
* IPIs and be sure that no more will come in after this.
@@ -180,6 +182,7 @@ static void kexec_prepare_cpus_wait(int wait_state)
{
int my_cpu, i, notified=-1;
+ hw_breakpoint_disable();
my_cpu = get_cpu();
/* Make sure each CPU has atleast made it to the state we need */
for_each_online_cpu(i) {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 773424df828a..1e78453645be 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,6 +37,7 @@
#include <linux/kernel_stat.h>
#include <linux/personality.h>
#include <linux/random.h>
+#include <linux/hw_breakpoint.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -462,8 +463,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
switch_booke_debug_regs(&new->thread);
#else
+/*
+ * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
+ * schedule DABR
+ */
+#ifndef CONFIG_HAVE_HW_BREAKPOINT
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
set_dabr(new->thread.dabr);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
#endif
@@ -642,7 +649,11 @@ void flush_thread(void)
{
discard_lazy_cpu_state();
+#ifdef CONFIG_HAVE_HW_BREAKPOINTS
+ flush_ptrace_hw_breakpoint(current);
+#else /* CONFIG_HAVE_HW_BREAKPOINTS */
set_debug_reg_defaults(&current->thread);
+#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
}
void
@@ -660,6 +671,9 @@ void prepare_to_copy(struct task_struct *tsk)
flush_altivec_to_thread(current);
flush_vsx_to_thread(current);
flush_spe_to_thread(current);
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ flush_ptrace_hw_breakpoint(tsk);
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
}
/*
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 7a0c0199ea28..11f3cd9c832f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -32,6 +32,8 @@
#ifdef CONFIG_PPC32
#include <linux/module.h>
#endif
+#include <linux/hw_breakpoint.h>
+#include <linux/perf_event.h>
#include <asm/uaccess.h>
#include <asm/page.h>
@@ -866,9 +868,34 @@ void user_disable_single_step(struct task_struct *task)
clear_tsk_thread_flag(task, TIF_SINGLESTEP);
}
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+void ptrace_triggered(struct perf_event *bp, int nmi,
+ struct perf_sample_data *data, struct pt_regs *regs)
+{
+ struct perf_event_attr attr;
+
+ /*
+ * Disable the breakpoint request here since ptrace has defined a
+ * one-shot behaviour for breakpoint exceptions in PPC64.
+ * The SIGTRAP signal is generated automatically for us in do_dabr().
+ * We don't have to do anything about that here
+ */
+ attr = bp->attr;
+ attr.disabled = true;
+ modify_user_hw_breakpoint(bp, &attr);
+}
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
unsigned long data)
{
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ int ret;
+ struct thread_struct *thread = &(task->thread);
+ struct perf_event *bp;
+ struct perf_event_attr attr;
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
+
/* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
* For embedded processors we support one DAC and no IAC's at the
* moment.
@@ -896,6 +923,43 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
/* Ensure breakpoint translation bit is set */
if (data && !(data & DABR_TRANSLATION))
return -EIO;
+#ifdef CONFIG_HAVE_HW_BREAKPOINT
+ bp = thread->ptrace_bps[0];
+ if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
+ if (bp) {
+ unregister_hw_breakpoint(bp);
+ thread->ptrace_bps[0] = NULL;
+ }
+ return 0;
+ }
+ if (bp) {
+ attr = bp->attr;
+ attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+ arch_bp_generic_fields(data &
+ (DABR_DATA_WRITE | DABR_DATA_READ),
+ &attr.bp_type);
+ ret = modify_user_hw_breakpoint(bp, &attr);
+ if (ret)
+ return ret;
+ thread->ptrace_bps[0] = bp;
+ thread->dabr = data;
+ return 0;
+ }
+
+ /* Create a new breakpoint request if one doesn't exist already */
+ hw_breakpoint_init(&attr);
+ attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
+ arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ),
+ &attr.bp_type);
+
+ thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
+ ptrace_triggered, task);
+ if (IS_ERR(bp)) {
+ thread->ptrace_bps[0] = NULL;
+ return PTR_ERR(bp);
+ }
+
+#endif /* CONFIG_HAVE_HW_BREAKPOINT */
/* Move contents to the DABR register */
task->thread.dabr = data;
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 0e1ec6f746f6..41cfde0ca11b 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -47,14 +47,6 @@ struct rtas_t rtas = {
};
EXPORT_SYMBOL(rtas);
-struct rtas_suspend_me_data {
- atomic_t working; /* number of cpus accessing this struct */
- atomic_t done;
- int token; /* ibm,suspend-me */
- int error;
- struct completion *complete; /* wait on this until working == 0 */
-};
-
DEFINE_SPINLOCK(rtas_data_buf_lock);
EXPORT_SYMBOL(rtas_data_buf_lock);
@@ -714,14 +706,53 @@ void rtas_os_term(char *str)
static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
#ifdef CONFIG_PPC_PSERIES
-static void rtas_percpu_suspend_me(void *info)
+static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
+{
+ u16 slb_size = mmu_slb_size;
+ int rc = H_MULTI_THREADS_ACTIVE;
+ int cpu;
+
+ slb_set_size(SLB_MIN_SIZE);
+ printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id());
+
+ while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) &&
+ !atomic_read(&data->error))
+ rc = rtas_call(data->token, 0, 1, NULL);
+
+ if (rc || atomic_read(&data->error)) {
+ printk(KERN_DEBUG "ibm,suspend-me returned %d\n", rc);
+ slb_set_size(slb_size);
+ }
+
+ if (atomic_read(&data->error))
+ rc = atomic_read(&data->error);
+
+ atomic_set(&data->error, rc);
+
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
+
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
+
+ if (atomic_dec_return(&data->working) == 0)
+ complete(data->complete);
+
+ return rc;
+}
+
+int rtas_suspend_last_cpu(struct rtas_suspend_me_data *data)
+{
+ atomic_inc(&data->working);
+ return __rtas_suspend_last_cpu(data, 0);
+}
+
+static int __rtas_suspend_cpu(struct rtas_suspend_me_data *data, int wake_when_done)
{
long rc = H_SUCCESS;
unsigned long msr_save;
- u16 slb_size = mmu_slb_size;
int cpu;
- struct rtas_suspend_me_data *data =
- (struct rtas_suspend_me_data *)info;
atomic_inc(&data->working);
@@ -729,7 +760,7 @@ static void rtas_percpu_suspend_me(void *info)
msr_save = mfmsr();
mtmsr(msr_save & ~(MSR_EE));
- while (rc == H_SUCCESS && !atomic_read(&data->done))
+ while (rc == H_SUCCESS && !atomic_read(&data->done) && !atomic_read(&data->error))
rc = plpar_hcall_norets(H_JOIN);
mtmsr(msr_save);
@@ -741,33 +772,37 @@ static void rtas_percpu_suspend_me(void *info)
/* All other cpus are in H_JOIN, this cpu does
* the suspend.
*/
- slb_set_size(SLB_MIN_SIZE);
- printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n",
- smp_processor_id());
- data->error = rtas_call(data->token, 0, 1, NULL);
-
- if (data->error) {
- printk(KERN_DEBUG "ibm,suspend-me returned %d\n",
- data->error);
- slb_set_size(slb_size);
- }
+ return __rtas_suspend_last_cpu(data, wake_when_done);
} else {
printk(KERN_ERR "H_JOIN on cpu %i failed with rc = %ld\n",
smp_processor_id(), rc);
- data->error = rc;
+ atomic_set(&data->error, rc);
}
- atomic_set(&data->done, 1);
+ if (wake_when_done) {
+ atomic_set(&data->done, 1);
- /* This cpu did the suspend or got an error; in either case,
- * we need to prod all other other cpus out of join state.
- * Extra prods are harmless.
- */
- for_each_online_cpu(cpu)
- plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ /* This cpu did the suspend or got an error; in either case,
+ * we need to prod all other other cpus out of join state.
+ * Extra prods are harmless.
+ */
+ for_each_online_cpu(cpu)
+ plpar_hcall_norets(H_PROD, get_hard_smp_processor_id(cpu));
+ }
out:
if (atomic_dec_return(&data->working) == 0)
complete(data->complete);
+ return rc;
+}
+
+int rtas_suspend_cpu(struct rtas_suspend_me_data *data)
+{
+ return __rtas_suspend_cpu(data, 0);
+}
+
+static void rtas_percpu_suspend_me(void *info)
+{
+ __rtas_suspend_cpu((struct rtas_suspend_me_data *)info, 1);
}
static int rtas_ibm_suspend_me(struct rtas_args *args)
@@ -802,22 +837,22 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
atomic_set(&data.working, 0);
atomic_set(&data.done, 0);
+ atomic_set(&data.error, 0);
data.token = rtas_token("ibm,suspend-me");
- data.error = 0;
data.complete = &done;
/* Call function on all CPUs. One of us will make the
* rtas call
*/
if (on_each_cpu(rtas_percpu_suspend_me, &data, 0))
- data.error = -EINVAL;
+ atomic_set(&data.error, -EINVAL);
wait_for_completion(&done);
- if (data.error != 0)
+ if (atomic_read(&data.error) != 0)
printk(KERN_ERR "Error doing global join\n");
- return data.error;
+ return atomic_read(&data.error);
}
#else /* CONFIG_PPC_PSERIES */
static int rtas_ibm_suspend_me(struct rtas_args *args)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 5e4d852f640c..8b6ada66060b 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -94,6 +94,10 @@ struct screen_info screen_info = {
.orig_video_points = 16
};
+/* Variables required to store legacy IO irq routing */
+int of_i8042_kbd_irq;
+int of_i8042_aux_irq;
+
#ifdef __DO_IRQ_CANON
/* XXX should go elsewhere eventually */
int ppc_do_canonicalize_irqs;
@@ -575,6 +579,15 @@ int check_legacy_ioport(unsigned long base_port)
np = of_find_compatible_node(NULL, NULL, "pnpPNP,f03");
if (np) {
parent = of_get_parent(np);
+
+ of_i8042_kbd_irq = irq_of_parse_and_map(parent, 0);
+ if (!of_i8042_kbd_irq)
+ of_i8042_kbd_irq = 1;
+
+ of_i8042_aux_irq = irq_of_parse_and_map(parent, 1);
+ if (!of_i8042_aux_irq)
+ of_i8042_aux_irq = 12;
+
of_node_put(np);
np = parent;
break;
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 643dcac40fcb..c352f322dbdd 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -600,6 +600,9 @@ static int pcpu_cpu_distance(unsigned int from, unsigned int to)
return REMOTE_DISTANCE;
}
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+EXPORT_SYMBOL(__per_cpu_offset);
+
void __init setup_per_cpu_areas(void)
{
const size_t dyn_size = PERCPU_MODULE_RESERVE + PERCPU_DYNAMIC_RESERVE;
@@ -624,8 +627,10 @@ void __init setup_per_cpu_areas(void)
panic("cannot initialize percpu area (err=%d)", rc);
delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
- for_each_possible_cpu(cpu)
- paca[cpu].data_offset = delta + pcpu_unit_offsets[cpu];
+ for_each_possible_cpu(cpu) {
+ __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
+ paca[cpu].data_offset = __per_cpu_offset[cpu];
+ }
}
#endif
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a0afb555a7c9..7109f5b1baa8 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/tracehook.h>
#include <linux/signal.h>
+#include <asm/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
if (current->thread.dabr)
set_dabr(current->thread.dabr);
#endif
+ /* Re-enable the breakpoints for the signal stack */
+ thread_change_pc(current, regs);
if (is32) {
if (ka.sa.sa_flags & SA_SIGINFO)
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 5c196d1086d9..8764daad309b 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -288,8 +288,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = NR_CPUS;
else
max_cpus = 1;
-
- smp_space_timers(max_cpus);
for_each_possible_cpu(cpu)
if (cpu != boot_cpuid)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 0441bbdadbd1..ccb8759c8532 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -149,16 +149,6 @@ unsigned long tb_ticks_per_usec = 100; /* sane default */
EXPORT_SYMBOL(tb_ticks_per_usec);
unsigned long tb_ticks_per_sec;
EXPORT_SYMBOL(tb_ticks_per_sec); /* for cputime_t conversions */
-u64 tb_to_xs;
-unsigned tb_to_us;
-
-#define TICKLEN_SCALE NTP_SCALE_SHIFT
-static u64 last_tick_len; /* units are ns / 2^TICKLEN_SCALE */
-static u64 ticklen_to_xs; /* 0.64 fraction */
-
-/* If last_tick_len corresponds to about 1/HZ seconds, then
- last_tick_len << TICKLEN_SHIFT will be about 2^63. */
-#define TICKLEN_SHIFT (63 - 30 - TICKLEN_SCALE + SHIFT_HZ)
DEFINE_SPINLOCK(rtc_lock);
EXPORT_SYMBOL_GPL(rtc_lock);
@@ -174,7 +164,6 @@ unsigned long ppc_proc_freq;
EXPORT_SYMBOL(ppc_proc_freq);
unsigned long ppc_tb_freq;
-static u64 tb_last_jiffy __cacheline_aligned_in_smp;
static DEFINE_PER_CPU(u64, last_jiffy);
#ifdef CONFIG_VIRT_CPU_ACCOUNTING
@@ -423,30 +412,6 @@ void udelay(unsigned long usecs)
}
EXPORT_SYMBOL(udelay);
-static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
- u64 new_tb_to_xs)
-{
- /*
- * tb_update_count is used to allow the userspace gettimeofday code
- * to assure itself that it sees a consistent view of the tb_to_xs and
- * stamp_xsec variables. It reads the tb_update_count, then reads
- * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
- * the two values of tb_update_count match and are even then the
- * tb_to_xs and stamp_xsec values are consistent. If not, then it
- * loops back and reads them again until this criteria is met.
- * We expect the caller to have done the first increment of
- * vdso_data->tb_update_count already.
- */
- vdso_data->tb_orig_stamp = new_tb_stamp;
- vdso_data->stamp_xsec = new_stamp_xsec;
- vdso_data->tb_to_xs = new_tb_to_xs;
- vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
- vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
- vdso_data->stamp_xtime = xtime;
- smp_wmb();
- ++(vdso_data->tb_update_count);
-}
-
#ifdef CONFIG_SMP
unsigned long profile_pc(struct pt_regs *regs)
{
@@ -470,7 +435,6 @@ EXPORT_SYMBOL(profile_pc);
static int __init iSeries_tb_recal(void)
{
- struct div_result divres;
unsigned long titan, tb;
/* Make sure we only run on iSeries */
@@ -501,10 +465,7 @@ static int __init iSeries_tb_recal(void)
tb_ticks_per_jiffy = new_tb_ticks_per_jiffy;
tb_ticks_per_sec = new_tb_ticks_per_sec;
calc_cputime_factors();
- div128_by_32( XSEC_PER_SEC, 0, tb_ticks_per_sec, &divres );
- tb_to_xs = divres.result_low;
vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
- vdso_data->tb_to_xs = tb_to_xs;
setup_cputime_one_jiffy();
}
else {
@@ -667,27 +628,9 @@ void timer_interrupt(struct pt_regs * regs)
trace_timer_interrupt_exit(regs);
}
-void wakeup_decrementer(void)
-{
- unsigned long ticks;
-
- /*
- * The timebase gets saved on sleep and restored on wakeup,
- * so all we need to do is to reset the decrementer.
- */
- ticks = tb_ticks_since(__get_cpu_var(last_jiffy));
- if (ticks < tb_ticks_per_jiffy)
- ticks = tb_ticks_per_jiffy - ticks;
- else
- ticks = 1;
- set_dec(ticks);
-}
-
#ifdef CONFIG_SUSPEND
-void generic_suspend_disable_irqs(void)
+static void generic_suspend_disable_irqs(void)
{
- preempt_disable();
-
/* Disable the decrementer, so that it doesn't interfere
* with suspending.
*/
@@ -697,12 +640,9 @@ void generic_suspend_disable_irqs(void)
set_dec(0x7fffffff);
}
-void generic_suspend_enable_irqs(void)
+static void generic_suspend_enable_irqs(void)
{
- wakeup_decrementer();
-
local_irq_enable();
- preempt_enable();
}
/* Overrides the weak version in kernel/power/main.c */
@@ -722,23 +662,6 @@ void arch_suspend_enable_irqs(void)
}
#endif
-#ifdef CONFIG_SMP
-void __init smp_space_timers(unsigned int max_cpus)
-{
- int i;
- u64 previous_tb = per_cpu(last_jiffy, boot_cpuid);
-
- /* make sure tb > per_cpu(last_jiffy, cpu) for all cpus always */
- previous_tb -= tb_ticks_per_jiffy;
-
- for_each_possible_cpu(i) {
- if (i == boot_cpuid)
- continue;
- per_cpu(last_jiffy, i) = previous_tb;
- }
-}
-#endif
-
/*
* Scheduler clock - returns current time in nanosec units.
*
@@ -873,10 +796,37 @@ static cycle_t timebase_read(struct clocksource *cs)
return (cycle_t)get_tb();
}
+static inline void update_gtod(u64 new_tb_stamp, u64 new_stamp_xsec,
+ u64 new_tb_to_xs, struct timespec *now,
+ u32 frac_sec)
+{
+ /*
+ * tb_update_count is used to allow the userspace gettimeofday code
+ * to assure itself that it sees a consistent view of the tb_to_xs and
+ * stamp_xsec variables. It reads the tb_update_count, then reads
+ * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
+ * the two values of tb_update_count match and are even then the
+ * tb_to_xs and stamp_xsec values are consistent. If not, then it
+ * loops back and reads them again until this criteria is met.
+ * We expect the caller to have done the first increment of
+ * vdso_data->tb_update_count already.
+ */
+ vdso_data->tb_orig_stamp = new_tb_stamp;
+ vdso_data->stamp_xsec = new_stamp_xsec;
+ vdso_data->tb_to_xs = new_tb_to_xs;
+ vdso_data->wtom_clock_sec = wall_to_monotonic.tv_sec;
+ vdso_data->wtom_clock_nsec = wall_to_monotonic.tv_nsec;
+ vdso_data->stamp_xtime = *now;
+ vdso_data->stamp_sec_fraction = frac_sec;
+ smp_wmb();
+ ++(vdso_data->tb_update_count);
+}
+
void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
u32 mult)
{
u64 t2x, stamp_xsec;
+ u32 frac_sec;
if (clock != &clocksource_timebase)
return;
@@ -888,10 +838,14 @@ void update_vsyscall(struct timespec *wall_time, struct clocksource *clock,
/* XXX this assumes clock->shift == 22 */
/* 4611686018 ~= 2^(20+64-22) / 1e9 */
t2x = (u64) mult * 4611686018ULL;
- stamp_xsec = (u64) xtime.tv_nsec * XSEC_PER_SEC;
+ stamp_xsec = (u64) wall_time->tv_nsec * XSEC_PER_SEC;
do_div(stamp_xsec, 1000000000);
- stamp_xsec += (u64) xtime.tv_sec * XSEC_PER_SEC;
- update_gtod(clock->cycle_last, stamp_xsec, t2x);
+ stamp_xsec += (u64) wall_time->tv_sec * XSEC_PER_SEC;
+
+ BUG_ON(wall_time->tv_nsec >= NSEC_PER_SEC);
+ /* this is tv_nsec / 1e9 as a 0.32 fraction */
+ frac_sec = ((u64) wall_time->tv_nsec * 18446744073ULL) >> 32;
+ update_gtod(clock->cycle_last, stamp_xsec, t2x, wall_time, frac_sec);
}
void update_vsyscall_tz(void)
@@ -1007,15 +961,13 @@ void secondary_cpu_time_init(void)
/* This function is only called on the boot processor */
void __init time_init(void)
{
- unsigned long flags;
struct div_result res;
- u64 scale, x;
+ u64 scale;
unsigned shift;
if (__USE_RTC()) {
/* 601 processor: dec counts down by 128 every 128ns */
ppc_tb_freq = 1000000000;
- tb_last_jiffy = get_rtcl();
} else {
/* Normal PowerPC with timebase register */
ppc_md.calibrate_decr();
@@ -1023,50 +975,15 @@ void __init time_init(void)
ppc_tb_freq / 1000000, ppc_tb_freq % 1000000);
printk(KERN_DEBUG "time_init: processor frequency = %lu.%.6lu MHz\n",
ppc_proc_freq / 1000000, ppc_proc_freq % 1000000);
- tb_last_jiffy = get_tb();
}
tb_ticks_per_jiffy = ppc_tb_freq / HZ;
tb_ticks_per_sec = ppc_tb_freq;
tb_ticks_per_usec = ppc_tb_freq / 1000000;
- tb_to_us = mulhwu_scale_factor(ppc_tb_freq, 1000000);
calc_cputime_factors();
setup_cputime_one_jiffy();
/*
- * Calculate the length of each tick in ns. It will not be
- * exactly 1e9/HZ unless ppc_tb_freq is divisible by HZ.
- * We compute 1e9 * tb_ticks_per_jiffy / ppc_tb_freq,
- * rounded up.
- */
- x = (u64) NSEC_PER_SEC * tb_ticks_per_jiffy + ppc_tb_freq - 1;
- do_div(x, ppc_tb_freq);
- tick_nsec = x;
- last_tick_len = x << TICKLEN_SCALE;
-
- /*
- * Compute ticklen_to_xs, which is a factor which gets multiplied
- * by (last_tick_len << TICKLEN_SHIFT) to get a tb_to_xs value.
- * It is computed as:
- * ticklen_to_xs = 2^N / (tb_ticks_per_jiffy * 1e9)
- * where N = 64 + 20 - TICKLEN_SCALE - TICKLEN_SHIFT
- * which turns out to be N = 51 - SHIFT_HZ.
- * This gives the result as a 0.64 fixed-point fraction.
- * That value is reduced by an offset amounting to 1 xsec per
- * 2^31 timebase ticks to avoid problems with time going backwards
- * by 1 xsec when we do timer_recalc_offset due to losing the
- * fractional xsec. That offset is equal to ppc_tb_freq/2^51
- * since there are 2^20 xsec in a second.
- */
- div128_by_32((1ULL << 51) - ppc_tb_freq, 0,
- tb_ticks_per_jiffy << SHIFT_HZ, &res);
- div128_by_32(res.result_high, res.result_low, NSEC_PER_SEC, &res);
- ticklen_to_xs = res.result_low;
-
- /* Compute tb_to_xs from tick_nsec */
- tb_to_xs = mulhdu(last_tick_len << TICKLEN_SHIFT, ticklen_to_xs);
-
- /*
* Compute scale factor for sched_clock.
* The calibrate_decr() function has set tb_ticks_per_sec,
* which is the timebase frequency.
@@ -1087,21 +1004,14 @@ void __init time_init(void)
/* Save the current timebase to pretty up CONFIG_PRINTK_TIME */
boot_tb = get_tb_or_rtc();
- write_seqlock_irqsave(&xtime_lock, flags);
-
/* If platform provided a timezone (pmac), we correct the time */
if (timezone_offset) {
sys_tz.tz_minuteswest = -timezone_offset / 60;
sys_tz.tz_dsttime = 0;
}
- vdso_data->tb_orig_stamp = tb_last_jiffy;
vdso_data->tb_update_count = 0;
vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
- vdso_data->stamp_xsec = (u64) xtime.tv_sec * XSEC_PER_SEC;
- vdso_data->tb_to_xs = tb_to_xs;
-
- write_sequnlock_irqrestore(&xtime_lock, flags);
/* Start the decrementer on CPUs that have manual control
* such as BookE
@@ -1195,39 +1105,6 @@ void to_tm(int tim, struct rtc_time * tm)
GregorianDay(tm);
}
-/* Auxiliary function to compute scaling factors */
-/* Actually the choice of a timebase running at 1/4 the of the bus
- * frequency giving resolution of a few tens of nanoseconds is quite nice.
- * It makes this computation very precise (27-28 bits typically) which
- * is optimistic considering the stability of most processor clock
- * oscillators and the precision with which the timebase frequency
- * is measured but does not harm.
- */
-unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale)
-{
- unsigned mlt=0, tmp, err;
- /* No concern for performance, it's done once: use a stupid
- * but safe and compact method to find the multiplier.
- */
-
- for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
- if (mulhwu(inscale, mlt|tmp) < outscale)
- mlt |= tmp;
- }
-
- /* We might still be off by 1 for the best approximation.
- * A side effect of this is that if outscale is too large
- * the returned value will be zero.
- * Many corner cases have been checked and seem to work,
- * some might have been forgotten in the test however.
- */
-
- err = inscale * (mlt+1);
- if (err <= inscale/2)
- mlt++;
- return mlt;
-}
-
/*
* Divide a 128-bit dividend by a 32-bit divisor, leaving a 128 bit
* result.
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 25fc33984c2b..e5fe5a8522a6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -688,7 +688,7 @@ void RunModeException(struct pt_regs *regs)
void __kprobes single_step_exception(struct pt_regs *regs)
{
- regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */
+ clear_single_step(regs);
if (notify_die(DIE_SSTEP, "single_step", regs, 5,
5, SIGTRAP) == NOTIFY_STOP)
@@ -707,10 +707,8 @@ void __kprobes single_step_exception(struct pt_regs *regs)
*/
static void emulate_single_step(struct pt_regs *regs)
{
- if (single_stepping(regs)) {
- clear_single_step(regs);
- _exception(SIGTRAP, regs, TRAP_TRACE, 0);
- }
+ if (single_stepping(regs))
+ single_step_exception(regs);
}
static inline int __parse_fpscr(unsigned long fpscr)
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index ee038d4bf252..4ee09ee2e836 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -19,8 +19,10 @@
/* Offset for the low 32-bit part of a field of long type */
#ifdef CONFIG_PPC64
#define LOPART 4
+#define TSPEC_TV_SEC TSPC64_TV_SEC+LOPART
#else
#define LOPART 0
+#define TSPEC_TV_SEC TSPC32_TV_SEC
#endif
.text
@@ -41,23 +43,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
mr r9, r3 /* datapage ptr in r9 */
cmplwi r10,0 /* check if tv is NULL */
beq 3f
- bl __do_get_xsec@local /* get xsec from tb & kernel */
- bne- 2f /* out of line -> do syscall */
-
- /* seconds are xsec >> 20 */
- rlwinm r5,r4,12,20,31
- rlwimi r5,r3,12,0,19
- stw r5,TVAL32_TV_SEC(r10)
-
- /* get remaining xsec and convert to usec. we scale
- * up remaining xsec by 12 bits and get the top 32 bits
- * of the multiplication
- */
- rlwinm r5,r4,12,0,19
- lis r6,1000000@h
- ori r6,r6,1000000@l
- mulhwu r5,r5,r6
- stw r5,TVAL32_TV_USEC(r10)
+ lis r7,1000000@ha /* load up USEC_PER_SEC */
+ addi r7,r7,1000000@l /* so we get microseconds in r4 */
+ bl __do_get_tspec@local /* get sec/usec from tb & kernel */
+ stw r3,TVAL32_TV_SEC(r10)
+ stw r4,TVAL32_TV_USEC(r10)
3: cmplwi r11,0 /* check if tz is NULL */
beq 1f
@@ -70,14 +60,6 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
crclr cr0*4+so
li r3,0
blr
-
-2:
- mtlr r12
- mr r3,r10
- mr r4,r11
- li r0,__NR_gettimeofday
- sc
- blr
.cfi_endproc
V_FUNCTION_END(__kernel_gettimeofday)
@@ -100,7 +82,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
mr r11,r4 /* r11 saves tp */
bl __get_datapage@local /* get data page */
mr r9,r3 /* datapage ptr in r9 */
-
+ lis r7,NSEC_PER_SEC@h /* want nanoseconds */
+ ori r7,r7,NSEC_PER_SEC@l
50: bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
bne cr1,80f /* not monotonic -> all done */
@@ -198,83 +181,12 @@ V_FUNCTION_END(__kernel_clock_getres)
/*
- * This is the core of gettimeofday() & friends, it returns the xsec
- * value in r3 & r4 and expects the datapage ptr (non clobbered)
- * in r9. clobbers r0,r4,r5,r6,r7,r8.
- * When returning, r8 contains the counter value that can be reused
- * by the monotonic clock implementation
- */
-__do_get_xsec:
- .cfi_startproc
- /* Check for update count & load values. We use the low
- * order 32 bits of the update count
- */
-1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- andi. r0,r8,1 /* pending update ? loop */
- bne- 1b
- xor r0,r8,r8 /* create dependency */
- add r9,r9,r0
-
- /* Load orig stamp (offset to TB) */
- lwz r5,CFG_TB_ORIG_STAMP(r9)
- lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
-
- /* Get a stable TB value */
-2: mftbu r3
- mftbl r4
- mftbu r0
- cmpl cr0,r3,r0
- bne- 2b
-
- /* Substract tb orig stamp. If the high part is non-zero, we jump to
- * the slow path which call the syscall.
- * If it's ok, then we have our 32 bits tb_ticks value in r7
- */
- subfc r7,r6,r4
- subfe. r0,r5,r3
- bne- 3f
-
- /* Load scale factor & do multiplication */
- lwz r5,CFG_TB_TO_XS(r9) /* load values */
- lwz r6,(CFG_TB_TO_XS+4)(r9)
- mulhwu r4,r7,r5
- mulhwu r6,r7,r6
- mullw r0,r7,r5
- addc r6,r6,r0
-
- /* At this point, we have the scaled xsec value in r4 + XER:CA
- * we load & add the stamp since epoch
- */
- lwz r5,CFG_STAMP_XSEC(r9)
- lwz r6,(CFG_STAMP_XSEC+4)(r9)
- adde r4,r4,r6
- addze r3,r5
-
- /* We now have our result in r3,r4. We create a fake dependency
- * on that result and re-check the counter
- */
- or r6,r4,r3
- xor r0,r6,r6
- add r9,r9,r0
- lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- cmpl cr0,r8,r0 /* check if updated */
- bne- 1b
-
- /* Warning ! The caller expects CR:EQ to be set to indicate a
- * successful calculation (so it won't fallback to the syscall
- * method). We have overriden that CR bit in the counter check,
- * but fortunately, the loop exit condition _is_ CR:EQ set, so
- * we can exit safely here. If you change this code, be careful
- * of that side effect.
- */
-3: blr
- .cfi_endproc
-
-/*
- * This is the core of clock_gettime(), it returns the current
- * time in seconds and nanoseconds in r3 and r4.
+ * This is the core of clock_gettime() and gettimeofday(),
+ * it returns the current time in r3 (seconds) and r4.
+ * On entry, r7 gives the resolution of r4, either USEC_PER_SEC
+ * or NSEC_PER_SEC, giving r4 in microseconds or nanoseconds.
* It expects the datapage ptr in r9 and doesn't clobber it.
- * It clobbers r0, r5, r6, r10 and returns NSEC_PER_SEC in r7.
+ * It clobbers r0, r5 and r6.
* On return, r8 contains the counter value that can be reused.
* This clobbers cr0 but not any other cr field.
*/
@@ -297,70 +209,58 @@ __do_get_tspec:
2: mftbu r3
mftbl r4
mftbu r0
- cmpl cr0,r3,r0
+ cmplw cr0,r3,r0
bne- 2b
/* Subtract tb orig stamp and shift left 12 bits.
*/
- subfc r7,r6,r4
+ subfc r4,r6,r4
subfe r0,r5,r3
slwi r0,r0,12
- rlwimi. r0,r7,12,20,31
- slwi r7,r7,12
+ rlwimi. r0,r4,12,20,31
+ slwi r4,r4,12
- /* Load scale factor & do multiplication */
+ /*
+ * Load scale factor & do multiplication.
+ * We only use the high 32 bits of the tb_to_xs value.
+ * Even with a 1GHz timebase clock, the high 32 bits of
+ * tb_to_xs will be at least 4 million, so the error from
+ * ignoring the low 32 bits will be no more than 0.25ppm.
+ * The error will just make the clock run very very slightly
+ * slow until the next time the kernel updates the VDSO data,
+ * at which point the clock will catch up to the kernel's value,
+ * so there is no long-term error accumulation.
+ */
lwz r5,CFG_TB_TO_XS(r9) /* load values */
- lwz r6,(CFG_TB_TO_XS+4)(r9)
- mulhwu r3,r7,r6
- mullw r10,r7,r5
- mulhwu r4,r7,r5
- addc r10,r3,r10
+ mulhwu r4,r4,r5
li r3,0
beq+ 4f /* skip high part computation if 0 */
mulhwu r3,r0,r5
- mullw r7,r0,r5
- mulhwu r5,r0,r6
- mullw r6,r0,r6
- adde r4,r4,r7
- addze r3,r3
+ mullw r5,r0,r5
addc r4,r4,r5
addze r3,r3
- addc r10,r10,r6
-
-4: addze r4,r4 /* add in carry */
- lis r7,NSEC_PER_SEC@h
- ori r7,r7,NSEC_PER_SEC@l
- mulhwu r4,r4,r7 /* convert to nanoseconds */
-
- /* At this point, we have seconds & nanoseconds since the xtime
- * stamp in r3+CA and r4. Load & add the xtime stamp.
+4:
+ /* At this point, we have seconds since the xtime stamp
+ * as a 32.32 fixed-point number in r3 and r4.
+ * Load & add the xtime stamp.
*/
-#ifdef CONFIG_PPC64
- lwz r5,STAMP_XTIME+TSPC64_TV_SEC+LOPART(r9)
- lwz r6,STAMP_XTIME+TSPC64_TV_NSEC+LOPART(r9)
-#else
- lwz r5,STAMP_XTIME+TSPC32_TV_SEC(r9)
- lwz r6,STAMP_XTIME+TSPC32_TV_NSEC(r9)
-#endif
- add r4,r4,r6
+ lwz r5,STAMP_XTIME+TSPEC_TV_SEC(r9)
+ lwz r6,STAMP_SEC_FRAC(r9)
+ addc r4,r4,r6
adde r3,r3,r5
- /* We now have our result in r3,r4. We create a fake dependency
- * on that result and re-check the counter
+ /* We create a fake dependency on the result in r3/r4
+ * and re-check the counter
*/
or r6,r4,r3
xor r0,r6,r6
add r9,r9,r0
lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- cmpl cr0,r8,r0 /* check if updated */
+ cmplw cr0,r8,r0 /* check if updated */
bne- 1b
- /* check for nanosecond overflow and adjust if necessary */
- cmpw r4,r7
- bltlr /* all done if no overflow */
- subf r4,r7,r4 /* adjust if overflow */
- addi r3,r3,1
+ mulhwu r4,r4,r7 /* convert to micro or nanoseconds */
blr
.cfi_endproc
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index 262cd5857a56..e97a9a0dc4ac 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -33,18 +33,11 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
bl V_LOCAL_FUNC(__get_datapage) /* get data page */
cmpldi r11,0 /* check if tv is NULL */
beq 2f
- bl V_LOCAL_FUNC(__do_get_xsec) /* get xsec from tb & kernel */
- lis r7,15 /* r7 = 1000000 = USEC_PER_SEC */
- ori r7,r7,16960
- rldicl r5,r4,44,20 /* r5 = sec = xsec / XSEC_PER_SEC */
- rldicr r6,r5,20,43 /* r6 = sec * XSEC_PER_SEC */
- std r5,TVAL64_TV_SEC(r11) /* store sec in tv */
- subf r0,r6,r4 /* r0 = xsec = (xsec - r6) */
- mulld r0,r0,r7 /* usec = (xsec * USEC_PER_SEC) /
- * XSEC_PER_SEC
- */
- rldicl r0,r0,44,20
- std r0,TVAL64_TV_USEC(r11) /* store usec in tv */
+ lis r7,1000000@ha /* load up USEC_PER_SEC */
+ addi r7,r7,1000000@l
+ bl V_LOCAL_FUNC(__do_get_tspec) /* get sec/us from tb & kernel */
+ std r4,TVAL64_TV_SEC(r11) /* store sec in tv */
+ std r5,TVAL64_TV_USEC(r11) /* store usec in tv */
2: cmpldi r10,0 /* check if tz is NULL */
beq 1f
lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */
@@ -77,6 +70,8 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
.cfi_register lr,r12
mr r11,r4 /* r11 saves tp */
bl V_LOCAL_FUNC(__get_datapage) /* get data page */
+ lis r7,NSEC_PER_SEC@h /* want nanoseconds */
+ ori r7,r7,NSEC_PER_SEC@l
50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */
bne cr1,80f /* if not monotonic, all done */
@@ -171,49 +166,12 @@ V_FUNCTION_END(__kernel_clock_getres)
/*
- * This is the core of gettimeofday(), it returns the xsec
- * value in r4 and expects the datapage ptr (non clobbered)
- * in r3. clobbers r0,r4,r5,r6,r7,r8
- * When returning, r8 contains the counter value that can be reused
- */
-V_FUNCTION_BEGIN(__do_get_xsec)
- .cfi_startproc
- /* check for update count & load values */
-1: ld r8,CFG_TB_UPDATE_COUNT(r3)
- andi. r0,r8,1 /* pending update ? loop */
- bne- 1b
- xor r0,r8,r8 /* create dependency */
- add r3,r3,r0
-
- /* Get TB & offset it. We use the MFTB macro which will generate
- * workaround code for Cell.
- */
- MFTB(r7)
- ld r9,CFG_TB_ORIG_STAMP(r3)
- subf r7,r9,r7
-
- /* Scale result */
- ld r5,CFG_TB_TO_XS(r3)
- mulhdu r7,r7,r5
-
- /* Add stamp since epoch */
- ld r6,CFG_STAMP_XSEC(r3)
- add r4,r6,r7
-
- xor r0,r4,r4
- add r3,r3,r0
- ld r0,CFG_TB_UPDATE_COUNT(r3)
- cmpld cr0,r0,r8 /* check if updated */
- bne- 1b
- blr
- .cfi_endproc
-V_FUNCTION_END(__do_get_xsec)
-
-/*
- * This is the core of clock_gettime(), it returns the current
- * time in seconds and nanoseconds in r4 and r5.
+ * This is the core of clock_gettime() and gettimeofday(),
+ * it returns the current time in r4 (seconds) and r5.
+ * On entry, r7 gives the resolution of r5, either USEC_PER_SEC
+ * or NSEC_PER_SEC, giving r5 in microseconds or nanoseconds.
* It expects the datapage ptr in r3 and doesn't clobber it.
- * It clobbers r0 and r6 and returns NSEC_PER_SEC in r7.
+ * It clobbers r0, r6 and r9.
* On return, r8 contains the counter value that can be reused.
* This clobbers cr0 but not any other cr field.
*/
@@ -229,18 +187,18 @@ V_FUNCTION_BEGIN(__do_get_tspec)
/* Get TB & offset it. We use the MFTB macro which will generate
* workaround code for Cell.
*/
- MFTB(r7)
+ MFTB(r6)
ld r9,CFG_TB_ORIG_STAMP(r3)
- subf r7,r9,r7
+ subf r6,r9,r6
/* Scale result */
ld r5,CFG_TB_TO_XS(r3)
- sldi r7,r7,12 /* compute time since stamp_xtime */
- mulhdu r6,r7,r5 /* in units of 2^-32 seconds */
+ sldi r6,r6,12 /* compute time since stamp_xtime */
+ mulhdu r6,r6,r5 /* in units of 2^-32 seconds */
/* Add stamp since epoch */
ld r4,STAMP_XTIME+TSPC64_TV_SEC(r3)
- ld r5,STAMP_XTIME+TSPC64_TV_NSEC(r3)
+ lwz r5,STAMP_SEC_FRAC(r3)
or r0,r4,r5
or r0,r0,r6
xor r0,r0,r0
@@ -250,17 +208,11 @@ V_FUNCTION_BEGIN(__do_get_tspec)
bne- 1b /* reload if so */
/* convert to seconds & nanoseconds and add to stamp */
- lis r7,NSEC_PER_SEC@h
- ori r7,r7,NSEC_PER_SEC@l
- mulhwu r0,r6,r7 /* compute nanoseconds and */
+ add r6,r6,r5 /* add on fractional seconds of xtime */
+ mulhwu r5,r6,r7 /* compute micro or nanoseconds and */
srdi r6,r6,32 /* seconds since stamp_xtime */
- clrldi r0,r0,32
- add r5,r5,r0 /* add nanoseconds together */
- cmpd r5,r7 /* overflow? */
+ clrldi r5,r5,32
add r4,r4,r6
- bltlr /* all done if no overflow */
- subf r5,r7,r5 /* if overflow, adjust */
- addi r4,r4,1
blr
.cfi_endproc
V_FUNCTION_END(__do_get_tspec)
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 111da1c03a11..5bb89c828070 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -18,8 +18,9 @@ obj-$(CONFIG_HAS_IOMEM) += devres.o
obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \
memcpy_64.o usercopy_64.o mem_64.o string.o
-obj-$(CONFIG_XMON) += sstep.o
-obj-$(CONFIG_KPROBES) += sstep.o
+obj-$(CONFIG_XMON) += sstep.o ldstfp.o
+obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o
+obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o
ifeq ($(CONFIG_PPC64),y)
obj-$(CONFIG_SMP) += locks.o
diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S
new file mode 100644
index 000000000000..f6448636baf5
--- /dev/null
+++ b/arch/powerpc/lib/ldstfp.S
@@ -0,0 +1,375 @@
+/*
+ * Floating-point, VMX/Altivec and VSX loads and stores
+ * for use in instruction emulation.
+ *
+ * Copyright 2010 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+#include <asm/ppc-opcode.h>
+#include <asm/reg.h>
+#include <asm/asm-offsets.h>
+#include <linux/errno.h>
+
+#define STKFRM (PPC_MIN_STKFRM + 16)
+
+ .macro extab instr,handler
+ .section __ex_table,"a"
+ PPC_LONG \instr,\handler
+ .previous
+ .endm
+
+ .macro inst32 op
+reg = 0
+ .rept 32
+20: \op reg,0,r4
+ b 3f
+ extab 20b,99f
+reg = reg + 1
+ .endr
+ .endm
+
+/* Get the contents of frN into fr0; N is in r3. */
+_GLOBAL(get_fpr)
+ mflr r0
+ rlwinm r3,r3,3,0xf8
+ bcl 20,31,1f
+ blr /* fr0 is already in fr0 */
+ nop
+reg = 1
+ .rept 31
+ fmr fr0,reg
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Put the contents of fr0 into frN; N is in r3. */
+_GLOBAL(put_fpr)
+ mflr r0
+ rlwinm r3,r3,3,0xf8
+ bcl 20,31,1f
+ blr /* fr0 is already in fr0 */
+ nop
+reg = 1
+ .rept 31
+ fmr reg,fr0
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Load FP reg N from float at *p. N is in r3, p in r4. */
+_GLOBAL(do_lfs)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ ori r7,r6,MSR_FP
+ cmpwi cr7,r3,0
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stfd fr0,STKFRM-16(r1)
+1: li r9,-EFAULT
+2: lfs fr0,0(r4)
+ li r9,0
+3: bl put_fpr
+ beq cr7,4f
+ lfd fr0,STKFRM-16(r1)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+/* Load FP reg N from double at *p. N is in r3, p in r4. */
+_GLOBAL(do_lfd)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ ori r7,r6,MSR_FP
+ cmpwi cr7,r3,0
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stfd fr0,STKFRM-16(r1)
+1: li r9,-EFAULT
+2: lfd fr0,0(r4)
+ li r9,0
+3: beq cr7,4f
+ bl put_fpr
+ lfd fr0,STKFRM-16(r1)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+/* Store FP reg N to float at *p. N is in r3, p in r4. */
+_GLOBAL(do_stfs)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ ori r7,r6,MSR_FP
+ cmpwi cr7,r3,0
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stfd fr0,STKFRM-16(r1)
+ bl get_fpr
+1: li r9,-EFAULT
+2: stfs fr0,0(r4)
+ li r9,0
+3: beq cr7,4f
+ lfd fr0,STKFRM-16(r1)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+/* Store FP reg N to double at *p. N is in r3, p in r4. */
+_GLOBAL(do_stfd)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ ori r7,r6,MSR_FP
+ cmpwi cr7,r3,0
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stfd fr0,STKFRM-16(r1)
+ bl get_fpr
+1: li r9,-EFAULT
+2: stfd fr0,0(r4)
+ li r9,0
+3: beq cr7,4f
+ lfd fr0,STKFRM-16(r1)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+#ifdef CONFIG_ALTIVEC
+/* Get the contents of vrN into vr0; N is in r3. */
+_GLOBAL(get_vr)
+ mflr r0
+ rlwinm r3,r3,3,0xf8
+ bcl 20,31,1f
+ blr /* vr0 is already in vr0 */
+ nop
+reg = 1
+ .rept 31
+ vor vr0,reg,reg /* assembler doesn't know vmr? */
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Put the contents of vr0 into vrN; N is in r3. */
+_GLOBAL(put_vr)
+ mflr r0
+ rlwinm r3,r3,3,0xf8
+ bcl 20,31,1f
+ blr /* vr0 is already in vr0 */
+ nop
+reg = 1
+ .rept 31
+ vor reg,vr0,vr0
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Load vector reg N from *p. N is in r3, p in r4. */
+_GLOBAL(do_lvx)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ oris r7,r6,MSR_VEC@h
+ cmpwi cr7,r3,0
+ li r8,STKFRM-16
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stvx vr0,r1,r8
+1: li r9,-EFAULT
+2: lvx vr0,0,r4
+ li r9,0
+3: beq cr7,4f
+ bl put_vr
+ lvx vr0,r1,r8
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+/* Store vector reg N to *p. N is in r3, p in r4. */
+_GLOBAL(do_stvx)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ oris r7,r6,MSR_VEC@h
+ cmpwi cr7,r3,0
+ li r8,STKFRM-16
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ stvx vr0,r1,r8
+ bl get_vr
+1: li r9,-EFAULT
+2: stvx vr0,0,r4
+ li r9,0
+3: beq cr7,4f
+ lvx vr0,r1,r8
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_VSX
+/* Get the contents of vsrN into vsr0; N is in r3. */
+_GLOBAL(get_vsr)
+ mflr r0
+ rlwinm r3,r3,3,0x1f8
+ bcl 20,31,1f
+ blr /* vsr0 is already in vsr0 */
+ nop
+reg = 1
+ .rept 63
+ XXLOR(0,reg,reg)
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Put the contents of vsr0 into vsrN; N is in r3. */
+_GLOBAL(put_vsr)
+ mflr r0
+ rlwinm r3,r3,3,0x1f8
+ bcl 20,31,1f
+ blr /* vr0 is already in vr0 */
+ nop
+reg = 1
+ .rept 63
+ XXLOR(reg,0,0)
+ blr
+reg = reg + 1
+ .endr
+1: mflr r5
+ add r5,r3,r5
+ mtctr r5
+ mtlr r0
+ bctr
+
+/* Load VSX reg N from vector doubleword *p. N is in r3, p in r4. */
+_GLOBAL(do_lxvd2x)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ oris r7,r6,MSR_VSX@h
+ cmpwi cr7,r3,0
+ li r8,STKFRM-16
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ STXVD2X(0,r1,r8)
+1: li r9,-EFAULT
+2: LXVD2X(0,0,r4)
+ li r9,0
+3: beq cr7,4f
+ bl put_vsr
+ LXVD2X(0,r1,r8)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+/* Store VSX reg N to vector doubleword *p. N is in r3, p in r4. */
+_GLOBAL(do_stxvd2x)
+ PPC_STLU r1,-STKFRM(r1)
+ mflr r0
+ PPC_STL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mfmsr r6
+ oris r7,r6,MSR_VSX@h
+ cmpwi cr7,r3,0
+ li r8,STKFRM-16
+ mtmsrd r7
+ isync
+ beq cr7,1f
+ STXVD2X(0,r1,r8)
+ bl get_vsr
+1: li r9,-EFAULT
+2: STXVD2X(0,0,r4)
+ li r9,0
+3: beq cr7,4f
+ LXVD2X(0,r1,r8)
+4: PPC_LL r0,STKFRM+PPC_LR_STKOFF(r1)
+ mtlr r0
+ mtmsrd r6
+ isync
+ mr r3,r9
+ addi r1,r1,STKFRM
+ blr
+ extab 2b,3b
+
+#endif /* CONFIG_VSX */
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 13b7d54f185b..e0a9858d537e 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -13,6 +13,8 @@
#include <linux/ptrace.h>
#include <asm/sstep.h>
#include <asm/processor.h>
+#include <asm/uaccess.h>
+#include <asm/cputable.h>
extern char system_call_common[];
@@ -23,6 +25,23 @@ extern char system_call_common[];
#define MSR_MASK 0x87c0ffff
#endif
+/* Bits in XER */
+#define XER_SO 0x80000000U
+#define XER_OV 0x40000000U
+#define XER_CA 0x20000000U
+
+/*
+ * Functions in ldstfp.S
+ */
+extern int do_lfs(int rn, unsigned long ea);
+extern int do_lfd(int rn, unsigned long ea);
+extern int do_stfs(int rn, unsigned long ea);
+extern int do_stfd(int rn, unsigned long ea);
+extern int do_lvx(int rn, unsigned long ea);
+extern int do_stvx(int rn, unsigned long ea);
+extern int do_lxvd2x(int rn, unsigned long ea);
+extern int do_stxvd2x(int rn, unsigned long ea);
+
/*
* Determine whether a conditional branch instruction would branch.
*/
@@ -46,16 +65,499 @@ static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs)
return 1;
}
+
+static long __kprobes address_ok(struct pt_regs *regs, unsigned long ea, int nb)
+{
+ if (!user_mode(regs))
+ return 1;
+ return __access_ok(ea, nb, USER_DS);
+}
+
+/*
+ * Calculate effective address for a D-form instruction
+ */
+static unsigned long __kprobes dform_ea(unsigned int instr, struct pt_regs *regs)
+{
+ int ra;
+ unsigned long ea;
+
+ ra = (instr >> 16) & 0x1f;
+ ea = (signed short) instr; /* sign-extend */
+ if (ra) {
+ ea += regs->gpr[ra];
+ if (instr & 0x04000000) /* update forms */
+ regs->gpr[ra] = ea;
+ }
+#ifdef __powerpc64__
+ if (!(regs->msr & MSR_SF))
+ ea &= 0xffffffffUL;
+#endif
+ return ea;
+}
+
+#ifdef __powerpc64__
+/*
+ * Calculate effective address for a DS-form instruction
+ */
+static unsigned long __kprobes dsform_ea(unsigned int instr, struct pt_regs *regs)
+{
+ int ra;
+ unsigned long ea;
+
+ ra = (instr >> 16) & 0x1f;
+ ea = (signed short) (instr & ~3); /* sign-extend */
+ if (ra) {
+ ea += regs->gpr[ra];
+ if ((instr & 3) == 1) /* update forms */
+ regs->gpr[ra] = ea;
+ }
+ if (!(regs->msr & MSR_SF))
+ ea &= 0xffffffffUL;
+ return ea;
+}
+#endif /* __powerpc64 */
+
+/*
+ * Calculate effective address for an X-form instruction
+ */
+static unsigned long __kprobes xform_ea(unsigned int instr, struct pt_regs *regs,
+ int do_update)
+{
+ int ra, rb;
+ unsigned long ea;
+
+ ra = (instr >> 16) & 0x1f;
+ rb = (instr >> 11) & 0x1f;
+ ea = regs->gpr[rb];
+ if (ra) {
+ ea += regs->gpr[ra];
+ if (do_update) /* update forms */
+ regs->gpr[ra] = ea;
+ }
+#ifdef __powerpc64__
+ if (!(regs->msr & MSR_SF))
+ ea &= 0xffffffffUL;
+#endif
+ return ea;
+}
+
+/*
+ * Return the largest power of 2, not greater than sizeof(unsigned long),
+ * such that x is a multiple of it.
+ */
+static inline unsigned long max_align(unsigned long x)
+{
+ x |= sizeof(unsigned long);
+ return x & -x; /* isolates rightmost bit */
+}
+
+
+static inline unsigned long byterev_2(unsigned long x)
+{
+ return ((x >> 8) & 0xff) | ((x & 0xff) << 8);
+}
+
+static inline unsigned long byterev_4(unsigned long x)
+{
+ return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) |
+ ((x & 0xff00) << 8) | ((x & 0xff) << 24);
+}
+
+#ifdef __powerpc64__
+static inline unsigned long byterev_8(unsigned long x)
+{
+ return (byterev_4(x) << 32) | byterev_4(x >> 32);
+}
+#endif
+
+static int __kprobes read_mem_aligned(unsigned long *dest, unsigned long ea,
+ int nb)
+{
+ int err = 0;
+ unsigned long x = 0;
+
+ switch (nb) {
+ case 1:
+ err = __get_user(x, (unsigned char __user *) ea);
+ break;
+ case 2:
+ err = __get_user(x, (unsigned short __user *) ea);
+ break;
+ case 4:
+ err = __get_user(x, (unsigned int __user *) ea);
+ break;
+#ifdef __powerpc64__
+ case 8:
+ err = __get_user(x, (unsigned long __user *) ea);
+ break;
+#endif
+ }
+ if (!err)
+ *dest = x;
+ return err;
+}
+
+static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
+ int nb, struct pt_regs *regs)
+{
+ int err;
+ unsigned long x, b, c;
+
+ /* unaligned, do this in pieces */
+ x = 0;
+ for (; nb > 0; nb -= c) {
+ c = max_align(ea);
+ if (c > nb)
+ c = max_align(nb);
+ err = read_mem_aligned(&b, ea, c);
+ if (err)
+ return err;
+ x = (x << (8 * c)) + b;
+ ea += c;
+ }
+ *dest = x;
+ return 0;
+}
+
+/*
+ * Read memory at address ea for nb bytes, return 0 for success
+ * or -EFAULT if an error occurred.
+ */
+static int __kprobes read_mem(unsigned long *dest, unsigned long ea, int nb,
+ struct pt_regs *regs)
+{
+ if (!address_ok(regs, ea, nb))
+ return -EFAULT;
+ if ((ea & (nb - 1)) == 0)
+ return read_mem_aligned(dest, ea, nb);
+ return read_mem_unaligned(dest, ea, nb, regs);
+}
+
+static int __kprobes write_mem_aligned(unsigned long val, unsigned long ea,
+ int nb)
+{
+ int err = 0;
+
+ switch (nb) {
+ case 1:
+ err = __put_user(val, (unsigned char __user *) ea);
+ break;
+ case 2:
+ err = __put_user(val, (unsigned short __user *) ea);
+ break;
+ case 4:
+ err = __put_user(val, (unsigned int __user *) ea);
+ break;
+#ifdef __powerpc64__
+ case 8:
+ err = __put_user(val, (unsigned long __user *) ea);
+ break;
+#endif
+ }
+ return err;
+}
+
+static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea,
+ int nb, struct pt_regs *regs)
+{
+ int err;
+ unsigned long c;
+
+ /* unaligned or little-endian, do this in pieces */
+ for (; nb > 0; nb -= c) {
+ c = max_align(ea);
+ if (c > nb)
+ c = max_align(nb);
+ err = write_mem_aligned(val >> (nb - c) * 8, ea, c);
+ if (err)
+ return err;
+ ++ea;
+ }
+ return 0;
+}
+
+/*
+ * Write memory at address ea for nb bytes, return 0 for success
+ * or -EFAULT if an error occurred.
+ */
+static int __kprobes write_mem(unsigned long val, unsigned long ea, int nb,
+ struct pt_regs *regs)
+{
+ if (!address_ok(regs, ea, nb))
+ return -EFAULT;
+ if ((ea & (nb - 1)) == 0)
+ return write_mem_aligned(val, ea, nb);
+ return write_mem_unaligned(val, ea, nb, regs);
+}
+
/*
- * Emulate instructions that cause a transfer of control.
+ * Check the address and alignment, and call func to do the actual
+ * load or store.
+ */
+static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, int nb,
+ struct pt_regs *regs)
+{
+ int err;
+ unsigned long val[sizeof(double) / sizeof(long)];
+ unsigned long ptr;
+
+ if (!address_ok(regs, ea, nb))
+ return -EFAULT;
+ if ((ea & 3) == 0)
+ return (*func)(rn, ea);
+ ptr = (unsigned long) &val[0];
+ if (sizeof(unsigned long) == 8 || nb == 4) {
+ err = read_mem_unaligned(&val[0], ea, nb, regs);
+ ptr += sizeof(unsigned long) - nb;
+ } else {
+ /* reading a double on 32-bit */
+ err = read_mem_unaligned(&val[0], ea, 4, regs);
+ if (!err)
+ err = read_mem_unaligned(&val[1], ea + 4, 4, regs);
+ }
+ if (err)
+ return err;
+ return (*func)(rn, ptr);
+}
+
+static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, int nb,
+ struct pt_regs *regs)
+{
+ int err;
+ unsigned long val[sizeof(double) / sizeof(long)];
+ unsigned long ptr;
+
+ if (!address_ok(regs, ea, nb))
+ return -EFAULT;
+ if ((ea & 3) == 0)
+ return (*func)(rn, ea);
+ ptr = (unsigned long) &val[0];
+ if (sizeof(unsigned long) == 8 || nb == 4) {
+ ptr += sizeof(unsigned long) - nb;
+ err = (*func)(rn, ptr);
+ if (err)
+ return err;
+ err = write_mem_unaligned(val[0], ea, nb, regs);
+ } else {
+ /* writing a double on 32-bit */
+ err = (*func)(rn, ptr);
+ if (err)
+ return err;
+ err = write_mem_unaligned(val[0], ea, 4, regs);
+ if (!err)
+ err = write_mem_unaligned(val[1], ea + 4, 4, regs);
+ }
+ return err;
+}
+
+#ifdef CONFIG_ALTIVEC
+/* For Altivec/VMX, no need to worry about alignment */
+static int __kprobes do_vec_load(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, struct pt_regs *regs)
+{
+ if (!address_ok(regs, ea & ~0xfUL, 16))
+ return -EFAULT;
+ return (*func)(rn, ea);
+}
+
+static int __kprobes do_vec_store(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, struct pt_regs *regs)
+{
+ if (!address_ok(regs, ea & ~0xfUL, 16))
+ return -EFAULT;
+ return (*func)(rn, ea);
+}
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef CONFIG_VSX
+static int __kprobes do_vsx_load(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, struct pt_regs *regs)
+{
+ int err;
+ unsigned long val[2];
+
+ if (!address_ok(regs, ea, 16))
+ return -EFAULT;
+ if ((ea & 3) == 0)
+ return (*func)(rn, ea);
+ err = read_mem_unaligned(&val[0], ea, 8, regs);
+ if (!err)
+ err = read_mem_unaligned(&val[1], ea + 8, 8, regs);
+ if (!err)
+ err = (*func)(rn, (unsigned long) &val[0]);
+ return err;
+}
+
+static int __kprobes do_vsx_store(int rn, int (*func)(int, unsigned long),
+ unsigned long ea, struct pt_regs *regs)
+{
+ int err;
+ unsigned long val[2];
+
+ if (!address_ok(regs, ea, 16))
+ return -EFAULT;
+ if ((ea & 3) == 0)
+ return (*func)(rn, ea);
+ err = (*func)(rn, (unsigned long) &val[0]);
+ if (err)
+ return err;
+ err = write_mem_unaligned(val[0], ea, 8, regs);
+ if (!err)
+ err = write_mem_unaligned(val[1], ea + 8, 8, regs);
+ return err;
+}
+#endif /* CONFIG_VSX */
+
+#define __put_user_asmx(x, addr, err, op, cr) \
+ __asm__ __volatile__( \
+ "1: " op " %2,0,%3\n" \
+ " mfcr %1\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%4\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ PPC_LONG_ALIGN "\n" \
+ PPC_LONG "1b,3b\n" \
+ ".previous" \
+ : "=r" (err), "=r" (cr) \
+ : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
+
+#define __get_user_asmx(x, addr, err, op) \
+ __asm__ __volatile__( \
+ "1: "op" %1,0,%2\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%3\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ PPC_LONG_ALIGN "\n" \
+ PPC_LONG "1b,3b\n" \
+ ".previous" \
+ : "=r" (err), "=r" (x) \
+ : "r" (addr), "i" (-EFAULT), "0" (err))
+
+#define __cacheop_user_asmx(addr, err, op) \
+ __asm__ __volatile__( \
+ "1: "op" 0,%1\n" \
+ "2:\n" \
+ ".section .fixup,\"ax\"\n" \
+ "3: li %0,%3\n" \
+ " b 2b\n" \
+ ".previous\n" \
+ ".section __ex_table,\"a\"\n" \
+ PPC_LONG_ALIGN "\n" \
+ PPC_LONG "1b,3b\n" \
+ ".previous" \
+ : "=r" (err) \
+ : "r" (addr), "i" (-EFAULT), "0" (err))
+
+static void __kprobes set_cr0(struct pt_regs *regs, int rd)
+{
+ long val = regs->gpr[rd];
+
+ regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
+#ifdef __powerpc64__
+ if (!(regs->msr & MSR_SF))
+ val = (int) val;
+#endif
+ if (val < 0)
+ regs->ccr |= 0x80000000;
+ else if (val > 0)
+ regs->ccr |= 0x40000000;
+ else
+ regs->ccr |= 0x20000000;
+}
+
+static void __kprobes add_with_carry(struct pt_regs *regs, int rd,
+ unsigned long val1, unsigned long val2,
+ unsigned long carry_in)
+{
+ unsigned long val = val1 + val2;
+
+ if (carry_in)
+ ++val;
+ regs->gpr[rd] = val;
+#ifdef __powerpc64__
+ if (!(regs->msr & MSR_SF)) {
+ val = (unsigned int) val;
+ val1 = (unsigned int) val1;
+ }
+#endif
+ if (val < val1 || (carry_in && val == val1))
+ regs->xer |= XER_CA;
+ else
+ regs->xer &= ~XER_CA;
+}
+
+static void __kprobes do_cmp_signed(struct pt_regs *regs, long v1, long v2,
+ int crfld)
+{
+ unsigned int crval, shift;
+
+ crval = (regs->xer >> 31) & 1; /* get SO bit */
+ if (v1 < v2)
+ crval |= 8;
+ else if (v1 > v2)
+ crval |= 4;
+ else
+ crval |= 2;
+ shift = (7 - crfld) * 4;
+ regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift);
+}
+
+static void __kprobes do_cmp_unsigned(struct pt_regs *regs, unsigned long v1,
+ unsigned long v2, int crfld)
+{
+ unsigned int crval, shift;
+
+ crval = (regs->xer >> 31) & 1; /* get SO bit */
+ if (v1 < v2)
+ crval |= 8;
+ else if (v1 > v2)
+ crval |= 4;
+ else
+ crval |= 2;
+ shift = (7 - crfld) * 4;
+ regs->ccr = (regs->ccr & ~(0xf << shift)) | (crval << shift);
+}
+
+/*
+ * Elements of 32-bit rotate and mask instructions.
+ */
+#define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \
+ ((signed long)-0x80000000L >> (me)) + ((me) >= (mb)))
+#ifdef __powerpc64__
+#define MASK64_L(mb) (~0UL >> (mb))
+#define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me))
+#define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb)))
+#define DATA32(x) (((x) & 0xffffffffUL) | (((x) & 0xffffffffUL) << 32))
+#else
+#define DATA32(x) (x)
+#endif
+#define ROTATE(x, n) ((n) ? (((x) << (n)) | ((x) >> (8 * sizeof(long) - (n)))) : (x))
+
+/*
+ * Emulate instructions that cause a transfer of control,
+ * loads and stores, and a few other instructions.
* Returns 1 if the step was emulated, 0 if not,
* or -1 if the instruction is one that should not be stepped,
* such as an rfid, or a mtmsrd that would clear MSR_RI.
*/
int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
{
- unsigned int opcode, rs, rb, rd, spr;
+ unsigned int opcode, ra, rb, rd, spr, u;
unsigned long int imm;
+ unsigned long int val, val2;
+ unsigned long int ea;
+ unsigned int cr, mb, me, sh;
+ int err;
+ unsigned long old_ra;
+ long ival;
opcode = instr >> 26;
switch (opcode) {
@@ -78,7 +580,13 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
* entry code works. If that is changed, this will
* need to be changed also.
*/
+ if (regs->gpr[0] == 0x1ebe &&
+ cpu_has_feature(CPU_FTR_REAL_LE)) {
+ regs->msr ^= MSR_LE;
+ goto instr_done;
+ }
regs->gpr[9] = regs->gpr[13];
+ regs->gpr[10] = MSR_KERNEL;
regs->gpr[11] = regs->nip + 4;
regs->gpr[12] = regs->msr & MSR_MASK;
regs->gpr[13] = (unsigned long) get_paca();
@@ -102,9 +610,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
regs->nip = imm;
return 1;
case 19:
- switch (instr & 0x7fe) {
- case 0x20: /* bclr */
- case 0x420: /* bcctr */
+ switch ((instr >> 1) & 0x3ff) {
+ case 16: /* bclr */
+ case 528: /* bcctr */
imm = (instr & 0x400)? regs->ctr: regs->link;
regs->nip += 4;
if ((regs->msr & MSR_SF) == 0) {
@@ -116,30 +624,233 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
if (branch_taken(instr, regs))
regs->nip = imm;
return 1;
- case 0x24: /* rfid, scary */
+
+ case 18: /* rfid, scary */
return -1;
+
+ case 150: /* isync */
+ isync();
+ goto instr_done;
+
+ case 33: /* crnor */
+ case 129: /* crandc */
+ case 193: /* crxor */
+ case 225: /* crnand */
+ case 257: /* crand */
+ case 289: /* creqv */
+ case 417: /* crorc */
+ case 449: /* cror */
+ ra = (instr >> 16) & 0x1f;
+ rb = (instr >> 11) & 0x1f;
+ rd = (instr >> 21) & 0x1f;
+ ra = (regs->ccr >> (31 - ra)) & 1;
+ rb = (regs->ccr >> (31 - rb)) & 1;
+ val = (instr >> (6 + ra * 2 + rb)) & 1;
+ regs->ccr = (regs->ccr & ~(1UL << (31 - rd))) |
+ (val << (31 - rd));
+ goto instr_done;
+ }
+ break;
+ case 31:
+ switch ((instr >> 1) & 0x3ff) {
+ case 598: /* sync */
+#ifdef __powerpc64__
+ switch ((instr >> 21) & 3) {
+ case 1: /* lwsync */
+ asm volatile("lwsync" : : : "memory");
+ goto instr_done;
+ case 2: /* ptesync */
+ asm volatile("ptesync" : : : "memory");
+ goto instr_done;
+ }
+#endif
+ mb();
+ goto instr_done;
+
+ case 854: /* eieio */
+ eieio();
+ goto instr_done;
+ }
+ break;
+ }
+
+ /* Following cases refer to regs->gpr[], so we need all regs */
+ if (!FULL_REGS(regs))
+ return 0;
+
+ rd = (instr >> 21) & 0x1f;
+ ra = (instr >> 16) & 0x1f;
+ rb = (instr >> 11) & 0x1f;
+
+ switch (opcode) {
+ case 7: /* mulli */
+ regs->gpr[rd] = regs->gpr[ra] * (short) instr;
+ goto instr_done;
+
+ case 8: /* subfic */
+ imm = (short) instr;
+ add_with_carry(regs, rd, ~regs->gpr[ra], imm, 1);
+ goto instr_done;
+
+ case 10: /* cmpli */
+ imm = (unsigned short) instr;
+ val = regs->gpr[ra];
+#ifdef __powerpc64__
+ if ((rd & 1) == 0)
+ val = (unsigned int) val;
+#endif
+ do_cmp_unsigned(regs, val, imm, rd >> 2);
+ goto instr_done;
+
+ case 11: /* cmpi */
+ imm = (short) instr;
+ val = regs->gpr[ra];
+#ifdef __powerpc64__
+ if ((rd & 1) == 0)
+ val = (int) val;
+#endif
+ do_cmp_signed(regs, val, imm, rd >> 2);
+ goto instr_done;
+
+ case 12: /* addic */
+ imm = (short) instr;
+ add_with_carry(regs, rd, regs->gpr[ra], imm, 0);
+ goto instr_done;
+
+ case 13: /* addic. */
+ imm = (short) instr;
+ add_with_carry(regs, rd, regs->gpr[ra], imm, 0);
+ set_cr0(regs, rd);
+ goto instr_done;
+
+ case 14: /* addi */
+ imm = (short) instr;
+ if (ra)
+ imm += regs->gpr[ra];
+ regs->gpr[rd] = imm;
+ goto instr_done;
+
+ case 15: /* addis */
+ imm = ((short) instr) << 16;
+ if (ra)
+ imm += regs->gpr[ra];
+ regs->gpr[rd] = imm;
+ goto instr_done;
+
+ case 20: /* rlwimi */
+ mb = (instr >> 6) & 0x1f;
+ me = (instr >> 1) & 0x1f;
+ val = DATA32(regs->gpr[rd]);
+ imm = MASK32(mb, me);
+ regs->gpr[ra] = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm);
+ goto logical_done;
+
+ case 21: /* rlwinm */
+ mb = (instr >> 6) & 0x1f;
+ me = (instr >> 1) & 0x1f;
+ val = DATA32(regs->gpr[rd]);
+ regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me);
+ goto logical_done;
+
+ case 23: /* rlwnm */
+ mb = (instr >> 6) & 0x1f;
+ me = (instr >> 1) & 0x1f;
+ rb = regs->gpr[rb] & 0x1f;
+ val = DATA32(regs->gpr[rd]);
+ regs->gpr[ra] = ROTATE(val, rb) & MASK32(mb, me);
+ goto logical_done;
+
+ case 24: /* ori */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] | imm;
+ goto instr_done;
+
+ case 25: /* oris */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] | (imm << 16);
+ goto instr_done;
+
+ case 26: /* xori */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] ^ imm;
+ goto instr_done;
+
+ case 27: /* xoris */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] ^ (imm << 16);
+ goto instr_done;
+
+ case 28: /* andi. */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] & imm;
+ set_cr0(regs, ra);
+ goto instr_done;
+
+ case 29: /* andis. */
+ imm = (unsigned short) instr;
+ regs->gpr[ra] = regs->gpr[rd] & (imm << 16);
+ set_cr0(regs, ra);
+ goto instr_done;
+
+#ifdef __powerpc64__
+ case 30: /* rld* */
+ mb = ((instr >> 6) & 0x1f) | (instr & 0x20);
+ val = regs->gpr[rd];
+ if ((instr & 0x10) == 0) {
+ sh = rb | ((instr & 2) << 4);
+ val = ROTATE(val, sh);
+ switch ((instr >> 2) & 3) {
+ case 0: /* rldicl */
+ regs->gpr[ra] = val & MASK64_L(mb);
+ goto logical_done;
+ case 1: /* rldicr */
+ regs->gpr[ra] = val & MASK64_R(mb);
+ goto logical_done;
+ case 2: /* rldic */
+ regs->gpr[ra] = val & MASK64(mb, 63 - sh);
+ goto logical_done;
+ case 3: /* rldimi */
+ imm = MASK64(mb, 63 - sh);
+ regs->gpr[ra] = (regs->gpr[ra] & ~imm) |
+ (val & imm);
+ goto logical_done;
+ }
+ } else {
+ sh = regs->gpr[rb] & 0x3f;
+ val = ROTATE(val, sh);
+ switch ((instr >> 1) & 7) {
+ case 0: /* rldcl */
+ regs->gpr[ra] = val & MASK64_L(mb);
+ goto logical_done;
+ case 1: /* rldcr */
+ regs->gpr[ra] = val & MASK64_R(mb);
+ goto logical_done;
+ }
}
+#endif
+
case 31:
- rd = (instr >> 21) & 0x1f;
- switch (instr & 0x7fe) {
- case 0xa6: /* mfmsr */
+ switch ((instr >> 1) & 0x3ff) {
+ case 83: /* mfmsr */
+ if (regs->msr & MSR_PR)
+ break;
regs->gpr[rd] = regs->msr & MSR_MASK;
- regs->nip += 4;
- if ((regs->msr & MSR_SF) == 0)
- regs->nip &= 0xffffffffUL;
- return 1;
- case 0x124: /* mtmsr */
+ goto instr_done;
+ case 146: /* mtmsr */
+ if (regs->msr & MSR_PR)
+ break;
imm = regs->gpr[rd];
if ((imm & MSR_RI) == 0)
/* can't step mtmsr that would clear MSR_RI */
return -1;
regs->msr = imm;
- regs->nip += 4;
- return 1;
+ goto instr_done;
#ifdef CONFIG_PPC64
- case 0x164: /* mtmsrd */
+ case 178: /* mtmsrd */
/* only MSR_EE and MSR_RI get changed if bit 15 set */
/* mtmsrd doesn't change MSR_HV and MSR_ME */
+ if (regs->msr & MSR_PR)
+ break;
imm = (instr & 0x10000)? 0x8002: 0xefffffffffffefffUL;
imm = (regs->msr & MSR_MASK & ~imm)
| (regs->gpr[rd] & imm);
@@ -147,57 +858,770 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr)
/* can't step mtmsrd that would clear MSR_RI */
return -1;
regs->msr = imm;
- regs->nip += 4;
- if ((imm & MSR_SF) == 0)
- regs->nip &= 0xffffffffUL;
- return 1;
+ goto instr_done;
#endif
- case 0x26: /* mfcr */
+ case 19: /* mfcr */
regs->gpr[rd] = regs->ccr;
regs->gpr[rd] &= 0xffffffffUL;
- goto mtspr_out;
- case 0x2a6: /* mfspr */
+ goto instr_done;
+
+ case 144: /* mtcrf */
+ imm = 0xf0000000UL;
+ val = regs->gpr[rd];
+ for (sh = 0; sh < 8; ++sh) {
+ if (instr & (0x80000 >> sh))
+ regs->ccr = (regs->ccr & ~imm) |
+ (val & imm);
+ imm >>= 4;
+ }
+ goto instr_done;
+
+ case 339: /* mfspr */
spr = (instr >> 11) & 0x3ff;
switch (spr) {
case 0x20: /* mfxer */
regs->gpr[rd] = regs->xer;
regs->gpr[rd] &= 0xffffffffUL;
- goto mtspr_out;
+ goto instr_done;
case 0x100: /* mflr */
regs->gpr[rd] = regs->link;
- goto mtspr_out;
+ goto instr_done;
case 0x120: /* mfctr */
regs->gpr[rd] = regs->ctr;
- goto mtspr_out;
- }
- break;
- case 0x378: /* orx */
- if (instr & 1)
- break;
- rs = (instr >> 21) & 0x1f;
- rb = (instr >> 11) & 0x1f;
- if (rs == rb) { /* mr */
- rd = (instr >> 16) & 0x1f;
- regs->gpr[rd] = regs->gpr[rs];
- goto mtspr_out;
+ goto instr_done;
}
break;
- case 0x3a6: /* mtspr */
+
+ case 467: /* mtspr */
spr = (instr >> 11) & 0x3ff;
switch (spr) {
case 0x20: /* mtxer */
regs->xer = (regs->gpr[rd] & 0xffffffffUL);
- goto mtspr_out;
+ goto instr_done;
case 0x100: /* mtlr */
regs->link = regs->gpr[rd];
- goto mtspr_out;
+ goto instr_done;
case 0x120: /* mtctr */
regs->ctr = regs->gpr[rd];
-mtspr_out:
- regs->nip += 4;
- return 1;
+ goto instr_done;
}
+ break;
+
+/*
+ * Compare instructions
+ */
+ case 0: /* cmp */
+ val = regs->gpr[ra];
+ val2 = regs->gpr[rb];
+#ifdef __powerpc64__
+ if ((rd & 1) == 0) {
+ /* word (32-bit) compare */
+ val = (int) val;
+ val2 = (int) val2;
+ }
+#endif
+ do_cmp_signed(regs, val, val2, rd >> 2);
+ goto instr_done;
+
+ case 32: /* cmpl */
+ val = regs->gpr[ra];
+ val2 = regs->gpr[rb];
+#ifdef __powerpc64__
+ if ((rd & 1) == 0) {
+ /* word (32-bit) compare */
+ val = (unsigned int) val;
+ val2 = (unsigned int) val2;
+ }
+#endif
+ do_cmp_unsigned(regs, val, val2, rd >> 2);
+ goto instr_done;
+
+/*
+ * Arithmetic instructions
+ */
+ case 8: /* subfc */
+ add_with_carry(regs, rd, ~regs->gpr[ra],
+ regs->gpr[rb], 1);
+ goto arith_done;
+#ifdef __powerpc64__
+ case 9: /* mulhdu */
+ asm("mulhdu %0,%1,%2" : "=r" (regs->gpr[rd]) :
+ "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
+ goto arith_done;
+#endif
+ case 10: /* addc */
+ add_with_carry(regs, rd, regs->gpr[ra],
+ regs->gpr[rb], 0);
+ goto arith_done;
+
+ case 11: /* mulhwu */
+ asm("mulhwu %0,%1,%2" : "=r" (regs->gpr[rd]) :
+ "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
+ goto arith_done;
+
+ case 40: /* subf */
+ regs->gpr[rd] = regs->gpr[rb] - regs->gpr[ra];
+ goto arith_done;
+#ifdef __powerpc64__
+ case 73: /* mulhd */
+ asm("mulhd %0,%1,%2" : "=r" (regs->gpr[rd]) :
+ "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
+ goto arith_done;
+#endif
+ case 75: /* mulhw */
+ asm("mulhw %0,%1,%2" : "=r" (regs->gpr[rd]) :
+ "r" (regs->gpr[ra]), "r" (regs->gpr[rb]));
+ goto arith_done;
+
+ case 104: /* neg */
+ regs->gpr[rd] = -regs->gpr[ra];
+ goto arith_done;
+
+ case 136: /* subfe */
+ add_with_carry(regs, rd, ~regs->gpr[ra], regs->gpr[rb],
+ regs->xer & XER_CA);
+ goto arith_done;
+
+ case 138: /* adde */
+ add_with_carry(regs, rd, regs->gpr[ra], regs->gpr[rb],
+ regs->xer & XER_CA);
+ goto arith_done;
+
+ case 200: /* subfze */
+ add_with_carry(regs, rd, ~regs->gpr[ra], 0L,
+ regs->xer & XER_CA);
+ goto arith_done;
+
+ case 202: /* addze */
+ add_with_carry(regs, rd, regs->gpr[ra], 0L,
+ regs->xer & XER_CA);
+ goto arith_done;
+
+ case 232: /* subfme */
+ add_with_carry(regs, rd, ~regs->gpr[ra], -1L,
+ regs->xer & XER_CA);
+ goto arith_done;
+#ifdef __powerpc64__
+ case 233: /* mulld */
+ regs->gpr[rd] = regs->gpr[ra] * regs->gpr[rb];
+ goto arith_done;
+#endif
+ case 234: /* addme */
+ add_with_carry(regs, rd, regs->gpr[ra], -1L,
+ regs->xer & XER_CA);
+ goto arith_done;
+
+ case 235: /* mullw */
+ regs->gpr[rd] = (unsigned int) regs->gpr[ra] *
+ (unsigned int) regs->gpr[rb];
+ goto arith_done;
+
+ case 266: /* add */
+ regs->gpr[rd] = regs->gpr[ra] + regs->gpr[rb];
+ goto arith_done;
+#ifdef __powerpc64__
+ case 457: /* divdu */
+ regs->gpr[rd] = regs->gpr[ra] / regs->gpr[rb];
+ goto arith_done;
+#endif
+ case 459: /* divwu */
+ regs->gpr[rd] = (unsigned int) regs->gpr[ra] /
+ (unsigned int) regs->gpr[rb];
+ goto arith_done;
+#ifdef __powerpc64__
+ case 489: /* divd */
+ regs->gpr[rd] = (long int) regs->gpr[ra] /
+ (long int) regs->gpr[rb];
+ goto arith_done;
+#endif
+ case 491: /* divw */
+ regs->gpr[rd] = (int) regs->gpr[ra] /
+ (int) regs->gpr[rb];
+ goto arith_done;
+
+
+/*
+ * Logical instructions
+ */
+ case 26: /* cntlzw */
+ asm("cntlzw %0,%1" : "=r" (regs->gpr[ra]) :
+ "r" (regs->gpr[rd]));
+ goto logical_done;
+#ifdef __powerpc64__
+ case 58: /* cntlzd */
+ asm("cntlzd %0,%1" : "=r" (regs->gpr[ra]) :
+ "r" (regs->gpr[rd]));
+ goto logical_done;
+#endif
+ case 28: /* and */
+ regs->gpr[ra] = regs->gpr[rd] & regs->gpr[rb];
+ goto logical_done;
+
+ case 60: /* andc */
+ regs->gpr[ra] = regs->gpr[rd] & ~regs->gpr[rb];
+ goto logical_done;
+
+ case 124: /* nor */
+ regs->gpr[ra] = ~(regs->gpr[rd] | regs->gpr[rb]);
+ goto logical_done;
+
+ case 284: /* xor */
+ regs->gpr[ra] = ~(regs->gpr[rd] ^ regs->gpr[rb]);
+ goto logical_done;
+
+ case 316: /* xor */
+ regs->gpr[ra] = regs->gpr[rd] ^ regs->gpr[rb];
+ goto logical_done;
+
+ case 412: /* orc */
+ regs->gpr[ra] = regs->gpr[rd] | ~regs->gpr[rb];
+ goto logical_done;
+
+ case 444: /* or */
+ regs->gpr[ra] = regs->gpr[rd] | regs->gpr[rb];
+ goto logical_done;
+
+ case 476: /* nand */
+ regs->gpr[ra] = ~(regs->gpr[rd] & regs->gpr[rb]);
+ goto logical_done;
+
+ case 922: /* extsh */
+ regs->gpr[ra] = (signed short) regs->gpr[rd];
+ goto logical_done;
+
+ case 954: /* extsb */
+ regs->gpr[ra] = (signed char) regs->gpr[rd];
+ goto logical_done;
+#ifdef __powerpc64__
+ case 986: /* extsw */
+ regs->gpr[ra] = (signed int) regs->gpr[rd];
+ goto logical_done;
+#endif
+
+/*
+ * Shift instructions
+ */
+ case 24: /* slw */
+ sh = regs->gpr[rb] & 0x3f;
+ if (sh < 32)
+ regs->gpr[ra] = (regs->gpr[rd] << sh) & 0xffffffffUL;
+ else
+ regs->gpr[ra] = 0;
+ goto logical_done;
+
+ case 536: /* srw */
+ sh = regs->gpr[rb] & 0x3f;
+ if (sh < 32)
+ regs->gpr[ra] = (regs->gpr[rd] & 0xffffffffUL) >> sh;
+ else
+ regs->gpr[ra] = 0;
+ goto logical_done;
+
+ case 792: /* sraw */
+ sh = regs->gpr[rb] & 0x3f;
+ ival = (signed int) regs->gpr[rd];
+ regs->gpr[ra] = ival >> (sh < 32 ? sh : 31);
+ if (ival < 0 && (sh >= 32 || (ival & ((1 << sh) - 1)) != 0))
+ regs->xer |= XER_CA;
+ else
+ regs->xer &= ~XER_CA;
+ goto logical_done;
+
+ case 824: /* srawi */
+ sh = rb;
+ ival = (signed int) regs->gpr[rd];
+ regs->gpr[ra] = ival >> sh;
+ if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+ regs->xer |= XER_CA;
+ else
+ regs->xer &= ~XER_CA;
+ goto logical_done;
+
+#ifdef __powerpc64__
+ case 27: /* sld */
+ sh = regs->gpr[rd] & 0x7f;
+ if (sh < 64)
+ regs->gpr[ra] = regs->gpr[rd] << sh;
+ else
+ regs->gpr[ra] = 0;
+ goto logical_done;
+
+ case 539: /* srd */
+ sh = regs->gpr[rb] & 0x7f;
+ if (sh < 64)
+ regs->gpr[ra] = regs->gpr[rd] >> sh;
+ else
+ regs->gpr[ra] = 0;
+ goto logical_done;
+
+ case 794: /* srad */
+ sh = regs->gpr[rb] & 0x7f;
+ ival = (signed long int) regs->gpr[rd];
+ regs->gpr[ra] = ival >> (sh < 64 ? sh : 63);
+ if (ival < 0 && (sh >= 64 || (ival & ((1 << sh) - 1)) != 0))
+ regs->xer |= XER_CA;
+ else
+ regs->xer &= ~XER_CA;
+ goto logical_done;
+
+ case 826: /* sradi with sh_5 = 0 */
+ case 827: /* sradi with sh_5 = 1 */
+ sh = rb | ((instr & 2) << 4);
+ ival = (signed long int) regs->gpr[rd];
+ regs->gpr[ra] = ival >> sh;
+ if (ival < 0 && (ival & ((1 << sh) - 1)) != 0)
+ regs->xer |= XER_CA;
+ else
+ regs->xer &= ~XER_CA;
+ goto logical_done;
+#endif /* __powerpc64__ */
+
+/*
+ * Cache instructions
+ */
+ case 54: /* dcbst */
+ ea = xform_ea(instr, regs, 0);
+ if (!address_ok(regs, ea, 8))
+ return 0;
+ err = 0;
+ __cacheop_user_asmx(ea, err, "dcbst");
+ if (err)
+ return 0;
+ goto instr_done;
+
+ case 86: /* dcbf */
+ ea = xform_ea(instr, regs, 0);
+ if (!address_ok(regs, ea, 8))
+ return 0;
+ err = 0;
+ __cacheop_user_asmx(ea, err, "dcbf");
+ if (err)
+ return 0;
+ goto instr_done;
+
+ case 246: /* dcbtst */
+ if (rd == 0) {
+ ea = xform_ea(instr, regs, 0);
+ prefetchw((void *) ea);
+ }
+ goto instr_done;
+
+ case 278: /* dcbt */
+ if (rd == 0) {
+ ea = xform_ea(instr, regs, 0);
+ prefetch((void *) ea);
+ }
+ goto instr_done;
+
}
+ break;
}
- return 0;
+
+ /*
+ * Following cases are for loads and stores, so bail out
+ * if we're in little-endian mode.
+ */
+ if (regs->msr & MSR_LE)
+ return 0;
+
+ /*
+ * Save register RA in case it's an update form load or store
+ * and the access faults.
+ */
+ old_ra = regs->gpr[ra];
+
+ switch (opcode) {
+ case 31:
+ u = instr & 0x40;
+ switch ((instr >> 1) & 0x3ff) {
+ case 20: /* lwarx */
+ ea = xform_ea(instr, regs, 0);
+ if (ea & 3)
+ break; /* can't handle misaligned */
+ err = -EFAULT;
+ if (!address_ok(regs, ea, 4))
+ goto ldst_done;
+ err = 0;
+ __get_user_asmx(val, ea, err, "lwarx");
+ if (!err)
+ regs->gpr[rd] = val;
+ goto ldst_done;
+
+ case 150: /* stwcx. */
+ ea = xform_ea(instr, regs, 0);
+ if (ea & 3)
+ break; /* can't handle misaligned */
+ err = -EFAULT;
+ if (!address_ok(regs, ea, 4))
+ goto ldst_done;
+ err = 0;
+ __put_user_asmx(regs->gpr[rd], ea, err, "stwcx.", cr);
+ if (!err)
+ regs->ccr = (regs->ccr & 0x0fffffff) |
+ (cr & 0xe0000000) |
+ ((regs->xer >> 3) & 0x10000000);
+ goto ldst_done;
+
+#ifdef __powerpc64__
+ case 84: /* ldarx */
+ ea = xform_ea(instr, regs, 0);
+ if (ea & 7)
+ break; /* can't handle misaligned */
+ err = -EFAULT;
+ if (!address_ok(regs, ea, 8))
+ goto ldst_done;
+ err = 0;
+ __get_user_asmx(val, ea, err, "ldarx");
+ if (!err)
+ regs->gpr[rd] = val;
+ goto ldst_done;
+
+ case 214: /* stdcx. */
+ ea = xform_ea(instr, regs, 0);
+ if (ea & 7)
+ break; /* can't handle misaligned */
+ err = -EFAULT;
+ if (!address_ok(regs, ea, 8))
+ goto ldst_done;
+ err = 0;
+ __put_user_asmx(regs->gpr[rd], ea, err, "stdcx.", cr);
+ if (!err)
+ regs->ccr = (regs->ccr & 0x0fffffff) |
+ (cr & 0xe0000000) |
+ ((regs->xer >> 3) & 0x10000000);
+ goto ldst_done;
+
+ case 21: /* ldx */
+ case 53: /* ldux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 8, regs);
+ goto ldst_done;
+#endif
+
+ case 23: /* lwzx */
+ case 55: /* lwzux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 4, regs);
+ goto ldst_done;
+
+ case 87: /* lbzx */
+ case 119: /* lbzux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 1, regs);
+ goto ldst_done;
+
+#ifdef CONFIG_ALTIVEC
+ case 103: /* lvx */
+ case 359: /* lvxl */
+ if (!(regs->msr & MSR_VEC))
+ break;
+ ea = xform_ea(instr, regs, 0);
+ err = do_vec_load(rd, do_lvx, ea, regs);
+ goto ldst_done;
+
+ case 231: /* stvx */
+ case 487: /* stvxl */
+ if (!(regs->msr & MSR_VEC))
+ break;
+ ea = xform_ea(instr, regs, 0);
+ err = do_vec_store(rd, do_stvx, ea, regs);
+ goto ldst_done;
+#endif /* CONFIG_ALTIVEC */
+
+#ifdef __powerpc64__
+ case 149: /* stdx */
+ case 181: /* stdux */
+ val = regs->gpr[rd];
+ err = write_mem(val, xform_ea(instr, regs, u), 8, regs);
+ goto ldst_done;
+#endif
+
+ case 151: /* stwx */
+ case 183: /* stwux */
+ val = regs->gpr[rd];
+ err = write_mem(val, xform_ea(instr, regs, u), 4, regs);
+ goto ldst_done;
+
+ case 215: /* stbx */
+ case 247: /* stbux */
+ val = regs->gpr[rd];
+ err = write_mem(val, xform_ea(instr, regs, u), 1, regs);
+ goto ldst_done;
+
+ case 279: /* lhzx */
+ case 311: /* lhzux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 2, regs);
+ goto ldst_done;
+
+#ifdef __powerpc64__
+ case 341: /* lwax */
+ case 373: /* lwaux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 4, regs);
+ if (!err)
+ regs->gpr[rd] = (signed int) regs->gpr[rd];
+ goto ldst_done;
+#endif
+
+ case 343: /* lhax */
+ case 375: /* lhaux */
+ err = read_mem(&regs->gpr[rd], xform_ea(instr, regs, u),
+ 2, regs);
+ if (!err)
+ regs->gpr[rd] = (signed short) regs->gpr[rd];
+ goto ldst_done;
+
+ case 407: /* sthx */
+ case 439: /* sthux */
+ val = regs->gpr[rd];
+ err = write_mem(val, xform_ea(instr, regs, u), 2, regs);
+ goto ldst_done;
+
+#ifdef __powerpc64__
+ case 532: /* ldbrx */
+ err = read_mem(&val, xform_ea(instr, regs, 0), 8, regs);
+ if (!err)
+ regs->gpr[rd] = byterev_8(val);
+ goto ldst_done;
+
+#endif
+
+ case 534: /* lwbrx */
+ err = read_mem(&val, xform_ea(instr, regs, 0), 4, regs);
+ if (!err)
+ regs->gpr[rd] = byterev_4(val);
+ goto ldst_done;
+
+ case 535: /* lfsx */
+ case 567: /* lfsux */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = xform_ea(instr, regs, u);
+ err = do_fp_load(rd, do_lfs, ea, 4, regs);
+ goto ldst_done;
+
+ case 599: /* lfdx */
+ case 631: /* lfdux */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = xform_ea(instr, regs, u);
+ err = do_fp_load(rd, do_lfd, ea, 8, regs);
+ goto ldst_done;
+
+ case 663: /* stfsx */
+ case 695: /* stfsux */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = xform_ea(instr, regs, u);
+ err = do_fp_store(rd, do_stfs, ea, 4, regs);
+ goto ldst_done;
+
+ case 727: /* stfdx */
+ case 759: /* stfdux */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = xform_ea(instr, regs, u);
+ err = do_fp_store(rd, do_stfd, ea, 8, regs);
+ goto ldst_done;
+
+#ifdef __powerpc64__
+ case 660: /* stdbrx */
+ val = byterev_8(regs->gpr[rd]);
+ err = write_mem(val, xform_ea(instr, regs, 0), 8, regs);
+ goto ldst_done;
+
+#endif
+ case 662: /* stwbrx */
+ val = byterev_4(regs->gpr[rd]);
+ err = write_mem(val, xform_ea(instr, regs, 0), 4, regs);
+ goto ldst_done;
+
+ case 790: /* lhbrx */
+ err = read_mem(&val, xform_ea(instr, regs, 0), 2, regs);
+ if (!err)
+ regs->gpr[rd] = byterev_2(val);
+ goto ldst_done;
+
+ case 918: /* sthbrx */
+ val = byterev_2(regs->gpr[rd]);
+ err = write_mem(val, xform_ea(instr, regs, 0), 2, regs);
+ goto ldst_done;
+
+#ifdef CONFIG_VSX
+ case 844: /* lxvd2x */
+ case 876: /* lxvd2ux */
+ if (!(regs->msr & MSR_VSX))
+ break;
+ rd |= (instr & 1) << 5;
+ ea = xform_ea(instr, regs, u);
+ err = do_vsx_load(rd, do_lxvd2x, ea, regs);
+ goto ldst_done;
+
+ case 972: /* stxvd2x */
+ case 1004: /* stxvd2ux */
+ if (!(regs->msr & MSR_VSX))
+ break;
+ rd |= (instr & 1) << 5;
+ ea = xform_ea(instr, regs, u);
+ err = do_vsx_store(rd, do_stxvd2x, ea, regs);
+ goto ldst_done;
+
+#endif /* CONFIG_VSX */
+ }
+ break;
+
+ case 32: /* lwz */
+ case 33: /* lwzu */
+ err = read_mem(&regs->gpr[rd], dform_ea(instr, regs), 4, regs);
+ goto ldst_done;
+
+ case 34: /* lbz */
+ case 35: /* lbzu */
+ err = read_mem(&regs->gpr[rd], dform_ea(instr, regs), 1, regs);
+ goto ldst_done;
+
+ case 36: /* stw */
+ case 37: /* stwu */
+ val = regs->gpr[rd];
+ err = write_mem(val, dform_ea(instr, regs), 4, regs);
+ goto ldst_done;
+
+ case 38: /* stb */
+ case 39: /* stbu */
+ val = regs->gpr[rd];
+ err = write_mem(val, dform_ea(instr, regs), 1, regs);
+ goto ldst_done;
+
+ case 40: /* lhz */
+ case 41: /* lhzu */
+ err = read_mem(&regs->gpr[rd], dform_ea(instr, regs), 2, regs);
+ goto ldst_done;
+
+ case 42: /* lha */
+ case 43: /* lhau */
+ err = read_mem(&regs->gpr[rd], dform_ea(instr, regs), 2, regs);
+ if (!err)
+ regs->gpr[rd] = (signed short) regs->gpr[rd];
+ goto ldst_done;
+
+ case 44: /* sth */
+ case 45: /* sthu */
+ val = regs->gpr[rd];
+ err = write_mem(val, dform_ea(instr, regs), 2, regs);
+ goto ldst_done;
+
+ case 46: /* lmw */
+ ra = (instr >> 16) & 0x1f;
+ if (ra >= rd)
+ break; /* invalid form, ra in range to load */
+ ea = dform_ea(instr, regs);
+ do {
+ err = read_mem(&regs->gpr[rd], ea, 4, regs);
+ if (err)
+ return 0;
+ ea += 4;
+ } while (++rd < 32);
+ goto instr_done;
+
+ case 47: /* stmw */
+ ea = dform_ea(instr, regs);
+ do {
+ err = write_mem(regs->gpr[rd], ea, 4, regs);
+ if (err)
+ return 0;
+ ea += 4;
+ } while (++rd < 32);
+ goto instr_done;
+
+ case 48: /* lfs */
+ case 49: /* lfsu */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = dform_ea(instr, regs);
+ err = do_fp_load(rd, do_lfs, ea, 4, regs);
+ goto ldst_done;
+
+ case 50: /* lfd */
+ case 51: /* lfdu */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = dform_ea(instr, regs);
+ err = do_fp_load(rd, do_lfd, ea, 8, regs);
+ goto ldst_done;
+
+ case 52: /* stfs */
+ case 53: /* stfsu */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = dform_ea(instr, regs);
+ err = do_fp_store(rd, do_stfs, ea, 4, regs);
+ goto ldst_done;
+
+ case 54: /* stfd */
+ case 55: /* stfdu */
+ if (!(regs->msr & MSR_FP))
+ break;
+ ea = dform_ea(instr, regs);
+ err = do_fp_store(rd, do_stfd, ea, 8, regs);
+ goto ldst_done;
+
+#ifdef __powerpc64__
+ case 58: /* ld[u], lwa */
+ switch (instr & 3) {
+ case 0: /* ld */
+ err = read_mem(&regs->gpr[rd], dsform_ea(instr, regs),
+ 8, regs);
+ goto ldst_done;
+ case 1: /* ldu */
+ err = read_mem(&regs->gpr[rd], dsform_ea(instr, regs),
+ 8, regs);
+ goto ldst_done;
+ case 2: /* lwa */
+ err = read_mem(&regs->gpr[rd], dsform_ea(instr, regs),
+ 4, regs);
+ if (!err)
+ regs->gpr[rd] = (signed int) regs->gpr[rd];
+ goto ldst_done;
+ }
+ break;
+
+ case 62: /* std[u] */
+ val = regs->gpr[rd];
+ switch (instr & 3) {
+ case 0: /* std */
+ err = write_mem(val, dsform_ea(instr, regs), 8, regs);
+ goto ldst_done;
+ case 1: /* stdu */
+ err = write_mem(val, dsform_ea(instr, regs), 8, regs);
+ goto ldst_done;
+ }
+ break;
+#endif /* __powerpc64__ */
+
+ }
+ err = -EINVAL;
+
+ ldst_done:
+ if (err) {
+ regs->gpr[ra] = old_ra;
+ return 0; /* invoke DSI if -EFAULT? */
+ }
+ instr_done:
+ regs->nip += 4;
+#ifdef __powerpc64__
+ if ((regs->msr & MSR_SF) == 0)
+ regs->nip &= 0xffffffffUL;
+#endif
+ return 1;
+
+ logical_done:
+ if (instr & 1)
+ set_cr0(regs, ra);
+ goto instr_done;
+
+ arith_done:
+ if (instr & 1)
+ set_cr0(regs, rd);
+ goto instr_done;
}
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index cdc7526e9c93..4b66a1ece6d8 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -104,9 +104,10 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
}
/*
- * Set up one of the I/D BAT (block address translation) register pairs.
- * The parameters are not checked; in particular size must be a power
- * of 4 between 4k and 256M.
+ * Set up a variable-size TLB entry (tlbcam). The parameters are not checked;
+ * in particular size must be a power of 4 between 4k and 256M (or 1G, for cpus
+ * that support extended page sizes). Note that while some cpus support a
+ * page size of 4G, we don't allow its use here.
*/
static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
unsigned long size, unsigned long flags, unsigned int pid)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 80d110635d24..f78f19e0a2a4 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -42,6 +42,12 @@ EXPORT_SYMBOL(node_data);
static int min_common_depth;
static int n_mem_addr_cells, n_mem_size_cells;
+static int form1_affinity;
+
+#define MAX_DISTANCE_REF_POINTS 4
+static int distance_ref_points_depth;
+static const unsigned int *distance_ref_points;
+static int distance_lookup_table[MAX_NUMNODES][MAX_DISTANCE_REF_POINTS];
/*
* Allocate node_to_cpumask_map based on number of available nodes
@@ -204,6 +210,39 @@ static const u32 *of_get_usable_memory(struct device_node *memory)
return prop;
}
+int __node_distance(int a, int b)
+{
+ int i;
+ int distance = LOCAL_DISTANCE;
+
+ if (!form1_affinity)
+ return distance;
+
+ for (i = 0; i < distance_ref_points_depth; i++) {
+ if (distance_lookup_table[a][i] == distance_lookup_table[b][i])
+ break;
+
+ /* Double the distance for each NUMA level */
+ distance *= 2;
+ }
+
+ return distance;
+}
+
+static void initialize_distance_lookup_table(int nid,
+ const unsigned int *associativity)
+{
+ int i;
+
+ if (!form1_affinity)
+ return;
+
+ for (i = 0; i < distance_ref_points_depth; i++) {
+ distance_lookup_table[nid][i] =
+ associativity[distance_ref_points[i]];
+ }
+}
+
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
* info is found.
*/
@@ -225,6 +264,10 @@ static int of_node_to_nid_single(struct device_node *device)
/* POWER4 LPAR uses 0xffff as invalid node */
if (nid == 0xffff || nid >= MAX_NUMNODES)
nid = -1;
+
+ if (nid > 0 && tmp[0] >= distance_ref_points_depth)
+ initialize_distance_lookup_table(nid, tmp);
+
out:
return nid;
}
@@ -251,26 +294,10 @@ int of_node_to_nid(struct device_node *device)
}
EXPORT_SYMBOL_GPL(of_node_to_nid);
-/*
- * In theory, the "ibm,associativity" property may contain multiple
- * associativity lists because a resource may be multiply connected
- * into the machine. This resource then has different associativity
- * characteristics relative to its multiple connections. We ignore
- * this for now. We also assume that all cpu and memory sets have
- * their distances represented at a common level. This won't be
- * true for hierarchical NUMA.
- *
- * In any case the ibm,associativity-reference-points should give
- * the correct depth for a normal NUMA system.
- *
- * - Dave Hansen <haveblue@us.ibm.com>
- */
static int __init find_min_common_depth(void)
{
- int depth, index;
- const unsigned int *ref_points;
+ int depth;
struct device_node *rtas_root;
- unsigned int len;
struct device_node *chosen;
const char *vec5;
@@ -280,18 +307,28 @@ static int __init find_min_common_depth(void)
return -1;
/*
- * this property is 2 32-bit integers, each representing a level of
- * depth in the associativity nodes. The first is for an SMP
- * configuration (should be all 0's) and the second is for a normal
- * NUMA configuration.
+ * This property is a set of 32-bit integers, each representing
+ * an index into the ibm,associativity nodes.
+ *
+ * With form 0 affinity the first integer is for an SMP configuration
+ * (should be all 0's) and the second is for a normal NUMA
+ * configuration. We have only one level of NUMA.
+ *
+ * With form 1 affinity the first integer is the most significant
+ * NUMA boundary and the following are progressively less significant
+ * boundaries. There can be more than one level of NUMA.
*/
- index = 1;
- ref_points = of_get_property(rtas_root,
- "ibm,associativity-reference-points", &len);
+ distance_ref_points = of_get_property(rtas_root,
+ "ibm,associativity-reference-points",
+ &distance_ref_points_depth);
+
+ if (!distance_ref_points) {
+ dbg("NUMA: ibm,associativity-reference-points not found.\n");
+ goto err;
+ }
+
+ distance_ref_points_depth /= sizeof(int);
- /*
- * For form 1 affinity information we want the first field
- */
#define VEC5_AFFINITY_BYTE 5
#define VEC5_AFFINITY 0x80
chosen = of_find_node_by_path("/chosen");
@@ -299,19 +336,38 @@ static int __init find_min_common_depth(void)
vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
dbg("Using form 1 affinity\n");
- index = 0;
+ form1_affinity = 1;
}
}
- if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
- depth = ref_points[index];
+ if (form1_affinity) {
+ depth = distance_ref_points[0];
} else {
- dbg("NUMA: ibm,associativity-reference-points not found.\n");
- depth = -1;
+ if (distance_ref_points_depth < 2) {
+ printk(KERN_WARNING "NUMA: "
+ "short ibm,associativity-reference-points\n");
+ goto err;
+ }
+
+ depth = distance_ref_points[1];
}
- of_node_put(rtas_root);
+ /*
+ * Warn and cap if the hardware supports more than
+ * MAX_DISTANCE_REF_POINTS domains.
+ */
+ if (distance_ref_points_depth > MAX_DISTANCE_REF_POINTS) {
+ printk(KERN_WARNING "NUMA: distance array capped at "
+ "%d entries\n", MAX_DISTANCE_REF_POINTS);
+ distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
+ }
+
+ of_node_put(rtas_root);
return depth;
+
+err:
+ of_node_put(rtas_root);
+ return -1;
}
static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index ebc2f38eb381..2c7e801ab20b 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -92,7 +92,6 @@ static void pte_free_rcu_callback(struct rcu_head *head)
static void pte_free_submit(struct pte_freelist_batch *batch)
{
- INIT_RCU_HEAD(&batch->rcu);
call_rcu(&batch->rcu, pte_free_rcu_callback);
}
diff --git a/arch/powerpc/mm/tlb_hash32.c b/arch/powerpc/mm/tlb_hash32.c
index 8aaa8b7eb324..690566b66e8e 100644
--- a/arch/powerpc/mm/tlb_hash32.c
+++ b/arch/powerpc/mm/tlb_hash32.c
@@ -89,17 +89,6 @@ void tlb_flush(struct mmu_gather *tlb)
* -- Cort
*/
-/*
- * 750 SMP is a Bad Idea because the 750 doesn't broadcast all
- * the cache operations on the bus. Hence we need to use an IPI
- * to get the other CPU(s) to invalidate their TLBs.
- */
-#ifdef CONFIG_SMP_750
-#define FINISH_FLUSH smp_send_tlb_invalidate(0)
-#else
-#define FINISH_FLUSH do { } while (0)
-#endif
-
static void flush_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
@@ -138,7 +127,6 @@ static void flush_range(struct mm_struct *mm, unsigned long start,
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
flush_range(&init_mm, start, end);
- FINISH_FLUSH;
}
EXPORT_SYMBOL(flush_tlb_kernel_range);
@@ -162,7 +150,6 @@ void flush_tlb_mm(struct mm_struct *mm)
*/
for (mp = mm->mmap; mp != NULL; mp = mp->vm_next)
flush_range(mp->vm_mm, mp->vm_start, mp->vm_end);
- FINISH_FLUSH;
}
EXPORT_SYMBOL(flush_tlb_mm);
@@ -179,7 +166,6 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr)
pmd = pmd_offset(pud_offset(pgd_offset(mm, vmaddr), vmaddr), vmaddr);
if (!pmd_none(*pmd))
flush_hash_pages(mm->context.id, vmaddr, pmd_val(*pmd), 1);
- FINISH_FLUSH;
}
EXPORT_SYMBOL(flush_tlb_page);
@@ -192,6 +178,5 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
unsigned long end)
{
flush_range(vma->vm_mm, start, end);
- FINISH_FLUSH;
}
EXPORT_SYMBOL(flush_tlb_range);
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
index 4dac9b0525a4..e9dca280a4d2 100644
--- a/arch/powerpc/platforms/512x/Kconfig
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -1,29 +1,24 @@
config PPC_MPC512x
- bool
+ bool "512x-based boards"
+ depends on 6xx
select FSL_SOC
select IPIC
select PPC_CLOCK
select PPC_PCI_CHOICE
select FSL_PCI if PCI
-config PPC_MPC5121
- bool
- select PPC_MPC512x
-
config MPC5121_ADS
bool "Freescale MPC5121E ADS"
- depends on 6xx
+ depends on PPC_MPC512x
select DEFAULT_UIMAGE
- select PPC_MPC5121
select MPC5121_ADS_CPLD
help
This option enables support for the MPC5121E ADS board.
config MPC5121_GENERIC
bool "Generic support for simple MPC5121 based boards"
- depends on 6xx
+ depends on PPC_MPC512x
select DEFAULT_UIMAGE
- select PPC_MPC5121
help
This option enables support for simple MPC5121 based boards
which do not need custom platform specific setup.
diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c
index b5c753db125e..80234e5921f5 100644
--- a/arch/powerpc/platforms/52xx/lite5200_pm.c
+++ b/arch/powerpc/platforms/52xx/lite5200_pm.c
@@ -216,9 +216,6 @@ static int lite5200_pm_enter(suspend_state_t state)
lite5200_restore_regs();
- /* restart jiffies */
- wakeup_decrementer();
-
iounmap(mbar);
return 0;
}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
index 76722532bd95..568cef636275 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c
@@ -171,9 +171,6 @@ int mpc52xx_pm_enter(suspend_state_t state)
/* restore SRAM */
memcpy(sram, saved_sram, sram_size);
- /* restart jiffies */
- wakeup_decrementer();
-
/* reenable interrupts in PIC */
out_be32(&intr->main_mask, intr_main_mask);
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index e5e5f823d687..5dec408d6703 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -110,7 +110,9 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
if ((attr->ia_valid & ATTR_SIZE) &&
(attr->ia_size != inode->i_size))
return -EINVAL;
- return inode_setattr(inode, attr);
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
@@ -141,15 +143,14 @@ out:
}
static void
-spufs_delete_inode(struct inode *inode)
+spufs_evict_inode(struct inode *inode)
{
struct spufs_inode_info *ei = SPUFS_I(inode);
-
+ end_writeback(inode);
if (ei->i_ctx)
put_spu_context(ei->i_ctx);
if (ei->i_gang)
put_spu_gang(ei->i_gang);
- clear_inode(inode);
}
static void spufs_prune_dir(struct dentry *dir)
@@ -777,8 +778,7 @@ spufs_fill_super(struct super_block *sb, void *data, int silent)
.alloc_inode = spufs_alloc_inode,
.destroy_inode = spufs_destroy_inode,
.statfs = simple_statfs,
- .delete_inode = spufs_delete_inode,
- .drop_inode = generic_delete_inode,
+ .evict_inode = spufs_evict_inode,
.show_options = generic_show_options,
};
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c
index 00b6730bc48f..b6db7cef83b4 100644
--- a/arch/powerpc/platforms/iseries/vio.c
+++ b/arch/powerpc/platforms/iseries/vio.c
@@ -87,12 +87,11 @@ static struct device_node *new_node(const char *path,
if (!np)
return NULL;
- np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+ np->full_name = kstrdup(path, GFP_KERNEL);
if (!np->full_name) {
kfree(np);
return NULL;
}
- strcpy(np->full_name, path);
of_node_set_flag(np, OF_DYNAMIC);
kref_init(&np->kref);
np->parent = of_node_get(parent);
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c
index 1e9eba175ff0..415ca6d6b273 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_32.c
@@ -310,8 +310,12 @@ static int pmu_set_cpu_speed(int low_speed)
/* Restore low level PMU operations */
pmu_unlock();
- /* Restore decrementer */
- wakeup_decrementer();
+ /*
+ * Restore decrementer; we'll take a decrementer interrupt
+ * as soon as interrupts are re-enabled and the generic
+ * clockevents code will reprogram it with the right value.
+ */
+ set_dec(1);
/* Restore interrupts */
mpic_cpu_set_priority(pic_prio);
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index 3dbef309bc8d..046ace9c4381 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -26,3 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
obj-$(CONFIG_PHYP_DUMP) += phyp_dump.o
obj-$(CONFIG_CMM) += cmm.o
obj-$(CONFIG_DTL) += dtl.o
+
+ifeq ($(CONFIG_PPC_PSERIES),y)
+obj-$(CONFIG_SUSPEND) += suspend.o
+endif
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c
index 30b987b73c20..8ed0d2d0e1b5 100644
--- a/arch/powerpc/platforms/pseries/eeh_cache.c
+++ b/arch/powerpc/platforms/pseries/eeh_cache.c
@@ -288,8 +288,7 @@ void __init pci_addr_cache_build(void)
spin_lock_init(&pci_io_addr_cache_root.piar_lock);
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-
+ for_each_pci_dev(dev) {
pci_addr_cache_insert_device(dev);
dn = pci_device_to_OF_node(dev);
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c
index e889c9d9586a..2605c310166a 100644
--- a/arch/powerpc/platforms/pseries/event_sources.c
+++ b/arch/powerpc/platforms/pseries/event_sources.c
@@ -41,9 +41,12 @@ void request_event_sources_irqs(struct device_node *np,
if (count > 15)
break;
virqs[count] = irq_create_mapping(NULL, *(opicprop++));
- if (virqs[count] == NO_IRQ)
- printk(KERN_ERR "Unable to allocate interrupt "
- "number for %s\n", np->full_name);
+ if (virqs[count] == NO_IRQ) {
+ pr_err("event-sources: Unable to allocate "
+ "interrupt number for %s\n",
+ np->full_name);
+ WARN_ON(1);
+ }
else
count++;
@@ -59,9 +62,12 @@ void request_event_sources_irqs(struct device_node *np,
virqs[count] = irq_create_of_mapping(oirq.controller,
oirq.specifier,
oirq.size);
- if (virqs[count] == NO_IRQ)
- printk(KERN_ERR "Unable to allocate interrupt "
- "number for %s\n", np->full_name);
+ if (virqs[count] == NO_IRQ) {
+ pr_err("event-sources: Unable to allocate "
+ "interrupt number for %s\n",
+ np->full_name);
+ WARN_ON(1);
+ }
else
count++;
}
@@ -70,8 +76,9 @@ void request_event_sources_irqs(struct device_node *np,
/* Now request them */
for (i = 0; i < count; i++) {
if (request_irq(virqs[i], handler, 0, name, NULL)) {
- printk(KERN_ERR "Unable to request interrupt %d for "
- "%s\n", virqs[i], np->full_name);
+ pr_err("event-sources: Unable to request interrupt "
+ "%d for %s\n", virqs[i], np->full_name);
+ WARN_ON(1);
return;
}
}
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 8f85f399ab9f..bbe507635364 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -116,6 +116,9 @@ static void pseries_mach_cpu_die(void)
if (get_preferred_offline_state(cpu) == CPU_STATE_INACTIVE) {
set_cpu_current_state(cpu, CPU_STATE_INACTIVE);
+ if (ppc_md.suspend_disable_cpu)
+ ppc_md.suspend_disable_cpu();
+
cede_latency_hint = 2;
get_lppaca()->idle = 1;
diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c
index 41a3e9a039ed..a4fc6da87c2e 100644
--- a/arch/powerpc/platforms/pseries/ras.c
+++ b/arch/powerpc/platforms/pseries/ras.c
@@ -61,7 +61,6 @@ static int ras_check_exception_token;
#define EPOW_SENSOR_TOKEN 9
#define EPOW_SENSOR_INDEX 0
-#define RAS_VECTOR_OFFSET 0x500
static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
@@ -121,7 +120,7 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id)
spin_lock(&ras_log_buf_lock);
status = rtas_call(ras_check_exception_token, 6, 1, NULL,
- RAS_VECTOR_OFFSET,
+ RTAS_VECTOR_EXTERNAL_INTERRUPT,
irq_map[irq].hwirq,
RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
critical, __pa(&ras_log_buf),
@@ -156,7 +155,7 @@ static irqreturn_t ras_error_interrupt(int irq, void *dev_id)
spin_lock(&ras_log_buf_lock);
status = rtas_call(ras_check_exception_token, 6, 1, NULL,
- RAS_VECTOR_OFFSET,
+ RTAS_VECTOR_EXTERNAL_INTERRUPT,
irq_map[irq].hwirq,
RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
__pa(&ras_log_buf),
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 1a58637bcea5..57ddbb43b33a 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -118,12 +118,10 @@ static int pSeries_reconfig_add_node(const char *path, struct property *proplist
if (!np)
goto out_err;
- np->full_name = kmalloc(strlen(path) + 1, GFP_KERNEL);
+ np->full_name = kstrdup(path, GFP_KERNEL);
if (!np->full_name)
goto out_err;
- strcpy(np->full_name, path);
-
np->properties = proplist;
of_node_set_flag(np, OF_DYNAMIC);
kref_init(&np->kref);
diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c
new file mode 100644
index 000000000000..ed72098bb4e3
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/suspend.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2010 Brian King IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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/delay.h>
+#include <linux/suspend.h>
+#include <asm/firmware.h>
+#include <asm/hvcall.h>
+#include <asm/machdep.h>
+#include <asm/mmu.h>
+#include <asm/rtas.h>
+
+static u64 stream_id;
+static struct sys_device suspend_sysdev;
+static DECLARE_COMPLETION(suspend_work);
+static struct rtas_suspend_me_data suspend_data;
+static atomic_t suspending;
+
+/**
+ * pseries_suspend_begin - First phase of hibernation
+ *
+ * Check to ensure we are in a valid state to hibernate
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_begin(suspend_state_t state)
+{
+ long vasi_state, rc;
+ unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+ /* Make sure the state is valid */
+ rc = plpar_hcall(H_VASI_STATE, retbuf, stream_id);
+
+ vasi_state = retbuf[0];
+
+ if (rc) {
+ pr_err("pseries_suspend_begin: vasi_state returned %ld\n",rc);
+ return rc;
+ } else if (vasi_state == H_VASI_ENABLED) {
+ return -EAGAIN;
+ } else if (vasi_state != H_VASI_SUSPENDING) {
+ pr_err("pseries_suspend_begin: vasi_state returned state %ld\n",
+ vasi_state);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+/**
+ * pseries_suspend_cpu - Suspend a single CPU
+ *
+ * Makes the H_JOIN call to suspend the CPU
+ *
+ **/
+static int pseries_suspend_cpu(void)
+{
+ if (atomic_read(&suspending))
+ return rtas_suspend_cpu(&suspend_data);
+ return 0;
+}
+
+/**
+ * pseries_suspend_enter - Final phase of hibernation
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_enter(suspend_state_t state)
+{
+ int rc = rtas_suspend_last_cpu(&suspend_data);
+
+ atomic_set(&suspending, 0);
+ atomic_set(&suspend_data.done, 1);
+ return rc;
+}
+
+/**
+ * pseries_prepare_late - Prepare to suspend all other CPUs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_prepare_late(void)
+{
+ atomic_set(&suspending, 1);
+ atomic_set(&suspend_data.working, 0);
+ atomic_set(&suspend_data.done, 0);
+ atomic_set(&suspend_data.error, 0);
+ suspend_data.complete = &suspend_work;
+ INIT_COMPLETION(suspend_work);
+ return 0;
+}
+
+/**
+ * store_hibernate - Initiate partition hibernation
+ * @classdev: sysdev class struct
+ * @attr: class device attribute struct
+ * @buf: buffer
+ * @count: buffer size
+ *
+ * Write the stream ID received from the HMC to this file
+ * to trigger hibernating the partition
+ *
+ * Return value:
+ * number of bytes printed to buffer / other on failure
+ **/
+static ssize_t store_hibernate(struct sysdev_class *classdev,
+ struct sysdev_class_attribute *attr,
+ const char *buf, size_t count)
+{
+ int rc;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ stream_id = simple_strtoul(buf, NULL, 16);
+
+ do {
+ rc = pseries_suspend_begin(PM_SUSPEND_MEM);
+ if (rc == -EAGAIN)
+ ssleep(1);
+ } while (rc == -EAGAIN);
+
+ if (!rc)
+ rc = pm_suspend(PM_SUSPEND_MEM);
+
+ stream_id = 0;
+
+ if (!rc)
+ rc = count;
+ return rc;
+}
+
+static SYSDEV_CLASS_ATTR(hibernate, S_IWUSR, NULL, store_hibernate);
+
+static struct sysdev_class suspend_sysdev_class = {
+ .name = "power",
+};
+
+static struct platform_suspend_ops pseries_suspend_ops = {
+ .valid = suspend_valid_only_mem,
+ .begin = pseries_suspend_begin,
+ .prepare_late = pseries_prepare_late,
+ .enter = pseries_suspend_enter,
+};
+
+/**
+ * pseries_suspend_sysfs_register - Register with sysfs
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int pseries_suspend_sysfs_register(struct sys_device *sysdev)
+{
+ int rc;
+
+ if ((rc = sysdev_class_register(&suspend_sysdev_class)))
+ return rc;
+
+ sysdev->id = 0;
+ sysdev->cls = &suspend_sysdev_class;
+
+ if ((rc = sysdev_class_create_file(&suspend_sysdev_class, &attr_hibernate)))
+ goto class_unregister;
+
+ return 0;
+
+class_unregister:
+ sysdev_class_unregister(&suspend_sysdev_class);
+ return rc;
+}
+
+/**
+ * pseries_suspend_init - initcall for pSeries suspend
+ *
+ * Return value:
+ * 0 on success / other on failure
+ **/
+static int __init pseries_suspend_init(void)
+{
+ int rc;
+
+ if (!machine_is(pseries) || !firmware_has_feature(FW_FEATURE_LPAR))
+ return 0;
+
+ suspend_data.token = rtas_token("ibm,suspend-me");
+ if (suspend_data.token == RTAS_UNKNOWN_SERVICE)
+ return 0;
+
+ if ((rc = pseries_suspend_sysfs_register(&suspend_sysdev)))
+ return rc;
+
+ ppc_md.suspend_disable_cpu = pseries_suspend_cpu;
+ suspend_set_ops(&pseries_suspend_ops);
+ return 0;
+}
+
+__initcall(pseries_suspend_init);
diff --git a/arch/powerpc/sysdev/micropatch.c b/arch/powerpc/sysdev/micropatch.c
index d8d602840757..c0bb76ef7242 100644
--- a/arch/powerpc/sysdev/micropatch.c
+++ b/arch/powerpc/sysdev/micropatch.c
@@ -4,6 +4,7 @@
* also relocates SMC2, but this would require additional changes
* to uart.c, so I am holding off on that for a moment.
*/
+#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -16,6 +17,7 @@
#include <asm/page.h>
#include <asm/pgtable.h>
#include <asm/8xx_immap.h>
+#include <asm/cpm.h>
#include <asm/cpm1.h>
/*
@@ -24,7 +26,7 @@
#ifdef CONFIG_I2C_SPI_UCODE_PATCH
-uint patch_2000[] = {
+static uint patch_2000[] __initdata = {
0x7FFFEFD9,
0x3FFD0000,
0x7FFB49F7,
@@ -143,7 +145,7 @@ uint patch_2000[] = {
0x5F8247F8
};
-uint patch_2f00[] = {
+static uint patch_2f00[] __initdata = {
0x3E303430,
0x34343737,
0xABF7BF9B,
@@ -182,7 +184,7 @@ uint patch_2f00[] = {
#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
-uint patch_2000[] = {
+static uint patch_2000[] __initdata = {
0x3fff0000,
0x3ffd0000,
0x3ffb0000,
@@ -505,7 +507,7 @@ uint patch_2000[] = {
0x6079e2bb
};
-uint patch_2f00[] = {
+static uint patch_2f00[] __initdata = {
0x30303030,
0x3e3e3434,
0xabbf9b99,
@@ -572,7 +574,7 @@ uint patch_2f00[] = {
0xf22f3f23
};
-uint patch_2e00[] = {
+static uint patch_2e00[] __initdata = {
0x27eeeeee,
0xeeeeeeee,
0xeeeeeeee,
@@ -598,7 +600,7 @@ uint patch_2e00[] = {
#ifdef CONFIG_USB_SOF_UCODE_PATCH
-uint patch_2000[] = {
+static uint patch_2000[] __initdata = {
0x7fff0000,
0x7ffd0000,
0x7ffb0000,
@@ -613,21 +615,25 @@ uint patch_2000[] = {
0x60750000
};
-uint patch_2f00[] = {
+static uint patch_2f00[] __initdata = {
0x3030304c,
0xcab9e441,
0xa1aaf220
};
#endif
-void
-cpm_load_patch(cpm8xx_t *cp)
+void __init cpm_load_patch(cpm8xx_t *cp)
{
volatile uint *dp; /* Dual-ported RAM. */
volatile cpm8xx_t *commproc;
+#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \
+ defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
volatile iic_t *iip;
- volatile spi_t *spp;
+ volatile struct spi_pram *spp;
+#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
volatile smc_uart_t *smp;
+#endif
+#endif
int i;
commproc = cp;
@@ -668,8 +674,8 @@ cpm_load_patch(cpm8xx_t *cp)
/* Put SPI above the IIC, also 32-byte aligned.
*/
i = (RPBASE + sizeof(iic_t) + 31) & ~31;
- spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
- spp->spi_rpbase = i;
+ spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI];
+ spp->rpbase = i;
# if defined(CONFIG_I2C_SPI_UCODE_PATCH)
commproc->cp_cpmcr1 = 0x802a;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 20b73c025a45..7c1342618a30 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1636,6 +1636,24 @@ void __devinit smp_mpic_setup_cpu(int cpu)
{
mpic_setup_this_cpu();
}
+
+void mpic_reset_core(int cpu)
+{
+ struct mpic *mpic = mpic_primary;
+ u32 pir;
+ int cpuid = get_hard_smp_processor_id(cpu);
+
+ /* Set target bit for core reset */
+ pir = mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
+ pir |= (1 << cpuid);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
+
+ /* Restore target bit after reset complete */
+ pir &= ~(1 << cpuid);
+ mpic_write(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT), pir);
+ mpic_read(mpic->gregs, MPIC_INFO(GREG_PROCESSOR_INIT));
+}
#endif /* CONFIG_SMP */
#ifdef CONFIG_PM
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index eff433c322a0..e4a6df77b8d7 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -37,5 +37,6 @@ static inline int mpic_pasemi_msi_init(struct mpic *mpic)
extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
extern void mpic_set_vector(unsigned int virq, unsigned int vector);
extern int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask);
+extern void mpic_reset_core(int cpu);
#endif /* _POWERPC_SYSDEV_MPIC_H */
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index 6b120f073043..98a4a4c267a7 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -117,10 +117,10 @@ static struct inode *hypfs_make_inode(struct super_block *sb, int mode)
return ret;
}
-static void hypfs_drop_inode(struct inode *inode)
+static void hypfs_evict_inode(struct inode *inode)
{
+ end_writeback(inode);
kfree(inode->i_private);
- generic_delete_inode(inode);
}
static int hypfs_open(struct inode *inode, struct file *filp)
@@ -460,7 +460,7 @@ static struct file_system_type hypfs_type = {
static const struct super_operations hypfs_s_ops = {
.statfs = simple_statfs,
- .drop_inode = hypfs_drop_inode,
+ .evict_inode = hypfs_evict_inode,
.show_options = hypfs_show_options,
};
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h
index 1c0030f9b890..f3ba0fa98de6 100644
--- a/arch/s390/include/asm/ccwdev.h
+++ b/arch/s390/include/asm/ccwdev.h
@@ -208,6 +208,8 @@ extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *);
extern struct ccw_device *ccw_device_probe_console(void);
extern int ccw_device_force_console(void);
+int ccw_device_siosl(struct ccw_device *);
+
// FIXME: these have to go
extern int _ccw_device_get_subchannel_number(struct ccw_device *);
diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c
index eb6a2ef5f82e..a9550dca3e4b 100644
--- a/arch/s390/mm/cmm.c
+++ b/arch/s390/mm/cmm.c
@@ -427,7 +427,7 @@ static struct notifier_block cmm_power_notifier = {
.notifier_call = cmm_power_event,
};
-static int cmm_init(void)
+static int __init cmm_init(void)
{
int rc = -ENOMEM;
@@ -435,6 +435,13 @@ static int cmm_init(void)
if (!cmm_sysctl_header)
goto out_sysctl;
#ifdef CONFIG_CMM_IUCV
+ /* convert sender to uppercase characters */
+ if (sender) {
+ int len = strlen(sender);
+ while (len--)
+ sender[len] = toupper(sender[len]);
+ }
+
rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target);
if (rc < 0)
goto out_smsg;
@@ -467,7 +474,7 @@ out_sysctl:
}
module_init(cmm_init);
-static void cmm_exit(void)
+static void __exit cmm_exit(void)
{
unregister_sysctl_table(cmm_sysctl_header);
#ifdef CONFIG_CMM_IUCV
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 573fca1fbd9b..4b5a1d53704d 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -23,6 +23,7 @@ config SUPERH
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_LZO
select HAVE_SYSCALL_TRACEPOINTS
+ select HAVE_REGS_AND_STACK_ACCESS_API
select RTC_LIB
select GENERIC_ATOMIC64
help
@@ -572,7 +573,7 @@ config SH_CLK_CPG
config SH_CLK_CPG_LEGACY
depends on SH_CLK_CPG
def_bool y if !CPU_SUBTYPE_SH7785 && !ARCH_SHMOBILE && \
- !CPU_SUBTYPE_SH7786
+ !CPU_SUBTYPE_SH7786 && !CPU_SUBTYPE_SH7757
config SH_CLK_MD
int "CPU Mode Pin Setting"
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 07b35ca2f644..90ed1ec6921d 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -165,6 +165,11 @@ config SH_HIGHLANDER
select SYS_SUPPORTS_PCI
select IO_TRAPPED if MMU
+config SH_SH7757LCR
+ bool "SH7757LCR"
+ depends on CPU_SUBTYPE_SH7757
+ select ARCH_REQUIRE_GPIOLIB
+
config SH_SH7785LCR
bool "SH7785LCR"
depends on CPU_SUBTYPE_SH7785
@@ -309,6 +314,17 @@ config SH_POLARIS
help
Select if configuring for an SMSC Polaris development board
+config SH_SH2007
+ bool "SH-2007 board"
+ select NO_IOPORT
+ depends on CPU_SUBTYPE_SH7780
+ help
+ SH-2007 is a single-board computer based around SH7780 chip
+ intended for embedded applications.
+ It has an Ethernet interface (SMC9118), direct connected
+ Compact Flash socket, two serial ports and PC-104 bus.
+ More information at <http://sh2000.sh-linux.org>.
+
endmenu
source "arch/sh/boards/mach-r2d/Kconfig"
diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile
index 4f90f9b7a922..38ef655cc0f0 100644
--- a/arch/sh/boards/Makefile
+++ b/arch/sh/boards/Makefile
@@ -2,6 +2,7 @@
# Specific board support, not covered by a mach group.
#
obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o
+obj-$(CONFIG_SH_SH2007) += board-sh2007.o
obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o
obj-$(CONFIG_SH_URQUELL) += board-urquell.o
obj-$(CONFIG_SH_SHMIN) += board-shmin.o
@@ -9,3 +10,4 @@ obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o
obj-$(CONFIG_SH_ESPT) += board-espt.o
obj-$(CONFIG_SH_POLARIS) += board-polaris.o
obj-$(CONFIG_SH_TITAN) += board-titan.o
+obj-$(CONFIG_SH_SH7757LCR) += board-sh7757lcr.o
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c
new file mode 100644
index 000000000000..b90b78f6a829
--- /dev/null
+++ b/arch/sh/boards/board-sh2007.c
@@ -0,0 +1,133 @@
+/*
+ * SH-2007 board support.
+ *
+ * Copyright (C) 2003, 2004 SUGIOKA Toshinobu
+ * Copyright (C) 2010 Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/smsc911x.h>
+#include <linux/platform_device.h>
+#include <linux/ata_platform.h>
+#include <linux/io.h>
+#include <asm/machvec.h>
+#include <mach/sh2007.h>
+
+struct smsc911x_platform_config smc911x_info = {
+ .flags = SMSC911X_USE_32BIT,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct resource smsc9118_0_resources[] = {
+ [0] = {
+ .start = SMC0_BASE,
+ .end = SMC0_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x240),
+ .end = evt2irq(0x240),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct resource smsc9118_1_resources[] = {
+ [0] = {
+ .start = SMC1_BASE,
+ .end = SMC1_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x280),
+ .end = evt2irq(0x280),
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device smsc9118_0_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(smsc9118_0_resources),
+ .resource = smsc9118_0_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct platform_device smsc9118_1_device = {
+ .name = "smsc911x",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(smsc9118_1_resources),
+ .resource = smsc9118_1_resources,
+ .dev = {
+ .platform_data = &smc911x_info,
+ },
+};
+
+static struct resource cf_resources[] = {
+ [0] = {
+ .start = CF_BASE + CF_OFFSET,
+ .end = CF_BASE + CF_OFFSET + 0x0f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = CF_BASE + CF_OFFSET + 0x206,
+ .end = CF_BASE + CF_OFFSET + 0x20f,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = evt2irq(0x2c0),
+ .end = evt2irq(0x2c0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device cf_device = {
+ .name = "pata_platform",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(cf_resources),
+ .resource = cf_resources,
+};
+
+static struct platform_device *sh2007_devices[] __initdata = {
+ &smsc9118_0_device,
+ &smsc9118_1_device,
+ &cf_device,
+};
+
+static int __init sh2007_io_init(void)
+{
+ platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices));
+ return 0;
+}
+subsys_initcall(sh2007_io_init);
+
+static void __init sh2007_init_irq(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ);
+}
+
+/*
+ * Initialize the board
+ */
+static void __init sh2007_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "SH-2007 Setup...");
+
+ /* setup wait control registers for area 5 */
+ __raw_writel(CS5BCR_D, CS5BCR);
+ __raw_writel(CS5WCR_D, CS5WCR);
+ __raw_writel(CS5PCR_D, CS5PCR);
+
+ printk(KERN_INFO " done.\n");
+}
+
+/*
+ * The Machine Vector
+ */
+struct sh_machine_vector mv_sh2007 __initmv = {
+ .mv_setup = sh2007_setup,
+ .mv_name = "sh2007",
+ .mv_init_irq = sh2007_init_irq,
+};
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
new file mode 100644
index 000000000000..c475f1056ab4
--- /dev/null
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -0,0 +1,374 @@
+/*
+ * Renesas R0P7757LC0012RL Support.
+ *
+ * Copyright (C) 2009 - 2010 Renesas Solutions Corp.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/io.h>
+#include <cpu/sh7757.h>
+#include <asm/sh_eth.h>
+#include <asm/heartbeat.h>
+
+static struct resource heartbeat_resource = {
+ .start = 0xffec005c, /* PUDR */
+ .end = 0xffec005c,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+};
+
+static unsigned char heartbeat_bit_pos[] = { 0, 1, 2, 3 };
+
+static struct heartbeat_data heartbeat_data = {
+ .bit_pos = heartbeat_bit_pos,
+ .nr_bits = ARRAY_SIZE(heartbeat_bit_pos),
+ .flags = HEARTBEAT_INVERTED,
+};
+
+static struct platform_device heartbeat_device = {
+ .name = "heartbeat",
+ .id = -1,
+ .dev = {
+ .platform_data = &heartbeat_data,
+ },
+ .num_resources = 1,
+ .resource = &heartbeat_resource,
+};
+
+/* Fast Ethernet */
+static struct resource sh_eth0_resources[] = {
+ {
+ .start = 0xfef00000,
+ .end = 0xfef001ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 84,
+ .end = 84,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth0_pdata = {
+ .phy = 1,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth0_device = {
+ .name = "sh-eth",
+ .resource = sh_eth0_resources,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(sh_eth0_resources),
+ .dev = {
+ .platform_data = &sh7757_eth0_pdata,
+ },
+};
+
+static struct resource sh_eth1_resources[] = {
+ {
+ .start = 0xfef00800,
+ .end = 0xfef009ff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = 84,
+ .end = 84,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct sh_eth_plat_data sh7757_eth1_pdata = {
+ .phy = 1,
+ .edmac_endian = EDMAC_LITTLE_ENDIAN,
+};
+
+static struct platform_device sh7757_eth1_device = {
+ .name = "sh-eth",
+ .resource = sh_eth1_resources,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sh_eth1_resources),
+ .dev = {
+ .platform_data = &sh7757_eth1_pdata,
+ },
+};
+
+static struct platform_device *sh7757lcr_devices[] __initdata = {
+ &heartbeat_device,
+ &sh7757_eth0_device,
+ &sh7757_eth1_device,
+};
+
+static int __init sh7757lcr_devices_setup(void)
+{
+ /* RGMII (PTA) */
+ gpio_request(GPIO_FN_ET0_MDC, NULL);
+ gpio_request(GPIO_FN_ET0_MDIO, NULL);
+ gpio_request(GPIO_FN_ET1_MDC, NULL);
+ gpio_request(GPIO_FN_ET1_MDIO, NULL);
+
+ /* ONFI (PTB, PTZ) */
+ gpio_request(GPIO_FN_ON_NRE, NULL);
+ gpio_request(GPIO_FN_ON_NWE, NULL);
+ gpio_request(GPIO_FN_ON_NWP, NULL);
+ gpio_request(GPIO_FN_ON_NCE0, NULL);
+ gpio_request(GPIO_FN_ON_R_B0, NULL);
+ gpio_request(GPIO_FN_ON_ALE, NULL);
+ gpio_request(GPIO_FN_ON_CLE, NULL);
+
+ gpio_request(GPIO_FN_ON_DQ7, NULL);
+ gpio_request(GPIO_FN_ON_DQ6, NULL);
+ gpio_request(GPIO_FN_ON_DQ5, NULL);
+ gpio_request(GPIO_FN_ON_DQ4, NULL);
+ gpio_request(GPIO_FN_ON_DQ3, NULL);
+ gpio_request(GPIO_FN_ON_DQ2, NULL);
+ gpio_request(GPIO_FN_ON_DQ1, NULL);
+ gpio_request(GPIO_FN_ON_DQ0, NULL);
+
+ /* IRQ8 to 0 (PTB, PTC) */
+ gpio_request(GPIO_FN_IRQ8, NULL);
+ gpio_request(GPIO_FN_IRQ7, NULL);
+ gpio_request(GPIO_FN_IRQ6, NULL);
+ gpio_request(GPIO_FN_IRQ5, NULL);
+ gpio_request(GPIO_FN_IRQ4, NULL);
+ gpio_request(GPIO_FN_IRQ3, NULL);
+ gpio_request(GPIO_FN_IRQ2, NULL);
+ gpio_request(GPIO_FN_IRQ1, NULL);
+ gpio_request(GPIO_FN_IRQ0, NULL);
+
+ /* SPI0 (PTD) */
+ gpio_request(GPIO_FN_SP0_MOSI, NULL);
+ gpio_request(GPIO_FN_SP0_MISO, NULL);
+ gpio_request(GPIO_FN_SP0_SCK, NULL);
+ gpio_request(GPIO_FN_SP0_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP0_SS0, NULL);
+ gpio_request(GPIO_FN_SP0_SS1, NULL);
+ gpio_request(GPIO_FN_SP0_SS2, NULL);
+ gpio_request(GPIO_FN_SP0_SS3, NULL);
+
+ /* RMII 0/1 (PTE, PTF) */
+ gpio_request(GPIO_FN_RMII0_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII0_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII0_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII0_RX_ER, NULL);
+ gpio_request(GPIO_FN_RMII1_CRS_DV, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_TXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_TXEN, NULL);
+ gpio_request(GPIO_FN_RMII1_REFCLK, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD1, NULL);
+ gpio_request(GPIO_FN_RMII1_RXD0, NULL);
+ gpio_request(GPIO_FN_RMII1_RX_ER, NULL);
+
+ /* eMMC (PTG) */
+ gpio_request(GPIO_FN_MMCCLK, NULL);
+ gpio_request(GPIO_FN_MMCCMD, NULL);
+ gpio_request(GPIO_FN_MMCDAT7, NULL);
+ gpio_request(GPIO_FN_MMCDAT6, NULL);
+ gpio_request(GPIO_FN_MMCDAT5, NULL);
+ gpio_request(GPIO_FN_MMCDAT4, NULL);
+ gpio_request(GPIO_FN_MMCDAT3, NULL);
+ gpio_request(GPIO_FN_MMCDAT2, NULL);
+ gpio_request(GPIO_FN_MMCDAT1, NULL);
+ gpio_request(GPIO_FN_MMCDAT0, NULL);
+
+ /* LPC (PTG, PTH, PTQ, PTU) */
+ gpio_request(GPIO_FN_SERIRQ, NULL);
+ gpio_request(GPIO_FN_LPCPD, NULL);
+ gpio_request(GPIO_FN_LDRQ, NULL);
+ gpio_request(GPIO_FN_WP, NULL);
+ gpio_request(GPIO_FN_FMS0, NULL);
+ gpio_request(GPIO_FN_LAD3, NULL);
+ gpio_request(GPIO_FN_LAD2, NULL);
+ gpio_request(GPIO_FN_LAD1, NULL);
+ gpio_request(GPIO_FN_LAD0, NULL);
+ gpio_request(GPIO_FN_LFRAME, NULL);
+ gpio_request(GPIO_FN_LRESET, NULL);
+ gpio_request(GPIO_FN_LCLK, NULL);
+ gpio_request(GPIO_FN_LGPIO7, NULL);
+ gpio_request(GPIO_FN_LGPIO6, NULL);
+ gpio_request(GPIO_FN_LGPIO5, NULL);
+ gpio_request(GPIO_FN_LGPIO4, NULL);
+
+ /* SPI1 (PTH) */
+ gpio_request(GPIO_FN_SP1_MOSI, NULL);
+ gpio_request(GPIO_FN_SP1_MISO, NULL);
+ gpio_request(GPIO_FN_SP1_SCK, NULL);
+ gpio_request(GPIO_FN_SP1_SCK_FB, NULL);
+ gpio_request(GPIO_FN_SP1_SS0, NULL);
+ gpio_request(GPIO_FN_SP1_SS1, NULL);
+
+ /* SDHI (PTI) */
+ gpio_request(GPIO_FN_SD_WP, NULL);
+ gpio_request(GPIO_FN_SD_CD, NULL);
+ gpio_request(GPIO_FN_SD_CLK, NULL);
+ gpio_request(GPIO_FN_SD_CMD, NULL);
+ gpio_request(GPIO_FN_SD_D3, NULL);
+ gpio_request(GPIO_FN_SD_D2, NULL);
+ gpio_request(GPIO_FN_SD_D1, NULL);
+ gpio_request(GPIO_FN_SD_D0, NULL);
+
+ /* SCIF3/4 (PTJ, PTW) */
+ gpio_request(GPIO_FN_RTS3, NULL);
+ gpio_request(GPIO_FN_CTS3, NULL);
+ gpio_request(GPIO_FN_TXD3, NULL);
+ gpio_request(GPIO_FN_RXD3, NULL);
+ gpio_request(GPIO_FN_RTS4, NULL);
+ gpio_request(GPIO_FN_RXD4, NULL);
+ gpio_request(GPIO_FN_TXD4, NULL);
+ gpio_request(GPIO_FN_CTS4, NULL);
+
+ /* SERMUX (PTK, PTL, PTO, PTV) */
+ gpio_request(GPIO_FN_COM2_TXD, NULL);
+ gpio_request(GPIO_FN_COM2_RXD, NULL);
+ gpio_request(GPIO_FN_COM2_RTS, NULL);
+ gpio_request(GPIO_FN_COM2_CTS, NULL);
+ gpio_request(GPIO_FN_COM2_DTR, NULL);
+ gpio_request(GPIO_FN_COM2_DSR, NULL);
+ gpio_request(GPIO_FN_COM2_DCD, NULL);
+ gpio_request(GPIO_FN_COM2_RI, NULL);
+ gpio_request(GPIO_FN_RAC_RXD, NULL);
+ gpio_request(GPIO_FN_RAC_RTS, NULL);
+ gpio_request(GPIO_FN_RAC_CTS, NULL);
+ gpio_request(GPIO_FN_RAC_DTR, NULL);
+ gpio_request(GPIO_FN_RAC_DSR, NULL);
+ gpio_request(GPIO_FN_RAC_DCD, NULL);
+ gpio_request(GPIO_FN_RAC_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_TXD, NULL);
+ gpio_request(GPIO_FN_COM1_RXD, NULL);
+ gpio_request(GPIO_FN_COM1_RTS, NULL);
+ gpio_request(GPIO_FN_COM1_CTS, NULL);
+
+ writeb(0x10, 0xfe470000); /* SMR0: SerMux mode 0 */
+
+ /* IIC (PTM, PTR, PTS) */
+ gpio_request(GPIO_FN_SDA7, NULL);
+ gpio_request(GPIO_FN_SCL7, NULL);
+ gpio_request(GPIO_FN_SDA6, NULL);
+ gpio_request(GPIO_FN_SCL6, NULL);
+ gpio_request(GPIO_FN_SDA5, NULL);
+ gpio_request(GPIO_FN_SCL5, NULL);
+ gpio_request(GPIO_FN_SDA4, NULL);
+ gpio_request(GPIO_FN_SCL4, NULL);
+ gpio_request(GPIO_FN_SDA3, NULL);
+ gpio_request(GPIO_FN_SCL3, NULL);
+ gpio_request(GPIO_FN_SDA2, NULL);
+ gpio_request(GPIO_FN_SCL2, NULL);
+ gpio_request(GPIO_FN_SDA1, NULL);
+ gpio_request(GPIO_FN_SCL1, NULL);
+ gpio_request(GPIO_FN_SDA0, NULL);
+ gpio_request(GPIO_FN_SCL0, NULL);
+
+ /* USB (PTN) */
+ gpio_request(GPIO_FN_VBUS_EN, NULL);
+ gpio_request(GPIO_FN_VBUS_OC, NULL);
+
+ /* SGPIO1/0 (PTN, PTO) */
+ gpio_request(GPIO_FN_SGPIO1_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO1_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO1_DO, NULL);
+ gpio_request(GPIO_FN_SGPIO0_CLK, NULL);
+ gpio_request(GPIO_FN_SGPIO0_LOAD, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DI, NULL);
+ gpio_request(GPIO_FN_SGPIO0_DO, NULL);
+
+ /* WDT (PTN) */
+ gpio_request(GPIO_FN_SUB_CLKIN, NULL);
+
+ /* System (PTT) */
+ gpio_request(GPIO_FN_STATUS1, NULL);
+ gpio_request(GPIO_FN_STATUS0, NULL);
+
+ /* PWMX (PTT) */
+ gpio_request(GPIO_FN_PWMX1, NULL);
+ gpio_request(GPIO_FN_PWMX0, NULL);
+
+ /* R-SPI (PTV) */
+ gpio_request(GPIO_FN_R_SPI_MOSI, NULL);
+ gpio_request(GPIO_FN_R_SPI_MISO, NULL);
+ gpio_request(GPIO_FN_R_SPI_RSPCK, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL0, NULL);
+ gpio_request(GPIO_FN_R_SPI_SSL1, NULL);
+
+ /* EVC (PTV, PTW) */
+ gpio_request(GPIO_FN_EVENT7, NULL);
+ gpio_request(GPIO_FN_EVENT6, NULL);
+ gpio_request(GPIO_FN_EVENT5, NULL);
+ gpio_request(GPIO_FN_EVENT4, NULL);
+ gpio_request(GPIO_FN_EVENT3, NULL);
+ gpio_request(GPIO_FN_EVENT2, NULL);
+ gpio_request(GPIO_FN_EVENT1, NULL);
+ gpio_request(GPIO_FN_EVENT0, NULL);
+
+ /* LED for heartbeat */
+ gpio_request(GPIO_PTU3, NULL);
+ gpio_direction_output(GPIO_PTU3, 1);
+ gpio_request(GPIO_PTU2, NULL);
+ gpio_direction_output(GPIO_PTU2, 1);
+ gpio_request(GPIO_PTU1, NULL);
+ gpio_direction_output(GPIO_PTU1, 1);
+ gpio_request(GPIO_PTU0, NULL);
+ gpio_direction_output(GPIO_PTU0, 1);
+
+ /* control for MDIO of Gigabit Ethernet */
+ gpio_request(GPIO_PTT4, NULL);
+ gpio_direction_output(GPIO_PTT4, 1);
+
+ /* control for eMMC */
+ gpio_request(GPIO_PTT7, NULL); /* eMMC_RST# */
+ gpio_direction_output(GPIO_PTT7, 0);
+ gpio_request(GPIO_PTT6, NULL); /* eMMC_INDEX# */
+ gpio_direction_output(GPIO_PTT6, 0);
+ gpio_request(GPIO_PTT5, NULL); /* eMMC_PRST# */
+ gpio_direction_output(GPIO_PTT5, 1);
+
+ /* General platform */
+ return platform_add_devices(sh7757lcr_devices,
+ ARRAY_SIZE(sh7757lcr_devices));
+}
+arch_initcall(sh7757lcr_devices_setup);
+
+/* Initialize IRQ setting */
+void __init init_sh7757lcr_IRQ(void)
+{
+ plat_irq_setup_pins(IRQ_MODE_IRQ7654);
+ plat_irq_setup_pins(IRQ_MODE_IRQ3210);
+}
+
+/* Initialize the board */
+static void __init sh7757lcr_setup(char **cmdline_p)
+{
+ printk(KERN_INFO "Renesas R0P7757LC0012RL support.\n");
+}
+
+static int sh7757lcr_mode_pins(void)
+{
+ int value = 0;
+
+ /* These are the factory default settings of S3 (Low active).
+ * If you change these dip switches then you will need to
+ * adjust the values below as well.
+ */
+ value |= MODE_PIN0; /* Clock Mode: 1 */
+
+ return value;
+}
+
+/* The Machine Vector */
+static struct sh_machine_vector mv_sh7757lcr __initmv = {
+ .mv_name = "SH7757LCR",
+ .mv_setup = sh7757lcr_setup,
+ .mv_init_irq = init_sh7757lcr_IRQ,
+ .mv_mode_pins = sh7757lcr_mode_pins,
+};
+
diff --git a/arch/sh/configs/sh2007_defconfig b/arch/sh/configs/sh2007_defconfig
new file mode 100644
index 000000000000..adf7a6b05814
--- /dev/null
+++ b/arch/sh/configs/sh2007_defconfig
@@ -0,0 +1,1357 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35-rc2
+# Fri Jun 18 19:46:14 2010
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_NO_IOPORT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+# CONFIG_TASKSTATS is not set
+CONFIG_AUDIT=y
+CONFIG_AUDITSYSCALL=y
+CONFIG_AUDIT_TREE=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+# CONFIG_IKCONFIG_PROC is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+# CONFIG_MODULES is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
+# CONFIG_CPU_SUBTYPE_SH7757 is not set
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+CONFIG_CPU_SUBTYPE_SH7780=y
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x08000000
+CONFIG_MEMORY_SIZE=0x08000000
+CONFIG_29BIT=y
+# CONFIG_PMB is not set
+# CONFIG_VSYSCALL is not set
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_UNCACHED_MAPPING=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=1
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+# CONFIG_SPECULATIVE_EXECUTION is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+# CONFIG_SH_7780_SOLUTION_ENGINE is not set
+# CONFIG_SH_SDK7780 is not set
+# CONFIG_SH_HIGHLANDER is not set
+CONFIG_SH_SH2007=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+CONFIG_SH_PCLK_FREQ=50000000
+CONFIG_SH_CLK_CPG=y
+CONFIG_SH_CLK_CPG_LEGACY=y
+CONFIG_TICK_ONESHOT=y
+# CONFIG_NO_HZ is not set
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+CONFIG_SH_DMA=y
+CONFIG_SH_DMA_IRQ_MULTI=y
+CONFIG_SH_DMA_API=y
+CONFIG_NR_ONCHIP_DMA_CHANNELS=12
+CONFIG_NR_DMA_CHANNELS_BOOL=y
+CONFIG_NR_DMA_CHANNELS=12
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+# CONFIG_HEARTBEAT is not set
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+# CONFIG_SECCOMP is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_INTC_USERIMASK is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_OVERWRITE=y
+# CONFIG_CMDLINE_EXTEND is not set
+CONFIG_CMDLINE="console=ttySC1,115200 ip=dhcp root=/dev/nfs rw nfsroot=/nfs/rootfs,rsize=1024,wsize=1024 earlyprintk=sh-sci.1"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+
+#
+# PC-card bridges
+#
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+# CONFIG_XFRM_SUB_POLICY is not set
+CONFIG_XFRM_MIGRATE=y
+# CONFIG_XFRM_STATISTICS is not set
+CONFIG_NET_KEY=y
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=y
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_FIB_RULES=y
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_CDROM_PKTCDVD_BUFFERS=8
+# CONFIG_CDROM_PKTCDVD_WCACHE is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+CONFIG_RAID_ATTRS=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_TGT=y
+CONFIG_SCSI_NETLINK=y
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+
+#
+# SCSI Transports
+#
+CONFIG_SCSI_SPI_ATTRS=y
+CONFIG_SCSI_FC_ATTRS=y
+# CONFIG_SCSI_FC_TGT_ATTRS is not set
+CONFIG_SCSI_ISCSI_ATTRS=y
+# CONFIG_SCSI_SAS_LIBSAS is not set
+CONFIG_SCSI_SRP_ATTRS=y
+# CONFIG_SCSI_SRP_TGT_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+CONFIG_EQUALIZER=y
+CONFIG_TUN=y
+CONFIG_VETH=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_NET_PCMCIA is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=2
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SH_WDT=y
+# CONFIG_SH_WDT_MMAP is not set
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB=y
+CONFIG_SSB_PCMCIAHOST_POSSIBLE=y
+# CONFIG_SSB_PCMCIAHOST is not set
+# CONFIG_SSB_SILENT is not set
+# CONFIG_SSB_DEBUG is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+# CONFIG_FB_CFB_FILLRECT is not set
+# CONFIG_FB_CFB_COPYAREA is not set
+# CONFIG_FB_CFB_IMAGEBLIT is not set
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_SH_MOBILE_LCDC is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_FB_BROADSHEET is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_LOGO_SUPERH_MONO=y
+CONFIG_LOGO_SUPERH_VGA16=y
+CONFIG_LOGO_SUPERH_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+# CONFIG_USB_STORAGE is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_NOP_USB_XCEIV is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_TRIGGERS=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGER_TIMER is not set
+# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
+# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+
+#
+# iptables trigger is under Netfilter config (LED target)
+#
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+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_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_SH is not set
+# CONFIG_RTC_DRV_GENERIC is not set
+CONFIG_DMADEVICES=y
+# CONFIG_DMADEVICES_DEBUG is not set
+
+#
+# DMA Devices
+#
+CONFIG_TIMB_DMA=y
+CONFIG_DMA_ENGINE=y
+
+#
+# DMA Clients
+#
+# CONFIG_NET_DMA is not set
+# CONFIG_ASYNC_TX_DMA is not set
+# CONFIG_DMATEST is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=y
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=932
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+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 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=y
+CONFIG_NLS_CODEPAGE_775=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_CODEPAGE_852=y
+CONFIG_NLS_CODEPAGE_855=y
+CONFIG_NLS_CODEPAGE_857=y
+CONFIG_NLS_CODEPAGE_860=y
+CONFIG_NLS_CODEPAGE_861=y
+CONFIG_NLS_CODEPAGE_862=y
+CONFIG_NLS_CODEPAGE_863=y
+CONFIG_NLS_CODEPAGE_864=y
+CONFIG_NLS_CODEPAGE_865=y
+CONFIG_NLS_CODEPAGE_866=y
+CONFIG_NLS_CODEPAGE_869=y
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+CONFIG_NLS_CODEPAGE_874=y
+CONFIG_NLS_ISO8859_8=y
+CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_CODEPAGE_1251=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_2=y
+CONFIG_NLS_ISO8859_3=y
+CONFIG_NLS_ISO8859_4=y
+CONFIG_NLS_ISO8859_5=y
+CONFIG_NLS_ISO8859_6=y
+CONFIG_NLS_ISO8859_7=y
+CONFIG_NLS_ISO8859_9=y
+CONFIG_NLS_ISO8859_13=y
+CONFIG_NLS_ISO8859_14=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_KOI8_R=y
+CONFIG_NLS_KOI8_U=y
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+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_SYSCALL_TRACEPOINTS=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_FTRACE_SYSCALLS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KSYM_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_SH_STANDARD_BIOS=y
+# CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+CONFIG_DUMP_CODE=y
+# CONFIG_DWARF_UNWINDER is not set
+# CONFIG_SH_NO_BSS_INIT is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_GF128MUL=y
+CONFIG_CRYPTO_NULL=y
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_PCBC=y
+CONFIG_CRYPTO_XTS=y
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=y
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANUBIS=y
+CONFIG_CRYPTO_ARC4=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_CAST5=y
+CONFIG_CRYPTO_CAST6=y
+CONFIG_CRYPTO_DES=y
+CONFIG_CRYPTO_FCRYPT=y
+CONFIG_CRYPTO_KHAZAD=y
+# CONFIG_CRYPTO_SALSA20 is not set
+CONFIG_CRYPTO_SEED=y
+CONFIG_CRYPTO_SERPENT=y
+CONFIG_CRYPTO_TEA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_TWOFISH_COMMON=y
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+# CONFIG_CRC_T10DIF is not set
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/configs/sh7757lcr_defconfig b/arch/sh/configs/sh7757lcr_defconfig
new file mode 100644
index 000000000000..635933e76e31
--- /dev/null
+++ b/arch/sh/configs/sh7757lcr_defconfig
@@ -0,0 +1,1126 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.35-rc3
+# Mon Jul 5 20:42:01 2010
+#
+CONFIG_SUPERH=y
+CONFIG_SUPERH32=y
+# CONFIG_SUPERH64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sh/configs/shx3_defconfig"
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_BUG=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+# CONFIG_ARCH_SUSPEND_POSSIBLE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_SYS_SUPPORTS_TMU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_NO_VIRT_TO_BUS=y
+CONFIG_ARCH_HAS_DEFAULT_IDLE=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_DMA_NONCOHERENT=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_NEED_SG_DMA_LENGTH=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+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_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+# CONFIG_SYSCTL_SYSCALL is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_KALLSYMS_EXTRA_PASS 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_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_COMPAT_BRK=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+
+#
+# System type
+#
+CONFIG_CPU_SH4=y
+CONFIG_CPU_SH4A=y
+CONFIG_CPU_SHX2=y
+# CONFIG_CPU_SUBTYPE_SH7619 is not set
+# CONFIG_CPU_SUBTYPE_SH7201 is not set
+# CONFIG_CPU_SUBTYPE_SH7203 is not set
+# CONFIG_CPU_SUBTYPE_SH7206 is not set
+# CONFIG_CPU_SUBTYPE_SH7263 is not set
+# CONFIG_CPU_SUBTYPE_MXG is not set
+# CONFIG_CPU_SUBTYPE_SH7705 is not set
+# CONFIG_CPU_SUBTYPE_SH7706 is not set
+# CONFIG_CPU_SUBTYPE_SH7707 is not set
+# CONFIG_CPU_SUBTYPE_SH7708 is not set
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7710 is not set
+# CONFIG_CPU_SUBTYPE_SH7712 is not set
+# CONFIG_CPU_SUBTYPE_SH7720 is not set
+# CONFIG_CPU_SUBTYPE_SH7721 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+# CONFIG_CPU_SUBTYPE_SH7091 is not set
+# CONFIG_CPU_SUBTYPE_SH7750R is not set
+# CONFIG_CPU_SUBTYPE_SH7750S is not set
+# CONFIG_CPU_SUBTYPE_SH7751 is not set
+# CONFIG_CPU_SUBTYPE_SH7751R is not set
+# CONFIG_CPU_SUBTYPE_SH7760 is not set
+# CONFIG_CPU_SUBTYPE_SH4_202 is not set
+# CONFIG_CPU_SUBTYPE_SH7723 is not set
+# CONFIG_CPU_SUBTYPE_SH7724 is not set
+CONFIG_CPU_SUBTYPE_SH7757=y
+# CONFIG_CPU_SUBTYPE_SH7763 is not set
+# CONFIG_CPU_SUBTYPE_SH7770 is not set
+# CONFIG_CPU_SUBTYPE_SH7780 is not set
+# CONFIG_CPU_SUBTYPE_SH7785 is not set
+# CONFIG_CPU_SUBTYPE_SH7786 is not set
+# CONFIG_CPU_SUBTYPE_SHX3 is not set
+# CONFIG_CPU_SUBTYPE_SH7343 is not set
+# CONFIG_CPU_SUBTYPE_SH7722 is not set
+# CONFIG_CPU_SUBTYPE_SH7366 is not set
+
+#
+# Memory management options
+#
+CONFIG_QUICKLIST=y
+CONFIG_MMU=y
+CONFIG_PAGE_OFFSET=0x80000000
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x0f000000
+# CONFIG_29BIT is not set
+CONFIG_32BIT=y
+CONFIG_PMB=y
+CONFIG_X2TLB=y
+CONFIG_VSYSCALL=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_ARCH_SPARSEMEM_DEFAULT=y
+CONFIG_MAX_ACTIVE_REGIONS=1
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_ARCH_SELECT_MEMORY_MODEL=y
+CONFIG_IOREMAP_FIXED=y
+CONFIG_UNCACHED_MAPPING=y
+CONFIG_PAGE_SIZE_4KB=y
+# CONFIG_PAGE_SIZE_8KB is not set
+# CONFIG_PAGE_SIZE_16KB is not set
+# CONFIG_PAGE_SIZE_64KB is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_NR_QUICK=1
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+
+#
+# Cache configuration
+#
+CONFIG_CACHE_WRITEBACK=y
+# CONFIG_CACHE_WRITETHROUGH is not set
+# CONFIG_CACHE_OFF is not set
+
+#
+# Processor features
+#
+CONFIG_CPU_LITTLE_ENDIAN=y
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_SH_FPU=y
+# CONFIG_SH_STORE_QUEUES is not set
+CONFIG_CPU_HAS_INTEVT=y
+CONFIG_CPU_HAS_SR_RB=y
+CONFIG_CPU_HAS_FPU=y
+
+#
+# Board support
+#
+CONFIG_SH_SH7757LCR=y
+
+#
+# Timer and clock configuration
+#
+CONFIG_SH_TIMER_TMU=y
+CONFIG_SH_CLK_CPG=y
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# DMA support
+#
+# CONFIG_SH_DMA is not set
+
+#
+# Companion Chips
+#
+
+#
+# Additional SuperH Device Drivers
+#
+CONFIG_HEARTBEAT=y
+# CONFIG_PUSH_SWITCH is not set
+
+#
+# Kernel features
+#
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_KEXEC is not set
+# CONFIG_CRASH_DUMP is not set
+CONFIG_SECCOMP=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_GUSA=y
+# CONFIG_INTC_USERIMASK is not set
+
+#
+# Boot options
+#
+CONFIG_ZERO_PAGE_OFFSET=0x00001000
+CONFIG_BOOT_LINK_OFFSET=0x00800000
+CONFIG_ENTRY_OFFSET=0x00001000
+CONFIG_CMDLINE_OVERWRITE=y
+# CONFIG_CMDLINE_EXTEND is not set
+CONFIG_CMDLINE="console=ttySC2,115200 root=/dev/nfs ip=dhcp"
+
+#
+# Bus options
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options (EXPERIMENTAL)
+#
+# CONFIG_PM is not set
+# CONFIG_CPU_IDLE is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+CONFIG_VITESSE_PHY=y
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+CONFIG_MDIO_BITBANG=y
+# CONFIG_MDIO_GPIO is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_STNIC is not set
+CONFIG_SH_ETH=y
+# CONFIG_SMC91X is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_SH_KEYSC is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+# CONFIG_MOUSE_PS2 is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_SH_SCI=y
+CONFIG_SERIAL_SH_SCI_NR_UARTS=3
+CONFIG_SERIAL_SH_SCI_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+# CONFIG_GPIO_SYSFS is not set
+
+#
+# Memory mapped GPIO expanders:
+#
+# CONFIG_GPIO_IT8761E is not set
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+
+#
+# MODULbus GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_SH_MOBILE_SDHI is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLBFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+CONFIG_SQUASHFS=y
+# CONFIG_SQUASHFS_XATTRS is not set
+# CONFIG_SQUASHFS_EMBEDDED is not set
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+# CONFIG_VXFS_FS is not set
+CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_CODEPAGE_932=y
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+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_SYSCALL_TRACEPOINTS=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_SH_STANDARD_BIOS is not set
+# CONFIG_STACK_DEBUG is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_4KSTACKS is not set
+# CONFIG_DUMP_CODE is not set
+# CONFIG_DWARF_UNWINDER is not set
+# CONFIG_SH_NO_BSS_INIT is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_VIRTUALIZATION is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index f98141b3b7d7..86adb1e235cd 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -81,7 +81,7 @@ static int __init sh7751_pci_init(void)
unsigned int id;
u32 word, reg;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
chan->reg_base = 0xfe200000;
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index ffdcbf10b95e..edb7cca14882 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -246,7 +246,7 @@ static int __init sh7780_pci_init(void)
const char *type;
int ret, i;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
chan->reg_base = 0xfe040000;
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index 68cb9b0ac9d2..78f378731858 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -392,7 +392,7 @@ static int __init sh7786_pcie_init(void)
{
int ret = 0, i;
- printk(KERN_NOTICE "PCI: Starting intialization.\n");
+ printk(KERN_NOTICE "PCI: Starting initialization.\n");
sh7786_pcie_hwops = &sh7786_65nm_pcie_hwops;
diff --git a/arch/sh/include/asm/Kbuild b/arch/sh/include/asm/Kbuild
index 46cb93477bcb..b4d3462f1dc3 100644
--- a/arch/sh/include/asm/Kbuild
+++ b/arch/sh/include/asm/Kbuild
@@ -8,3 +8,5 @@ unifdef-y += unistd_32.h
unifdef-y += unistd_64.h
unifdef-y += posix_types_32.h
unifdef-y += posix_types_64.h
+unifdef-y += ptrace_32.h
+unifdef-y += ptrace_64.h
diff --git a/arch/sh/include/asm/elf.h b/arch/sh/include/asm/elf.h
index ce830faeebbf..f38112be67d2 100644
--- a/arch/sh/include/asm/elf.h
+++ b/arch/sh/include/asm/elf.h
@@ -50,25 +50,14 @@
#define R_SH_GOTPC 167
/* FDPIC relocs */
-#define R_SH_GOT20 70
-#define R_SH_GOTOFF20 71
-#define R_SH_GOTFUNCDESC 72
-#define R_SH_GOTFUNCDESC20 73
-#define R_SH_GOTOFFFUNCDESC 74
-#define R_SH_GOTOFFFUNCDESC20 75
-#define R_SH_FUNCDESC 76
-#define R_SH_FUNCDESC_VALUE 77
-
-#if 0 /* XXX - later .. */
-#define R_SH_GOT20 198
-#define R_SH_GOTOFF20 199
-#define R_SH_GOTFUNCDESC 200
-#define R_SH_GOTFUNCDESC20 201
-#define R_SH_GOTOFFFUNCDESC 202
-#define R_SH_GOTOFFFUNCDESC20 203
-#define R_SH_FUNCDESC 204
-#define R_SH_FUNCDESC_VALUE 205
-#endif
+#define R_SH_GOT20 201
+#define R_SH_GOTOFF20 202
+#define R_SH_GOTFUNCDESC 203
+#define R_SH_GOTFUNCDESC20 204
+#define R_SH_GOTOFFFUNCDESC 205
+#define R_SH_GOTOFFFUNCDESC20 206
+#define R_SH_FUNCDESC 207
+#define R_SH_FUNCDESC_VALUE 208
/* SHmedia relocs */
#define R_SH_IMM_LOW16 246
diff --git a/arch/sh/include/asm/fixmap.h b/arch/sh/include/asm/fixmap.h
index 6e7cea453895..bd7e79a12653 100644
--- a/arch/sh/include/asm/fixmap.h
+++ b/arch/sh/include/asm/fixmap.h
@@ -58,7 +58,7 @@ enum fixed_addresses {
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
- FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1,
#endif
#ifdef CONFIG_IOREMAP_FIXED
@@ -69,7 +69,7 @@ enum fixed_addresses {
*/
#define FIX_N_IOREMAPS 32
FIX_IOREMAP_BEGIN,
- FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS,
+ FIX_IOREMAP_END = FIX_IOREMAP_BEGIN + FIX_N_IOREMAPS - 1,
#endif
__end_of_fixed_addresses
diff --git a/arch/sh/include/asm/irq.h b/arch/sh/include/asm/irq.h
index 02c2f0102cfa..45d08b6a5ef7 100644
--- a/arch/sh/include/asm/irq.h
+++ b/arch/sh/include/asm/irq.h
@@ -9,7 +9,7 @@
* advised to cap this at the hard limit that they're interested in
* through the machvec.
*/
-#define NR_IRQS 256
+#define NR_IRQS 512
#define NR_IRQS_LEGACY 8 /* Legacy external IRQ0-7 */
/*
diff --git a/arch/sh/include/asm/kprobes.h b/arch/sh/include/asm/kprobes.h
index 036c3311233c..134f3980e44a 100644
--- a/arch/sh/include/asm/kprobes.h
+++ b/arch/sh/include/asm/kprobes.h
@@ -16,7 +16,6 @@ typedef insn_size_t kprobe_opcode_t;
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
-#define regs_return_value(_regs) ((_regs)->regs[0])
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
diff --git a/arch/sh/include/asm/processor_32.h b/arch/sh/include/asm/processor_32.h
index 61a445d2d02a..46d5179c9f49 100644
--- a/arch/sh/include/asm/processor_32.h
+++ b/arch/sh/include/asm/processor_32.h
@@ -13,7 +13,6 @@
#include <linux/linkage.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#include <asm/hw_breakpoint.h>
/*
@@ -194,8 +193,6 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->pc)
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[15])
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
#define PREFETCH_STRIDE L1_CACHE_BYTES
#define ARCH_HAS_PREFETCH
diff --git a/arch/sh/include/asm/processor_64.h b/arch/sh/include/asm/processor_64.h
index 621bc4618c6b..2a541ddb5a1b 100644
--- a/arch/sh/include/asm/processor_64.h
+++ b/arch/sh/include/asm/processor_64.h
@@ -17,7 +17,6 @@
#include <linux/compiler.h>
#include <asm/page.h>
#include <asm/types.h>
-#include <asm/ptrace.h>
#include <cpu/registers.h>
/*
@@ -231,7 +230,5 @@ extern unsigned long get_wchan(struct task_struct *p);
#define KSTK_EIP(tsk) ((tsk)->thread.pc)
#define KSTK_ESP(tsk) ((tsk)->thread.sp)
-#define user_stack_pointer(_regs) ((_regs)->regs[15])
-
#endif /* __ASSEMBLY__ */
#endif /* __ASM_SH_PROCESSOR_64_H */
diff --git a/arch/sh/include/asm/ptrace.h b/arch/sh/include/asm/ptrace.h
index 2168fde25611..f6edc10aa0d3 100644
--- a/arch/sh/include/asm/ptrace.h
+++ b/arch/sh/include/asm/ptrace.h
@@ -3,90 +3,7 @@
/*
* Copyright (C) 1999, 2000 Niibe Yutaka
- *
- */
-#if defined(__SH5__)
-struct pt_regs {
- unsigned long long pc;
- unsigned long long sr;
- long long syscall_nr;
- unsigned long long regs[63];
- unsigned long long tregs[8];
- unsigned long long pad[2];
-};
-#else
-/*
- * GCC defines register number like this:
- * -----------------------------
- * 0 - 15 are integer registers
- * 17 - 22 are control/special registers
- * 24 - 39 fp registers
- * 40 - 47 xd registers
- * 48 - fpscr register
- * -----------------------------
- *
- * We follows above, except:
- * 16 --- program counter (PC)
- * 22 --- syscall #
- * 23 --- floating point communication register
*/
-#define REG_REG0 0
-#define REG_REG15 15
-
-#define REG_PC 16
-
-#define REG_PR 17
-#define REG_SR 18
-#define REG_GBR 19
-#define REG_MACH 20
-#define REG_MACL 21
-
-#define REG_SYSCALL 22
-
-#define REG_FPREG0 23
-#define REG_FPREG15 38
-#define REG_XFREG0 39
-#define REG_XFREG15 54
-
-#define REG_FPSCR 55
-#define REG_FPUL 56
-
-/*
- * This struct defines the way the registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_regs {
- unsigned long regs[16];
- unsigned long pc;
- unsigned long pr;
- unsigned long sr;
- unsigned long gbr;
- unsigned long mach;
- unsigned long macl;
- long tra;
-};
-
-/*
- * This struct defines the way the DSP registers are stored on the
- * kernel stack during a system call or other kernel entry.
- */
-struct pt_dspregs {
- unsigned long a1;
- unsigned long a0g;
- unsigned long a1g;
- unsigned long m0;
- unsigned long m1;
- unsigned long a0;
- unsigned long x0;
- unsigned long x1;
- unsigned long y0;
- unsigned long y1;
- unsigned long dsr;
- unsigned long rs;
- unsigned long re;
- unsigned long mod;
-};
-#endif
#define PTRACE_GETREGS 12 /* General registers */
#define PTRACE_SETREGS 13
@@ -107,22 +24,102 @@ struct pt_dspregs {
#define PT_DATA_ADDR 248 /* &(struct user)->start_data */
#define PT_TEXT_LEN 252
+#if defined(__SH5__) || defined(CONFIG_CPU_SH5)
+#include "ptrace_64.h"
+#else
+#include "ptrace_32.h"
+#endif
+
#ifdef __KERNEL__
+
+#include <linux/stringify.h>
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
#include <asm/addrspace.h>
#include <asm/page.h>
#include <asm/system.h>
#define user_mode(regs) (((regs)->sr & 0x40000000)==0)
+#define user_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
+#define kernel_stack_pointer(regs) ((unsigned long)(regs)->regs[15])
#define instruction_pointer(regs) ((unsigned long)(regs)->pc)
extern void show_regs(struct pt_regs *);
+#define arch_has_single_step() (1)
+
/*
- * These are defined as per linux/ptrace.h.
+ * kprobe-based event tracer support
*/
-struct task_struct;
+struct pt_regs_offset {
+ const char *name;
+ int offset;
+};
-#define arch_has_single_step() (1)
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define REGS_OFFSET_NAME(num) \
+ {.name = __stringify(r##num), .offset = offsetof(struct pt_regs, regs[num])}
+#define TREGS_OFFSET_NAME(num) \
+ {.name = __stringify(tr##num), .offset = offsetof(struct pt_regs, tregs[num])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+/* Query offset/name of register from its name/offset */
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+
+extern const struct pt_regs_offset regoffset_table[];
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs: pt_regs from which register value is gotten.
+ * @offset: offset number of the register.
+ *
+ * regs_get_register returns the value of a register. The @offset is the
+ * offset of the register in struct pt_regs address which specified by @regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+ unsigned int offset)
+{
+ if (unlikely(offset > MAX_REG_OFFSET))
+ return 0;
+ return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @addr: address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+static inline int regs_within_kernel_stack(struct pt_regs *regs,
+ unsigned long addr)
+{
+ return ((addr & ~(THREAD_SIZE - 1)) ==
+ (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs: pt_regs which contains kernel stack pointer.
+ * @n: stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+ unsigned int n)
+{
+ unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+ addr += n;
+ if (regs_within_kernel_stack(regs, (unsigned long)addr))
+ return *addr;
+ else
+ return 0;
+}
struct perf_event;
struct perf_sample_data;
diff --git a/arch/sh/include/asm/ptrace_32.h b/arch/sh/include/asm/ptrace_32.h
new file mode 100644
index 000000000000..35d9e257558c
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_32.h
@@ -0,0 +1,83 @@
+#ifndef __ASM_SH_PTRACE_32_H
+#define __ASM_SH_PTRACE_32_H
+
+/*
+ * GCC defines register number like this:
+ * -----------------------------
+ * 0 - 15 are integer registers
+ * 17 - 22 are control/special registers
+ * 24 - 39 fp registers
+ * 40 - 47 xd registers
+ * 48 - fpscr register
+ * -----------------------------
+ *
+ * We follows above, except:
+ * 16 --- program counter (PC)
+ * 22 --- syscall #
+ * 23 --- floating point communication register
+ */
+#define REG_REG0 0
+#define REG_REG15 15
+
+#define REG_PC 16
+
+#define REG_PR 17
+#define REG_SR 18
+#define REG_GBR 19
+#define REG_MACH 20
+#define REG_MACL 21
+
+#define REG_SYSCALL 22
+
+#define REG_FPREG0 23
+#define REG_FPREG15 38
+#define REG_XFREG0 39
+#define REG_XFREG15 54
+
+#define REG_FPSCR 55
+#define REG_FPUL 56
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_regs {
+ unsigned long regs[16];
+ unsigned long pc;
+ unsigned long pr;
+ unsigned long sr;
+ unsigned long gbr;
+ unsigned long mach;
+ unsigned long macl;
+ long tra;
+};
+
+/*
+ * This struct defines the way the DSP registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ */
+struct pt_dspregs {
+ unsigned long a1;
+ unsigned long a0g;
+ unsigned long a1g;
+ unsigned long m0;
+ unsigned long m1;
+ unsigned long a0;
+ unsigned long x0;
+ unsigned long x1;
+ unsigned long y0;
+ unsigned long y1;
+ unsigned long dsr;
+ unsigned long rs;
+ unsigned long re;
+ unsigned long mod;
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tra)
+#define regs_return_value(regs) ((regs)->regs[0])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_32_H */
diff --git a/arch/sh/include/asm/ptrace_64.h b/arch/sh/include/asm/ptrace_64.h
new file mode 100644
index 000000000000..d43c1cb0bbe7
--- /dev/null
+++ b/arch/sh/include/asm/ptrace_64.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_SH_PTRACE_64_H
+#define __ASM_SH_PTRACE_64_H
+
+struct pt_regs {
+ unsigned long long pc;
+ unsigned long long sr;
+ long long syscall_nr;
+ unsigned long long regs[63];
+ unsigned long long tregs[8];
+ unsigned long long pad[2];
+};
+
+#ifdef __KERNEL__
+
+#define MAX_REG_OFFSET offsetof(struct pt_regs, tregs[7])
+#define regs_return_value(regs) ((regs)->regs[3])
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_SH_PTRACE_64_H */
diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h
index 51296b36770e..9bd2684f908e 100644
--- a/arch/sh/include/asm/system_32.h
+++ b/arch/sh/include/asm/system_32.h
@@ -216,13 +216,12 @@ int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
static inline void trigger_address_error(void)
{
- if (__in_29bit_mode())
- __asm__ __volatile__ (
- "ldc %0, sr\n\t"
- "mov.l @%1, %0"
- :
- : "r" (0x10000000), "r" (0x80000001)
- );
+ __asm__ __volatile__ (
+ "ldc %0, sr\n\t"
+ "mov.l @%1, %0"
+ :
+ : "r" (0x10000000), "r" (0x80000001)
+ );
}
asmlinkage void do_address_error(struct pt_regs *regs,
diff --git a/arch/sh/include/asm/tlbflush.h b/arch/sh/include/asm/tlbflush.h
index e0ac97221ae6..0df66f0c7284 100644
--- a/arch/sh/include/asm/tlbflush.h
+++ b/arch/sh/include/asm/tlbflush.h
@@ -21,6 +21,8 @@ extern void local_flush_tlb_kernel_range(unsigned long start,
unsigned long end);
extern void local_flush_tlb_one(unsigned long asid, unsigned long page);
+extern void __flush_tlb_global(void);
+
#ifdef CONFIG_SMP
extern void flush_tlb_all(void);
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h
index f4d267efad71..15f3de11c55a 100644
--- a/arch/sh/include/cpu-sh4/cpu/sh7757.h
+++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h
@@ -3,241 +3,252 @@
enum {
/* PTA */
- GPIO_PTA7, GPIO_PTA6, GPIO_PTA5, GPIO_PTA4,
- GPIO_PTA3, GPIO_PTA2, GPIO_PTA1, GPIO_PTA0,
+ GPIO_PTA0, GPIO_PTA1, GPIO_PTA2, GPIO_PTA3,
+ GPIO_PTA4, GPIO_PTA5, GPIO_PTA6, GPIO_PTA7,
/* PTB */
- GPIO_PTB7, GPIO_PTB6, GPIO_PTB5, GPIO_PTB4,
- GPIO_PTB3, GPIO_PTB2, GPIO_PTB1, GPIO_PTB0,
+ GPIO_PTB0, GPIO_PTB1, GPIO_PTB2, GPIO_PTB3,
+ GPIO_PTB4, GPIO_PTB5, GPIO_PTB6, GPIO_PTB7,
/* PTC */
- GPIO_PTC7, GPIO_PTC6, GPIO_PTC5, GPIO_PTC4,
- GPIO_PTC3, GPIO_PTC2, GPIO_PTC1, GPIO_PTC0,
+ GPIO_PTC0, GPIO_PTC1, GPIO_PTC2, GPIO_PTC3,
+ GPIO_PTC4, GPIO_PTC5, GPIO_PTC6, GPIO_PTC7,
/* PTD */
- GPIO_PTD7, GPIO_PTD6, GPIO_PTD5, GPIO_PTD4,
- GPIO_PTD3, GPIO_PTD2, GPIO_PTD1, GPIO_PTD0,
+ GPIO_PTD0, GPIO_PTD1, GPIO_PTD2, GPIO_PTD3,
+ GPIO_PTD4, GPIO_PTD5, GPIO_PTD6, GPIO_PTD7,
/* PTE */
- GPIO_PTE7, GPIO_PTE6, GPIO_PTE5, GPIO_PTE4,
- GPIO_PTE3, GPIO_PTE2, GPIO_PTE1, GPIO_PTE0,
+ GPIO_PTE0, GPIO_PTE1, GPIO_PTE2, GPIO_PTE3,
+ GPIO_PTE4, GPIO_PTE5, GPIO_PTE6, GPIO_PTE7,
/* PTF */
- GPIO_PTF7, GPIO_PTF6, GPIO_PTF5, GPIO_PTF4,
- GPIO_PTF3, GPIO_PTF2, GPIO_PTF1, GPIO_PTF0,
+ GPIO_PTF0, GPIO_PTF1, GPIO_PTF2, GPIO_PTF3,
+ GPIO_PTF4, GPIO_PTF5, GPIO_PTF6, GPIO_PTF7,
/* PTG */
- GPIO_PTG7, GPIO_PTG6, GPIO_PTG5, GPIO_PTG4,
- GPIO_PTG3, GPIO_PTG2, GPIO_PTG1, GPIO_PTG0,
+ GPIO_PTG0, GPIO_PTG1, GPIO_PTG2, GPIO_PTG3,
+ GPIO_PTG4, GPIO_PTG5, GPIO_PTG6, GPIO_PTG7,
/* PTH */
- GPIO_PTH7, GPIO_PTH6, GPIO_PTH5, GPIO_PTH4,
- GPIO_PTH3, GPIO_PTH2, GPIO_PTH1, GPIO_PTH0,
+ GPIO_PTH0, GPIO_PTH1, GPIO_PTH2, GPIO_PTH3,
+ GPIO_PTH4, GPIO_PTH5, GPIO_PTH6, GPIO_PTH7,
/* PTI */
- GPIO_PTI7, GPIO_PTI6, GPIO_PTI5, GPIO_PTI4,
- GPIO_PTI3, GPIO_PTI2, GPIO_PTI1, GPIO_PTI0,
+ GPIO_PTI0, GPIO_PTI1, GPIO_PTI2, GPIO_PTI3,
+ GPIO_PTI4, GPIO_PTI5, GPIO_PTI6, GPIO_PTI7,
/* PTJ */
- GPIO_PTJ7, GPIO_PTJ6, GPIO_PTJ5, GPIO_PTJ4,
- GPIO_PTJ3, GPIO_PTJ2, GPIO_PTJ1, GPIO_PTJ0,
+ GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
+ GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV,
/* PTK */
- GPIO_PTK7, GPIO_PTK6, GPIO_PTK5, GPIO_PTK4,
- GPIO_PTK3, GPIO_PTK2, GPIO_PTK1, GPIO_PTK0,
+ GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
+ GPIO_PTK4, GPIO_PTK5, GPIO_PTK6, GPIO_PTK7,
/* PTL */
- GPIO_PTL7, GPIO_PTL6, GPIO_PTL5, GPIO_PTL4,
- GPIO_PTL3, GPIO_PTL2, GPIO_PTL1, GPIO_PTL0,
+ GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
+ GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV,
/* PTM */
- GPIO_PTM6, GPIO_PTM5, GPIO_PTM4,
- GPIO_PTM3, GPIO_PTM2, GPIO_PTM1, GPIO_PTM0,
+ GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
+ GPIO_PTM4, GPIO_PTM5, GPIO_PTM6, GPIO_PTM7,
/* PTN */
- GPIO_PTN7, GPIO_PTN6, GPIO_PTN5, GPIO_PTN4,
- GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
+ GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
+ GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV,
/* PTO */
- GPIO_PTO7, GPIO_PTO6, GPIO_PTO5, GPIO_PTO4,
- GPIO_PTO3, GPIO_PTO2, GPIO_PTO1, GPIO_PTO0,
+ GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
+ GPIO_PTO4, GPIO_PTO5, GPIO_PTO6, GPIO_PTO7,
/* PTP */
- GPIO_PTP6, GPIO_PTP5, GPIO_PTP4,
- GPIO_PTP3, GPIO_PTP2, GPIO_PTP1, GPIO_PTP0,
+ GPIO_PTP0, GPIO_PTP1, GPIO_PTP2, GPIO_PTP3,
+ GPIO_PTP4, GPIO_PTP5, GPIO_PTP6, GPIO_PTP7,
/* PTQ */
- GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
- GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
+ GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
+ GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV,
/* PTR */
- GPIO_PTR7, GPIO_PTR6, GPIO_PTR5, GPIO_PTR4,
- GPIO_PTR3, GPIO_PTR2, GPIO_PTR1, GPIO_PTR0,
+ GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
+ GPIO_PTR4, GPIO_PTR5, GPIO_PTR6, GPIO_PTR7,
/* PTS */
- GPIO_PTS7, GPIO_PTS6, GPIO_PTS5, GPIO_PTS4,
- GPIO_PTS3, GPIO_PTS2, GPIO_PTS1, GPIO_PTS0,
+ GPIO_PTS0, GPIO_PTS1, GPIO_PTS2, GPIO_PTS3,
+ GPIO_PTS4, GPIO_PTS5, GPIO_PTS6, GPIO_PTS7,
/* PTT */
- GPIO_PTT5, GPIO_PTT4,
- GPIO_PTT3, GPIO_PTT2, GPIO_PTT1, GPIO_PTT0,
+ GPIO_PTT0, GPIO_PTT1, GPIO_PTT2, GPIO_PTT3,
+ GPIO_PTT4, GPIO_PTT5, GPIO_PTT6, GPIO_PTT7,
/* PTU */
- GPIO_PTU7, GPIO_PTU6, GPIO_PTU5, GPIO_PTU4,
- GPIO_PTU3, GPIO_PTU2, GPIO_PTU1, GPIO_PTU0,
+ GPIO_PTU0, GPIO_PTU1, GPIO_PTU2, GPIO_PTU3,
+ GPIO_PTU4, GPIO_PTU5, GPIO_PTU6, GPIO_PTU7,
/* PTV */
- GPIO_PTV7, GPIO_PTV6, GPIO_PTV5, GPIO_PTV4,
- GPIO_PTV3, GPIO_PTV2, GPIO_PTV1, GPIO_PTV0,
+ GPIO_PTV0, GPIO_PTV1, GPIO_PTV2, GPIO_PTV3,
+ GPIO_PTV4, GPIO_PTV5, GPIO_PTV6, GPIO_PTV7,
/* PTW */
- GPIO_PTW7, GPIO_PTW6, GPIO_PTW5, GPIO_PTW4,
- GPIO_PTW3, GPIO_PTW2, GPIO_PTW1, GPIO_PTW0,
+ GPIO_PTW0, GPIO_PTW1, GPIO_PTW2, GPIO_PTW3,
+ GPIO_PTW4, GPIO_PTW5, GPIO_PTW6, GPIO_PTW7,
/* PTX */
- GPIO_PTX7, GPIO_PTX6, GPIO_PTX5, GPIO_PTX4,
- GPIO_PTX3, GPIO_PTX2, GPIO_PTX1, GPIO_PTX0,
+ GPIO_PTX0, GPIO_PTX1, GPIO_PTX2, GPIO_PTX3,
+ GPIO_PTX4, GPIO_PTX5, GPIO_PTX6, GPIO_PTX7,
/* PTY */
- GPIO_PTY7, GPIO_PTY6, GPIO_PTY5, GPIO_PTY4,
- GPIO_PTY3, GPIO_PTY2, GPIO_PTY1, GPIO_PTY0,
+ GPIO_PTY0, GPIO_PTY1, GPIO_PTY2, GPIO_PTY3,
+ GPIO_PTY4, GPIO_PTY5, GPIO_PTY6, GPIO_PTY7,
/* PTZ */
- GPIO_PTZ7, GPIO_PTZ6, GPIO_PTZ5, GPIO_PTZ4,
- GPIO_PTZ3, GPIO_PTZ2, GPIO_PTZ1, GPIO_PTZ0,
+ GPIO_PTZ0, GPIO_PTZ1, GPIO_PTZ2, GPIO_PTZ3,
+ GPIO_PTZ4, GPIO_PTZ5, GPIO_PTZ6, GPIO_PTZ7,
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
GPIO_FN_BS, GPIO_FN_RDWR, GPIO_FN_WE1, GPIO_FN_RDY,
- GPIO_FN_MD10, GPIO_FN_MD9, GPIO_FN_MD8,
- GPIO_FN_LGPIO7, GPIO_FN_LGPIO6, GPIO_FN_LGPIO5, GPIO_FN_LGPIO4,
- GPIO_FN_LGPIO3, GPIO_FN_LGPIO2, GPIO_FN_LGPIO1, GPIO_FN_LGPIO0,
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12,
- GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8,
- GPIO_FN_ET0_MDC, GPIO_FN_ET0_MDIO,
- GPIO_FN_ET1_MDC, GPIO_FN_ET1_MDIO,
- GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
- GPIO_FN_WPSZ1, GPIO_FN_WPSZ0, GPIO_FN_FWID, GPIO_FN_FLSHSZ,
- GPIO_FN_LPC_SPIEN, GPIO_FN_BASEL,
+ GPIO_FN_ET0_MDC, GPIO_FN_ET0_MDIO,
+ GPIO_FN_ET1_MDC, GPIO_FN_ET1_MDIO,
- /* PTC (mobule: SD) */
- GPIO_FN_SD_WP, GPIO_FN_SD_CD, GPIO_FN_SD_CLK, GPIO_FN_SD_CMD,
- GPIO_FN_SD_D3, GPIO_FN_SD_D2, GPIO_FN_SD_D1, GPIO_FN_SD_D0,
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ GPIO_FN_IRQ15, GPIO_FN_IRQ14, GPIO_FN_IRQ13, GPIO_FN_IRQ12,
+ GPIO_FN_IRQ11, GPIO_FN_IRQ10, GPIO_FN_IRQ9, GPIO_FN_IRQ8,
+ GPIO_FN_ON_NRE, GPIO_FN_ON_NWE, GPIO_FN_ON_NWP, GPIO_FN_ON_NCE0,
+ GPIO_FN_ON_R_B0, GPIO_FN_ON_ALE, GPIO_FN_ON_CLE,
+ GPIO_FN_TCLK,
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTC (mobule: IRQ, PWMU) */
GPIO_FN_IRQ7, GPIO_FN_IRQ6, GPIO_FN_IRQ5, GPIO_FN_IRQ4,
GPIO_FN_IRQ3, GPIO_FN_IRQ2, GPIO_FN_IRQ1, GPIO_FN_IRQ0,
- GPIO_FN_MD6, GPIO_FN_MD5, GPIO_FN_MD3, GPIO_FN_MD2,
- GPIO_FN_MD1, GPIO_FN_MD0, GPIO_FN_ADTRG1, GPIO_FN_ADTRG0,
-
- /* PTE (mobule: EtherC) */
- GPIO_FN_ET0_CRS_DV, GPIO_FN_ET0_TXD1,
- GPIO_FN_ET0_TXD0, GPIO_FN_ET0_TX_EN,
- GPIO_FN_ET0_REF_CLK, GPIO_FN_ET0_RXD1,
- GPIO_FN_ET0_RXD0, GPIO_FN_ET0_RX_ER,
-
- /* PTF (mobule: EtherC) */
- GPIO_FN_ET1_CRS_DV, GPIO_FN_ET1_TXD1,
- GPIO_FN_ET1_TXD0, GPIO_FN_ET1_TX_EN,
- GPIO_FN_ET1_REF_CLK, GPIO_FN_ET1_RXD1,
- GPIO_FN_ET1_RXD0, GPIO_FN_ET1_RX_ER,
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- GPIO_FN_STATUS0, GPIO_FN_STATUS1,
- GPIO_FN_PWX0, GPIO_FN_PWX1, GPIO_FN_PWX2, GPIO_FN_PWX3,
- GPIO_FN_SERIRQ, GPIO_FN_CLKRUN, GPIO_FN_LPCPD, GPIO_FN_LDRQ,
-
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- GPIO_FN_TCLK, GPIO_FN_RXD4, GPIO_FN_TXD4,
+ GPIO_FN_PWMU0, GPIO_FN_PWMU1, GPIO_FN_PWMU2, GPIO_FN_PWMU3,
+ GPIO_FN_PWMU4, GPIO_FN_PWMU5,
+
+ /* PTD (mobule: SPI0, DMAC) */
+ GPIO_FN_SP0_MOSI, GPIO_FN_SP0_MISO, GPIO_FN_SP0_SCK,
+ GPIO_FN_SP0_SCK_FB, GPIO_FN_SP0_SS0, GPIO_FN_SP0_SS1,
+ GPIO_FN_SP0_SS2, GPIO_FN_SP0_SS3, GPIO_FN_DREQ0,
+ GPIO_FN_DACK0, GPIO_FN_TEND0,
+
+ /* PTE (mobule: RMII) */
+ GPIO_FN_RMII0_CRS_DV, GPIO_FN_RMII0_TXD1, GPIO_FN_RMII0_TXD0,
+ GPIO_FN_RMII0_TXEN, GPIO_FN_RMII0_REFCLK, GPIO_FN_RMII0_RXD1,
+ GPIO_FN_RMII0_RXD0, GPIO_FN_RMII0_RX_ER,
+
+ /* PTF (mobule: RMII, SerMux) */
+ GPIO_FN_RMII1_CRS_DV, GPIO_FN_RMII1_TXD1, GPIO_FN_RMII1_TXD0,
+ GPIO_FN_RMII1_TXEN, GPIO_FN_RMII1_REFCLK, GPIO_FN_RMII1_RXD1,
+ GPIO_FN_RMII1_RXD0, GPIO_FN_RMII1_RX_ER, GPIO_FN_RAC_RI,
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ GPIO_FN_BOOTFMS, GPIO_FN_BOOTWP,
+ GPIO_FN_A25, GPIO_FN_A24, GPIO_FN_SERIRQ, GPIO_FN_WDTOVF,
+ GPIO_FN_LPCPD, GPIO_FN_LDRQ, GPIO_FN_MMCCLK, GPIO_FN_MMCCMD,
+
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
GPIO_FN_SP1_MOSI, GPIO_FN_SP1_MISO,
GPIO_FN_SP1_SCK, GPIO_FN_SP1_SCK_FB,
GPIO_FN_SP1_SS0, GPIO_FN_SP1_SS1,
- GPIO_FN_SP0_SS1,
-
- /* PTI (mobule: INTC) */
- GPIO_FN_IRQ15, GPIO_FN_IRQ14, GPIO_FN_IRQ13, GPIO_FN_IRQ12,
- GPIO_FN_IRQ11, GPIO_FN_IRQ10, GPIO_FN_IRQ9, GPIO_FN_IRQ8,
-
- /* PTJ (mobule: SCIF234, SERMUX) */
- GPIO_FN_RXD3, GPIO_FN_TXD3, GPIO_FN_RXD2, GPIO_FN_TXD2,
- GPIO_FN_COM1_TXD, GPIO_FN_COM1_RXD,
- GPIO_FN_COM1_RTS, GPIO_FN_COM1_CTS,
-
- /* PTK (mobule: SERMUX) */
- GPIO_FN_COM2_TXD, GPIO_FN_COM2_RXD,
- GPIO_FN_COM2_RTS, GPIO_FN_COM2_CTS,
- GPIO_FN_COM2_DTR, GPIO_FN_COM2_DSR,
- GPIO_FN_COM2_DCD, GPIO_FN_COM2_RI,
+ GPIO_FN_WP, GPIO_FN_FMS0, GPIO_FN_TEND1, GPIO_FN_DREQ1,
+ GPIO_FN_DACK1, GPIO_FN_ADTRG1, GPIO_FN_ADTRG0,
- /* PTL (mobule: SERMUX) */
- GPIO_FN_RAC_TXD, GPIO_FN_RAC_RXD,
- GPIO_FN_RAC_RTS, GPIO_FN_RAC_CTS,
- GPIO_FN_RAC_DTR, GPIO_FN_RAC_DSR,
- GPIO_FN_RAC_DCD, GPIO_FN_RAC_RI,
+ /* PTI (mobule: LBSC, SDHI) */
+ GPIO_FN_D15, GPIO_FN_D14, GPIO_FN_D13, GPIO_FN_D12,
+ GPIO_FN_D11, GPIO_FN_D10, GPIO_FN_D9, GPIO_FN_D8,
+ GPIO_FN_SD_WP, GPIO_FN_SD_CD, GPIO_FN_SD_CLK, GPIO_FN_SD_CMD,
+ GPIO_FN_SD_D3, GPIO_FN_SD_D2, GPIO_FN_SD_D1, GPIO_FN_SD_D0,
- /* PTM (mobule: IIC, LPC) */
+ /* PTJ (mobule: SCIF234) */
+ GPIO_FN_RTS3, GPIO_FN_CTS3, GPIO_FN_TXD3, GPIO_FN_RXD3,
+ GPIO_FN_RTS4, GPIO_FN_RXD4, GPIO_FN_TXD4,
+
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
+ GPIO_FN_COM2_TXD, GPIO_FN_COM2_RXD, GPIO_FN_COM2_RTS,
+ GPIO_FN_COM2_CTS, GPIO_FN_COM2_DTR, GPIO_FN_COM2_DSR,
+ GPIO_FN_COM2_DCD, GPIO_FN_CLKOUT,
+ GPIO_FN_SCK2, GPIO_FN_SCK4, GPIO_FN_SCK3,
+
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+ GPIO_FN_RAC_RXD, GPIO_FN_RAC_RTS, GPIO_FN_RAC_CTS,
+ GPIO_FN_RAC_DTR, GPIO_FN_RAC_DSR, GPIO_FN_RAC_DCD,
+ GPIO_FN_RAC_TXD, GPIO_FN_RXD2, GPIO_FN_CS5,
+ GPIO_FN_CS6, GPIO_FN_AUDSYNC, GPIO_FN_AUDCK,
+ GPIO_FN_TXD2,
+
+ /* PTM (mobule: LBSC, IIC) */
+ GPIO_FN_CS4, GPIO_FN_RD, GPIO_FN_WE0, GPIO_FN_CS0,
GPIO_FN_SDA6, GPIO_FN_SCL6, GPIO_FN_SDA7, GPIO_FN_SCL7,
- GPIO_FN_WP, GPIO_FN_FMS0, GPIO_FN_FMS1,
-
- /* PTN (mobule: SCIF234, EVC) */
- GPIO_FN_SCK2, GPIO_FN_RTS4, GPIO_FN_RTS3, GPIO_FN_RTS2,
- GPIO_FN_CTS4, GPIO_FN_CTS3, GPIO_FN_CTS2,
- GPIO_FN_EVENT7, GPIO_FN_EVENT6, GPIO_FN_EVENT5, GPIO_FN_EVENT4,
- GPIO_FN_EVENT3, GPIO_FN_EVENT2, GPIO_FN_EVENT1, GPIO_FN_EVENT0,
- /* PTO (mobule: SGPIO) */
- GPIO_FN_SGPIO0_CLK, GPIO_FN_SGPIO0_LOAD,
- GPIO_FN_SGPIO0_DI, GPIO_FN_SGPIO0_DO,
- GPIO_FN_SGPIO1_CLK, GPIO_FN_SGPIO1_LOAD,
- GPIO_FN_SGPIO1_DI, GPIO_FN_SGPIO1_DO,
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ GPIO_FN_VBUS_EN, GPIO_FN_VBUS_OC, GPIO_FN_JMCTCK,
+ GPIO_FN_JMCTMS, GPIO_FN_JMCTDO, GPIO_FN_JMCTDI,
+ GPIO_FN_JMCTRST,
+ GPIO_FN_SGPIO1_CLK, GPIO_FN_SGPIO1_LOAD, GPIO_FN_SGPIO1_DI,
+ GPIO_FN_SGPIO1_DO, GPIO_FN_SUB_CLKIN,
- /* PTP (mobule: JMC, SCIF234) */
- GPIO_FN_JMCTCK, GPIO_FN_JMCTMS, GPIO_FN_JMCTDO, GPIO_FN_JMCTDI,
- GPIO_FN_JMCRST, GPIO_FN_SCK4, GPIO_FN_SCK3,
+ /* PTO (mobule: SGPIO, SerMux) */
+ GPIO_FN_SGPIO0_CLK, GPIO_FN_SGPIO0_LOAD, GPIO_FN_SGPIO0_DI,
+ GPIO_FN_SGPIO0_DO, GPIO_FN_SGPIO2_CLK, GPIO_FN_SGPIO2_LOAD,
+ GPIO_FN_SGPIO2_DI, GPIO_FN_SGPIO2_DO, GPIO_FN_COM1_TXD,
+ GPIO_FN_COM1_RXD, GPIO_FN_COM1_RTS, GPIO_FN_COM1_CTS,
/* PTQ (mobule: LPC) */
GPIO_FN_LAD3, GPIO_FN_LAD2, GPIO_FN_LAD1, GPIO_FN_LAD0,
GPIO_FN_LFRAME, GPIO_FN_LRESET, GPIO_FN_LCLK,
/* PTR (mobule: GRA, IIC) */
- GPIO_FN_DDC3, GPIO_FN_DDC2,
- GPIO_FN_SDA8, GPIO_FN_SCL8, GPIO_FN_SDA2, GPIO_FN_SCL2,
+ GPIO_FN_DDC3, GPIO_FN_DDC2, GPIO_FN_SDA2, GPIO_FN_SCL2,
GPIO_FN_SDA1, GPIO_FN_SCL1, GPIO_FN_SDA0, GPIO_FN_SCL0,
+ GPIO_FN_SDA8, GPIO_FN_SCL8,
/* PTS (mobule: GRA, IIC) */
- GPIO_FN_DDC1, GPIO_FN_DDC0,
- GPIO_FN_SDA9, GPIO_FN_SCL9, GPIO_FN_SDA5, GPIO_FN_SCL5,
+ GPIO_FN_DDC1, GPIO_FN_DDC0, GPIO_FN_SDA5, GPIO_FN_SCL5,
GPIO_FN_SDA4, GPIO_FN_SCL4, GPIO_FN_SDA3, GPIO_FN_SCL3,
+ GPIO_FN_SDA9, GPIO_FN_SCL9,
- /* PTT (mobule: SYSTEM, PWMX) */
- GPIO_FN_AUDSYNC, GPIO_FN_AUDCK,
- GPIO_FN_AUDATA3, GPIO_FN_AUDATA2,
- GPIO_FN_AUDATA1, GPIO_FN_AUDATA0,
- GPIO_FN_PWX7, GPIO_FN_PWX6, GPIO_FN_PWX5, GPIO_FN_PWX4,
+ /* PTT (mobule: PWMX, AUD) */
+ GPIO_FN_PWMX7, GPIO_FN_PWMX6, GPIO_FN_PWMX5, GPIO_FN_PWMX4,
+ GPIO_FN_PWMX3, GPIO_FN_PWMX2, GPIO_FN_PWMX1, GPIO_FN_PWMX0,
+ GPIO_FN_AUDATA3, GPIO_FN_AUDATA2, GPIO_FN_AUDATA1,
+ GPIO_FN_AUDATA0, GPIO_FN_STATUS1, GPIO_FN_STATUS0,
- /* PTU (mobule: LBSC, DMAC) */
- GPIO_FN_CS6, GPIO_FN_CS5, GPIO_FN_CS4, GPIO_FN_CS0,
- GPIO_FN_RD, GPIO_FN_WE0, GPIO_FN_A25, GPIO_FN_A24,
- GPIO_FN_DREQ0, GPIO_FN_DACK0,
+ /* PTU (mobule: LPC, APM) */
+ GPIO_FN_LGPIO7, GPIO_FN_LGPIO6, GPIO_FN_LGPIO5, GPIO_FN_LGPIO4,
+ GPIO_FN_LGPIO3, GPIO_FN_LGPIO2, GPIO_FN_LGPIO1, GPIO_FN_LGPIO0,
+ GPIO_FN_APMONCTL_O, GPIO_FN_APMPWBTOUT_O, GPIO_FN_APMSCI_O,
+ GPIO_FN_APMVDDON, GPIO_FN_APMSLPBTN, GPIO_FN_APMPWRBTN,
+ GPIO_FN_APMS5N, GPIO_FN_APMS3N,
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
GPIO_FN_A23, GPIO_FN_A22, GPIO_FN_A21, GPIO_FN_A20,
GPIO_FN_A19, GPIO_FN_A18, GPIO_FN_A17, GPIO_FN_A16,
- GPIO_FN_TEND0, GPIO_FN_DREQ1, GPIO_FN_DACK1, GPIO_FN_TEND1,
+ GPIO_FN_COM2_RI, GPIO_FN_R_SPI_MOSI, GPIO_FN_R_SPI_MISO,
+ GPIO_FN_R_SPI_RSPCK, GPIO_FN_R_SPI_SSL0, GPIO_FN_R_SPI_SSL1,
+ GPIO_FN_EVENT7, GPIO_FN_EVENT6, GPIO_FN_VBIOS_DI,
+ GPIO_FN_VBIOS_DO, GPIO_FN_VBIOS_CLK, GPIO_FN_VBIOS_CS,
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
GPIO_FN_A15, GPIO_FN_A14, GPIO_FN_A13, GPIO_FN_A12,
GPIO_FN_A11, GPIO_FN_A10, GPIO_FN_A9, GPIO_FN_A8,
+ GPIO_FN_EVENT5, GPIO_FN_EVENT4, GPIO_FN_EVENT3, GPIO_FN_EVENT2,
+ GPIO_FN_EVENT1, GPIO_FN_EVENT0, GPIO_FN_CTS4, GPIO_FN_CTS2,
- /* PTX (mobule: LBSC) */
+ /* PTX (mobule: LBSC, SCIF, SIM) */
GPIO_FN_A7, GPIO_FN_A6, GPIO_FN_A5, GPIO_FN_A4,
GPIO_FN_A3, GPIO_FN_A2, GPIO_FN_A1, GPIO_FN_A0,
+ GPIO_FN_RTS2, GPIO_FN_SIM_D, GPIO_FN_SIM_CLK, GPIO_FN_SIM_RST,
/* PTY (mobule: LBSC) */
GPIO_FN_D7, GPIO_FN_D6, GPIO_FN_D5, GPIO_FN_D4,
GPIO_FN_D3, GPIO_FN_D2, GPIO_FN_D1, GPIO_FN_D0,
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ GPIO_FN_MMCDAT7, GPIO_FN_MMCDAT6, GPIO_FN_MMCDAT5,
+ GPIO_FN_MMCDAT4, GPIO_FN_MMCDAT3, GPIO_FN_MMCDAT2,
+ GPIO_FN_MMCDAT1, GPIO_FN_MMCDAT0,
+ GPIO_FN_ON_DQ7, GPIO_FN_ON_DQ6, GPIO_FN_ON_DQ5, GPIO_FN_ON_DQ4,
+ GPIO_FN_ON_DQ3, GPIO_FN_ON_DQ2, GPIO_FN_ON_DQ1, GPIO_FN_ON_DQ0,
};
#endif /* __ASM_SH7757_H__ */
diff --git a/arch/sh/include/mach-common/mach/sh2007.h b/arch/sh/include/mach-common/mach/sh2007.h
new file mode 100644
index 000000000000..48180b9aa03d
--- /dev/null
+++ b/arch/sh/include/mach-common/mach/sh2007.h
@@ -0,0 +1,117 @@
+#ifndef __MACH_SH2007_H
+#define __MACH_SH2007_H
+
+#define CS5BCR 0xff802050
+#define CS5WCR 0xff802058
+#define CS5PCR 0xff802070
+
+#define BUS_SZ8 1
+#define BUS_SZ16 2
+#define BUS_SZ32 3
+
+#define PCMCIA_IODYN 1
+#define PCMCIA_ATA 0
+#define PCMCIA_IO8 2
+#define PCMCIA_IO16 3
+#define PCMCIA_COMM8 4
+#define PCMCIA_COMM16 5
+#define PCMCIA_ATTR8 6
+#define PCMCIA_ATTR16 7
+
+#define TYPE_SRAM 0
+#define TYPE_PCMCIA 4
+
+/* write-read/write-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWW5 0
+#define IWW6 3
+/* different area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWD5 2
+#define IWRWD6 2
+/* same area, read-write delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRWS5 2
+#define IWRWS6 2
+/* different area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRD5 2
+#define IWRRD6 2
+/* same area, read-read delay (0-7:0,1,2,3,4,5,6,7) */
+#define IWRRS5 0
+#define IWRRS6 2
+/* burst count (0-3:4,8,16,32) */
+#define BST5 0
+#define BST6 0
+/* bus size */
+#define SZ5 BUS_SZ16
+#define SZ6 BUS_SZ16
+/* RD hold for SRAM (0-1:0,1) */
+#define RDSPL5 0
+#define RDSPL6 0
+/* Burst pitch (0-7:0,1,2,3,4,5,6,7) */
+#define BW5 0
+#define BW6 0
+/* Multiplex (0-1:0,1) */
+#define MPX5 0
+#define MPX6 0
+/* device type */
+#define TYPE5 TYPE_PCMCIA
+#define TYPE6 TYPE_PCMCIA
+/* address setup before assert CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADS5 0
+#define ADS6 0
+/* address hold after negate CSn for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define ADH5 0
+#define ADH6 0
+/* CSn assert to RD assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDS5 0
+#define RDS6 0
+/* RD negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define RDH5 0
+#define RDH6 0
+/* CSn assert to WE assert delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTS5 0
+#define WTS6 0
+/* WE negate to CSn negate delay for SRAM (0-7:0,1,2,3,4,5,6,7) */
+#define WTH5 0
+#define WTH6 0
+/* BS hold (0-1:1,2) */
+#define BSH5 0
+#define BSH6 0
+/* wait cycle (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define IW5 6 /* 60ns PIO mode 4 */
+#define IW6 15 /* 250ns */
+
+#define SAA5 PCMCIA_IODYN /* IDE area b4000000-b5ffffff */
+#define SAB5 PCMCIA_IODYN /* CF area b6000000-b7ffffff */
+#define PCWA5 0 /* additional wait A (0-3:0,15,30,50) */
+#define PCWB5 0 /* additional wait B (0-3:0,15,30,50) */
+/* wait B (0-15:0,1,2,3,4,5,6,7,8,9,11,13,15,17,21,25) */
+#define PCIW5 12
+/* Address->OE/WE assert delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEDA5 2
+/* Address->OE/WE assert delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEDB5 4
+/* OE/WE negate->Address delay A (0-7:0,1,2,3,6,9,12,15) */
+#define TEHA5 2
+/* OE/WE negate->Address delay B (0-7:0,1,2,3,6,9,12,15) */
+#define TEHB5 3
+
+#define CS5BCR_D ((IWW5<<28)|(IWRWD5<<24)|(IWRWS5<<20)| \
+ (IWRRD5<<16)|(IWRRS5<<12)|(BST5<<10)| \
+ (SZ5<<8)|(RDSPL5<<7)|(BW5<<4)|(MPX5<<3)|TYPE5)
+#define CS5WCR_D ((ADS5<<28)|(ADH5<<24)|(RDS5<<20)| \
+ (RDH5<<16)|(WTS5<<12)|(WTH5<<8)|(BSH5<<4)|IW5)
+#define CS5PCR_D ((SAA5<<28)|(SAB5<<24)|(PCWA5<<22)| \
+ (PCWB5<<20)|(PCIW5<<16)|(TEDA5<<12)| \
+ (TEDB5<<8)|(TEHA5<<4)|TEHB5)
+
+#define SMC0_BASE 0xb0800000 /* eth0 */
+#define SMC1_BASE 0xb0900000 /* eth1 */
+#define CF_BASE 0xb6100000 /* Compact Flash (I/O area) */
+#define IDE_BASE 0xb4000000 /* IDE */
+#define PC104_IO_BASE 0xb8000000
+#define PC104_MEM_BASE 0xba000000
+#define SMC_IO_SIZE 0x100
+
+#define CF_OFFSET 0x1f0
+#define IDE_OFFSET 0x170
+
+#endif /* __MACH_SH2007_H */
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index e25f3c69525d..1086ba1abdab 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -14,7 +14,7 @@ CFLAGS_REMOVE_return_address.o = -pg
obj-y := clkdev.o debugtraps.o dma-nommu.o dumpstack.o \
idle.o io.o irq.o \
irq_$(BITS).o machvec.o nmi_debug.o process.o \
- process_$(BITS).o ptrace_$(BITS).o \
+ process_$(BITS).o ptrace.o ptrace_$(BITS).o \
reboot.o return_address.o \
setup.o signal_$(BITS).o sys_sh.o sys_sh$(BITS).o \
syscalls_$(BITS).o time.o topology.o traps.o \
diff --git a/arch/sh/kernel/cpu/sh4/probe.c b/arch/sh/kernel/cpu/sh4/probe.c
index d180f16281ed..b93458f33b74 100644
--- a/arch/sh/kernel/cpu/sh4/probe.c
+++ b/arch/sh/kernel/cpu/sh4/probe.c
@@ -150,7 +150,7 @@ void __cpuinit cpu_probe(void)
boot_cpu_data.type = CPU_SH7724;
boot_cpu_data.flags |= CPU_HAS_L2_CACHE;
break;
- case 0x50:
+ case 0x10:
boot_cpu_data.type = CPU_SH7757;
break;
}
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
index 0a752bd324ac..ce39a2ae8c6c 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c
@@ -3,7 +3,7 @@
*
* SH7757 support for the clock framework
*
- * Copyright (C) 2009 Renesas Solutions Corp.
+ * Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* 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
@@ -16,124 +16,147 @@
#include <asm/clock.h>
#include <asm/freq.h>
-static int ifc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int sfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int bfc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
-static int p1fc_divisors[] = { 2, 1, 4, 1, 1, 8, 1, 1,
- 16, 1, 1, 32, 1, 1, 1, 1 };
+/*
+ * Default rate for the root input clock, reset this with clk_set_rate()
+ * from the platform code.
+ */
+static struct clk extal_clk = {
+ .rate = 48000000,
+};
-static void master_clk_init(struct clk *clk)
+static unsigned long pll_recalc(struct clk *clk)
{
- clk->rate = CONFIG_SH_PCLK_FREQ * 16;
-}
+ int multiplier;
-static struct clk_ops sh7757_master_clk_ops = {
- .init = master_clk_init,
-};
+ multiplier = test_mode_pin(MODE_PIN0) ? 24 : 16;
-static void module_clk_recalc(struct clk *clk)
-{
- int idx = __raw_readl(FRQCR) & 0x0000000f;
- clk->rate = clk->parent->rate / p1fc_divisors[idx];
+ return clk->parent->rate * multiplier;
}
-static struct clk_ops sh7757_module_clk_ops = {
- .recalc = module_clk_recalc,
+static struct clk_ops pll_clk_ops = {
+ .recalc = pll_recalc,
};
-static void bus_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 8) & 0x0000000f;
- clk->rate = clk->parent->rate / bfc_divisors[idx];
-}
+static struct clk pll_clk = {
+ .ops = &pll_clk_ops,
+ .parent = &extal_clk,
+ .flags = CLK_ENABLE_ON_INIT,
+};
-static struct clk_ops sh7757_bus_clk_ops = {
- .recalc = bus_clk_recalc,
+static struct clk *clks[] = {
+ &extal_clk,
+ &pll_clk,
};
-static void cpu_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 20) & 0x0000000f;
- clk->rate = clk->parent->rate / ifc_divisors[idx];
-}
+static unsigned int div2[] = { 1, 1, 2, 1, 1, 4, 1, 6,
+ 1, 1, 1, 16, 1, 24, 1, 1 };
-static struct clk_ops sh7757_cpu_clk_ops = {
- .recalc = cpu_clk_recalc,
+static struct clk_div_mult_table div4_div_mult_table = {
+ .divisors = div2,
+ .nr_divisors = ARRAY_SIZE(div2),
};
-static struct clk_ops *sh7757_clk_ops[] = {
- &sh7757_master_clk_ops,
- &sh7757_module_clk_ops,
- &sh7757_bus_clk_ops,
- &sh7757_cpu_clk_ops,
+static struct clk_div4_table div4_table = {
+ .div_mult_table = &div4_div_mult_table,
};
-void __init arch_init_clk_ops(struct clk_ops **ops, int idx)
-{
- if (idx < ARRAY_SIZE(sh7757_clk_ops))
- *ops = sh7757_clk_ops[idx];
-}
+enum { DIV4_I, DIV4_SH, DIV4_P, DIV4_NR };
-static void shyway_clk_recalc(struct clk *clk)
-{
- int idx = (__raw_readl(FRQCR) >> 12) & 0x0000000f;
- clk->rate = clk->parent->rate / sfc_divisors[idx];
-}
-
-static struct clk_ops sh7757_shyway_clk_ops = {
- .recalc = shyway_clk_recalc,
-};
+#define DIV4(_bit, _mask, _flags) \
+ SH_CLK_DIV4(&pll_clk, FRQCR, _bit, _mask, _flags)
-static struct clk sh7757_shyway_clk = {
- .flags = CLK_ENABLE_ON_INIT,
- .ops = &sh7757_shyway_clk_ops,
+struct clk div4_clks[DIV4_NR] = {
+ /*
+ * P clock is always enable, because some P clock modules is used
+ * by Host PC.
+ */
+ [DIV4_P] = DIV4(0, 0x2800, CLK_ENABLE_ON_INIT),
+ [DIV4_SH] = DIV4(12, 0x00a0, CLK_ENABLE_ON_INIT),
+ [DIV4_I] = DIV4(20, 0x0004, CLK_ENABLE_ON_INIT),
};
-/*
- * Additional sh7757-specific on-chip clocks that aren't already part of the
- * clock framework
- */
-static struct clk *sh7757_onchip_clocks[] = {
- &sh7757_shyway_clk,
+#define MSTPCR0 0xffc80030
+#define MSTPCR1 0xffc80034
+
+enum { MSTP004, MSTP000, MSTP114, MSTP113, MSTP112,
+ MSTP111, MSTP110, MSTP103, MSTP102,
+ MSTP_NR };
+
+static struct clk mstp_clks[MSTP_NR] = {
+ /* MSTPCR0 */
+ [MSTP004] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 4, 0),
+ [MSTP000] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR0, 0, 0),
+
+ /* MSTPCR1 */
+ [MSTP114] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 14, 0),
+ [MSTP113] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 13, 0),
+ [MSTP112] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 12, 0),
+ [MSTP111] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 11, 0),
+ [MSTP110] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 10, 0),
+ [MSTP103] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 3, 0),
+ [MSTP102] = SH_CLK_MSTP32(&div4_clks[DIV4_P], MSTPCR1, 2, 0),
};
#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }
static struct clk_lookup lookups[] = {
/* main clocks */
- CLKDEV_CON_ID("shyway_clk", &sh7757_shyway_clk),
+ CLKDEV_CON_ID("extal", &extal_clk),
+ CLKDEV_CON_ID("pll_clk", &pll_clk),
+
+ /* DIV4 clocks */
+ CLKDEV_CON_ID("peripheral_clk", &div4_clks[DIV4_P]),
+ CLKDEV_CON_ID("shyway_clk", &div4_clks[DIV4_SH]),
+ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]),
+
+ /* MSTP32 clocks */
+ CLKDEV_CON_ID("sdhi0", &mstp_clks[MSTP004]),
+ CLKDEV_CON_ID("riic", &mstp_clks[MSTP000]),
+ {
+ /* TMU0 */
+ .dev_id = "sh_tmu.0",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP113],
+ }, {
+ /* TMU1 */
+ .dev_id = "sh_tmu.1",
+ .con_id = "tmu_fck",
+ .clk = &mstp_clks[MSTP114],
+ },
+ {
+ /* SCIF4 (But, ID is 2) */
+ .dev_id = "sh-sci.2",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP112],
+ }, {
+ /* SCIF3 */
+ .dev_id = "sh-sci.1",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP111],
+ }, {
+ /* SCIF2 */
+ .dev_id = "sh-sci.0",
+ .con_id = "sci_fck",
+ .clk = &mstp_clks[MSTP110],
+ },
+ CLKDEV_CON_ID("usb0", &mstp_clks[MSTP102]),
};
-static int __init sh7757_clk_init(void)
+int __init arch_clk_init(void)
{
- struct clk *clk = clk_get(NULL, "master_clk");
- int i;
-
- for (i = 0; i < ARRAY_SIZE(sh7757_onchip_clocks); i++) {
- struct clk *clkp = sh7757_onchip_clocks[i];
+ int i, ret = 0;
- clkp->parent = clk;
- clk_register(clkp);
- clk_enable(clkp);
- }
+ for (i = 0; i < ARRAY_SIZE(clks); i++)
+ ret |= clk_register(clks[i]);
+ for (i = 0; i < ARRAY_SIZE(lookups); i++)
+ clkdev_add(&lookups[i]);
- /*
- * Now that we have the rest of the clocks registered, we need to
- * force the parent clock to propagate so that these clocks will
- * automatically figure out their rate. We cheat by handing the
- * parent clock its current rate and forcing child propagation.
- */
- clk_set_rate(clk, clk_get_rate(clk));
+ if (!ret)
+ ret = sh_clk_div4_register(div4_clks, ARRAY_SIZE(div4_clks),
+ &div4_table);
+ if (!ret)
+ ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
- clk_put(clk);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- return 0;
+ return ret;
}
-arch_initcall(sh7757_clk_init);
-
diff --git a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
index ed23b155c097..4c74bd04bba4 100644
--- a/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/pinmux-sh7757.c
@@ -1,11 +1,11 @@
/*
- * SH7757 (A0 step) Pinmux
+ * SH7757 (B0 step) Pinmux
*
- * Copyright (C) 2009 Renesas Solutions Corp.
+ * Copyright (C) 2009-2010 Renesas Solutions Corp.
*
* Author : Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
- * Based on SH7757 Pinmux
+ * Based on SH7723 Pinmux
* Copyright (C) 2008 Magnus Damm
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -40,27 +40,27 @@ enum {
PTH3_DATA, PTH2_DATA, PTH1_DATA, PTH0_DATA,
PTI7_DATA, PTI6_DATA, PTI5_DATA, PTI4_DATA,
PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA,
- PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA,
PTK7_DATA, PTK6_DATA, PTK5_DATA, PTK4_DATA,
PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA,
- PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ PTL6_DATA, PTL5_DATA, PTL4_DATA,
PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA,
- PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA,
- PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ PTN6_DATA, PTN5_DATA, PTN4_DATA,
PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA,
PTO7_DATA, PTO6_DATA, PTO5_DATA, PTO4_DATA,
PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA,
- PTP6_DATA, PTP5_DATA, PTP4_DATA,
+ PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA,
- PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
+ PTQ6_DATA, PTQ5_DATA, PTQ4_DATA,
PTQ3_DATA, PTQ2_DATA, PTQ1_DATA, PTQ0_DATA,
PTR7_DATA, PTR6_DATA, PTR5_DATA, PTR4_DATA,
PTR3_DATA, PTR2_DATA, PTR1_DATA, PTR0_DATA,
PTS7_DATA, PTS6_DATA, PTS5_DATA, PTS4_DATA,
PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA,
- PTT5_DATA, PTT4_DATA,
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA,
PTU7_DATA, PTU6_DATA, PTU5_DATA, PTU4_DATA,
PTU3_DATA, PTU2_DATA, PTU1_DATA, PTU0_DATA,
@@ -95,27 +95,27 @@ enum {
PTH3_IN, PTH2_IN, PTH1_IN, PTH0_IN,
PTI7_IN, PTI6_IN, PTI5_IN, PTI4_IN,
PTI3_IN, PTI2_IN, PTI1_IN, PTI0_IN,
- PTJ7_IN, PTJ6_IN, PTJ5_IN, PTJ4_IN,
+ PTJ6_IN, PTJ5_IN, PTJ4_IN,
PTJ3_IN, PTJ2_IN, PTJ1_IN, PTJ0_IN,
PTK7_IN, PTK6_IN, PTK5_IN, PTK4_IN,
PTK3_IN, PTK2_IN, PTK1_IN, PTK0_IN,
- PTL7_IN, PTL6_IN, PTL5_IN, PTL4_IN,
+ PTL6_IN, PTL5_IN, PTL4_IN,
PTL3_IN, PTL2_IN, PTL1_IN, PTL0_IN,
- PTM6_IN, PTM5_IN, PTM4_IN,
+ PTM7_IN, PTM6_IN, PTM5_IN, PTM4_IN,
PTM3_IN, PTM2_IN, PTM1_IN, PTM0_IN,
- PTN7_IN, PTN6_IN, PTN5_IN, PTN4_IN,
+ PTN6_IN, PTN5_IN, PTN4_IN,
PTN3_IN, PTN2_IN, PTN1_IN, PTN0_IN,
PTO7_IN, PTO6_IN, PTO5_IN, PTO4_IN,
PTO3_IN, PTO2_IN, PTO1_IN, PTO0_IN,
- PTP6_IN, PTP5_IN, PTP4_IN,
+ PTP7_IN, PTP6_IN, PTP5_IN, PTP4_IN,
PTP3_IN, PTP2_IN, PTP1_IN, PTP0_IN,
- PTQ6_IN, PTQ5_IN, PTQ4_IN,
+ PTQ6_IN, PTQ5_IN, PTQ4_IN,
PTQ3_IN, PTQ2_IN, PTQ1_IN, PTQ0_IN,
PTR7_IN, PTR6_IN, PTR5_IN, PTR4_IN,
PTR3_IN, PTR2_IN, PTR1_IN, PTR0_IN,
PTS7_IN, PTS6_IN, PTS5_IN, PTS4_IN,
PTS3_IN, PTS2_IN, PTS1_IN, PTS0_IN,
- PTT5_IN, PTT4_IN,
+ PTT7_IN, PTT6_IN, PTT5_IN, PTT4_IN,
PTT3_IN, PTT2_IN, PTT1_IN, PTT0_IN,
PTU7_IN, PTU6_IN, PTU5_IN, PTU4_IN,
PTU3_IN, PTU2_IN, PTU1_IN, PTU0_IN,
@@ -132,16 +132,43 @@ enum {
PINMUX_INPUT_END,
PINMUX_INPUT_PULLUP_BEGIN,
+ PTA7_IN_PU, PTA6_IN_PU, PTA5_IN_PU, PTA4_IN_PU,
+ PTA3_IN_PU, PTA2_IN_PU, PTA1_IN_PU, PTA0_IN_PU,
+ PTD7_IN_PU, PTD6_IN_PU, PTD5_IN_PU, PTD4_IN_PU,
+ PTD3_IN_PU, PTD2_IN_PU, PTD1_IN_PU, PTD0_IN_PU,
+ PTE7_IN_PU, PTE6_IN_PU, PTE5_IN_PU, PTE4_IN_PU,
+ PTE3_IN_PU, PTE2_IN_PU, PTE1_IN_PU, PTE0_IN_PU,
+ PTF7_IN_PU, PTF6_IN_PU, PTF5_IN_PU, PTF4_IN_PU,
+ PTF3_IN_PU, PTF2_IN_PU, PTF1_IN_PU, PTF0_IN_PU,
+ PTG7_IN_PU, PTG6_IN_PU, PTG4_IN_PU,
+ PTH7_IN_PU, PTH6_IN_PU, PTH5_IN_PU, PTH4_IN_PU,
+ PTH3_IN_PU, PTH2_IN_PU, PTH1_IN_PU, PTH0_IN_PU,
+ PTI7_IN_PU, PTI6_IN_PU, PTI4_IN_PU,
+ PTI3_IN_PU, PTI2_IN_PU, PTI1_IN_PU, PTI0_IN_PU,
+ PTJ6_IN_PU, PTJ5_IN_PU, PTJ4_IN_PU,
+ PTJ3_IN_PU, PTJ2_IN_PU, PTJ1_IN_PU, PTJ0_IN_PU,
+ PTK7_IN_PU, PTK6_IN_PU, PTK5_IN_PU, PTK4_IN_PU,
+ PTK3_IN_PU, PTK2_IN_PU, PTK1_IN_PU, PTK0_IN_PU,
+ PTL6_IN_PU, PTL5_IN_PU, PTL4_IN_PU,
+ PTL3_IN_PU, PTL2_IN_PU, PTL1_IN_PU, PTL0_IN_PU,
+ PTM7_IN_PU, PTM6_IN_PU, PTM5_IN_PU, PTM4_IN_PU,
+ PTN4_IN_PU,
+ PTN3_IN_PU, PTN2_IN_PU, PTN1_IN_PU, PTN0_IN_PU,
+ PTO7_IN_PU, PTO6_IN_PU, PTO5_IN_PU, PTO4_IN_PU,
+ PTO3_IN_PU, PTO2_IN_PU, PTO1_IN_PU, PTO0_IN_PU,
+ PTT7_IN_PU, PTT6_IN_PU, PTT5_IN_PU, PTT4_IN_PU,
+ PTT3_IN_PU, PTT2_IN_PU, PTT1_IN_PU, PTT0_IN_PU,
PTU7_IN_PU, PTU6_IN_PU, PTU5_IN_PU, PTU4_IN_PU,
PTU3_IN_PU, PTU2_IN_PU, PTU1_IN_PU, PTU0_IN_PU,
PTV7_IN_PU, PTV6_IN_PU, PTV5_IN_PU, PTV4_IN_PU,
- PTV3_IN_PU, PTV2_IN_PU, PTV1_IN_PU, PTV0_IN_PU,
- PTW7_IN_PU, PTW6_IN_PU, PTW5_IN_PU, PTW4_IN_PU,
- PTW3_IN_PU, PTW2_IN_PU, PTW1_IN_PU, PTW0_IN_PU,
+ PTV3_IN_PU, PTV2_IN_PU,
+ PTW1_IN_PU, PTW0_IN_PU,
PTX7_IN_PU, PTX6_IN_PU, PTX5_IN_PU, PTX4_IN_PU,
PTX3_IN_PU, PTX2_IN_PU, PTX1_IN_PU, PTX0_IN_PU,
PTY7_IN_PU, PTY6_IN_PU, PTY5_IN_PU, PTY4_IN_PU,
PTY3_IN_PU, PTY2_IN_PU, PTY1_IN_PU, PTY0_IN_PU,
+ PTZ7_IN_PU, PTZ6_IN_PU, PTZ5_IN_PU, PTZ4_IN_PU,
+ PTZ3_IN_PU, PTZ2_IN_PU, PTZ1_IN_PU, PTZ0_IN_PU,
PINMUX_INPUT_PULLUP_END,
PINMUX_OUTPUT_BEGIN,
@@ -163,27 +190,27 @@ enum {
PTH3_OUT, PTH2_OUT, PTH1_OUT, PTH0_OUT,
PTI7_OUT, PTI6_OUT, PTI5_OUT, PTI4_OUT,
PTI3_OUT, PTI2_OUT, PTI1_OUT, PTI0_OUT,
- PTJ7_OUT, PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
+ PTJ6_OUT, PTJ5_OUT, PTJ4_OUT,
PTJ3_OUT, PTJ2_OUT, PTJ1_OUT, PTJ0_OUT,
PTK7_OUT, PTK6_OUT, PTK5_OUT, PTK4_OUT,
PTK3_OUT, PTK2_OUT, PTK1_OUT, PTK0_OUT,
- PTL7_OUT, PTL6_OUT, PTL5_OUT, PTL4_OUT,
+ PTL6_OUT, PTL5_OUT, PTL4_OUT,
PTL3_OUT, PTL2_OUT, PTL1_OUT, PTL0_OUT,
- PTM6_OUT, PTM5_OUT, PTM4_OUT,
+ PTM7_OUT, PTM6_OUT, PTM5_OUT, PTM4_OUT,
PTM3_OUT, PTM2_OUT, PTM1_OUT, PTM0_OUT,
- PTN7_OUT, PTN6_OUT, PTN5_OUT, PTN4_OUT,
+ PTN6_OUT, PTN5_OUT, PTN4_OUT,
PTN3_OUT, PTN2_OUT, PTN1_OUT, PTN0_OUT,
PTO7_OUT, PTO6_OUT, PTO5_OUT, PTO4_OUT,
PTO3_OUT, PTO2_OUT, PTO1_OUT, PTO0_OUT,
- PTP6_OUT, PTP5_OUT, PTP4_OUT,
+ PTP7_OUT, PTP6_OUT, PTP5_OUT, PTP4_OUT,
PTP3_OUT, PTP2_OUT, PTP1_OUT, PTP0_OUT,
- PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
+ PTQ6_OUT, PTQ5_OUT, PTQ4_OUT,
PTQ3_OUT, PTQ2_OUT, PTQ1_OUT, PTQ0_OUT,
PTR7_OUT, PTR6_OUT, PTR5_OUT, PTR4_OUT,
PTR3_OUT, PTR2_OUT, PTR1_OUT, PTR0_OUT,
PTS7_OUT, PTS6_OUT, PTS5_OUT, PTS4_OUT,
PTS3_OUT, PTS2_OUT, PTS1_OUT, PTS0_OUT,
- PTT5_OUT, PTT4_OUT,
+ PTT7_OUT, PTT6_OUT, PTT5_OUT, PTT4_OUT,
PTT3_OUT, PTT2_OUT, PTT1_OUT, PTT0_OUT,
PTU7_OUT, PTU6_OUT, PTU5_OUT, PTU4_OUT,
PTU3_OUT, PTU2_OUT, PTU1_OUT, PTU0_OUT,
@@ -218,27 +245,27 @@ enum {
PTH3_FN, PTH2_FN, PTH1_FN, PTH0_FN,
PTI7_FN, PTI6_FN, PTI5_FN, PTI4_FN,
PTI3_FN, PTI2_FN, PTI1_FN, PTI0_FN,
- PTJ7_FN, PTJ6_FN, PTJ5_FN, PTJ4_FN,
+ PTJ6_FN, PTJ5_FN, PTJ4_FN,
PTJ3_FN, PTJ2_FN, PTJ1_FN, PTJ0_FN,
PTK7_FN, PTK6_FN, PTK5_FN, PTK4_FN,
PTK3_FN, PTK2_FN, PTK1_FN, PTK0_FN,
- PTL7_FN, PTL6_FN, PTL5_FN, PTL4_FN,
+ PTL6_FN, PTL5_FN, PTL4_FN,
PTL3_FN, PTL2_FN, PTL1_FN, PTL0_FN,
- PTM6_FN, PTM5_FN, PTM4_FN,
+ PTM7_FN, PTM6_FN, PTM5_FN, PTM4_FN,
PTM3_FN, PTM2_FN, PTM1_FN, PTM0_FN,
- PTN7_FN, PTN6_FN, PTN5_FN, PTN4_FN,
+ PTN6_FN, PTN5_FN, PTN4_FN,
PTN3_FN, PTN2_FN, PTN1_FN, PTN0_FN,
PTO7_FN, PTO6_FN, PTO5_FN, PTO4_FN,
PTO3_FN, PTO2_FN, PTO1_FN, PTO0_FN,
- PTP6_FN, PTP5_FN, PTP4_FN,
+ PTP7_FN, PTP6_FN, PTP5_FN, PTP4_FN,
PTP3_FN, PTP2_FN, PTP1_FN, PTP0_FN,
- PTQ6_FN, PTQ5_FN, PTQ4_FN,
+ PTQ6_FN, PTQ5_FN, PTQ4_FN,
PTQ3_FN, PTQ2_FN, PTQ1_FN, PTQ0_FN,
PTR7_FN, PTR6_FN, PTR5_FN, PTR4_FN,
PTR3_FN, PTR2_FN, PTR1_FN, PTR0_FN,
PTS7_FN, PTS6_FN, PTS5_FN, PTS4_FN,
PTS3_FN, PTS2_FN, PTS1_FN, PTS0_FN,
- PTT5_FN, PTT4_FN,
+ PTT7_FN, PTT6_FN, PTT5_FN, PTT4_FN,
PTT3_FN, PTT2_FN, PTT1_FN, PTT0_FN,
PTU7_FN, PTU6_FN, PTU5_FN, PTU4_FN,
PTU3_FN, PTU2_FN, PTU1_FN, PTU0_FN,
@@ -253,181 +280,248 @@ enum {
PTZ7_FN, PTZ6_FN, PTZ5_FN, PTZ4_FN,
PTZ3_FN, PTZ2_FN, PTZ1_FN, PTZ0_FN,
- PS0_15_FN1, PS0_15_FN3,
- PS0_14_FN1, PS0_14_FN3,
- PS0_13_FN1, PS0_13_FN3,
- PS0_12_FN1, PS0_12_FN3,
+ PS0_15_FN1, PS0_15_FN2,
+ PS0_14_FN1, PS0_14_FN2,
+ PS0_13_FN1, PS0_13_FN2,
+ PS0_12_FN1, PS0_12_FN2,
+ PS0_11_FN1, PS0_11_FN2,
+ PS0_10_FN1, PS0_10_FN2,
+ PS0_9_FN1, PS0_9_FN2,
+ PS0_8_FN1, PS0_8_FN2,
PS0_7_FN1, PS0_7_FN2,
PS0_6_FN1, PS0_6_FN2,
PS0_5_FN1, PS0_5_FN2,
PS0_4_FN1, PS0_4_FN2,
PS0_3_FN1, PS0_3_FN2,
PS0_2_FN1, PS0_2_FN2,
- PS0_1_FN1, PS0_1_FN2,
- PS1_7_FN1, PS1_7_FN3,
- PS1_6_FN1, PS1_6_FN3,
+ PS1_10_FN1, PS1_10_FN2,
+ PS1_9_FN1, PS1_9_FN2,
+ PS1_8_FN1, PS1_8_FN2,
+ PS1_2_FN1, PS1_2_FN2,
+
+ PS2_13_FN1, PS2_13_FN2,
+ PS2_12_FN1, PS2_12_FN2,
+ PS2_7_FN1, PS2_7_FN2,
+ PS2_6_FN1, PS2_6_FN2,
+ PS2_5_FN1, PS2_5_FN2,
+ PS2_4_FN1, PS2_4_FN2,
+ PS2_2_FN1, PS2_2_FN2,
+
+ PS3_15_FN1, PS3_15_FN2,
+ PS3_14_FN1, PS3_14_FN2,
+ PS3_13_FN1, PS3_13_FN2,
+ PS3_12_FN1, PS3_12_FN2,
+ PS3_11_FN1, PS3_11_FN2,
+ PS3_10_FN1, PS3_10_FN2,
+ PS3_9_FN1, PS3_9_FN2,
+ PS3_8_FN1, PS3_8_FN2,
+ PS3_7_FN1, PS3_7_FN2,
+ PS3_2_FN1, PS3_2_FN2,
+ PS3_1_FN1, PS3_1_FN2,
- PS2_13_FN1, PS2_13_FN3,
- PS2_12_FN1, PS2_12_FN3,
- PS2_1_FN1, PS2_1_FN2,
- PS2_0_FN1, PS2_0_FN2,
-
- PS4_15_FN1, PS4_15_FN2,
PS4_14_FN1, PS4_14_FN2,
PS4_13_FN1, PS4_13_FN2,
PS4_12_FN1, PS4_12_FN2,
- PS4_11_FN1, PS4_11_FN2,
PS4_10_FN1, PS4_10_FN2,
PS4_9_FN1, PS4_9_FN2,
+ PS4_8_FN1, PS4_8_FN2,
+ PS4_4_FN1, PS4_4_FN2,
PS4_3_FN1, PS4_3_FN2,
PS4_2_FN1, PS4_2_FN2,
PS4_1_FN1, PS4_1_FN2,
PS4_0_FN1, PS4_0_FN2,
+ PS5_11_FN1, PS5_11_FN2,
+ PS5_10_FN1, PS5_10_FN2,
PS5_9_FN1, PS5_9_FN2,
PS5_8_FN1, PS5_8_FN2,
PS5_7_FN1, PS5_7_FN2,
PS5_6_FN1, PS5_6_FN2,
PS5_5_FN1, PS5_5_FN2,
PS5_4_FN1, PS5_4_FN2,
-
- /* AN15 to 8 : EVENT15 to 8 */
- PS6_7_FN_AN, PS6_7_FN_EV,
- PS6_6_FN_AN, PS6_6_FN_EV,
- PS6_5_FN_AN, PS6_5_FN_EV,
- PS6_4_FN_AN, PS6_4_FN_EV,
- PS6_3_FN_AN, PS6_3_FN_EV,
- PS6_2_FN_AN, PS6_2_FN_EV,
- PS6_1_FN_AN, PS6_1_FN_EV,
- PS6_0_FN_AN, PS6_0_FN_EV,
-
+ PS5_3_FN1, PS5_3_FN2,
+ PS5_2_FN1, PS5_2_FN2,
+
+ PS6_15_FN1, PS6_15_FN2,
+ PS6_14_FN1, PS6_14_FN2,
+ PS6_13_FN1, PS6_13_FN2,
+ PS6_12_FN1, PS6_12_FN2,
+ PS6_11_FN1, PS6_11_FN2,
+ PS6_10_FN1, PS6_10_FN2,
+ PS6_9_FN1, PS6_9_FN2,
+ PS6_8_FN1, PS6_8_FN2,
+ PS6_7_FN1, PS6_7_FN2,
+ PS6_6_FN1, PS6_6_FN2,
+ PS6_5_FN1, PS6_5_FN2,
+ PS6_4_FN1, PS6_4_FN2,
+ PS6_3_FN1, PS6_3_FN2,
+ PS6_2_FN1, PS6_2_FN2,
+ PS6_1_FN1, PS6_1_FN2,
+ PS6_0_FN1, PS6_0_FN2,
+
+ PS7_15_FN1, PS7_15_FN2,
+ PS7_14_FN1, PS7_14_FN2,
+ PS7_13_FN1, PS7_13_FN2,
+ PS7_12_FN1, PS7_12_FN2,
+ PS7_11_FN1, PS7_11_FN2,
+ PS7_10_FN1, PS7_10_FN2,
+ PS7_9_FN1, PS7_9_FN2,
+ PS7_8_FN1, PS7_8_FN2,
+ PS7_7_FN1, PS7_7_FN2,
+ PS7_6_FN1, PS7_6_FN2,
+ PS7_5_FN1, PS7_5_FN2,
+ PS7_4_FN1, PS7_4_FN2,
+
+ PS8_15_FN1, PS8_15_FN2,
+ PS8_14_FN1, PS8_14_FN2,
+ PS8_13_FN1, PS8_13_FN2,
+ PS8_12_FN1, PS8_12_FN2,
+ PS8_11_FN1, PS8_11_FN2,
+ PS8_10_FN1, PS8_10_FN2,
+ PS8_9_FN1, PS8_9_FN2,
+ PS8_8_FN1, PS8_8_FN2,
PINMUX_FUNCTION_END,
PINMUX_MARK_BEGIN,
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
BS_MARK, RDWR_MARK, WE1_MARK, RDY_MARK,
- MD10_MARK, MD9_MARK, MD8_MARK,
- LGPIO7_MARK, LGPIO6_MARK, LGPIO5_MARK, LGPIO4_MARK,
- LGPIO3_MARK, LGPIO2_MARK, LGPIO1_MARK, LGPIO0_MARK,
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- D15_MARK, D14_MARK, D13_MARK, D12_MARK,
- D11_MARK, D10_MARK, D9_MARK, D8_MARK,
ET0_MDC_MARK, ET0_MDIO_MARK, ET1_MDC_MARK, ET1_MDIO_MARK,
- SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
- WPSZ1_MARK, WPSZ0_MARK, FWID_MARK, FLSHSZ_MARK,
- LPC_SPIEN_MARK, BASEL_MARK,
- /* PTC (mobule: SD) */
- SD_WP_MARK, SD_CD_MARK, SD_CLK_MARK, SD_CMD_MARK,
- SD_D3_MARK, SD_D2_MARK, SD_D1_MARK, SD_D0_MARK,
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ IRQ15_MARK, IRQ14_MARK, IRQ13_MARK, IRQ12_MARK,
+ IRQ11_MARK, IRQ10_MARK, IRQ9_MARK, IRQ8_MARK,
+ ON_NRE_MARK, ON_NWE_MARK, ON_NWP_MARK, ON_NCE0_MARK,
+ ON_R_B0_MARK, ON_ALE_MARK, ON_CLE_MARK, TCLK_MARK,
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTC (mobule: IRQ, PWMU) */
IRQ7_MARK, IRQ6_MARK, IRQ5_MARK, IRQ4_MARK,
IRQ3_MARK, IRQ2_MARK, IRQ1_MARK, IRQ0_MARK,
- MD6_MARK, MD5_MARK, MD3_MARK, MD2_MARK,
- MD1_MARK, MD0_MARK, ADTRG1_MARK, ADTRG0_MARK,
-
- /* PTE (mobule: EtherC) */
- ET0_CRS_DV_MARK, ET0_TXD1_MARK,
- ET0_TXD0_MARK, ET0_TX_EN_MARK,
- ET0_REF_CLK_MARK, ET0_RXD1_MARK,
- ET0_RXD0_MARK, ET0_RX_ER_MARK,
-
- /* PTF (mobule: EtherC) */
- ET1_CRS_DV_MARK, ET1_TXD1_MARK,
- ET1_TXD0_MARK, ET1_TX_EN_MARK,
- ET1_REF_CLK_MARK, ET1_RXD1_MARK,
- ET1_RXD0_MARK, ET1_RX_ER_MARK,
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- STATUS0_MARK, STATUS1_MARK,
- PWX0_MARK, PWX1_MARK, PWX2_MARK, PWX3_MARK,
- SERIRQ_MARK, CLKRUN_MARK, LPCPD_MARK, LDRQ_MARK,
-
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- TCLK_MARK, RXD4_MARK, TXD4_MARK,
+ PWMU0_MARK, PWMU1_MARK, PWMU2_MARK, PWMU3_MARK,
+ PWMU4_MARK, PWMU5_MARK,
+
+ /* PTD (mobule: SPI0, DMAC) */
+ SP0_MOSI_MARK, SP0_MISO_MARK, SP0_SCK_MARK, SP0_SCK_FB_MARK,
+ SP0_SS0_MARK, SP0_SS1_MARK, SP0_SS2_MARK, SP0_SS3_MARK,
+ DREQ0_MARK, DACK0_MARK, TEND0_MARK,
+
+ /* PTE (mobule: RMII) */
+ RMII0_CRS_DV_MARK, RMII0_TXD1_MARK,
+ RMII0_TXD0_MARK, RMII0_TXEN_MARK,
+ RMII0_REFCLK_MARK, RMII0_RXD1_MARK,
+ RMII0_RXD0_MARK, RMII0_RX_ER_MARK,
+
+ /* PTF (mobule: RMII, SerMux) */
+ RMII1_CRS_DV_MARK, RMII1_TXD1_MARK,
+ RMII1_TXD0_MARK, RMII1_TXEN_MARK,
+ RMII1_REFCLK_MARK, RMII1_RXD1_MARK,
+ RMII1_RXD0_MARK, RMII1_RX_ER_MARK,
+ RAC_RI_MARK,
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ BOOTFMS_MARK, BOOTWP_MARK, A25_MARK, A24_MARK,
+ SERIRQ_MARK, WDTOVF_MARK, LPCPD_MARK, LDRQ_MARK,
+ MMCCLK_MARK, MMCCMD_MARK,
+
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
SP1_MOSI_MARK, SP1_MISO_MARK, SP1_SCK_MARK, SP1_SCK_FB_MARK,
- SP1_SS0_MARK, SP1_SS1_MARK, SP0_SS1_MARK,
+ SP1_SS0_MARK, SP1_SS1_MARK, WP_MARK, FMS0_MARK,
+ TEND1_MARK, DREQ1_MARK, DACK1_MARK, ADTRG1_MARK,
+ ADTRG0_MARK,
- /* PTI (mobule: INTC) */
- IRQ15_MARK, IRQ14_MARK, IRQ13_MARK, IRQ12_MARK,
- IRQ11_MARK, IRQ10_MARK, IRQ9_MARK, IRQ8_MARK,
+ /* PTI (mobule: LBSC, SDHI) */
+ D15_MARK, D14_MARK, D13_MARK, D12_MARK,
+ D11_MARK, D10_MARK, D9_MARK, D8_MARK,
+ SD_WP_MARK, SD_CD_MARK, SD_CLK_MARK, SD_CMD_MARK,
+ SD_D3_MARK, SD_D2_MARK, SD_D1_MARK, SD_D0_MARK,
- /* PTJ (mobule: SCIF234, SERMUX) */
- RXD3_MARK, TXD3_MARK, RXD2_MARK, TXD2_MARK,
- COM1_TXD_MARK, COM1_RXD_MARK, COM1_RTS_MARK, COM1_CTS_MARK,
+ /* PTJ (mobule: SCIF234) */
+ RTS3_MARK, CTS3_MARK, TXD3_MARK, RXD3_MARK,
+ RTS4_MARK, RXD4_MARK, TXD4_MARK,
- /* PTK (mobule: SERMUX) */
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
COM2_TXD_MARK, COM2_RXD_MARK, COM2_RTS_MARK, COM2_CTS_MARK,
- COM2_DTR_MARK, COM2_DSR_MARK, COM2_DCD_MARK, COM2_RI_MARK,
+ COM2_DTR_MARK, COM2_DSR_MARK, COM2_DCD_MARK, CLKOUT_MARK,
+ SCK2_MARK, SCK4_MARK, SCK3_MARK,
- /* PTL (mobule: SERMUX) */
- RAC_TXD_MARK, RAC_RXD_MARK, RAC_RTS_MARK, RAC_CTS_MARK,
- RAC_DTR_MARK, RAC_DSR_MARK, RAC_DCD_MARK, RAC_RI_MARK,
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
+ RAC_RXD_MARK, RAC_RTS_MARK, RAC_CTS_MARK, RAC_DTR_MARK,
+ RAC_DSR_MARK, RAC_DCD_MARK, RAC_TXD_MARK, RXD2_MARK,
+ CS5_MARK, CS6_MARK, AUDSYNC_MARK, AUDCK_MARK,
+ TXD2_MARK,
- /* PTM (mobule: IIC, LPC) */
+ /* PTM (mobule: LBSC, IIC) */
+ CS4_MARK, RD_MARK, WE0_MARK, CS0_MARK,
SDA6_MARK, SCL6_MARK, SDA7_MARK, SCL7_MARK,
- WP_MARK, FMS0_MARK, FMS1_MARK,
- /* PTN (mobule: SCIF234, EVC) */
- SCK2_MARK, RTS4_MARK, RTS3_MARK, RTS2_MARK,
- CTS4_MARK, CTS3_MARK, CTS2_MARK,
- EVENT7_MARK, EVENT6_MARK, EVENT5_MARK, EVENT4_MARK,
- EVENT3_MARK, EVENT2_MARK, EVENT1_MARK, EVENT0_MARK,
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ VBUS_EN_MARK, VBUS_OC_MARK, JMCTCK_MARK, JMCTMS_MARK,
+ JMCTDO_MARK, JMCTDI_MARK, JMCTRST_MARK,
+ SGPIO1_CLK_MARK, SGPIO1_LOAD_MARK, SGPIO1_DI_MARK,
+ SGPIO1_DO_MARK, SUB_CLKIN_MARK,
- /* PTO (mobule: SGPIO) */
- SGPIO0_CLK_MARK, SGPIO0_LOAD_MARK,
- SGPIO0_DI_MARK, SGPIO0_DO_MARK,
- SGPIO1_CLK_MARK, SGPIO1_LOAD_MARK,
- SGPIO1_DI_MARK, SGPIO1_DO_MARK,
-
- /* PTP (mobule: JMC, SCIF234) */
- JMCTCK_MARK, JMCTMS_MARK, JMCTDO_MARK, JMCTDI_MARK,
- JMCRST_MARK, SCK4_MARK, SCK3_MARK,
+ /* PTO (mobule: SGPIO, SerMux) */
+ SGPIO0_CLK_MARK, SGPIO0_LOAD_MARK, SGPIO0_DI_MARK,
+ SGPIO0_DO_MARK, SGPIO2_CLK_MARK, SGPIO2_LOAD_MARK,
+ SGPIO2_DI_MARK, SGPIO2_DO_MARK,
+ COM1_TXD_MARK, COM1_RXD_MARK, COM1_RTS_MARK, COM1_CTS_MARK,
/* PTQ (mobule: LPC) */
LAD3_MARK, LAD2_MARK, LAD1_MARK, LAD0_MARK,
LFRAME_MARK, LRESET_MARK, LCLK_MARK,
/* PTR (mobule: GRA, IIC) */
- DDC3_MARK, DDC2_MARK,
- SDA8_MARK, SCL8_MARK, SDA2_MARK, SCL2_MARK,
+ DDC3_MARK, DDC2_MARK, SDA2_MARK, SCL2_MARK,
SDA1_MARK, SCL1_MARK, SDA0_MARK, SCL0_MARK,
+ SDA8_MARK, SCL8_MARK,
/* PTS (mobule: GRA, IIC) */
- DDC1_MARK, DDC0_MARK,
- SDA9_MARK, SCL9_MARK, SDA5_MARK, SCL5_MARK,
+ DDC1_MARK, DDC0_MARK, SDA5_MARK, SCL5_MARK,
SDA4_MARK, SCL4_MARK, SDA3_MARK, SCL3_MARK,
+ SDA9_MARK, SCL9_MARK,
- /* PTT (mobule: SYSTEM, PWMX) */
- AUDSYNC_MARK, AUDCK_MARK,
- AUDATA3_MARK, AUDATA2_MARK,
- AUDATA1_MARK, AUDATA0_MARK,
- PWX7_MARK, PWX6_MARK, PWX5_MARK, PWX4_MARK,
+ /* PTT (mobule: PWMX, AUD) */
+ PWMX7_MARK, PWMX6_MARK, PWMX5_MARK, PWMX4_MARK,
+ PWMX3_MARK, PWMX2_MARK, PWMX1_MARK, PWMX0_MARK,
+ AUDATA3_MARK, AUDATA2_MARK, AUDATA1_MARK, AUDATA0_MARK,
+ STATUS1_MARK, STATUS0_MARK,
- /* PTU (mobule: LBSC, DMAC) */
- CS6_MARK, CS5_MARK, CS4_MARK, CS0_MARK,
- RD_MARK, WE0_MARK, A25_MARK, A24_MARK,
- DREQ0_MARK, DACK0_MARK,
+ /* PTU (mobule: LPC, APM) */
+ LGPIO7_MARK, LGPIO6_MARK, LGPIO5_MARK, LGPIO4_MARK,
+ LGPIO3_MARK, LGPIO2_MARK, LGPIO1_MARK, LGPIO0_MARK,
+ APMONCTL_O_MARK, APMPWBTOUT_O_MARK, APMSCI_O_MARK,
+ APMVDDON_MARK, APMSLPBTN_MARK, APMPWRBTN_MARK, APMS5N_MARK,
+ APMS3N_MARK,
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
A23_MARK, A22_MARK, A21_MARK, A20_MARK,
A19_MARK, A18_MARK, A17_MARK, A16_MARK,
- TEND0_MARK, DREQ1_MARK, DACK1_MARK, TEND1_MARK,
+ COM2_RI_MARK, R_SPI_MOSI_MARK, R_SPI_MISO_MARK,
+ R_SPI_RSPCK_MARK, R_SPI_SSL0_MARK, R_SPI_SSL1_MARK,
+ EVENT7_MARK, EVENT6_MARK, VBIOS_DI_MARK, VBIOS_DO_MARK,
+ VBIOS_CLK_MARK, VBIOS_CS_MARK,
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
A15_MARK, A14_MARK, A13_MARK, A12_MARK,
A11_MARK, A10_MARK, A9_MARK, A8_MARK,
+ EVENT5_MARK, EVENT4_MARK, EVENT3_MARK, EVENT2_MARK,
+ EVENT1_MARK, EVENT0_MARK, CTS4_MARK, CTS2_MARK,
- /* PTX (mobule: LBSC) */
+ /* PTX (mobule: LBSC, SCIF, SIM) */
A7_MARK, A6_MARK, A5_MARK, A4_MARK,
A3_MARK, A2_MARK, A1_MARK, A0_MARK,
+ RTS2_MARK, SIM_D_MARK, SIM_CLK_MARK, SIM_RST_MARK,
/* PTY (mobule: LBSC) */
D7_MARK, D6_MARK, D5_MARK, D4_MARK,
D3_MARK, D2_MARK, D1_MARK, D0_MARK,
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ MMCDAT7_MARK, MMCDAT6_MARK, MMCDAT5_MARK, MMCDAT4_MARK,
+ MMCDAT3_MARK, MMCDAT2_MARK, MMCDAT1_MARK, MMCDAT0_MARK,
+ ON_DQ7_MARK, ON_DQ6_MARK, ON_DQ5_MARK, ON_DQ4_MARK,
+ ON_DQ3_MARK, ON_DQ2_MARK, ON_DQ1_MARK, ON_DQ0_MARK,
+
PINMUX_MARK_END,
};
@@ -473,6 +567,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTD0_DATA, PTD0_IN, PTD0_OUT),
/* PTE GPIO */
+ PINMUX_DATA(PTE7_DATA, PTE7_IN, PTE7_OUT),
+ PINMUX_DATA(PTE6_DATA, PTE6_IN, PTE6_OUT),
PINMUX_DATA(PTE5_DATA, PTE5_IN, PTE5_OUT),
PINMUX_DATA(PTE4_DATA, PTE4_IN, PTE4_OUT),
PINMUX_DATA(PTE3_DATA, PTE3_IN, PTE3_OUT),
@@ -521,7 +617,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTI0_DATA, PTI0_IN, PTI0_OUT),
/* PTJ GPIO */
- PINMUX_DATA(PTJ7_DATA, PTJ7_IN, PTJ7_OUT),
PINMUX_DATA(PTJ6_DATA, PTJ6_IN, PTJ6_OUT),
PINMUX_DATA(PTJ5_DATA, PTJ5_IN, PTJ5_OUT),
PINMUX_DATA(PTJ4_DATA, PTJ4_IN, PTJ4_OUT),
@@ -541,7 +636,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTK0_DATA, PTK0_IN, PTK0_OUT),
/* PTL GPIO */
- PINMUX_DATA(PTL7_DATA, PTL7_IN, PTL7_OUT),
PINMUX_DATA(PTL6_DATA, PTL6_IN, PTL6_OUT),
PINMUX_DATA(PTL5_DATA, PTL5_IN, PTL5_OUT),
PINMUX_DATA(PTL4_DATA, PTL4_IN, PTL4_OUT),
@@ -560,7 +654,6 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTM0_DATA, PTM0_IN, PTM0_OUT),
/* PTN GPIO */
- PINMUX_DATA(PTN7_DATA, PTN7_IN, PTN7_OUT),
PINMUX_DATA(PTN6_DATA, PTN6_IN, PTN6_OUT),
PINMUX_DATA(PTN5_DATA, PTN5_IN, PTN5_OUT),
PINMUX_DATA(PTN4_DATA, PTN4_IN, PTN4_OUT),
@@ -609,6 +702,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTS0_DATA, PTS0_IN, PTS0_OUT),
/* PTT GPIO */
+ PINMUX_DATA(PTT7_DATA, PTT7_IN, PTT7_OUT),
+ PINMUX_DATA(PTT6_DATA, PTT6_IN, PTT6_OUT),
PINMUX_DATA(PTT5_DATA, PTT5_IN, PTT5_OUT),
PINMUX_DATA(PTT4_DATA, PTT4_IN, PTT4_OUT),
PINMUX_DATA(PTT3_DATA, PTT3_IN, PTT3_OUT),
@@ -677,186 +772,204 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(PTZ0_DATA, PTZ0_IN, PTZ0_OUT),
/* PTA FN */
- PINMUX_DATA(BS_MARK, PS0_15_FN1, PTA7_FN),
- PINMUX_DATA(LGPIO7_MARK, PS0_15_FN3, PTA7_FN),
- PINMUX_DATA(RDWR_MARK, PS0_14_FN1, PTA6_FN),
- PINMUX_DATA(LGPIO6_MARK, PS0_14_FN3, PTA6_FN),
- PINMUX_DATA(WE1_MARK, PS0_13_FN1, PTA5_FN),
- PINMUX_DATA(LGPIO5_MARK, PS0_13_FN3, PTA5_FN),
- PINMUX_DATA(RDY_MARK, PS0_12_FN1, PTA4_FN),
- PINMUX_DATA(LGPIO4_MARK, PS0_12_FN3, PTA4_FN),
- PINMUX_DATA(LGPIO3_MARK, PTA3_FN),
- PINMUX_DATA(LGPIO2_MARK, PTA2_FN),
- PINMUX_DATA(LGPIO1_MARK, PTA1_FN),
- PINMUX_DATA(LGPIO0_MARK, PTA0_FN),
+ PINMUX_DATA(BS_MARK, PTA7_FN),
+ PINMUX_DATA(RDWR_MARK, PTA6_FN),
+ PINMUX_DATA(WE1_MARK, PTA5_FN),
+ PINMUX_DATA(RDY_MARK, PTA4_FN),
+ PINMUX_DATA(ET0_MDC_MARK, PTA3_FN),
+ PINMUX_DATA(ET0_MDIO_MARK, PTA2_FN),
+ PINMUX_DATA(ET1_MDC_MARK, PTA1_FN),
+ PINMUX_DATA(ET1_MDIO_MARK, PTA0_FN),
/* PTB FN */
- PINMUX_DATA(D15_MARK, PS0_7_FN1, PTB7_FN),
- PINMUX_DATA(ET0_MDC_MARK, PS0_7_FN2, PTB7_FN),
- PINMUX_DATA(D14_MARK, PS0_6_FN1, PTB6_FN),
- PINMUX_DATA(ET0_MDIO_MARK, PS0_6_FN2, PTB6_FN),
- PINMUX_DATA(D13_MARK, PS0_5_FN1, PTB5_FN),
- PINMUX_DATA(ET1_MDC_MARK, PS0_5_FN2, PTB5_FN),
- PINMUX_DATA(D12_MARK, PS0_4_FN1, PTB4_FN),
- PINMUX_DATA(ET1_MDIO_MARK, PS0_4_FN2, PTB4_FN),
- PINMUX_DATA(D11_MARK, PS0_3_FN1, PTB3_FN),
- PINMUX_DATA(SIM_D_MARK, PS0_3_FN2, PTB3_FN),
- PINMUX_DATA(D10_MARK, PS0_2_FN1, PTB2_FN),
- PINMUX_DATA(SIM_CLK_MARK, PS0_2_FN2, PTB2_FN),
- PINMUX_DATA(D9_MARK, PS0_1_FN1, PTB1_FN),
- PINMUX_DATA(SIM_RST_MARK, PS0_1_FN2, PTB1_FN),
- PINMUX_DATA(D8_MARK, PTB0_FN),
+ PINMUX_DATA(IRQ15_MARK, PS0_15_FN1, PTB7_FN),
+ PINMUX_DATA(ON_NRE_MARK, PS0_15_FN2, PTB7_FN),
+ PINMUX_DATA(IRQ14_MARK, PS0_14_FN1, PTB6_FN),
+ PINMUX_DATA(ON_NWE_MARK, PS0_14_FN2, PTB6_FN),
+ PINMUX_DATA(IRQ13_MARK, PS0_13_FN1, PTB5_FN),
+ PINMUX_DATA(ON_NWP_MARK, PS0_13_FN2, PTB5_FN),
+ PINMUX_DATA(IRQ12_MARK, PS0_12_FN1, PTB4_FN),
+ PINMUX_DATA(ON_NCE0_MARK, PS0_12_FN2, PTB4_FN),
+ PINMUX_DATA(IRQ11_MARK, PS0_11_FN1, PTB3_FN),
+ PINMUX_DATA(ON_R_B0_MARK, PS0_11_FN2, PTB3_FN),
+ PINMUX_DATA(IRQ10_MARK, PS0_10_FN1, PTB2_FN),
+ PINMUX_DATA(ON_ALE_MARK, PS0_10_FN2, PTB2_FN),
+ PINMUX_DATA(IRQ9_MARK, PS0_9_FN1, PTB1_FN),
+ PINMUX_DATA(ON_CLE_MARK, PS0_9_FN2, PTB1_FN),
+ PINMUX_DATA(IRQ8_MARK, PS0_8_FN1, PTB0_FN),
+ PINMUX_DATA(TCLK_MARK, PS0_8_FN2, PTB0_FN),
/* PTC FN */
- PINMUX_DATA(SD_WP_MARK, PTC7_FN),
- PINMUX_DATA(SD_CD_MARK, PTC6_FN),
- PINMUX_DATA(SD_CLK_MARK, PTC5_FN),
- PINMUX_DATA(SD_CMD_MARK, PTC4_FN),
- PINMUX_DATA(SD_D3_MARK, PTC3_FN),
- PINMUX_DATA(SD_D2_MARK, PTC2_FN),
- PINMUX_DATA(SD_D1_MARK, PTC1_FN),
- PINMUX_DATA(SD_D0_MARK, PTC0_FN),
+ PINMUX_DATA(IRQ7_MARK, PS0_7_FN1, PTC7_FN),
+ PINMUX_DATA(PWMU0_MARK, PS0_7_FN2, PTC7_FN),
+ PINMUX_DATA(IRQ6_MARK, PS0_6_FN1, PTC6_FN),
+ PINMUX_DATA(PWMU1_MARK, PS0_6_FN2, PTC6_FN),
+ PINMUX_DATA(IRQ5_MARK, PS0_5_FN1, PTC5_FN),
+ PINMUX_DATA(PWMU2_MARK, PS0_5_FN2, PTC5_FN),
+ PINMUX_DATA(IRQ4_MARK, PS0_4_FN1, PTC5_FN),
+ PINMUX_DATA(PWMU3_MARK, PS0_4_FN2, PTC4_FN),
+ PINMUX_DATA(IRQ3_MARK, PS0_3_FN1, PTC3_FN),
+ PINMUX_DATA(PWMU4_MARK, PS0_3_FN2, PTC3_FN),
+ PINMUX_DATA(IRQ2_MARK, PS0_2_FN1, PTC2_FN),
+ PINMUX_DATA(PWMU5_MARK, PS0_2_FN2, PTC2_FN),
+ PINMUX_DATA(IRQ1_MARK, PTC1_FN),
+ PINMUX_DATA(IRQ0_MARK, PTC0_FN),
/* PTD FN */
- PINMUX_DATA(IRQ7_MARK, PS1_7_FN1, PTD7_FN),
- PINMUX_DATA(ADTRG1_MARK, PS1_7_FN3, PTD7_FN),
- PINMUX_DATA(IRQ6_MARK, PS1_6_FN1, PTD6_FN),
- PINMUX_DATA(ADTRG0_MARK, PS1_6_FN3, PTD6_FN),
- PINMUX_DATA(IRQ5_MARK, PTD5_FN),
- PINMUX_DATA(IRQ4_MARK, PTD4_FN),
- PINMUX_DATA(IRQ3_MARK, PTD3_FN),
- PINMUX_DATA(IRQ2_MARK, PTD2_FN),
- PINMUX_DATA(IRQ1_MARK, PTD1_FN),
- PINMUX_DATA(IRQ0_MARK, PTD0_FN),
+ PINMUX_DATA(SP0_MOSI_MARK, PTD7_FN),
+ PINMUX_DATA(SP0_MISO_MARK, PTD6_FN),
+ PINMUX_DATA(SP0_SCK_MARK, PTD5_FN),
+ PINMUX_DATA(SP0_SCK_FB_MARK, PTD4_FN),
+ PINMUX_DATA(SP0_SS0_MARK, PTD3_FN),
+ PINMUX_DATA(SP0_SS1_MARK, PS1_10_FN1, PTD2_FN),
+ PINMUX_DATA(DREQ0_MARK, PS1_10_FN2, PTD2_FN),
+ PINMUX_DATA(SP0_SS2_MARK, PS1_9_FN1, PTD1_FN),
+ PINMUX_DATA(DACK0_MARK, PS1_9_FN2, PTD1_FN),
+ PINMUX_DATA(SP0_SS3_MARK, PS1_8_FN1, PTD0_FN),
+ PINMUX_DATA(TEND0_MARK, PS1_8_FN2, PTD0_FN),
/* PTE FN */
- PINMUX_DATA(ET0_CRS_DV_MARK, PTE7_FN),
- PINMUX_DATA(ET0_TXD1_MARK, PTE6_FN),
- PINMUX_DATA(ET0_TXD0_MARK, PTE5_FN),
- PINMUX_DATA(ET0_TX_EN_MARK, PTE4_FN),
- PINMUX_DATA(ET0_REF_CLK_MARK, PTE3_FN),
- PINMUX_DATA(ET0_RXD1_MARK, PTE2_FN),
- PINMUX_DATA(ET0_RXD0_MARK, PTE1_FN),
- PINMUX_DATA(ET0_RX_ER_MARK, PTE0_FN),
+ PINMUX_DATA(RMII0_CRS_DV_MARK, PTE7_FN),
+ PINMUX_DATA(RMII0_TXD1_MARK, PTE6_FN),
+ PINMUX_DATA(RMII0_TXD0_MARK, PTE5_FN),
+ PINMUX_DATA(RMII0_TXEN_MARK, PTE4_FN),
+ PINMUX_DATA(RMII0_REFCLK_MARK, PTE3_FN),
+ PINMUX_DATA(RMII0_RXD1_MARK, PTE2_FN),
+ PINMUX_DATA(RMII0_RXD0_MARK, PTE1_FN),
+ PINMUX_DATA(RMII0_RX_ER_MARK, PTE0_FN),
/* PTF FN */
- PINMUX_DATA(ET1_CRS_DV_MARK, PTF7_FN),
- PINMUX_DATA(ET1_TXD1_MARK, PTF6_FN),
- PINMUX_DATA(ET1_TXD0_MARK, PTF5_FN),
- PINMUX_DATA(ET1_TX_EN_MARK, PTF4_FN),
- PINMUX_DATA(ET1_REF_CLK_MARK, PTF3_FN),
- PINMUX_DATA(ET1_RXD1_MARK, PTF2_FN),
- PINMUX_DATA(ET1_RXD0_MARK, PTF1_FN),
- PINMUX_DATA(ET1_RX_ER_MARK, PTF0_FN),
+ PINMUX_DATA(RMII1_CRS_DV_MARK, PTF7_FN),
+ PINMUX_DATA(RMII1_TXD1_MARK, PTF6_FN),
+ PINMUX_DATA(RMII1_TXD0_MARK, PTF5_FN),
+ PINMUX_DATA(RMII1_TXEN_MARK, PTF4_FN),
+ PINMUX_DATA(RMII1_REFCLK_MARK, PTF3_FN),
+ PINMUX_DATA(RMII1_RXD1_MARK, PS1_2_FN1, PTF2_FN),
+ PINMUX_DATA(RAC_RI_MARK, PS1_2_FN2, PTF2_FN),
+ PINMUX_DATA(RMII1_RXD0_MARK, PTF1_FN),
+ PINMUX_DATA(RMII1_RX_ER_MARK, PTF0_FN),
/* PTG FN */
- PINMUX_DATA(PWX0_MARK, PTG7_FN),
- PINMUX_DATA(PWX1_MARK, PTG6_FN),
- PINMUX_DATA(STATUS0_MARK, PS2_13_FN1, PTG5_FN),
- PINMUX_DATA(PWX2_MARK, PS2_13_FN3, PTG5_FN),
- PINMUX_DATA(STATUS1_MARK, PS2_12_FN1, PTG4_FN),
- PINMUX_DATA(PWX3_MARK, PS2_12_FN3, PTG4_FN),
+ PINMUX_DATA(BOOTFMS_MARK, PTG7_FN),
+ PINMUX_DATA(BOOTWP_MARK, PTG6_FN),
+ PINMUX_DATA(A25_MARK, PS2_13_FN1, PTG5_FN),
+ PINMUX_DATA(MMCCLK_MARK, PS2_13_FN2, PTG5_FN),
+ PINMUX_DATA(A24_MARK, PS2_12_FN1, PTG4_FN),
+ PINMUX_DATA(MMCCMD_MARK, PS2_12_FN2, PTG4_FN),
PINMUX_DATA(SERIRQ_MARK, PTG3_FN),
- PINMUX_DATA(CLKRUN_MARK, PTG2_FN),
+ PINMUX_DATA(WDTOVF_MARK, PTG2_FN),
PINMUX_DATA(LPCPD_MARK, PTG1_FN),
PINMUX_DATA(LDRQ_MARK, PTG0_FN),
/* PTH FN */
- PINMUX_DATA(SP1_MOSI_MARK, PTH7_FN),
- PINMUX_DATA(SP1_MISO_MARK, PTH6_FN),
- PINMUX_DATA(SP1_SCK_MARK, PTH5_FN),
- PINMUX_DATA(SP1_SCK_FB_MARK, PTH4_FN),
+ PINMUX_DATA(SP1_MOSI_MARK, PS2_7_FN1, PTH7_FN),
+ PINMUX_DATA(TEND1_MARK, PS2_7_FN2, PTH7_FN),
+ PINMUX_DATA(SP1_MISO_MARK, PS2_6_FN1, PTH6_FN),
+ PINMUX_DATA(DREQ1_MARK, PS2_6_FN2, PTH6_FN),
+ PINMUX_DATA(SP1_SCK_MARK, PS2_5_FN1, PTH5_FN),
+ PINMUX_DATA(DACK1_MARK, PS2_5_FN2, PTH5_FN),
+ PINMUX_DATA(SP1_SCK_FB_MARK, PS2_4_FN1, PTH4_FN),
+ PINMUX_DATA(ADTRG1_MARK, PS2_4_FN2, PTH4_FN),
PINMUX_DATA(SP1_SS0_MARK, PTH3_FN),
- PINMUX_DATA(TCLK_MARK, PTH2_FN),
- PINMUX_DATA(RXD4_MARK, PS2_1_FN1, PTH1_FN),
- PINMUX_DATA(SP1_SS1_MARK, PS2_1_FN2, PTH1_FN),
- PINMUX_DATA(TXD4_MARK, PS2_0_FN1, PTH0_FN),
- PINMUX_DATA(SP0_SS1_MARK, PS2_0_FN2, PTH0_FN),
+ PINMUX_DATA(SP1_SS1_MARK, PS2_2_FN1, PTH2_FN),
+ PINMUX_DATA(ADTRG0_MARK, PS2_2_FN2, PTH2_FN),
+ PINMUX_DATA(WP_MARK, PTH1_FN),
+ PINMUX_DATA(FMS0_MARK, PTH0_FN),
/* PTI FN */
- PINMUX_DATA(IRQ15_MARK, PTI7_FN),
- PINMUX_DATA(IRQ14_MARK, PTI6_FN),
- PINMUX_DATA(IRQ13_MARK, PTI5_FN),
- PINMUX_DATA(IRQ12_MARK, PTI4_FN),
- PINMUX_DATA(IRQ11_MARK, PTI3_FN),
- PINMUX_DATA(IRQ10_MARK, PTI2_FN),
- PINMUX_DATA(IRQ9_MARK, PTI1_FN),
- PINMUX_DATA(IRQ8_MARK, PTI0_FN),
+ PINMUX_DATA(D15_MARK, PS3_15_FN1, PTI7_FN),
+ PINMUX_DATA(SD_WP_MARK, PS3_15_FN2, PTI7_FN),
+ PINMUX_DATA(D14_MARK, PS3_14_FN1, PTI6_FN),
+ PINMUX_DATA(SD_CD_MARK, PS3_14_FN2, PTI6_FN),
+ PINMUX_DATA(D13_MARK, PS3_13_FN1, PTI5_FN),
+ PINMUX_DATA(SD_CLK_MARK, PS3_13_FN2, PTI5_FN),
+ PINMUX_DATA(D12_MARK, PS3_12_FN1, PTI4_FN),
+ PINMUX_DATA(SD_CMD_MARK, PS3_12_FN2, PTI4_FN),
+ PINMUX_DATA(D11_MARK, PS3_11_FN1, PTI3_FN),
+ PINMUX_DATA(SD_D3_MARK, PS3_11_FN2, PTI3_FN),
+ PINMUX_DATA(D10_MARK, PS3_10_FN1, PTI2_FN),
+ PINMUX_DATA(SD_D2_MARK, PS3_10_FN2, PTI2_FN),
+ PINMUX_DATA(D9_MARK, PS3_9_FN1, PTI1_FN),
+ PINMUX_DATA(SD_D1_MARK, PS3_9_FN2, PTI1_FN),
+ PINMUX_DATA(D8_MARK, PS3_8_FN1, PTI0_FN),
+ PINMUX_DATA(SD_D0_MARK, PS3_8_FN2, PTI0_FN),
/* PTJ FN */
- PINMUX_DATA(RXD3_MARK, PTJ7_FN),
- PINMUX_DATA(TXD3_MARK, PTJ6_FN),
- PINMUX_DATA(RXD2_MARK, PTJ5_FN),
- PINMUX_DATA(TXD2_MARK, PTJ4_FN),
- PINMUX_DATA(COM1_TXD_MARK, PTJ3_FN),
- PINMUX_DATA(COM1_RXD_MARK, PTJ2_FN),
- PINMUX_DATA(COM1_RTS_MARK, PTJ1_FN),
- PINMUX_DATA(COM1_CTS_MARK, PTJ0_FN),
+ PINMUX_DATA(RTS3_MARK, PTJ6_FN),
+ PINMUX_DATA(CTS3_MARK, PTJ5_FN),
+ PINMUX_DATA(TXD3_MARK, PTJ4_FN),
+ PINMUX_DATA(RXD3_MARK, PTJ3_FN),
+ PINMUX_DATA(RTS4_MARK, PTJ2_FN),
+ PINMUX_DATA(RXD4_MARK, PTJ1_FN),
+ PINMUX_DATA(TXD4_MARK, PTJ0_FN),
/* PTK FN */
- PINMUX_DATA(COM2_TXD_MARK, PTK7_FN),
+ PINMUX_DATA(COM2_TXD_MARK, PS3_7_FN1, PTK7_FN),
+ PINMUX_DATA(SCK2_MARK, PS3_7_FN2, PTK7_FN),
PINMUX_DATA(COM2_RXD_MARK, PTK6_FN),
PINMUX_DATA(COM2_RTS_MARK, PTK5_FN),
PINMUX_DATA(COM2_CTS_MARK, PTK4_FN),
PINMUX_DATA(COM2_DTR_MARK, PTK3_FN),
- PINMUX_DATA(COM2_DSR_MARK, PTK2_FN),
- PINMUX_DATA(COM2_DCD_MARK, PTK1_FN),
- PINMUX_DATA(COM2_RI_MARK, PTK0_FN),
+ PINMUX_DATA(COM2_DSR_MARK, PS3_2_FN1, PTK2_FN),
+ PINMUX_DATA(SCK4_MARK, PS3_2_FN2, PTK2_FN),
+ PINMUX_DATA(COM2_DCD_MARK, PS3_1_FN1, PTK1_FN),
+ PINMUX_DATA(SCK3_MARK, PS3_1_FN2, PTK1_FN),
+ PINMUX_DATA(CLKOUT_MARK, PTK0_FN),
/* PTL FN */
- PINMUX_DATA(RAC_TXD_MARK, PTL7_FN),
- PINMUX_DATA(RAC_RXD_MARK, PTL6_FN),
- PINMUX_DATA(RAC_RTS_MARK, PTL5_FN),
- PINMUX_DATA(RAC_CTS_MARK, PTL4_FN),
+ PINMUX_DATA(RAC_RXD_MARK, PS4_14_FN1, PTL6_FN),
+ PINMUX_DATA(RXD2_MARK, PS4_14_FN2, PTL6_FN),
+ PINMUX_DATA(RAC_RTS_MARK, PS4_13_FN1, PTL5_FN),
+ PINMUX_DATA(CS5_MARK, PS4_13_FN2, PTL5_FN),
+ PINMUX_DATA(RAC_CTS_MARK, PS4_12_FN1, PTL4_FN),
+ PINMUX_DATA(CS6_MARK, PS4_12_FN2, PTL4_FN),
PINMUX_DATA(RAC_DTR_MARK, PTL3_FN),
- PINMUX_DATA(RAC_DSR_MARK, PTL2_FN),
- PINMUX_DATA(RAC_DCD_MARK, PTL1_FN),
- PINMUX_DATA(RAC_RI_MARK, PTL0_FN),
+ PINMUX_DATA(RAC_DSR_MARK, PS4_10_FN1, PTL2_FN),
+ PINMUX_DATA(AUDSYNC_MARK, PS4_10_FN2, PTL2_FN),
+ PINMUX_DATA(RAC_DCD_MARK, PS4_9_FN1, PTL1_FN),
+ PINMUX_DATA(AUDCK_MARK, PS4_9_FN2, PTL1_FN),
+ PINMUX_DATA(RAC_TXD_MARK, PS4_8_FN1, PTL0_FN),
+ PINMUX_DATA(TXD2_MARK, PS4_8_FN1, PTL0_FN),
/* PTM FN */
- PINMUX_DATA(WP_MARK, PTM6_FN),
- PINMUX_DATA(FMS0_MARK, PTM5_FN),
- PINMUX_DATA(FMS1_MARK, PTM4_FN),
+ PINMUX_DATA(CS4_MARK, PTM7_FN),
+ PINMUX_DATA(RD_MARK, PTM6_FN),
+ PINMUX_DATA(WE0_MARK, PTM7_FN),
+ PINMUX_DATA(CS0_MARK, PTM4_FN),
PINMUX_DATA(SDA6_MARK, PTM3_FN),
PINMUX_DATA(SCL6_MARK, PTM2_FN),
PINMUX_DATA(SDA7_MARK, PTM1_FN),
PINMUX_DATA(SCL7_MARK, PTM0_FN),
/* PTN FN */
- PINMUX_DATA(SCK2_MARK, PS4_15_FN1, PTN7_FN),
- PINMUX_DATA(EVENT7_MARK, PS4_15_FN2, PTN7_FN),
- PINMUX_DATA(RTS4_MARK, PS4_14_FN1, PTN6_FN),
- PINMUX_DATA(EVENT6_MARK, PS4_14_FN2, PTN6_FN),
- PINMUX_DATA(RTS3_MARK, PS4_13_FN1, PTN5_FN),
- PINMUX_DATA(EVENT5_MARK, PS4_13_FN2, PTN5_FN),
- PINMUX_DATA(RTS2_MARK, PS4_12_FN1, PTN4_FN),
- PINMUX_DATA(EVENT4_MARK, PS4_12_FN2, PTN4_FN),
- PINMUX_DATA(CTS4_MARK, PS4_11_FN1, PTN3_FN),
- PINMUX_DATA(EVENT3_MARK, PS4_11_FN2, PTN3_FN),
- PINMUX_DATA(CTS3_MARK, PS4_10_FN1, PTN2_FN),
- PINMUX_DATA(EVENT2_MARK, PS4_10_FN2, PTN2_FN),
- PINMUX_DATA(CTS2_MARK, PS4_9_FN1, PTN1_FN),
- PINMUX_DATA(EVENT1_MARK, PS4_9_FN2, PTN1_FN),
- PINMUX_DATA(EVENT0_MARK, PTN0_FN),
+ PINMUX_DATA(VBUS_EN_MARK, PTN6_FN),
+ PINMUX_DATA(VBUS_OC_MARK, PTN5_FN),
+ PINMUX_DATA(JMCTCK_MARK, PS4_4_FN1, PTN4_FN),
+ PINMUX_DATA(SGPIO1_CLK_MARK, PS4_4_FN2, PTN4_FN),
+ PINMUX_DATA(JMCTMS_MARK, PS4_3_FN1, PTN5_FN),
+ PINMUX_DATA(SGPIO1_LOAD_MARK, PS4_3_FN2, PTN5_FN),
+ PINMUX_DATA(JMCTDO_MARK, PS4_2_FN1, PTN2_FN),
+ PINMUX_DATA(SGPIO1_DO_MARK, PS4_2_FN2, PTN2_FN),
+ PINMUX_DATA(JMCTDI_MARK, PS4_1_FN1, PTN1_FN),
+ PINMUX_DATA(SGPIO1_DI_MARK, PS4_1_FN2, PTN1_FN),
+ PINMUX_DATA(JMCTRST_MARK, PS4_0_FN1, PTN0_FN),
+ PINMUX_DATA(SUB_CLKIN_MARK, PS4_0_FN2, PTN0_FN),
/* PTO FN */
PINMUX_DATA(SGPIO0_CLK_MARK, PTO7_FN),
PINMUX_DATA(SGPIO0_LOAD_MARK, PTO6_FN),
PINMUX_DATA(SGPIO0_DI_MARK, PTO5_FN),
PINMUX_DATA(SGPIO0_DO_MARK, PTO4_FN),
- PINMUX_DATA(SGPIO1_CLK_MARK, PTO3_FN),
- PINMUX_DATA(SGPIO1_LOAD_MARK, PTO2_FN),
- PINMUX_DATA(SGPIO1_DI_MARK, PTO1_FN),
- PINMUX_DATA(SGPIO1_DO_MARK, PTO0_FN),
+ PINMUX_DATA(SGPIO2_CLK_MARK, PS5_11_FN1, PTO3_FN),
+ PINMUX_DATA(COM1_TXD_MARK, PS5_11_FN2, PTO3_FN),
+ PINMUX_DATA(SGPIO2_LOAD_MARK, PS5_10_FN1, PTO2_FN),
+ PINMUX_DATA(COM1_RXD_MARK, PS5_10_FN2, PTO2_FN),
+ PINMUX_DATA(SGPIO2_DI_MARK, PS5_9_FN1, PTO1_FN),
+ PINMUX_DATA(COM1_RTS_MARK, PS5_9_FN2, PTO1_FN),
+ PINMUX_DATA(SGPIO2_DO_MARK, PS5_8_FN1, PTO0_FN),
+ PINMUX_DATA(COM1_CTS_MARK, PS5_8_FN2, PTO0_FN),
/* PTP FN */
- PINMUX_DATA(JMCTCK_MARK, PTP6_FN),
- PINMUX_DATA(JMCTMS_MARK, PTP5_FN),
- PINMUX_DATA(JMCTDO_MARK, PTP4_FN),
- PINMUX_DATA(JMCTDI_MARK, PTP3_FN),
- PINMUX_DATA(JMCRST_MARK, PTP2_FN),
- PINMUX_DATA(SCK4_MARK, PTP1_FN),
- PINMUX_DATA(SCK3_MARK, PTP0_FN),
/* PTQ FN */
PINMUX_DATA(LAD3_MARK, PTQ6_FN),
@@ -864,8 +977,8 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(LAD1_MARK, PTQ4_FN),
PINMUX_DATA(LAD0_MARK, PTQ3_FN),
PINMUX_DATA(LFRAME_MARK, PTQ2_FN),
- PINMUX_DATA(SCK4_MARK, PTQ1_FN),
- PINMUX_DATA(SCK3_MARK, PTQ0_FN),
+ PINMUX_DATA(LRESET_MARK, PTQ1_FN),
+ PINMUX_DATA(LCLK_MARK, PTQ0_FN),
/* PTR FN */
PINMUX_DATA(SDA8_MARK, PTR7_FN), /* DDC3? */
@@ -888,58 +1001,84 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(SCL3_MARK, PTS0_FN),
/* PTT FN */
- PINMUX_DATA(AUDSYNC_MARK, PTS5_FN),
- PINMUX_DATA(AUDCK_MARK, PTS4_FN),
- PINMUX_DATA(AUDATA3_MARK, PS4_3_FN1, PTS3_FN),
- PINMUX_DATA(PWX7_MARK, PS4_3_FN2, PTS3_FN),
- PINMUX_DATA(AUDATA2_MARK, PS4_2_FN1, PTS2_FN),
- PINMUX_DATA(PWX6_MARK, PS4_2_FN2, PTS2_FN),
- PINMUX_DATA(AUDATA1_MARK, PS4_1_FN1, PTS1_FN),
- PINMUX_DATA(PWX5_MARK, PS4_1_FN2, PTS1_FN),
- PINMUX_DATA(AUDATA0_MARK, PS4_0_FN1, PTS0_FN),
- PINMUX_DATA(PWX4_MARK, PS4_0_FN2, PTS0_FN),
+ PINMUX_DATA(PWMX7_MARK, PS5_7_FN1, PTT7_FN),
+ PINMUX_DATA(AUDATA3_MARK, PS5_7_FN2, PTT7_FN),
+ PINMUX_DATA(PWMX6_MARK, PS5_6_FN1, PTT6_FN),
+ PINMUX_DATA(AUDATA2_MARK, PS5_6_FN2, PTT6_FN),
+ PINMUX_DATA(PWMX5_MARK, PS5_5_FN1, PTT5_FN),
+ PINMUX_DATA(AUDATA1_MARK, PS5_5_FN2, PTT5_FN),
+ PINMUX_DATA(PWMX4_MARK, PS5_4_FN1, PTT4_FN),
+ PINMUX_DATA(AUDATA0_MARK, PS5_4_FN2, PTT4_FN),
+ PINMUX_DATA(PWMX3_MARK, PS5_3_FN1, PTT3_FN),
+ PINMUX_DATA(STATUS1_MARK, PS5_3_FN2, PTT3_FN),
+ PINMUX_DATA(PWMX2_MARK, PS5_2_FN1, PTT2_FN),
+ PINMUX_DATA(STATUS0_MARK, PS5_2_FN2, PTT2_FN),
+ PINMUX_DATA(PWMX1_MARK, PTT1_FN),
+ PINMUX_DATA(PWMX0_MARK, PTT0_FN),
/* PTU FN */
- PINMUX_DATA(CS6_MARK, PTU7_FN),
- PINMUX_DATA(CS5_MARK, PTU6_FN),
- PINMUX_DATA(CS4_MARK, PTU5_FN),
- PINMUX_DATA(CS0_MARK, PTU4_FN),
- PINMUX_DATA(RD_MARK, PTU3_FN),
- PINMUX_DATA(WE0_MARK, PTU2_FN),
- PINMUX_DATA(A25_MARK, PS5_9_FN1, PTU1_FN),
- PINMUX_DATA(DREQ0_MARK, PS5_9_FN2, PTU1_FN),
- PINMUX_DATA(A24_MARK, PS5_8_FN1, PTU0_FN),
- PINMUX_DATA(DACK0_MARK, PS5_8_FN2, PTU0_FN),
+ PINMUX_DATA(LGPIO7_MARK, PS6_15_FN1, PTU7_FN),
+ PINMUX_DATA(APMONCTL_O_MARK, PS6_15_FN2, PTU7_FN),
+ PINMUX_DATA(LGPIO6_MARK, PS6_14_FN1, PTU6_FN),
+ PINMUX_DATA(APMPWBTOUT_O_MARK, PS6_14_FN2, PTU6_FN),
+ PINMUX_DATA(LGPIO5_MARK, PS6_13_FN1, PTU5_FN),
+ PINMUX_DATA(APMSCI_O_MARK, PS6_13_FN2, PTU5_FN),
+ PINMUX_DATA(LGPIO4_MARK, PS6_12_FN1, PTU4_FN),
+ PINMUX_DATA(APMVDDON_MARK, PS6_12_FN2, PTU4_FN),
+ PINMUX_DATA(LGPIO3_MARK, PS6_11_FN1, PTU3_FN),
+ PINMUX_DATA(APMSLPBTN_MARK, PS6_11_FN2, PTU3_FN),
+ PINMUX_DATA(LGPIO2_MARK, PS6_10_FN1, PTU2_FN),
+ PINMUX_DATA(APMPWRBTN_MARK, PS6_10_FN2, PTU2_FN),
+ PINMUX_DATA(LGPIO1_MARK, PS6_9_FN1, PTU1_FN),
+ PINMUX_DATA(APMS5N_MARK, PS6_9_FN2, PTU1_FN),
+ PINMUX_DATA(LGPIO0_MARK, PS6_8_FN1, PTU0_FN),
+ PINMUX_DATA(APMS3N_MARK, PS6_8_FN2, PTU0_FN),
/* PTV FN */
- PINMUX_DATA(A23_MARK, PS5_7_FN1, PTV7_FN),
- PINMUX_DATA(TEND0_MARK, PS5_7_FN2, PTV7_FN),
- PINMUX_DATA(A22_MARK, PS5_6_FN1, PTV6_FN),
- PINMUX_DATA(DREQ1_MARK, PS5_6_FN2, PTV6_FN),
- PINMUX_DATA(A21_MARK, PS5_5_FN1, PTV5_FN),
- PINMUX_DATA(DACK1_MARK, PS5_5_FN2, PTV5_FN),
- PINMUX_DATA(A20_MARK, PS5_4_FN1, PTV4_FN),
- PINMUX_DATA(TEND1_MARK, PS5_4_FN2, PTV4_FN),
- PINMUX_DATA(A19_MARK, PTV3_FN),
- PINMUX_DATA(A18_MARK, PTV2_FN),
- PINMUX_DATA(A17_MARK, PTV1_FN),
- PINMUX_DATA(A16_MARK, PTV0_FN),
+ PINMUX_DATA(A23_MARK, PS6_7_FN1, PTV7_FN),
+ PINMUX_DATA(COM2_RI_MARK, PS6_7_FN2, PTV7_FN),
+ PINMUX_DATA(A22_MARK, PS6_6_FN1, PTV6_FN),
+ PINMUX_DATA(R_SPI_MOSI_MARK, PS6_6_FN2, PTV6_FN),
+ PINMUX_DATA(A21_MARK, PS6_5_FN1, PTV5_FN),
+ PINMUX_DATA(R_SPI_MISO_MARK, PS6_5_FN2, PTV5_FN),
+ PINMUX_DATA(A20_MARK, PS6_4_FN1, PTV4_FN),
+ PINMUX_DATA(R_SPI_RSPCK_MARK, PS6_4_FN2, PTV4_FN),
+ PINMUX_DATA(A19_MARK, PS6_3_FN1, PTV3_FN),
+ PINMUX_DATA(R_SPI_SSL0_MARK, PS6_3_FN2, PTV3_FN),
+ PINMUX_DATA(A18_MARK, PS6_2_FN1, PTV2_FN),
+ PINMUX_DATA(R_SPI_SSL1_MARK, PS6_2_FN2, PTV2_FN),
+ PINMUX_DATA(A17_MARK, PS6_1_FN1, PTV1_FN),
+ PINMUX_DATA(EVENT7_MARK, PS6_1_FN2, PTV1_FN),
+ PINMUX_DATA(A16_MARK, PS6_0_FN1, PTV0_FN),
+ PINMUX_DATA(EVENT6_MARK, PS6_0_FN1, PTV0_FN),
/* PTW FN */
- PINMUX_DATA(A15_MARK, PTW7_FN),
- PINMUX_DATA(A14_MARK, PTW6_FN),
- PINMUX_DATA(A13_MARK, PTW5_FN),
- PINMUX_DATA(A12_MARK, PTW4_FN),
- PINMUX_DATA(A11_MARK, PTW3_FN),
- PINMUX_DATA(A10_MARK, PTW2_FN),
- PINMUX_DATA(A9_MARK, PTW1_FN),
- PINMUX_DATA(A8_MARK, PTW0_FN),
+ PINMUX_DATA(A15_MARK, PS7_15_FN1, PTW7_FN),
+ PINMUX_DATA(EVENT5_MARK, PS7_15_FN2, PTW7_FN),
+ PINMUX_DATA(A14_MARK, PS7_14_FN1, PTW6_FN),
+ PINMUX_DATA(EVENT4_MARK, PS7_14_FN2, PTW6_FN),
+ PINMUX_DATA(A13_MARK, PS7_13_FN1, PTW5_FN),
+ PINMUX_DATA(EVENT3_MARK, PS7_13_FN2, PTW5_FN),
+ PINMUX_DATA(A12_MARK, PS7_12_FN1, PTW4_FN),
+ PINMUX_DATA(EVENT2_MARK, PS7_12_FN2, PTW4_FN),
+ PINMUX_DATA(A11_MARK, PS7_11_FN1, PTW3_FN),
+ PINMUX_DATA(EVENT1_MARK, PS7_11_FN2, PTW3_FN),
+ PINMUX_DATA(A10_MARK, PS7_10_FN1, PTW2_FN),
+ PINMUX_DATA(EVENT0_MARK, PS7_10_FN2, PTW2_FN),
+ PINMUX_DATA(A9_MARK, PS7_9_FN1, PTW1_FN),
+ PINMUX_DATA(CTS4_MARK, PS7_9_FN2, PTW1_FN),
+ PINMUX_DATA(A8_MARK, PS7_8_FN1, PTW0_FN),
+ PINMUX_DATA(CTS2_MARK, PS7_8_FN2, PTW0_FN),
/* PTX FN */
- PINMUX_DATA(A7_MARK, PTX7_FN),
- PINMUX_DATA(A6_MARK, PTX6_FN),
- PINMUX_DATA(A5_MARK, PTX5_FN),
- PINMUX_DATA(A4_MARK, PTX4_FN),
+ PINMUX_DATA(A7_MARK, PS7_7_FN1, PTX7_FN),
+ PINMUX_DATA(RTS2_MARK, PS7_7_FN2, PTX7_FN),
+ PINMUX_DATA(A6_MARK, PS7_6_FN1, PTX6_FN),
+ PINMUX_DATA(SIM_D_MARK, PS7_6_FN2, PTX6_FN),
+ PINMUX_DATA(A5_MARK, PS7_5_FN1, PTX5_FN),
+ PINMUX_DATA(SIM_CLK_MARK, PS7_5_FN2, PTX5_FN),
+ PINMUX_DATA(A4_MARK, PS7_4_FN1, PTX4_FN),
+ PINMUX_DATA(SIM_RST_MARK, PS7_4_FN2, PTX4_FN),
PINMUX_DATA(A3_MARK, PTX3_FN),
PINMUX_DATA(A2_MARK, PTX2_FN),
PINMUX_DATA(A1_MARK, PTX1_FN),
@@ -954,6 +1093,24 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(D2_MARK, PTY2_FN),
PINMUX_DATA(D1_MARK, PTY1_FN),
PINMUX_DATA(D0_MARK, PTY0_FN),
+
+ /* PTZ FN */
+ PINMUX_DATA(MMCDAT7_MARK, PS8_15_FN1, PTZ7_FN),
+ PINMUX_DATA(ON_DQ7_MARK, PS8_15_FN2, PTZ7_FN),
+ PINMUX_DATA(MMCDAT6_MARK, PS8_14_FN1, PTZ6_FN),
+ PINMUX_DATA(ON_DQ6_MARK, PS8_14_FN2, PTZ6_FN),
+ PINMUX_DATA(MMCDAT5_MARK, PS8_13_FN1, PTZ5_FN),
+ PINMUX_DATA(ON_DQ5_MARK, PS8_13_FN2, PTZ5_FN),
+ PINMUX_DATA(MMCDAT4_MARK, PS8_12_FN1, PTZ4_FN),
+ PINMUX_DATA(ON_DQ4_MARK, PS8_12_FN2, PTZ4_FN),
+ PINMUX_DATA(MMCDAT3_MARK, PS8_11_FN1, PTZ3_FN),
+ PINMUX_DATA(ON_DQ3_MARK, PS8_11_FN2, PTZ3_FN),
+ PINMUX_DATA(MMCDAT2_MARK, PS8_10_FN1, PTZ2_FN),
+ PINMUX_DATA(ON_DQ2_MARK, PS8_10_FN2, PTZ2_FN),
+ PINMUX_DATA(MMCDAT1_MARK, PS8_9_FN1, PTZ1_FN),
+ PINMUX_DATA(ON_DQ1_MARK, PS8_9_FN2, PTZ1_FN),
+ PINMUX_DATA(MMCDAT0_MARK, PS8_8_FN1, PTZ0_FN),
+ PINMUX_DATA(ON_DQ0_MARK, PS8_8_FN2, PTZ0_FN),
};
static struct pinmux_gpio pinmux_gpios[] = {
@@ -1048,7 +1205,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTI0, PTI0_DATA),
/* PTJ */
- PINMUX_GPIO(GPIO_PTJ7, PTJ7_DATA),
PINMUX_GPIO(GPIO_PTJ6, PTJ6_DATA),
PINMUX_GPIO(GPIO_PTJ5, PTJ5_DATA),
PINMUX_GPIO(GPIO_PTJ4, PTJ4_DATA),
@@ -1068,7 +1224,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTK0, PTK0_DATA),
/* PTL */
- PINMUX_GPIO(GPIO_PTL7, PTL7_DATA),
PINMUX_GPIO(GPIO_PTL6, PTL6_DATA),
PINMUX_GPIO(GPIO_PTL5, PTL5_DATA),
PINMUX_GPIO(GPIO_PTL4, PTL4_DATA),
@@ -1078,6 +1233,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTL0, PTL0_DATA),
/* PTM */
+ PINMUX_GPIO(GPIO_PTM7, PTM7_DATA),
PINMUX_GPIO(GPIO_PTM6, PTM6_DATA),
PINMUX_GPIO(GPIO_PTM5, PTM5_DATA),
PINMUX_GPIO(GPIO_PTM4, PTM4_DATA),
@@ -1087,7 +1243,6 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTM0, PTM0_DATA),
/* PTN */
- PINMUX_GPIO(GPIO_PTN7, PTN7_DATA),
PINMUX_GPIO(GPIO_PTN6, PTN6_DATA),
PINMUX_GPIO(GPIO_PTN5, PTN5_DATA),
PINMUX_GPIO(GPIO_PTN4, PTN4_DATA),
@@ -1107,6 +1262,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTO0, PTO0_DATA),
/* PTP */
+ PINMUX_GPIO(GPIO_PTP7, PTP7_DATA),
PINMUX_GPIO(GPIO_PTP6, PTP6_DATA),
PINMUX_GPIO(GPIO_PTP5, PTP5_DATA),
PINMUX_GPIO(GPIO_PTP4, PTP4_DATA),
@@ -1145,6 +1301,8 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTS0, PTS0_DATA),
/* PTT */
+ PINMUX_GPIO(GPIO_PTT7, PTT7_DATA),
+ PINMUX_GPIO(GPIO_PTT6, PTT6_DATA),
PINMUX_GPIO(GPIO_PTT5, PTT5_DATA),
PINMUX_GPIO(GPIO_PTT4, PTT4_DATA),
PINMUX_GPIO(GPIO_PTT3, PTT3_DATA),
@@ -1212,54 +1370,35 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_PTZ1, PTZ1_DATA),
PINMUX_GPIO(GPIO_PTZ0, PTZ0_DATA),
- /* PTA (mobule: LBSC, CPG, LPC) */
+ /* PTA (mobule: LBSC, RGMII) */
PINMUX_GPIO(GPIO_FN_BS, BS_MARK),
PINMUX_GPIO(GPIO_FN_RDWR, RDWR_MARK),
PINMUX_GPIO(GPIO_FN_WE1, WE1_MARK),
PINMUX_GPIO(GPIO_FN_RDY, RDY_MARK),
- PINMUX_GPIO(GPIO_FN_MD10, MD10_MARK),
- PINMUX_GPIO(GPIO_FN_MD9, MD9_MARK),
- PINMUX_GPIO(GPIO_FN_MD8, MD8_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
- PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
-
- /* PTB (mobule: LBSC, EtherC, SIM, LPC) */
- PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
- PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
- PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
- PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
- PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
- PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
- PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
- PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
PINMUX_GPIO(GPIO_FN_ET0_MDC, ET0_MDC_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDIO_MARK),
+ PINMUX_GPIO(GPIO_FN_ET0_MDIO, ET0_MDC_MARK),
PINMUX_GPIO(GPIO_FN_ET1_MDC, ET1_MDC_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDIO_MARK),
- PINMUX_GPIO(GPIO_FN_WPSZ1, WPSZ1_MARK),
- PINMUX_GPIO(GPIO_FN_WPSZ0, WPSZ0_MARK),
- PINMUX_GPIO(GPIO_FN_FWID, FWID_MARK),
- PINMUX_GPIO(GPIO_FN_FLSHSZ, FLSHSZ_MARK),
- PINMUX_GPIO(GPIO_FN_LPC_SPIEN, LPC_SPIEN_MARK),
- PINMUX_GPIO(GPIO_FN_BASEL, BASEL_MARK),
-
- /* PTC (mobule: SD) */
- PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
- PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
+ PINMUX_GPIO(GPIO_FN_ET1_MDIO, ET1_MDC_MARK),
- /* PTD (mobule: INTC, SPI0, LBSC, CPG, ADC) */
+ /* PTB (mobule: INTC, ONFI, TMU) */
+ PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
+ PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NRE, ON_NRE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NWE, ON_NWE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NWP, ON_NWP_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_NCE0, ON_NCE0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_R_B0, ON_R_B0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_ALE, ON_ALE_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_CLE, ON_CLE_MARK),
+ PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
+
+ /* PTC (mobule: IRQ, PWMU) */
PINMUX_GPIO(GPIO_FN_IRQ7, IRQ7_MARK),
PINMUX_GPIO(GPIO_FN_IRQ6, IRQ6_MARK),
PINMUX_GPIO(GPIO_FN_IRQ5, IRQ5_MARK),
@@ -1268,80 +1407,102 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_IRQ2, IRQ2_MARK),
PINMUX_GPIO(GPIO_FN_IRQ1, IRQ1_MARK),
PINMUX_GPIO(GPIO_FN_IRQ0, IRQ0_MARK),
- PINMUX_GPIO(GPIO_FN_MD6, MD6_MARK),
- PINMUX_GPIO(GPIO_FN_MD5, MD5_MARK),
- PINMUX_GPIO(GPIO_FN_MD3, MD3_MARK),
- PINMUX_GPIO(GPIO_FN_MD2, MD2_MARK),
- PINMUX_GPIO(GPIO_FN_MD1, MD1_MARK),
- PINMUX_GPIO(GPIO_FN_MD0, MD0_MARK),
- PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
- PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU0, PWMU0_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU1, PWMU1_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU2, PWMU2_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU3, PWMU3_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU4, PWMU4_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMU5, PWMU5_MARK),
+
+ /* PTD (mobule: SPI0, DMAC) */
+ PINMUX_GPIO(GPIO_FN_SP0_MOSI, SP0_MOSI_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_MISO, SP0_MISO_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SCK, SP0_SCK_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SCK_FB, SP0_SCK_FB_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS0, SP0_SS0_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS2, SP0_SS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SP0_SS3, SP0_SS3_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
- /* PTE (mobule: EtherC) */
- PINMUX_GPIO(GPIO_FN_ET0_CRS_DV, ET0_CRS_DV_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TXD1, ET0_TXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TXD0, ET0_TXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_TX_EN, ET0_TX_EN_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_REF_CLK, ET0_REF_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RXD1, ET0_RXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RXD0, ET0_RXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET0_RX_ER, ET0_RX_ER_MARK),
-
- /* PTF (mobule: EtherC) */
- PINMUX_GPIO(GPIO_FN_ET1_CRS_DV, ET1_CRS_DV_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TXD1, ET1_TXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TXD0, ET1_TXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_TX_EN, ET1_TX_EN_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_REF_CLK, ET1_REF_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RXD1, ET1_RXD1_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RXD0, ET1_RXD0_MARK),
- PINMUX_GPIO(GPIO_FN_ET1_RX_ER, ET1_RX_ER_MARK),
-
- /* PTG (mobule: SYSTEM, PWMX, LPC) */
- PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
- PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
- PINMUX_GPIO(GPIO_FN_PWX0, PWX0_MARK),
- PINMUX_GPIO(GPIO_FN_PWX1, PWX1_MARK),
- PINMUX_GPIO(GPIO_FN_PWX2, PWX2_MARK),
- PINMUX_GPIO(GPIO_FN_PWX3, PWX3_MARK),
+ /* PTE (mobule: RMII) */
+ PINMUX_GPIO(GPIO_FN_RMII0_CRS_DV, RMII0_CRS_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXD1, RMII0_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXD0, RMII0_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_TXEN, RMII0_TXEN_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_REFCLK, RMII0_REFCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RXD1, RMII0_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RXD0, RMII0_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII0_RX_ER, RMII0_RX_ER_MARK),
+
+ /* PTF (mobule: RMII, SerMux) */
+ PINMUX_GPIO(GPIO_FN_RMII1_CRS_DV, RMII1_CRS_DV_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXD1, RMII1_TXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXD0, RMII1_TXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_TXEN, RMII1_TXEN_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_REFCLK, RMII1_REFCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RXD1, RMII1_RXD1_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RXD0, RMII1_RXD0_MARK),
+ PINMUX_GPIO(GPIO_FN_RMII1_RX_ER, RMII1_RX_ER_MARK),
+ PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+
+ /* PTG (mobule: system, LBSC, LPC, WDT, LPC, eMMC) */
+ PINMUX_GPIO(GPIO_FN_BOOTFMS, BOOTFMS_MARK),
+ PINMUX_GPIO(GPIO_FN_BOOTWP, BOOTWP_MARK),
+ PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
+ PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
PINMUX_GPIO(GPIO_FN_SERIRQ, SERIRQ_MARK),
- PINMUX_GPIO(GPIO_FN_CLKRUN, CLKRUN_MARK),
+ PINMUX_GPIO(GPIO_FN_WDTOVF, WDTOVF_MARK),
PINMUX_GPIO(GPIO_FN_LPCPD, LPCPD_MARK),
PINMUX_GPIO(GPIO_FN_LDRQ, LDRQ_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCCLK, MMCCLK_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCCMD, MMCCMD_MARK),
- /* PTH (mobule: TMU, SCIF234, SPI1, SPI0) */
- PINMUX_GPIO(GPIO_FN_TCLK, TCLK_MARK),
- PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
- PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
+ /* PTH (mobule: SPI1, LPC, DMAC, ADC) */
PINMUX_GPIO(GPIO_FN_SP1_MOSI, SP1_MOSI_MARK),
PINMUX_GPIO(GPIO_FN_SP1_MISO, SP1_MISO_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SCK, SP1_SCK_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SCK_FB, SP1_SCK_FB_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SS0, SP1_SS0_MARK),
PINMUX_GPIO(GPIO_FN_SP1_SS1, SP1_SS1_MARK),
- PINMUX_GPIO(GPIO_FN_SP0_SS1, SP0_SS1_MARK),
+ PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
+ PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
+ PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+ PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG1, ADTRG1_MARK),
+ PINMUX_GPIO(GPIO_FN_ADTRG0, ADTRG0_MARK),
- /* PTI (mobule: INTC) */
- PINMUX_GPIO(GPIO_FN_IRQ15, IRQ15_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ14, IRQ14_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ13, IRQ13_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ12, IRQ12_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ11, IRQ11_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ10, IRQ10_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ9, IRQ9_MARK),
- PINMUX_GPIO(GPIO_FN_IRQ8, IRQ8_MARK),
+ /* PTI (mobule: LBSC, SDHI) */
+ PINMUX_GPIO(GPIO_FN_D15, D15_MARK),
+ PINMUX_GPIO(GPIO_FN_D14, D14_MARK),
+ PINMUX_GPIO(GPIO_FN_D13, D13_MARK),
+ PINMUX_GPIO(GPIO_FN_D12, D12_MARK),
+ PINMUX_GPIO(GPIO_FN_D11, D11_MARK),
+ PINMUX_GPIO(GPIO_FN_D10, D10_MARK),
+ PINMUX_GPIO(GPIO_FN_D9, D9_MARK),
+ PINMUX_GPIO(GPIO_FN_D8, D8_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_WP, SD_WP_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CD, SD_CD_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CLK, SD_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_CMD, SD_CMD_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D3, SD_D3_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D2, SD_D2_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D1, SD_D1_MARK),
+ PINMUX_GPIO(GPIO_FN_SD_D0, SD_D0_MARK),
/* PTJ (mobule: SCIF234, SERMUX) */
- PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
PINMUX_GPIO(GPIO_FN_TXD3, TXD3_MARK),
- PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
- PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
- PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD3, RXD3_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD4, RXD4_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD4, TXD4_MARK),
- /* PTK (mobule: SERMUX) */
+ /* PTK (mobule: SERMUX, LBSC, SCIF) */
PINMUX_GPIO(GPIO_FN_COM2_TXD, COM2_TXD_MARK),
PINMUX_GPIO(GPIO_FN_COM2_RXD, COM2_RXD_MARK),
PINMUX_GPIO(GPIO_FN_COM2_RTS, COM2_RTS_MARK),
@@ -1349,62 +1510,65 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_COM2_DTR, COM2_DTR_MARK),
PINMUX_GPIO(GPIO_FN_COM2_DSR, COM2_DSR_MARK),
PINMUX_GPIO(GPIO_FN_COM2_DCD, COM2_DCD_MARK),
- PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_CLKOUT, CLKOUT_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
+ PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
- /* PTL (mobule: SERMUX) */
- PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+ /* PTL (mobule: SERMUX, SCIF, LBSC, AUD) */
PINMUX_GPIO(GPIO_FN_RAC_RXD, RAC_RXD_MARK),
PINMUX_GPIO(GPIO_FN_RAC_RTS, RAC_RTS_MARK),
PINMUX_GPIO(GPIO_FN_RAC_CTS, RAC_CTS_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DTR, RAC_DTR_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DSR, RAC_DSR_MARK),
PINMUX_GPIO(GPIO_FN_RAC_DCD, RAC_DCD_MARK),
- PINMUX_GPIO(GPIO_FN_RAC_RI, RAC_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_RAC_TXD, RAC_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_RXD2, RXD2_MARK),
+ PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
+ PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
+ PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ PINMUX_GPIO(GPIO_FN_TXD2, TXD2_MARK),
- /* PTM (mobule: IIC, LPC) */
+ /* PTM (mobule: LBSC, IIC) */
+ PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
+ PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
+ PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
+ PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
PINMUX_GPIO(GPIO_FN_SDA6, SDA6_MARK),
PINMUX_GPIO(GPIO_FN_SCL6, SCL6_MARK),
PINMUX_GPIO(GPIO_FN_SDA7, SDA7_MARK),
PINMUX_GPIO(GPIO_FN_SCL7, SCL7_MARK),
- PINMUX_GPIO(GPIO_FN_WP, WP_MARK),
- PINMUX_GPIO(GPIO_FN_FMS0, FMS0_MARK),
- PINMUX_GPIO(GPIO_FN_FMS1, FMS1_MARK),
- /* PTN (mobule: SCIF234, EVC) */
- PINMUX_GPIO(GPIO_FN_SCK2, SCK2_MARK),
- PINMUX_GPIO(GPIO_FN_RTS4, RTS4_MARK),
- PINMUX_GPIO(GPIO_FN_RTS3, RTS3_MARK),
- PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
- PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
- PINMUX_GPIO(GPIO_FN_CTS3, CTS3_MARK),
- PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
- PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+ /* PTN (mobule: USB, JMC, SGPIO, WDT) */
+ PINMUX_GPIO(GPIO_FN_VBUS_EN, VBUS_EN_MARK),
+ PINMUX_GPIO(GPIO_FN_VBUS_OC, VBUS_OC_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
+ PINMUX_GPIO(GPIO_FN_JMCTRST, JMCTRST_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_SUB_CLKIN, SUB_CLKIN_MARK),
- /* PTO (mobule: SGPIO) */
+ /* PTO (mobule: SGPIO, SerMux) */
PINMUX_GPIO(GPIO_FN_SGPIO0_CLK, SGPIO0_CLK_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_LOAD, SGPIO0_LOAD_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_DI, SGPIO0_DI_MARK),
PINMUX_GPIO(GPIO_FN_SGPIO0_DO, SGPIO0_DO_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_CLK, SGPIO1_CLK_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_LOAD, SGPIO1_LOAD_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_DI, SGPIO1_DI_MARK),
- PINMUX_GPIO(GPIO_FN_SGPIO1_DO, SGPIO1_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_CLK, SGPIO2_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_LOAD, SGPIO2_LOAD_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_DI, SGPIO2_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_SGPIO2_DO, SGPIO2_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_TXD, COM1_TXD_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_RXD, COM1_RXD_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_RTS, COM1_RTS_MARK),
+ PINMUX_GPIO(GPIO_FN_COM1_CTS, COM1_CTS_MARK),
- /* PTP (mobule: JMC, SCIF234) */
- PINMUX_GPIO(GPIO_FN_JMCTCK, JMCTCK_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTMS, JMCTMS_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTDO, JMCTDO_MARK),
- PINMUX_GPIO(GPIO_FN_JMCTDI, JMCTDI_MARK),
- PINMUX_GPIO(GPIO_FN_JMCRST, JMCRST_MARK),
- PINMUX_GPIO(GPIO_FN_SCK4, SCK4_MARK),
- PINMUX_GPIO(GPIO_FN_SCK3, SCK3_MARK),
+ /* PTP (mobule: EVC, ADC) */
/* PTQ (mobule: LPC) */
PINMUX_GPIO(GPIO_FN_LAD3, LAD3_MARK),
@@ -1439,31 +1603,41 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_SDA3, SDA3_MARK),
PINMUX_GPIO(GPIO_FN_SCL3, SCL3_MARK),
- /* PTT (mobule: SYSTEM, PWMX) */
- PINMUX_GPIO(GPIO_FN_AUDSYNC, AUDSYNC_MARK),
- PINMUX_GPIO(GPIO_FN_AUDCK, AUDCK_MARK),
+ /* PTT (mobule: PWMX, AUD) */
+ PINMUX_GPIO(GPIO_FN_PWMX7, PWMX7_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX6, PWMX6_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX5, PWMX5_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX4, PWMX4_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX3, PWMX3_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX2, PWMX2_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX1, PWMX1_MARK),
+ PINMUX_GPIO(GPIO_FN_PWMX0, PWMX0_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA3, AUDATA3_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA2, AUDATA2_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA1, AUDATA1_MARK),
PINMUX_GPIO(GPIO_FN_AUDATA0, AUDATA0_MARK),
- PINMUX_GPIO(GPIO_FN_PWX7, PWX7_MARK),
- PINMUX_GPIO(GPIO_FN_PWX6, PWX6_MARK),
- PINMUX_GPIO(GPIO_FN_PWX5, PWX5_MARK),
- PINMUX_GPIO(GPIO_FN_PWX4, PWX4_MARK),
-
- /* PTU (mobule: LBSC, DMAC) */
- PINMUX_GPIO(GPIO_FN_CS6, CS6_MARK),
- PINMUX_GPIO(GPIO_FN_CS5, CS5_MARK),
- PINMUX_GPIO(GPIO_FN_CS4, CS4_MARK),
- PINMUX_GPIO(GPIO_FN_CS0, CS0_MARK),
- PINMUX_GPIO(GPIO_FN_RD, RD_MARK),
- PINMUX_GPIO(GPIO_FN_WE0, WE0_MARK),
- PINMUX_GPIO(GPIO_FN_A25, A25_MARK),
- PINMUX_GPIO(GPIO_FN_A24, A24_MARK),
- PINMUX_GPIO(GPIO_FN_DREQ0, DREQ0_MARK),
- PINMUX_GPIO(GPIO_FN_DACK0, DACK0_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS1, STATUS1_MARK),
+ PINMUX_GPIO(GPIO_FN_STATUS0, STATUS0_MARK),
- /* PTV (mobule: LBSC, DMAC) */
+ /* PTU (mobule: LPC, APM) */
+ PINMUX_GPIO(GPIO_FN_LGPIO7, LGPIO7_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO6, LGPIO6_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO5, LGPIO5_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO4, LGPIO4_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO3, LGPIO3_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO2, LGPIO2_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO1, LGPIO1_MARK),
+ PINMUX_GPIO(GPIO_FN_LGPIO0, LGPIO0_MARK),
+ PINMUX_GPIO(GPIO_FN_APMONCTL_O, APMONCTL_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMPWBTOUT_O, APMPWBTOUT_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMSCI_O, APMSCI_O_MARK),
+ PINMUX_GPIO(GPIO_FN_APMVDDON, APMVDDON_MARK),
+ PINMUX_GPIO(GPIO_FN_APMSLPBTN, APMSLPBTN_MARK),
+ PINMUX_GPIO(GPIO_FN_APMPWRBTN, APMPWRBTN_MARK),
+ PINMUX_GPIO(GPIO_FN_APMS5N, APMS5N_MARK),
+ PINMUX_GPIO(GPIO_FN_APMS3N, APMS3N_MARK),
+
+ /* PTV (mobule: LBSC, SerMux, R-SPI, EVC, GRA) */
PINMUX_GPIO(GPIO_FN_A23, A23_MARK),
PINMUX_GPIO(GPIO_FN_A22, A22_MARK),
PINMUX_GPIO(GPIO_FN_A21, A21_MARK),
@@ -1472,12 +1646,20 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A18, A18_MARK),
PINMUX_GPIO(GPIO_FN_A17, A17_MARK),
PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
- PINMUX_GPIO(GPIO_FN_TEND0, TEND0_MARK),
- PINMUX_GPIO(GPIO_FN_DREQ1, DREQ1_MARK),
- PINMUX_GPIO(GPIO_FN_DACK1, DACK1_MARK),
- PINMUX_GPIO(GPIO_FN_TEND1, TEND1_MARK),
+ PINMUX_GPIO(GPIO_FN_COM2_RI, COM2_RI_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_MOSI, R_SPI_MOSI_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_MISO, R_SPI_MISO_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_RSPCK, R_SPI_RSPCK_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_SSL0, R_SPI_SSL0_MARK),
+ PINMUX_GPIO(GPIO_FN_R_SPI_SSL1, R_SPI_SSL1_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT7, EVENT7_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT6, EVENT6_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_DI, VBIOS_DI_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_DO, VBIOS_DO_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_CLK, VBIOS_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_VBIOS_CS, VBIOS_CS_MARK),
- /* PTW (mobule: LBSC) */
+ /* PTW (mobule: LBSC, EVC, SCIF) */
PINMUX_GPIO(GPIO_FN_A16, A16_MARK),
PINMUX_GPIO(GPIO_FN_A15, A15_MARK),
PINMUX_GPIO(GPIO_FN_A14, A14_MARK),
@@ -1487,6 +1669,14 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A10, A10_MARK),
PINMUX_GPIO(GPIO_FN_A9, A9_MARK),
PINMUX_GPIO(GPIO_FN_A8, A8_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT5, EVENT5_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT4, EVENT4_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT3, EVENT3_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT2, EVENT2_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT1, EVENT1_MARK),
+ PINMUX_GPIO(GPIO_FN_EVENT0, EVENT0_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS4, CTS4_MARK),
+ PINMUX_GPIO(GPIO_FN_CTS2, CTS2_MARK),
/* PTX (mobule: LBSC) */
PINMUX_GPIO(GPIO_FN_A7, A7_MARK),
@@ -1497,6 +1687,10 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_A2, A2_MARK),
PINMUX_GPIO(GPIO_FN_A1, A1_MARK),
PINMUX_GPIO(GPIO_FN_A0, A0_MARK),
+ PINMUX_GPIO(GPIO_FN_RTS2, RTS2_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_D, SIM_D_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_CLK, SIM_CLK_MARK),
+ PINMUX_GPIO(GPIO_FN_SIM_RST, SIM_RST_MARK),
/* PTY (mobule: LBSC) */
PINMUX_GPIO(GPIO_FN_D7, D7_MARK),
@@ -1507,18 +1701,36 @@ static struct pinmux_gpio pinmux_gpios[] = {
PINMUX_GPIO(GPIO_FN_D2, D2_MARK),
PINMUX_GPIO(GPIO_FN_D1, D1_MARK),
PINMUX_GPIO(GPIO_FN_D0, D0_MARK),
+
+ /* PTZ (mobule: eMMC, ONFI) */
+ PINMUX_GPIO(GPIO_FN_MMCDAT7, MMCDAT7_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT6, MMCDAT6_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT5, MMCDAT5_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT4, MMCDAT4_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT3, MMCDAT3_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT2, MMCDAT2_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT1, MMCDAT1_MARK),
+ PINMUX_GPIO(GPIO_FN_MMCDAT0, MMCDAT0_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ7, ON_DQ7_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ6, ON_DQ6_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ5, ON_DQ5_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ4, ON_DQ4_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ3, ON_DQ3_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ2, ON_DQ2_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ1, ON_DQ1_MARK),
+ PINMUX_GPIO(GPIO_FN_ON_DQ0, ON_DQ0_MARK),
};
static struct pinmux_cfg_reg pinmux_config_regs[] = {
{ PINMUX_CFG_REG("PACR", 0xffec0000, 16, 2) {
- PTA7_FN, PTA7_OUT, PTA7_IN, 0,
- PTA6_FN, PTA6_OUT, PTA6_IN, 0,
- PTA5_FN, PTA5_OUT, PTA5_IN, 0,
- PTA4_FN, PTA4_OUT, PTA4_IN, 0,
- PTA3_FN, PTA3_OUT, PTA3_IN, 0,
- PTA2_FN, PTA2_OUT, PTA2_IN, 0,
- PTA1_FN, PTA1_OUT, PTA1_IN, 0,
- PTA0_FN, PTA0_OUT, PTA0_IN, 0 }
+ PTA7_FN, PTA7_OUT, PTA7_IN, PTA7_IN_PU,
+ PTA6_FN, PTA6_OUT, PTA6_IN, PTA6_IN_PU,
+ PTA5_FN, PTA5_OUT, PTA5_IN, PTA5_IN_PU,
+ PTA4_FN, PTA4_OUT, PTA4_IN, PTA4_IN_PU,
+ PTA3_FN, PTA3_OUT, PTA3_IN, PTA3_IN_PU,
+ PTA2_FN, PTA2_OUT, PTA2_IN, PTA2_IN_PU,
+ PTA1_FN, PTA1_OUT, PTA1_IN, PTA1_IN_PU,
+ PTA0_FN, PTA0_OUT, PTA0_IN, PTA0_IN_PU }
},
{ PINMUX_CFG_REG("PBCR", 0xffec0002, 16, 2) {
PTB7_FN, PTB7_OUT, PTB7_IN, 0,
@@ -1541,125 +1753,126 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTC0_FN, PTC0_OUT, PTC0_IN, 0 }
},
{ PINMUX_CFG_REG("PDCR", 0xffec0006, 16, 2) {
- PTD7_FN, PTD7_OUT, PTD7_IN, 0,
- PTD6_FN, PTD6_OUT, PTD6_IN, 0,
- PTD5_FN, PTD5_OUT, PTD5_IN, 0,
- PTD4_FN, PTD4_OUT, PTD4_IN, 0,
- PTD3_FN, PTD3_OUT, PTD3_IN, 0,
- PTD2_FN, PTD2_OUT, PTD2_IN, 0,
- PTD1_FN, PTD1_OUT, PTD1_IN, 0,
- PTD0_FN, PTD0_OUT, PTD0_IN, 0 }
+ PTD7_FN, PTD7_OUT, PTD7_IN, PTD7_IN_PU,
+ PTD6_FN, PTD6_OUT, PTD6_IN, PTD6_IN_PU,
+ PTD5_FN, PTD5_OUT, PTD5_IN, PTD5_IN_PU,
+ PTD4_FN, PTD4_OUT, PTD4_IN, PTD4_IN_PU,
+ PTD3_FN, PTD3_OUT, PTD3_IN, PTD3_IN_PU,
+ PTD2_FN, PTD2_OUT, PTD2_IN, PTD2_IN_PU,
+ PTD1_FN, PTD1_OUT, PTD1_IN, PTD1_IN_PU,
+ PTD0_FN, PTD0_OUT, PTD0_IN, PTD0_IN_PU }
},
{ PINMUX_CFG_REG("PECR", 0xffec0008, 16, 2) {
- PTE7_FN, PTE7_OUT, PTE7_IN, 0,
- PTE6_FN, PTE6_OUT, PTE6_IN, 0,
- PTE5_FN, PTE5_OUT, PTE5_IN, 0,
- PTE4_FN, PTE4_OUT, PTE4_IN, 0,
- PTE3_FN, PTE3_OUT, PTE3_IN, 0,
- PTE2_FN, PTE2_OUT, PTE2_IN, 0,
- PTE1_FN, PTE1_OUT, PTE1_IN, 0,
- PTE0_FN, PTE0_OUT, PTE0_IN, 0 }
+ PTE7_FN, PTE7_OUT, PTE7_IN, PTE7_IN_PU,
+ PTE6_FN, PTE6_OUT, PTE6_IN, PTE6_IN_PU,
+ PTE5_FN, PTE5_OUT, PTE5_IN, PTE5_IN_PU,
+ PTE4_FN, PTE4_OUT, PTE4_IN, PTE4_IN_PU,
+ PTE3_FN, PTE3_OUT, PTE3_IN, PTE3_IN_PU,
+ PTE2_FN, PTE2_OUT, PTE2_IN, PTE2_IN_PU,
+ PTE1_FN, PTE1_OUT, PTE1_IN, PTE1_IN_PU,
+ PTE0_FN, PTE0_OUT, PTE0_IN, PTE0_IN_PU }
},
{ PINMUX_CFG_REG("PFCR", 0xffec000a, 16, 2) {
- PTF7_FN, PTF7_OUT, PTF7_IN, 0,
- PTF6_FN, PTF6_OUT, PTF6_IN, 0,
- PTF5_FN, PTF5_OUT, PTF5_IN, 0,
- PTF4_FN, PTF4_OUT, PTF4_IN, 0,
- PTF3_FN, PTF3_OUT, PTF3_IN, 0,
- PTF2_FN, PTF2_OUT, PTF2_IN, 0,
- PTF1_FN, PTF1_OUT, PTF1_IN, 0,
- PTF0_FN, PTF0_OUT, PTF0_IN, 0 }
+ PTF7_FN, PTF7_OUT, PTF7_IN, PTF7_IN_PU,
+ PTF6_FN, PTF6_OUT, PTF6_IN, PTF6_IN_PU,
+ PTF5_FN, PTF5_OUT, PTF5_IN, PTF5_IN_PU,
+ PTF4_FN, PTF4_OUT, PTF4_IN, PTF4_IN_PU,
+ PTF3_FN, PTF3_OUT, PTF3_IN, PTF3_IN_PU,
+ PTF2_FN, PTF2_OUT, PTF2_IN, PTF2_IN_PU,
+ PTF1_FN, PTF1_OUT, PTF1_IN, PTF1_IN_PU,
+ PTF0_FN, PTF0_OUT, PTF0_IN, PTF0_IN_PU }
},
{ PINMUX_CFG_REG("PGCR", 0xffec000c, 16, 2) {
- PTG7_FN, PTG7_OUT, PTG7_IN, 0,
- PTG6_FN, PTG6_OUT, PTG6_IN, 0,
+ PTG7_FN, PTG7_OUT, PTG7_IN, PTG7_IN_PU ,
+ PTG6_FN, PTG6_OUT, PTG6_IN, PTG6_IN_PU ,
PTG5_FN, PTG5_OUT, PTG5_IN, 0,
- PTG4_FN, PTG4_OUT, PTG4_IN, 0,
+ PTG4_FN, PTG4_OUT, PTG4_IN, PTG4_IN_PU ,
PTG3_FN, PTG3_OUT, PTG3_IN, 0,
PTG2_FN, PTG2_OUT, PTG2_IN, 0,
PTG1_FN, PTG1_OUT, PTG1_IN, 0,
PTG0_FN, PTG0_OUT, PTG0_IN, 0 }
},
{ PINMUX_CFG_REG("PHCR", 0xffec000e, 16, 2) {
- PTH7_FN, PTH7_OUT, PTH7_IN, 0,
- PTH6_FN, PTH6_OUT, PTH6_IN, 0,
- PTH5_FN, PTH5_OUT, PTH5_IN, 0,
- PTH4_FN, PTH4_OUT, PTH4_IN, 0,
- PTH3_FN, PTH3_OUT, PTH3_IN, 0,
- PTH2_FN, PTH2_OUT, PTH2_IN, 0,
- PTH1_FN, PTH1_OUT, PTH1_IN, 0,
- PTH0_FN, PTH0_OUT, PTH0_IN, 0 }
+ PTH7_FN, PTH7_OUT, PTH7_IN, PTH7_IN_PU,
+ PTH6_FN, PTH6_OUT, PTH6_IN, PTH6_IN_PU,
+ PTH5_FN, PTH5_OUT, PTH5_IN, PTH5_IN_PU,
+ PTH4_FN, PTH4_OUT, PTH4_IN, PTH4_IN_PU,
+ PTH3_FN, PTH3_OUT, PTH3_IN, PTH3_IN_PU,
+ PTH2_FN, PTH2_OUT, PTH2_IN, PTH2_IN_PU,
+ PTH1_FN, PTH1_OUT, PTH1_IN, PTH1_IN_PU,
+ PTH0_FN, PTH0_OUT, PTH0_IN, PTH0_IN_PU }
},
{ PINMUX_CFG_REG("PICR", 0xffec0010, 16, 2) {
- PTI7_FN, PTI7_OUT, PTI7_IN, 0,
- PTI6_FN, PTI6_OUT, PTI6_IN, 0,
+ PTI7_FN, PTI7_OUT, PTI7_IN, PTI7_IN_PU,
+ PTI6_FN, PTI6_OUT, PTI6_IN, PTI6_IN_PU,
PTI5_FN, PTI5_OUT, PTI5_IN, 0,
- PTI4_FN, PTI4_OUT, PTI4_IN, 0,
- PTI3_FN, PTI3_OUT, PTI3_IN, 0,
- PTI2_FN, PTI2_OUT, PTI2_IN, 0,
- PTI1_FN, PTI1_OUT, PTI1_IN, 0,
- PTI0_FN, PTI0_OUT, PTI0_IN, 0 }
+ PTI4_FN, PTI4_OUT, PTI4_IN, PTI4_IN_PU,
+ PTI3_FN, PTI3_OUT, PTI3_IN, PTI3_IN_PU,
+ PTI2_FN, PTI2_OUT, PTI2_IN, PTI2_IN_PU,
+ PTI1_FN, PTI1_OUT, PTI1_IN, PTI1_IN_PU,
+ PTI0_FN, PTI0_OUT, PTI0_IN, PTI0_IN_PU }
},
{ PINMUX_CFG_REG("PJCR", 0xffec0012, 16, 2) {
- PTJ7_FN, PTJ7_OUT, PTJ7_IN, 0,
- PTJ6_FN, PTJ6_OUT, PTJ6_IN, 0,
- PTJ5_FN, PTJ5_OUT, PTJ5_IN, 0,
- PTJ4_FN, PTJ4_OUT, PTJ4_IN, 0,
- PTJ3_FN, PTJ3_OUT, PTJ3_IN, 0,
- PTJ2_FN, PTJ2_OUT, PTJ2_IN, 0,
- PTJ1_FN, PTJ1_OUT, PTJ1_IN, 0,
- PTJ0_FN, PTJ0_OUT, PTJ0_IN, 0 }
+ 0, 0, 0, 0, /* reserved: always set 1 */
+ PTJ6_FN, PTJ6_OUT, PTJ6_IN, PTJ6_IN_PU,
+ PTJ5_FN, PTJ5_OUT, PTJ5_IN, PTJ5_IN_PU,
+ PTJ4_FN, PTJ4_OUT, PTJ4_IN, PTJ4_IN_PU,
+ PTJ3_FN, PTJ3_OUT, PTJ3_IN, PTJ3_IN_PU,
+ PTJ2_FN, PTJ2_OUT, PTJ2_IN, PTJ2_IN_PU,
+ PTJ1_FN, PTJ1_OUT, PTJ1_IN, PTJ1_IN_PU,
+ PTJ0_FN, PTJ0_OUT, PTJ0_IN, PTJ0_IN_PU }
},
{ PINMUX_CFG_REG("PKCR", 0xffec0014, 16, 2) {
- PTK7_FN, PTK7_OUT, PTK7_IN, 0,
- PTK6_FN, PTK6_OUT, PTK6_IN, 0,
- PTK5_FN, PTK5_OUT, PTK5_IN, 0,
- PTK4_FN, PTK4_OUT, PTK4_IN, 0,
- PTK3_FN, PTK3_OUT, PTK3_IN, 0,
- PTK2_FN, PTK2_OUT, PTK2_IN, 0,
- PTK1_FN, PTK1_OUT, PTK1_IN, 0,
- PTK0_FN, PTK0_OUT, PTK0_IN, 0 }
+ PTK7_FN, PTK7_OUT, PTK7_IN, PTK7_IN_PU,
+ PTK6_FN, PTK6_OUT, PTK6_IN, PTK6_IN_PU,
+ PTK5_FN, PTK5_OUT, PTK5_IN, PTK5_IN_PU,
+ PTK4_FN, PTK4_OUT, PTK4_IN, PTK4_IN_PU,
+ PTK3_FN, PTK3_OUT, PTK3_IN, PTK3_IN_PU,
+ PTK2_FN, PTK2_OUT, PTK2_IN, PTK2_IN_PU,
+ PTK1_FN, PTK1_OUT, PTK1_IN, PTK1_IN_PU,
+ PTK0_FN, PTK0_OUT, PTK0_IN, PTK0_IN_PU }
},
{ PINMUX_CFG_REG("PLCR", 0xffec0016, 16, 2) {
- PTL7_FN, PTL7_OUT, PTL7_IN, 0,
- PTL6_FN, PTL6_OUT, PTL6_IN, 0,
- PTL5_FN, PTL5_OUT, PTL5_IN, 0,
- PTL4_FN, PTL4_OUT, PTL4_IN, 0,
- PTL3_FN, PTL3_OUT, PTL3_IN, 0,
- PTL2_FN, PTL2_OUT, PTL2_IN, 0,
- PTL1_FN, PTL1_OUT, PTL1_IN, 0,
- PTL0_FN, PTL0_OUT, PTL0_IN, 0 }
+ 0, 0, 0, 0, /* reserved: always set 1 */
+ PTL6_FN, PTL6_OUT, PTL6_IN, PTL6_IN_PU,
+ PTL5_FN, PTL5_OUT, PTL5_IN, PTL5_IN_PU,
+ PTL4_FN, PTL4_OUT, PTL4_IN, PTL4_IN_PU,
+ PTL3_FN, PTL3_OUT, PTL3_IN, PTL3_IN_PU,
+ PTL2_FN, PTL2_OUT, PTL2_IN, PTL2_IN_PU,
+ PTL1_FN, PTL1_OUT, PTL1_IN, PTL1_IN_PU,
+ PTL0_FN, PTL0_OUT, PTL0_IN, PTL0_IN_PU }
},
{ PINMUX_CFG_REG("PMCR", 0xffec0018, 16, 2) {
- 0, 0, 0, 0, /* reserved: always set 1 */
- PTM6_FN, PTM6_OUT, PTM6_IN, 0,
- PTM5_FN, PTM5_OUT, PTM5_IN, 0,
- PTM4_FN, PTM4_OUT, PTM4_IN, 0,
+ PTM7_FN, PTM7_OUT, PTM7_IN, PTM7_IN_PU,
+ PTM6_FN, PTM6_OUT, PTM6_IN, PTM6_IN_PU,
+ PTM5_FN, PTM5_OUT, PTM5_IN, PTM5_IN_PU,
+ PTM4_FN, PTM4_OUT, PTM4_IN, PTM4_IN_PU,
PTM3_FN, PTM3_OUT, PTM3_IN, 0,
PTM2_FN, PTM2_OUT, PTM2_IN, 0,
PTM1_FN, PTM1_OUT, PTM1_IN, 0,
PTM0_FN, PTM0_OUT, PTM0_IN, 0 }
},
{ PINMUX_CFG_REG("PNCR", 0xffec001a, 16, 2) {
- PTN7_FN, PTN7_OUT, PTN7_IN, 0,
+ 0, 0, 0, 0, /* reserved: always set 1 */
PTN6_FN, PTN6_OUT, PTN6_IN, 0,
PTN5_FN, PTN5_OUT, PTN5_IN, 0,
- PTN4_FN, PTN4_OUT, PTN4_IN, 0,
- PTN3_FN, PTN3_OUT, PTN3_IN, 0,
- PTN2_FN, PTN2_OUT, PTN2_IN, 0,
- PTN1_FN, PTN1_OUT, PTN1_IN, 0,
- PTN0_FN, PTN0_OUT, PTN0_IN, 0 }
+ PTN4_FN, PTN4_OUT, PTN4_IN, PTN4_IN_PU,
+ PTN3_FN, PTN3_OUT, PTN3_IN, PTN3_IN_PU,
+ PTN2_FN, PTN2_OUT, PTN2_IN, PTN2_IN_PU,
+ PTN1_FN, PTN1_OUT, PTN1_IN, PTN1_IN_PU,
+ PTN0_FN, PTN0_OUT, PTN0_IN, PTN0_IN_PU }
},
{ PINMUX_CFG_REG("POCR", 0xffec001c, 16, 2) {
- PTO7_FN, PTO7_OUT, PTO7_IN, 0,
- PTO6_FN, PTO6_OUT, PTO6_IN, 0,
- PTO5_FN, PTO5_OUT, PTO5_IN, 0,
- PTO4_FN, PTO4_OUT, PTO4_IN, 0,
- PTO3_FN, PTO3_OUT, PTO3_IN, 0,
- PTO2_FN, PTO2_OUT, PTO2_IN, 0,
- PTO1_FN, PTO1_OUT, PTO1_IN, 0,
- PTO0_FN, PTO0_OUT, PTO0_IN, 0 }
+ PTO7_FN, PTO7_OUT, PTO7_IN, PTO7_IN_PU,
+ PTO6_FN, PTO6_OUT, PTO6_IN, PTO6_IN_PU,
+ PTO5_FN, PTO5_OUT, PTO5_IN, PTO5_IN_PU,
+ PTO4_FN, PTO4_OUT, PTO4_IN, PTO4_IN_PU,
+ PTO3_FN, PTO3_OUT, PTO3_IN, PTO3_IN_PU,
+ PTO2_FN, PTO2_OUT, PTO2_IN, PTO2_IN_PU,
+ PTO1_FN, PTO1_OUT, PTO1_IN, PTO1_IN_PU,
+ PTO0_FN, PTO0_OUT, PTO0_IN, PTO0_IN_PU }
},
+#if 0 /* FIXME: Remove it? */
{ PINMUX_CFG_REG("PPCR", 0xffec001e, 16, 2) {
0, 0, 0, 0, /* reserved: always set 1 */
PTP6_FN, PTP6_OUT, PTP6_IN, 0,
@@ -1670,6 +1883,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTP1_FN, PTP1_OUT, PTP1_IN, 0,
PTP0_FN, PTP0_OUT, PTP0_IN, 0 }
},
+#endif
{ PINMUX_CFG_REG("PQCR", 0xffec0020, 16, 2) {
0, 0, 0, 0, /* reserved: always set 1 */
PTQ6_FN, PTQ6_OUT, PTQ6_IN, 0,
@@ -1701,14 +1915,14 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTS0_FN, PTS0_OUT, PTS0_IN, 0 }
},
{ PINMUX_CFG_REG("PTCR", 0xffec0026, 16, 2) {
- 0, 0, 0, 0, /* reserved: always set 1 */
- 0, 0, 0, 0, /* reserved: always set 1 */
- PTT5_FN, PTT5_OUT, PTT5_IN, 0,
- PTT4_FN, PTT4_OUT, PTT4_IN, 0,
- PTT3_FN, PTT3_OUT, PTT3_IN, 0,
- PTT2_FN, PTT2_OUT, PTT2_IN, 0,
- PTT1_FN, PTT1_OUT, PTT1_IN, 0,
- PTT0_FN, PTT0_OUT, PTT0_IN, 0 }
+ PTT7_FN, PTT7_OUT, PTT7_IN, PTO7_IN_PU,
+ PTT6_FN, PTT6_OUT, PTT6_IN, PTO6_IN_PU,
+ PTT5_FN, PTT5_OUT, PTT5_IN, PTO5_IN_PU,
+ PTT4_FN, PTT4_OUT, PTT4_IN, PTO4_IN_PU,
+ PTT3_FN, PTT3_OUT, PTT3_IN, PTO3_IN_PU,
+ PTT2_FN, PTT2_OUT, PTT2_IN, PTO2_IN_PU,
+ PTT1_FN, PTT1_OUT, PTT1_IN, PTO1_IN_PU,
+ PTT0_FN, PTT0_OUT, PTT0_IN, PTO0_IN_PU }
},
{ PINMUX_CFG_REG("PUCR", 0xffec0028, 16, 2) {
PTU7_FN, PTU7_OUT, PTU7_IN, PTU7_IN_PU,
@@ -1727,16 +1941,16 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTV4_FN, PTV4_OUT, PTV4_IN, PTV4_IN_PU,
PTV3_FN, PTV3_OUT, PTV3_IN, PTV3_IN_PU,
PTV2_FN, PTV2_OUT, PTV2_IN, PTV2_IN_PU,
- PTV1_FN, PTV1_OUT, PTV1_IN, PTV1_IN_PU,
- PTV0_FN, PTV0_OUT, PTV0_IN, PTV0_IN_PU }
+ PTV1_FN, PTV1_OUT, PTV1_IN, 0,
+ PTV0_FN, PTV0_OUT, PTV0_IN, 0 }
},
{ PINMUX_CFG_REG("PWCR", 0xffec002c, 16, 2) {
- PTW7_FN, PTW7_OUT, PTW7_IN, PTW7_IN_PU,
- PTW6_FN, PTW6_OUT, PTW6_IN, PTW6_IN_PU,
- PTW5_FN, PTW5_OUT, PTW5_IN, PTW5_IN_PU,
- PTW4_FN, PTW4_OUT, PTW4_IN, PTW4_IN_PU,
- PTW3_FN, PTW3_OUT, PTW3_IN, PTW3_IN_PU,
- PTW2_FN, PTW2_OUT, PTW2_IN, PTW2_IN_PU,
+ PTW7_FN, PTW7_OUT, PTW7_IN, 0,
+ PTW6_FN, PTW6_OUT, PTW6_IN, 0,
+ PTW5_FN, PTW5_OUT, PTW5_IN, 0,
+ PTW4_FN, PTW4_OUT, PTW4_IN, 0,
+ PTW3_FN, PTW3_OUT, PTW3_IN, 0,
+ PTW2_FN, PTW2_OUT, PTW2_IN, 0,
PTW1_FN, PTW1_OUT, PTW1_IN, PTW1_IN_PU,
PTW0_FN, PTW0_OUT, PTW0_IN, PTW0_IN_PU }
},
@@ -1761,32 +1975,32 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
PTY0_FN, PTY0_OUT, PTY0_IN, PTY0_IN_PU }
},
{ PINMUX_CFG_REG("PZCR", 0xffec0032, 16, 2) {
- 0, PTZ7_OUT, PTZ7_IN, 0,
- 0, PTZ6_OUT, PTZ6_IN, 0,
- 0, PTZ5_OUT, PTZ5_IN, 0,
- 0, PTZ4_OUT, PTZ4_IN, 0,
- 0, PTZ3_OUT, PTZ3_IN, 0,
- 0, PTZ2_OUT, PTZ2_IN, 0,
- 0, PTZ1_OUT, PTZ1_IN, 0,
- 0, PTZ0_OUT, PTZ0_IN, 0 }
+ PTZ7_FN, PTZ7_OUT, PTZ7_IN, 0,
+ PTZ6_FN, PTZ6_OUT, PTZ6_IN, 0,
+ PTZ5_FN, PTZ5_OUT, PTZ5_IN, 0,
+ PTZ4_FN, PTZ4_OUT, PTZ4_IN, 0,
+ PTZ3_FN, PTZ3_OUT, PTZ3_IN, 0,
+ PTZ2_FN, PTZ2_OUT, PTZ2_IN, 0,
+ PTZ1_FN, PTZ1_OUT, PTZ1_IN, 0,
+ PTZ0_FN, PTZ0_OUT, PTZ0_IN, 0 }
},
{ PINMUX_CFG_REG("PSEL0", 0xffec0070, 16, 1) {
- PS0_15_FN3, PS0_15_FN1,
- PS0_14_FN3, PS0_14_FN1,
- PS0_13_FN3, PS0_13_FN1,
- PS0_12_FN3, PS0_12_FN1,
- 0, 0,
- 0, 0,
+ PS0_15_FN1, PS0_15_FN2,
+ PS0_14_FN1, PS0_14_FN2,
+ PS0_13_FN1, PS0_13_FN2,
+ PS0_12_FN1, PS0_12_FN2,
+ PS0_11_FN1, PS0_11_FN2,
+ PS0_10_FN1, PS0_10_FN2,
+ PS0_9_FN1, PS0_9_FN2,
+ PS0_8_FN1, PS0_8_FN2,
+ PS0_7_FN1, PS0_7_FN2,
+ PS0_6_FN1, PS0_6_FN2,
+ PS0_5_FN1, PS0_5_FN2,
+ PS0_4_FN1, PS0_4_FN2,
+ PS0_3_FN1, PS0_3_FN2,
+ PS0_2_FN1, PS0_2_FN2,
0, 0,
- 0, 0,
- PS0_7_FN2, PS0_7_FN1,
- PS0_6_FN2, PS0_6_FN1,
- PS0_5_FN2, PS0_5_FN1,
- PS0_4_FN2, PS0_4_FN1,
- PS0_3_FN2, PS0_3_FN1,
- PS0_2_FN2, PS0_2_FN1,
- PS0_1_FN2, PS0_1_FN1,
0, 0, }
},
{ PINMUX_CFG_REG("PSEL1", 0xffec0072, 16, 1) {
@@ -1795,73 +2009,136 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
0, 0,
0, 0,
+ PS1_10_FN1, PS1_10_FN2,
+ PS1_9_FN1, PS1_9_FN2,
+ PS1_8_FN1, PS1_8_FN2,
0, 0,
0, 0,
0, 0,
- PS1_7_FN1, PS1_7_FN3,
- PS1_6_FN1, PS1_6_FN3,
- 0, 0,
- 0, 0,
0, 0,
0, 0,
+ PS1_2_FN1, PS1_2_FN2,
0, 0,
0, 0, }
},
{ PINMUX_CFG_REG("PSEL2", 0xffec0074, 16, 1) {
0, 0,
0, 0,
- PS2_13_FN3, PS2_13_FN1,
- PS2_12_FN3, PS2_12_FN1,
+ PS2_13_FN1, PS2_13_FN2,
+ PS2_12_FN1, PS2_12_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
+ PS2_7_FN1, PS2_7_FN2,
+ PS2_6_FN1, PS2_6_FN2,
+ PS2_5_FN1, PS2_5_FN2,
+ PS2_4_FN1, PS2_4_FN2,
0, 0,
+ PS2_2_FN1, PS2_2_FN2,
0, 0,
+ 0, 0, }
+ },
+ { PINMUX_CFG_REG("PSEL3", 0xffec0076, 16, 1) {
+ PS3_15_FN1, PS3_15_FN2,
+ PS3_14_FN1, PS3_14_FN2,
+ PS3_13_FN1, PS3_13_FN2,
+ PS3_12_FN1, PS3_12_FN2,
+ PS3_11_FN1, PS3_11_FN2,
+ PS3_10_FN1, PS3_10_FN2,
+ PS3_9_FN1, PS3_9_FN2,
+ PS3_8_FN1, PS3_8_FN2,
+ PS3_7_FN1, PS3_7_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
- PS2_1_FN1, PS2_1_FN2,
- PS2_0_FN1, PS2_0_FN2, }
+ PS3_2_FN1, PS3_2_FN2,
+ PS3_1_FN1, PS3_1_FN2,
+ 0, 0, }
},
+
{ PINMUX_CFG_REG("PSEL4", 0xffec0078, 16, 1) {
- PS4_15_FN2, PS4_15_FN1,
- PS4_14_FN2, PS4_14_FN1,
- PS4_13_FN2, PS4_13_FN1,
- PS4_12_FN2, PS4_12_FN1,
- PS4_11_FN2, PS4_11_FN1,
- PS4_10_FN2, PS4_10_FN1,
- PS4_9_FN2, PS4_9_FN1,
0, 0,
+ PS4_14_FN1, PS4_14_FN2,
+ PS4_13_FN1, PS4_13_FN2,
+ PS4_12_FN1, PS4_12_FN2,
0, 0,
+ PS4_10_FN1, PS4_10_FN2,
+ PS4_9_FN1, PS4_9_FN2,
+ PS4_8_FN1, PS4_8_FN2,
0, 0,
0, 0,
0, 0,
- PS4_3_FN2, PS4_3_FN1,
- PS4_2_FN2, PS4_2_FN1,
- PS4_1_FN2, PS4_1_FN1,
- PS4_0_FN2, PS4_0_FN1, }
+ PS4_4_FN1, PS4_4_FN2,
+ PS4_3_FN1, PS4_3_FN2,
+ PS4_2_FN1, PS4_2_FN2,
+ PS4_1_FN1, PS4_1_FN2,
+ PS4_0_FN1, PS4_0_FN2, }
},
{ PINMUX_CFG_REG("PSEL5", 0xffec007a, 16, 1) {
0, 0,
0, 0,
0, 0,
0, 0,
- 0, 0,
- 0, 0,
+ PS5_11_FN1, PS5_11_FN2,
+ PS5_10_FN1, PS5_10_FN2,
PS5_9_FN1, PS5_9_FN2,
PS5_8_FN1, PS5_8_FN2,
PS5_7_FN1, PS5_7_FN2,
PS5_6_FN1, PS5_6_FN2,
PS5_5_FN1, PS5_5_FN2,
+ PS5_4_FN1, PS5_4_FN2,
+ PS5_3_FN1, PS5_3_FN2,
+ PS5_2_FN1, PS5_2_FN2,
+ 0, 0,
+ 0, 0, }
+ },
+ { PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+ PS6_15_FN1, PS6_15_FN2,
+ PS6_14_FN1, PS6_14_FN2,
+ PS6_13_FN1, PS6_13_FN2,
+ PS6_12_FN1, PS6_12_FN2,
+ PS6_11_FN1, PS6_11_FN2,
+ PS6_10_FN1, PS6_10_FN2,
+ PS6_9_FN1, PS6_9_FN2,
+ PS6_8_FN1, PS6_8_FN2,
+ PS6_7_FN1, PS6_7_FN2,
+ PS6_6_FN1, PS6_6_FN2,
+ PS6_5_FN1, PS6_5_FN2,
+ PS6_4_FN1, PS6_4_FN2,
+ PS6_3_FN1, PS6_3_FN2,
+ PS6_2_FN1, PS6_2_FN2,
+ PS6_1_FN1, PS6_1_FN2,
+ PS6_0_FN1, PS6_0_FN2, }
+ },
+ { PINMUX_CFG_REG("PSEL7", 0xffec0082, 16, 1) {
+ PS7_15_FN1, PS7_15_FN2,
+ PS7_14_FN1, PS7_14_FN2,
+ PS7_13_FN1, PS7_13_FN2,
+ PS7_12_FN1, PS7_12_FN2,
+ PS7_11_FN1, PS7_11_FN2,
+ PS7_10_FN1, PS7_10_FN2,
+ PS7_9_FN1, PS7_9_FN2,
+ PS7_8_FN1, PS7_8_FN2,
+ PS7_7_FN1, PS7_7_FN2,
+ PS7_6_FN1, PS7_6_FN2,
+ PS7_5_FN1, PS7_5_FN2,
0, 0,
0, 0,
0, 0,
0, 0,
0, 0, }
},
- { PINMUX_CFG_REG("PSEL6", 0xffec007c, 16, 1) {
+ { PINMUX_CFG_REG("PSEL8", 0xffec0084, 16, 1) {
+ PS8_15_FN1, PS8_15_FN2,
+ PS8_14_FN1, PS8_14_FN2,
+ PS8_13_FN1, PS8_13_FN2,
+ PS8_12_FN1, PS8_12_FN2,
+ PS8_11_FN1, PS8_11_FN2,
+ PS8_10_FN1, PS8_10_FN2,
+ PS8_9_FN1, PS8_9_FN2,
+ PS8_8_FN1, PS8_8_FN2,
0, 0,
0, 0,
0, 0,
@@ -1869,15 +2146,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
0, 0,
0, 0,
0, 0,
- 0, 0,
- PS6_7_FN_AN, PS6_7_FN_EV,
- PS6_6_FN_AN, PS6_6_FN_EV,
- PS6_5_FN_AN, PS6_5_FN_EV,
- PS6_4_FN_AN, PS6_4_FN_EV,
- PS6_3_FN_AN, PS6_3_FN_EV,
- PS6_2_FN_AN, PS6_2_FN_EV,
- PS6_1_FN_AN, PS6_1_FN_EV,
- PS6_0_FN_AN, PS6_0_FN_EV, }
+ 0, 0, }
},
{}
};
@@ -1920,7 +2189,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTI3_DATA, PTI2_DATA, PTI1_DATA, PTI0_DATA }
},
{ PINMUX_DATA_REG("PJDR", 0xffec0046, 8) {
- PTJ7_DATA, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
+ 0, PTJ6_DATA, PTJ5_DATA, PTJ4_DATA,
PTJ3_DATA, PTJ2_DATA, PTJ1_DATA, PTJ0_DATA }
},
{ PINMUX_DATA_REG("PKDR", 0xffec0048, 8) {
@@ -1928,15 +2197,15 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTK3_DATA, PTK2_DATA, PTK1_DATA, PTK0_DATA }
},
{ PINMUX_DATA_REG("PLDR", 0xffec004a, 8) {
- PTL7_DATA, PTL6_DATA, PTL5_DATA, PTL4_DATA,
+ 0, PTL6_DATA, PTL5_DATA, PTL4_DATA,
PTL3_DATA, PTL2_DATA, PTL1_DATA, PTL0_DATA }
},
{ PINMUX_DATA_REG("PMDR", 0xffec004c, 8) {
- 0, PTM6_DATA, PTM5_DATA, PTM4_DATA,
+ PTM7_DATA, PTM6_DATA, PTM5_DATA, PTM4_DATA,
PTM3_DATA, PTM2_DATA, PTM1_DATA, PTM0_DATA }
},
{ PINMUX_DATA_REG("PNDR", 0xffec004e, 8) {
- PTN7_DATA, PTN6_DATA, PTN5_DATA, PTN4_DATA,
+ 0, PTN6_DATA, PTN5_DATA, PTN4_DATA,
PTN3_DATA, PTN2_DATA, PTN1_DATA, PTN0_DATA }
},
{ PINMUX_DATA_REG("PODR", 0xffec0050, 8) {
@@ -1944,7 +2213,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTO3_DATA, PTO2_DATA, PTO1_DATA, PTO0_DATA }
},
{ PINMUX_DATA_REG("PPDR", 0xffec0052, 8) {
- 0, PTP6_DATA, PTP5_DATA, PTP4_DATA,
+ PTP7_DATA, PTP6_DATA, PTP5_DATA, PTP4_DATA,
PTP3_DATA, PTP2_DATA, PTP1_DATA, PTP0_DATA }
},
{ PINMUX_DATA_REG("PQDR", 0xffec0054, 8) {
@@ -1960,7 +2229,7 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
PTS3_DATA, PTS2_DATA, PTS1_DATA, PTS0_DATA }
},
{ PINMUX_DATA_REG("PTDR", 0xffec005a, 8) {
- 0, 0, PTT5_DATA, PTT4_DATA,
+ PTT7_DATA, PTT6_DATA, PTT5_DATA, PTT4_DATA,
PTT3_DATA, PTT2_DATA, PTT1_DATA, PTT0_DATA }
},
{ PINMUX_DATA_REG("PUDR", 0xffec005c, 8) {
@@ -2000,8 +2269,8 @@ static struct pinmux_info sh7757_pinmux_info = {
.mark = { PINMUX_MARK_BEGIN, PINMUX_MARK_END },
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
- .first_gpio = GPIO_PTA7,
- .last_gpio = GPIO_FN_D0,
+ .first_gpio = GPIO_PTA0,
+ .last_gpio = GPIO_FN_ON_DQ0,
.gpios = pinmux_gpios,
.cfg_regs = pinmux_config_regs,
@@ -2015,5 +2284,4 @@ static int __init plat_pinmux_setup(void)
{
return register_pinmux(&sh7757_pinmux_info);
}
-
arch_initcall(plat_pinmux_setup);
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index 444aca95b20d..749c6388d5a5 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -26,7 +26,7 @@ static struct plat_sci_port scif2_platform_data = {
static struct platform_device scif2_device = {
.name = "sh-sci",
- .id = 2,
+ .id = 0,
.dev = {
.platform_data = &scif2_platform_data,
},
@@ -41,7 +41,7 @@ static struct plat_sci_port scif3_platform_data = {
static struct platform_device scif3_device = {
.name = "sh-sci",
- .id = 3,
+ .id = 1,
.dev = {
.platform_data = &scif3_platform_data,
},
@@ -56,7 +56,7 @@ static struct plat_sci_port scif4_platform_data = {
static struct platform_device scif4_device = {
.name = "sh-sci",
- .id = 4,
+ .id = 2,
.dev = {
.platform_data = &scif4_platform_data,
},
@@ -163,39 +163,23 @@ enum {
IRL4_HHLL, IRL4_HHLH, IRL4_HHHL,
IRQ0, IRQ1, IRQ2, IRQ3, IRQ4, IRQ5, IRQ6, IRQ7,
- SDHI,
- DVC,
- IRQ8, IRQ9, IRQ10,
- WDT0,
- TMU0, TMU1, TMU2, TMU2_TICPI,
+ SDHI, DVC,
+ IRQ8, IRQ9, IRQ11, IRQ10, IRQ12, IRQ13, IRQ14, IRQ15,
+ TMU0, TMU1, TMU2, TMU2_TICPI, TMU3, TMU4, TMU5,
HUDI,
-
ARC4,
- DMAC0,
- IRQ11,
- SCIF2,
- DMAC1_6,
- USB0,
- IRQ12,
+ DMAC0_5, DMAC6_7, DMAC8_11,
+ SCIF0, SCIF1, SCIF2, SCIF3, SCIF4,
+ USB0, USB1,
JMC,
- SPI1,
- IRQ13, IRQ14,
- USB1,
+ SPI0, SPI1,
TMR01, TMR23, TMR45,
- WDT1,
FRT,
- LPC,
- SCIF0, SCIF1, SCIF3,
- PECI0I, PECI1I, PECI2I,
- IRQ15,
+ LPC, LPC5, LPC6, LPC7, LPC8,
+ PECI0, PECI1, PECI2, PECI3, PECI4, PECI5,
ETHERC,
- SPI0,
- ADC1,
- DMAC1_8,
+ ADC0, ADC1,
SIM,
- TMU3, TMU4, TMU5,
- ADC0,
- SCIF4,
IIC0_0, IIC0_1, IIC0_2, IIC0_3,
IIC1_0, IIC1_1, IIC1_2, IIC1_3,
IIC2_0, IIC2_1, IIC2_2, IIC2_3,
@@ -206,9 +190,23 @@ enum {
IIC7_0, IIC7_1, IIC7_2, IIC7_3,
IIC8_0, IIC8_1, IIC8_2, IIC8_3,
IIC9_0, IIC9_1, IIC9_2, IIC9_3,
- PCIINTA,
- PCIE,
+ ONFICTL,
+ MMC1, MMC2,
+ ECCU,
+ PCIC,
+ G200,
+ RSPI,
SGPIO,
+ DMINT12, DMINT13, DMINT14, DMINT15, DMINT16, DMINT17, DMINT18, DMINT19,
+ DMINT20, DMINT21, DMINT22, DMINT23,
+ DDRECC,
+ TSIP,
+ PCIE_BRIDGE,
+ WDT0B, WDT1B, WDT2B, WDT3B, WDT4B, WDT5B, WDT6B, WDT7B, WDT8B,
+ GETHER0, GETHER1, GETHER2,
+ PBIA, PBIB, PBIC,
+ DMAE2, DMAE3,
+ SERMUX2, SERMUX3,
/* interrupt groups */
@@ -221,19 +219,18 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(DVC, 0x4e0),
INTC_VECT(IRQ8, 0x500), INTC_VECT(IRQ9, 0x520),
INTC_VECT(IRQ10, 0x540),
- INTC_VECT(WDT0, 0x560),
INTC_VECT(TMU0, 0x580), INTC_VECT(TMU1, 0x5a0),
INTC_VECT(TMU2, 0x5c0), INTC_VECT(TMU2_TICPI, 0x5e0),
INTC_VECT(HUDI, 0x600),
INTC_VECT(ARC4, 0x620),
- INTC_VECT(DMAC0, 0x640), INTC_VECT(DMAC0, 0x660),
- INTC_VECT(DMAC0, 0x680), INTC_VECT(DMAC0, 0x6a0),
- INTC_VECT(DMAC0, 0x6c0),
+ INTC_VECT(DMAC0_5, 0x640), INTC_VECT(DMAC0_5, 0x660),
+ INTC_VECT(DMAC0_5, 0x680), INTC_VECT(DMAC0_5, 0x6a0),
+ INTC_VECT(DMAC0_5, 0x6c0),
INTC_VECT(IRQ11, 0x6e0),
INTC_VECT(SCIF2, 0x700), INTC_VECT(SCIF2, 0x720),
INTC_VECT(SCIF2, 0x740), INTC_VECT(SCIF2, 0x760),
- INTC_VECT(DMAC0, 0x780), INTC_VECT(DMAC0, 0x7a0),
- INTC_VECT(DMAC1_6, 0x7c0), INTC_VECT(DMAC1_6, 0x7e0),
+ INTC_VECT(DMAC0_5, 0x780), INTC_VECT(DMAC0_5, 0x7a0),
+ INTC_VECT(DMAC6_7, 0x7c0), INTC_VECT(DMAC6_7, 0x7e0),
INTC_VECT(USB0, 0x840),
INTC_VECT(IRQ12, 0x880),
INTC_VECT(JMC, 0x8a0),
@@ -242,7 +239,6 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(USB1, 0x920),
INTC_VECT(TMR01, 0xa00), INTC_VECT(TMR23, 0xa20),
INTC_VECT(TMR45, 0xa40),
- INTC_VECT(WDT1, 0xa60),
INTC_VECT(FRT, 0xa80),
INTC_VECT(LPC, 0xaa0), INTC_VECT(LPC, 0xac0),
INTC_VECT(LPC, 0xae0), INTC_VECT(LPC, 0xb00),
@@ -250,14 +246,14 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(SCIF0, 0xb40), INTC_VECT(SCIF1, 0xb60),
INTC_VECT(SCIF3, 0xb80), INTC_VECT(SCIF3, 0xba0),
INTC_VECT(SCIF3, 0xbc0), INTC_VECT(SCIF3, 0xbe0),
- INTC_VECT(PECI0I, 0xc00), INTC_VECT(PECI1I, 0xc20),
- INTC_VECT(PECI2I, 0xc40),
+ INTC_VECT(PECI0, 0xc00), INTC_VECT(PECI1, 0xc20),
+ INTC_VECT(PECI2, 0xc40),
INTC_VECT(IRQ15, 0xc60),
INTC_VECT(ETHERC, 0xc80), INTC_VECT(ETHERC, 0xca0),
INTC_VECT(SPI0, 0xcc0),
INTC_VECT(ADC1, 0xce0),
- INTC_VECT(DMAC1_8, 0xd00), INTC_VECT(DMAC1_8, 0xd20),
- INTC_VECT(DMAC1_8, 0xd40), INTC_VECT(DMAC1_8, 0xd60),
+ INTC_VECT(DMAC8_11, 0xd00), INTC_VECT(DMAC8_11, 0xd20),
+ INTC_VECT(DMAC8_11, 0xd40), INTC_VECT(DMAC8_11, 0xd60),
INTC_VECT(SIM, 0xd80), INTC_VECT(SIM, 0xda0),
INTC_VECT(SIM, 0xdc0), INTC_VECT(SIM, 0xde0),
INTC_VECT(TMU3, 0xe00), INTC_VECT(TMU4, 0xe20),
@@ -278,17 +274,47 @@ static struct intc_vect vectors[] __initdata = {
INTC_VECT(IIC5_0, 0x1860), INTC_VECT(IIC5_1, 0x1880),
INTC_VECT(IIC5_2, 0x18a0), INTC_VECT(IIC5_3, 0x18c0),
INTC_VECT(IIC6_0, 0x18e0), INTC_VECT(IIC6_1, 0x1900),
- INTC_VECT(IIC6_2, 0x1920), INTC_VECT(IIC6_3, 0x1980),
+ INTC_VECT(IIC6_2, 0x1920),
+ INTC_VECT(ONFICTL, 0x1960),
+ INTC_VECT(IIC6_3, 0x1980),
INTC_VECT(IIC7_0, 0x19a0), INTC_VECT(IIC7_1, 0x1a00),
INTC_VECT(IIC7_2, 0x1a20), INTC_VECT(IIC7_3, 0x1a40),
INTC_VECT(IIC8_0, 0x1a60), INTC_VECT(IIC8_1, 0x1a80),
INTC_VECT(IIC8_2, 0x1aa0), INTC_VECT(IIC8_3, 0x1b40),
INTC_VECT(IIC9_0, 0x1b60), INTC_VECT(IIC9_1, 0x1b80),
INTC_VECT(IIC9_2, 0x1c00), INTC_VECT(IIC9_3, 0x1c20),
- INTC_VECT(PCIINTA, 0x1ce0),
- INTC_VECT(PCIE, 0x1e00),
- INTC_VECT(SGPIO, 0x1f80),
- INTC_VECT(SGPIO, 0x1fa0),
+ INTC_VECT(MMC1, 0x1c60), INTC_VECT(MMC2, 0x1c80),
+ INTC_VECT(ECCU, 0x1cc0),
+ INTC_VECT(PCIC, 0x1ce0),
+ INTC_VECT(G200, 0x1d00),
+ INTC_VECT(RSPI, 0x1d80), INTC_VECT(RSPI, 0x1da0),
+ INTC_VECT(RSPI, 0x1dc0), INTC_VECT(RSPI, 0x1de0),
+ INTC_VECT(PECI3, 0x1ec0), INTC_VECT(PECI4, 0x1ee0),
+ INTC_VECT(PECI5, 0x1f00),
+ INTC_VECT(SGPIO, 0x1f80), INTC_VECT(SGPIO, 0x1fa0),
+ INTC_VECT(SGPIO, 0x1fc0),
+ INTC_VECT(DMINT12, 0x2400), INTC_VECT(DMINT13, 0x2420),
+ INTC_VECT(DMINT14, 0x2440), INTC_VECT(DMINT15, 0x2460),
+ INTC_VECT(DMINT16, 0x2480), INTC_VECT(DMINT17, 0x24e0),
+ INTC_VECT(DMINT18, 0x2500), INTC_VECT(DMINT19, 0x2520),
+ INTC_VECT(DMINT20, 0x2540), INTC_VECT(DMINT21, 0x2560),
+ INTC_VECT(DMINT22, 0x2580), INTC_VECT(DMINT23, 0x2600),
+ INTC_VECT(DDRECC, 0x2620),
+ INTC_VECT(TSIP, 0x2640),
+ INTC_VECT(PCIE_BRIDGE, 0x27c0),
+ INTC_VECT(WDT0B, 0x2800), INTC_VECT(WDT1B, 0x2820),
+ INTC_VECT(WDT2B, 0x2840), INTC_VECT(WDT3B, 0x2860),
+ INTC_VECT(WDT4B, 0x2880), INTC_VECT(WDT5B, 0x28a0),
+ INTC_VECT(WDT6B, 0x28c0), INTC_VECT(WDT7B, 0x28e0),
+ INTC_VECT(WDT8B, 0x2900),
+ INTC_VECT(GETHER0, 0x2960), INTC_VECT(GETHER1, 0x2980),
+ INTC_VECT(GETHER2, 0x29a0),
+ INTC_VECT(PBIA, 0x2a00), INTC_VECT(PBIB, 0x2a20),
+ INTC_VECT(PBIC, 0x2a40),
+ INTC_VECT(DMAE2, 0x2a60), INTC_VECT(DMAE3, 0x2a80),
+ INTC_VECT(SERMUX2, 0x2aa0), INTC_VECT(SERMUX3, 0x2b40),
+ INTC_VECT(LPC5, 0x2b60), INTC_VECT(LPC6, 0x2b80),
+ INTC_VECT(LPC7, 0x2c00), INTC_VECT(LPC8, 0x2c20),
};
static struct intc_group groups[] __initdata = {
@@ -312,31 +338,45 @@ static struct intc_mask_reg mask_registers[] __initdata = {
{ 0xffd40038, 0xffd4003c, 32, /* INT2MSKR / INT2MSKCR */
{ 0, 0, 0, 0, 0, 0, 0, 0,
- 0, DMAC1_8, 0, PECI0I, LPC, FRT, WDT1, TMR45,
- TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0,
- HUDI, 0, WDT0, SCIF3, SCIF2, SDHI, TMU345, TMU012
+ 0, DMAC8_11, 0, PECI0, LPC, FRT, 0, TMR45,
+ TMR23, TMR01, 0, 0, 0, 0, 0, DMAC0_5,
+ HUDI, 0, 0, SCIF3, SCIF2, SDHI, TMU345, TMU012
} },
{ 0xffd400d0, 0xffd400d4, 32, /* INT2MSKR1 / INT2MSKCR1 */
{ IRQ15, IRQ14, IRQ13, IRQ12, IRQ11, IRQ10, SCIF4, ETHERC,
IRQ9, IRQ8, SCIF1, SCIF0, USB0, 0, 0, USB1,
- ADC1, 0, DMAC1_6, ADC0, SPI0, SIM, PECI2I, PECI1I,
+ ADC1, 0, DMAC6_7, ADC0, SPI0, SIM, PECI2, PECI1,
ARC4, 0, SPI1, JMC, 0, 0, 0, DVC
} },
{ 0xffd10038, 0xffd1003c, 32, /* INT2MSKR2 / INT2MSKCR2 */
- { IIC4_1, IIC4_2, IIC5_0, 0, 0, 0, SGPIO, 0,
- 0, 0, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
+ { IIC4_1, IIC4_2, IIC5_0, ONFICTL, 0, 0, SGPIO, 0,
+ 0, G200, 0, IIC9_2, IIC8_2, IIC8_1, IIC8_0, IIC7_3,
IIC7_2, IIC7_1, IIC6_3, IIC0_0, IIC0_1, IIC0_2, IIC0_3, IIC3_1,
- IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, PCIE, IIC2_2
+ IIC2_3, 0, IIC2_1, IIC9_1, IIC3_3, IIC1_0, 0, IIC2_2
} },
- { 0xffd100d0, 0xff1400d4, 32, /* INT2MSKR3 / INT2MSKCR4 */
- { 0, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, 0, 0,
+ { 0xffd100d0, 0xffd100d4, 32, /* INT2MSKR3 / INT2MSKCR3 */
+ { MMC1, IIC6_1, IIC6_0, IIC5_1, IIC3_2, IIC2_0, PECI5, MMC2,
IIC1_3, IIC1_2, IIC9_0, IIC8_3, IIC4_3, IIC7_0, 0, IIC6_2,
- PCIINTA, 0, IIC4_0, 0, 0, 0, 0, IIC9_3,
+ PCIC, 0, IIC4_0, 0, ECCU, RSPI, 0, IIC9_3,
IIC3_0, 0, IIC5_3, IIC5_2, 0, 0, 0, IIC1_1
} },
+
+ { 0xffd20038, 0xffd2003c, 32, /* INT2MSKR4 / INT2MSKCR4 */
+ { WDT0B, WDT1B, WDT3B, GETHER0, 0, 0, 0, 0,
+ 0, 0, 0, LPC7, SERMUX2, DMAE3, DMAE2, PBIC,
+ PBIB, PBIA, GETHER1, DMINT12, DMINT13, DMINT14, DMINT15, TSIP,
+ DMINT23, 0, DMINT21, LPC6, 0, DMINT16, 0, DMINT22
+ } },
+
+ { 0xffd200d0, 0xffd200d4, 32, /* INT2MSKR5 / INT2MSKCR5 */
+ { 0, WDT8B, WDT7B, WDT4B, 0, DMINT20, 0, 0,
+ DMINT19, DMINT18, LPC5, SERMUX3, WDT2B, GETHER2, 0, 0,
+ 0, 0, PCIE_BRIDGE, 0, 0, 0, 0, LPC8,
+ DDRECC, 0, WDT6B, WDT5B, 0, 0, 0, DMINT17
+ } },
};
#define INTPRI 0xffd00010
@@ -372,6 +412,22 @@ static struct intc_mask_reg mask_registers[] __initdata = {
#define INT2PRI29 0xffd100b4
#define INT2PRI30 0xffd100b8
#define INT2PRI31 0xffd100bc
+#define INT2PRI32 0xffd20000
+#define INT2PRI33 0xffd20004
+#define INT2PRI34 0xffd20008
+#define INT2PRI35 0xffd2000c
+#define INT2PRI36 0xffd20010
+#define INT2PRI37 0xffd20014
+#define INT2PRI38 0xffd20018
+#define INT2PRI39 0xffd2001c
+#define INT2PRI40 0xffd200a0
+#define INT2PRI41 0xffd200a4
+#define INT2PRI42 0xffd200a8
+#define INT2PRI43 0xffd200ac
+#define INT2PRI44 0xffd200b0
+#define INT2PRI45 0xffd200b4
+#define INT2PRI46 0xffd200b8
+#define INT2PRI47 0xffd200bc
static struct intc_prio_reg prio_registers[] __initdata = {
{ INTPRI, 0, 32, 4, { IRQ0, IRQ1, IRQ2, IRQ3,
@@ -379,39 +435,61 @@ static struct intc_prio_reg prio_registers[] __initdata = {
{ INT2PRI0, 0, 32, 8, { TMU0, TMU1, TMU2, TMU2_TICPI } },
{ INT2PRI1, 0, 32, 8, { TMU3, TMU4, TMU5, SDHI } },
- { INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, WDT0, IRQ8 } },
- { INT2PRI3, 0, 32, 8, { HUDI, DMAC0, ADC0, IRQ9 } },
+ { INT2PRI2, 0, 32, 8, { SCIF2, SCIF3, 0, IRQ8 } },
+ { INT2PRI3, 0, 32, 8, { HUDI, DMAC0_5, ADC0, IRQ9 } },
{ INT2PRI4, 0, 32, 8, { IRQ10, 0, TMR01, TMR23 } },
- { INT2PRI5, 0, 32, 8, { TMR45, WDT1, FRT, LPC } },
- { INT2PRI6, 0, 32, 8, { PECI0I, ETHERC, DMAC1_8, 0 } },
+ { INT2PRI5, 0, 32, 8, { TMR45, 0, FRT, LPC } },
+ { INT2PRI6, 0, 32, 8, { PECI0, ETHERC, DMAC8_11, 0 } },
{ INT2PRI7, 0, 32, 8, { SCIF4, 0, IRQ11, IRQ12 } },
{ INT2PRI8, 0, 32, 8, { 0, 0, 0, DVC } },
{ INT2PRI9, 0, 32, 8, { ARC4, 0, SPI1, JMC } },
- { INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2I, PECI1I } },
- { INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC1_6, IRQ14 } },
+ { INT2PRI10, 0, 32, 8, { SPI0, SIM, PECI2, PECI1 } },
+ { INT2PRI11, 0, 32, 8, { ADC1, IRQ13, DMAC6_7, IRQ14 } },
{ INT2PRI12, 0, 32, 8, { USB0, 0, IRQ15, USB1 } },
{ INT2PRI13, 0, 32, 8, { 0, 0, SCIF1, SCIF0 } },
{ INT2PRI16, 0, 32, 8, { IIC2_2, 0, 0, 0 } },
- { INT2PRI17, 0, 32, 8, { PCIE, 0, 0, IIC1_0 } },
+ { INT2PRI17, 0, 32, 8, { 0, 0, 0, IIC1_0 } },
{ INT2PRI18, 0, 32, 8, { IIC3_3, IIC9_1, IIC2_1, IIC1_2 } },
{ INT2PRI19, 0, 32, 8, { IIC2_3, IIC3_1, 0, IIC1_3 } },
{ INT2PRI20, 0, 32, 8, { IIC2_0, IIC6_3, IIC7_1, IIC7_2 } },
{ INT2PRI21, 0, 32, 8, { IIC7_3, IIC8_0, IIC8_1, IIC8_2 } },
- { INT2PRI22, 0, 32, 8, { IIC9_2, 0, 0, 0 } },
- { INT2PRI23, 0, 32, 8, { 0, SGPIO, IIC3_2, IIC5_1 } },
- { INT2PRI24, 0, 32, 8, { 0, 0, 0, IIC1_1 } },
+ { INT2PRI22, 0, 32, 8, { IIC9_2, MMC2, G200, 0 } },
+ { INT2PRI23, 0, 32, 8, { PECI5, SGPIO, IIC3_2, IIC5_1 } },
+ { INT2PRI24, 0, 32, 8, { PECI4, PECI3, 0, IIC1_1 } },
{ INT2PRI25, 0, 32, 8, { IIC3_0, 0, IIC5_3, IIC5_2 } },
- { INT2PRI26, 0, 32, 8, { 0, 0, 0, IIC9_3 } },
- { INT2PRI27, 0, 32, 8, { PCIINTA, IIC6_0, IIC4_0, IIC6_1 } },
- { INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, 0, IIC6_2 } },
+ { INT2PRI26, 0, 32, 8, { ECCU, RSPI, 0, IIC9_3 } },
+ { INT2PRI27, 0, 32, 8, { PCIC, IIC6_0, IIC4_0, IIC6_1 } },
+ { INT2PRI28, 0, 32, 8, { IIC4_3, IIC7_0, MMC1, IIC6_2 } },
{ INT2PRI29, 0, 32, 8, { 0, 0, IIC9_0, IIC8_3 } },
- { INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, 0 } },
+ { INT2PRI30, 0, 32, 8, { IIC4_1, IIC4_2, IIC5_0, ONFICTL } },
{ INT2PRI31, 0, 32, 8, { IIC0_0, IIC0_1, IIC0_2, IIC0_3 } },
+ { INT2PRI32, 0, 32, 8, { DMINT22, 0, 0, 0 } },
+ { INT2PRI33, 0, 32, 8, { 0, 0, 0, DMINT16 } },
+ { INT2PRI34, 0, 32, 8, { 0, LPC6, DMINT21, DMINT18 } },
+ { INT2PRI35, 0, 32, 8, { DMINT23, TSIP, 0, DMINT19 } },
+ { INT2PRI36, 0, 32, 8, { DMINT20, GETHER1, PBIA, PBIB } },
+ { INT2PRI37, 0, 32, 8, { PBIC, DMAE2, DMAE3, SERMUX2 } },
+ { INT2PRI38, 0, 32, 8, { LPC7, 0, 0, 0 } },
+ { INT2PRI39, 0, 32, 8, { 0, 0, 0, WDT4B } },
+ { INT2PRI40, 0, 32, 8, { 0, 0, 0, DMINT17 } },
+ { INT2PRI41, 0, 32, 8, { DDRECC, 0, WDT6B, WDT5B } },
+ { INT2PRI42, 0, 32, 8, { 0, 0, 0, LPC8 } },
+ { INT2PRI43, 0, 32, 8, { 0, WDT7B, PCIE_BRIDGE, WDT8B } },
+ { INT2PRI44, 0, 32, 8, { WDT2B, GETHER2, 0, 0 } },
+ { INT2PRI45, 0, 32, 8, { 0, 0, LPC5, SERMUX3 } },
+ { INT2PRI46, 0, 32, 8, { WDT0B, WDT1B, WDT3B, GETHER0 } },
+ { INT2PRI47, 0, 32, 8, { DMINT12, DMINT13, DMINT14, DMINT15 } },
+};
+
+static struct intc_sense_reg sense_registers_irq8to15[] __initdata = {
+ { 0xffd100f8, 32, 2, /* ICR2 */ { IRQ15, IRQ14, IRQ13, IRQ12,
+ IRQ11, IRQ10, IRQ9, IRQ8 } },
};
static DECLARE_INTC_DESC(intc_desc, "sh7757", vectors, groups,
- mask_registers, prio_registers, NULL);
+ mask_registers, prio_registers,
+ sense_registers_irq8to15);
/* Support for external interrupt pins in IRQ mode */
static struct intc_vect vectors_irq0123[] __initdata = {
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index 4049d99f76e1..1208b09e95c3 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -20,9 +20,9 @@
DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
-static struct kprobe saved_current_opcode;
-static struct kprobe saved_next_opcode;
-static struct kprobe saved_next_opcode2;
+static DEFINE_PER_CPU(struct kprobe, saved_current_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode);
+static DEFINE_PER_CPU(struct kprobe, saved_next_opcode2);
#define OPCODE_JMP(x) (((x) & 0xF0FF) == 0x402b)
#define OPCODE_JSR(x) (((x) & 0xF0FF) == 0x400b)
@@ -102,16 +102,21 @@ int __kprobes kprobe_handle_illslot(unsigned long pc)
void __kprobes arch_remove_kprobe(struct kprobe *p)
{
- if (saved_next_opcode.addr != 0x0) {
+ struct kprobe *saved = &__get_cpu_var(saved_next_opcode);
+
+ if (saved->addr) {
arch_disarm_kprobe(p);
- arch_disarm_kprobe(&saved_next_opcode);
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
-
- if (saved_next_opcode2.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode2);
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
+ arch_disarm_kprobe(saved);
+
+ saved->addr = NULL;
+ saved->opcode = 0;
+
+ saved = &__get_cpu_var(saved_next_opcode2);
+ if (saved->addr) {
+ arch_disarm_kprobe(saved);
+
+ saved->addr = NULL;
+ saved->opcode = 0;
}
}
}
@@ -141,57 +146,59 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
*/
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
{
- kprobe_opcode_t *addr = NULL;
- saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
- addr = saved_current_opcode.addr;
+ __get_cpu_var(saved_current_opcode).addr = (kprobe_opcode_t *)regs->pc;
if (p != NULL) {
+ struct kprobe *op1, *op2;
+
arch_disarm_kprobe(p);
+ op1 = &__get_cpu_var(saved_next_opcode);
+ op2 = &__get_cpu_var(saved_next_opcode2);
+
if (OPCODE_JSR(p->opcode) || OPCODE_JMP(p->opcode)) {
unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
- saved_next_opcode.addr =
- (kprobe_opcode_t *) regs->regs[reg_nr];
+ op1->addr = (kprobe_opcode_t *) regs->regs[reg_nr];
} else if (OPCODE_BRA(p->opcode) || OPCODE_BSR(p->opcode)) {
unsigned long disp = (p->opcode & 0x0FFF);
- saved_next_opcode.addr =
+ op1->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
} else if (OPCODE_BRAF(p->opcode) || OPCODE_BSRF(p->opcode)) {
unsigned int reg_nr = ((p->opcode >> 8) & 0x000F);
- saved_next_opcode.addr =
+ op1->addr =
(kprobe_opcode_t *) (regs->pc + 4 +
regs->regs[reg_nr]);
} else if (OPCODE_RTS(p->opcode)) {
- saved_next_opcode.addr = (kprobe_opcode_t *) regs->pr;
+ op1->addr = (kprobe_opcode_t *) regs->pr;
} else if (OPCODE_BF(p->opcode) || OPCODE_BT(p->opcode)) {
unsigned long disp = (p->opcode & 0x00FF);
/* case 1 */
- saved_next_opcode.addr = p->addr + 1;
+ op1->addr = p->addr + 1;
/* case 2 */
- saved_next_opcode2.addr =
+ op2->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
- saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
- arch_arm_kprobe(&saved_next_opcode2);
+ op2->opcode = *(op2->addr);
+ arch_arm_kprobe(op2);
} else if (OPCODE_BF_S(p->opcode) || OPCODE_BT_S(p->opcode)) {
unsigned long disp = (p->opcode & 0x00FF);
/* case 1 */
- saved_next_opcode.addr = p->addr + 2;
+ op1->addr = p->addr + 2;
/* case 2 */
- saved_next_opcode2.addr =
+ op2->addr =
(kprobe_opcode_t *) (regs->pc + 4 + disp * 2);
- saved_next_opcode2.opcode = *(saved_next_opcode2.addr);
- arch_arm_kprobe(&saved_next_opcode2);
+ op2->opcode = *(op2->addr);
+ arch_arm_kprobe(op2);
} else {
- saved_next_opcode.addr = p->addr + 1;
+ op1->addr = p->addr + 1;
}
- saved_next_opcode.opcode = *(saved_next_opcode.addr);
- arch_arm_kprobe(&saved_next_opcode);
+ op1->opcode = *(op1->addr);
+ arch_arm_kprobe(op1);
}
}
@@ -376,21 +383,23 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
cur->post_handler(cur, regs, 0);
}
- if (saved_next_opcode.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode);
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
+ p = &__get_cpu_var(saved_next_opcode);
+ if (p->addr) {
+ arch_disarm_kprobe(p);
+ p->addr = NULL;
+ p->opcode = 0;
- addr = saved_current_opcode.addr;
- saved_current_opcode.addr = 0x0;
+ addr = __get_cpu_var(saved_current_opcode).addr;
+ __get_cpu_var(saved_current_opcode).addr = NULL;
p = get_kprobe(addr);
arch_arm_kprobe(p);
- if (saved_next_opcode2.addr != 0x0) {
- arch_disarm_kprobe(&saved_next_opcode2);
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
+ p = &__get_cpu_var(saved_next_opcode2);
+ if (p->addr) {
+ arch_disarm_kprobe(p);
+ p->addr = NULL;
+ p->opcode = 0;
}
}
@@ -572,14 +581,5 @@ static struct kprobe trampoline_p = {
int __init arch_init_kprobes(void)
{
- saved_next_opcode.addr = 0x0;
- saved_next_opcode.opcode = 0x0;
-
- saved_current_opcode.addr = 0x0;
- saved_current_opcode.opcode = 0x0;
-
- saved_next_opcode2.addr = 0x0;
- saved_next_opcode2.opcode = 0x0;
-
return register_kprobe(&trampoline_p);
}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
new file mode 100644
index 000000000000..0a05983633ca
--- /dev/null
+++ b/arch/sh/kernel/ptrace.c
@@ -0,0 +1,33 @@
+#include <linux/ptrace.h>
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name: the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (!strcmp(roff->name, name))
+ return roff->offset;
+ return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset: the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+ const struct pt_regs_offset *roff;
+ for (roff = regoffset_table; roff->name != NULL; roff++)
+ if (roff->offset == offset)
+ return roff->name;
+ return NULL;
+}
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 6c4bbba2a675..2cd42b58cb20 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -274,6 +274,33 @@ static int dspregs_active(struct task_struct *target,
}
#endif
+const struct pt_regs_offset regoffset_table[] = {
+ REGS_OFFSET_NAME(0),
+ REGS_OFFSET_NAME(1),
+ REGS_OFFSET_NAME(2),
+ REGS_OFFSET_NAME(3),
+ REGS_OFFSET_NAME(4),
+ REGS_OFFSET_NAME(5),
+ REGS_OFFSET_NAME(6),
+ REGS_OFFSET_NAME(7),
+ REGS_OFFSET_NAME(8),
+ REGS_OFFSET_NAME(9),
+ REGS_OFFSET_NAME(10),
+ REGS_OFFSET_NAME(11),
+ REGS_OFFSET_NAME(12),
+ REGS_OFFSET_NAME(13),
+ REGS_OFFSET_NAME(14),
+ REGS_OFFSET_NAME(15),
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(pr),
+ REG_OFFSET_NAME(sr),
+ REG_OFFSET_NAME(gbr),
+ REG_OFFSET_NAME(mach),
+ REG_OFFSET_NAME(macl),
+ REG_OFFSET_NAME(tra),
+ REG_OFFSET_END,
+};
+
/*
* These are our native regset flavours.
*/
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 5fd644da7f02..b97817016b6a 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -252,6 +252,85 @@ static int fpregs_active(struct task_struct *target,
}
#endif
+const struct pt_regs_offset regoffset_table[] = {
+ REG_OFFSET_NAME(pc),
+ REG_OFFSET_NAME(sr),
+ REG_OFFSET_NAME(syscall_nr),
+ REGS_OFFSET_NAME(0),
+ REGS_OFFSET_NAME(1),
+ REGS_OFFSET_NAME(2),
+ REGS_OFFSET_NAME(3),
+ REGS_OFFSET_NAME(4),
+ REGS_OFFSET_NAME(5),
+ REGS_OFFSET_NAME(6),
+ REGS_OFFSET_NAME(7),
+ REGS_OFFSET_NAME(8),
+ REGS_OFFSET_NAME(9),
+ REGS_OFFSET_NAME(10),
+ REGS_OFFSET_NAME(11),
+ REGS_OFFSET_NAME(12),
+ REGS_OFFSET_NAME(13),
+ REGS_OFFSET_NAME(14),
+ REGS_OFFSET_NAME(15),
+ REGS_OFFSET_NAME(16),
+ REGS_OFFSET_NAME(17),
+ REGS_OFFSET_NAME(18),
+ REGS_OFFSET_NAME(19),
+ REGS_OFFSET_NAME(20),
+ REGS_OFFSET_NAME(21),
+ REGS_OFFSET_NAME(22),
+ REGS_OFFSET_NAME(23),
+ REGS_OFFSET_NAME(24),
+ REGS_OFFSET_NAME(25),
+ REGS_OFFSET_NAME(26),
+ REGS_OFFSET_NAME(27),
+ REGS_OFFSET_NAME(28),
+ REGS_OFFSET_NAME(29),
+ REGS_OFFSET_NAME(30),
+ REGS_OFFSET_NAME(31),
+ REGS_OFFSET_NAME(32),
+ REGS_OFFSET_NAME(33),
+ REGS_OFFSET_NAME(34),
+ REGS_OFFSET_NAME(35),
+ REGS_OFFSET_NAME(36),
+ REGS_OFFSET_NAME(37),
+ REGS_OFFSET_NAME(38),
+ REGS_OFFSET_NAME(39),
+ REGS_OFFSET_NAME(40),
+ REGS_OFFSET_NAME(41),
+ REGS_OFFSET_NAME(42),
+ REGS_OFFSET_NAME(43),
+ REGS_OFFSET_NAME(44),
+ REGS_OFFSET_NAME(45),
+ REGS_OFFSET_NAME(46),
+ REGS_OFFSET_NAME(47),
+ REGS_OFFSET_NAME(48),
+ REGS_OFFSET_NAME(49),
+ REGS_OFFSET_NAME(50),
+ REGS_OFFSET_NAME(51),
+ REGS_OFFSET_NAME(52),
+ REGS_OFFSET_NAME(53),
+ REGS_OFFSET_NAME(54),
+ REGS_OFFSET_NAME(55),
+ REGS_OFFSET_NAME(56),
+ REGS_OFFSET_NAME(57),
+ REGS_OFFSET_NAME(58),
+ REGS_OFFSET_NAME(59),
+ REGS_OFFSET_NAME(60),
+ REGS_OFFSET_NAME(61),
+ REGS_OFFSET_NAME(62),
+ REGS_OFFSET_NAME(63),
+ TREGS_OFFSET_NAME(0),
+ TREGS_OFFSET_NAME(1),
+ TREGS_OFFSET_NAME(2),
+ TREGS_OFFSET_NAME(3),
+ TREGS_OFFSET_NAME(4),
+ TREGS_OFFSET_NAME(5),
+ TREGS_OFFSET_NAME(6),
+ TREGS_OFFSET_NAME(7),
+ REG_OFFSET_END,
+};
+
/*
* These are our native regset flavours.
*/
diff --git a/arch/sh/kernel/reboot.c b/arch/sh/kernel/reboot.c
index b1fca66bb92e..ca6a5ca64015 100644
--- a/arch/sh/kernel/reboot.c
+++ b/arch/sh/kernel/reboot.c
@@ -9,6 +9,7 @@
#include <asm/addrspace.h>
#include <asm/reboot.h>
#include <asm/system.h>
+#include <asm/tlbflush.h>
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
@@ -25,6 +26,9 @@ static void native_machine_restart(char * __unused)
{
local_irq_disable();
+ /* Destroy all of the TLBs in preparation for reset by MMU */
+ __flush_tlb_global();
+
/* Address error with SR.BL=1 first. */
trigger_address_error();
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 46f84de62469..82d46096e531 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -47,7 +47,6 @@ static pte_t *__get_pte_phys(unsigned long addr)
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
pgd = pgd_offset_k(addr);
if (pgd_none(*pgd)) {
@@ -67,8 +66,7 @@ static pte_t *__get_pte_phys(unsigned long addr)
return NULL;
}
- pte = pte_offset_kernel(pmd, addr);
- return pte;
+ return pte_offset_kernel(pmd, addr);
}
static void set_pte_phys(unsigned long addr, unsigned long phys, pgprot_t prot)
@@ -125,13 +123,45 @@ void __clear_fixmap(enum fixed_addresses idx, pgprot_t prot)
clear_pte_phys(address, prot);
}
+static pmd_t * __init one_md_table_init(pud_t *pud)
+{
+ if (pud_none(*pud)) {
+ pmd_t *pmd;
+
+ pmd = alloc_bootmem_pages(PAGE_SIZE);
+ pud_populate(&init_mm, pud, pmd);
+ BUG_ON(pmd != pmd_offset(pud, 0));
+ }
+
+ return pmd_offset(pud, 0);
+}
+
+static pte_t * __init one_page_table_init(pmd_t *pmd)
+{
+ if (pmd_none(*pmd)) {
+ pte_t *pte;
+
+ pte = alloc_bootmem_pages(PAGE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd, pte);
+ BUG_ON(pte != pte_offset_kernel(pmd, 0));
+ }
+
+ return pte_offset_kernel(pmd, 0);
+}
+
+static pte_t * __init page_table_kmap_check(pte_t *pte, pmd_t *pmd,
+ unsigned long vaddr, pte_t *lastpte)
+{
+ return pte;
+}
+
void __init page_table_range_init(unsigned long start, unsigned long end,
pgd_t *pgd_base)
{
pgd_t *pgd;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
+ pte_t *pte = NULL;
int i, j, k;
unsigned long vaddr;
@@ -144,19 +174,13 @@ void __init page_table_range_init(unsigned long start, unsigned long end,
for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) {
pud = (pud_t *)pgd;
for ( ; (j < PTRS_PER_PUD) && (vaddr != end); pud++, j++) {
-#ifdef __PAGETABLE_PMD_FOLDED
- pmd = (pmd_t *)pud;
-#else
- pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
- pud_populate(&init_mm, pud, pmd);
+ pmd = one_md_table_init(pud);
+#ifndef __PAGETABLE_PMD_FOLDED
pmd += k;
#endif
for (; (k < PTRS_PER_PMD) && (vaddr != end); pmd++, k++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- pmd_populate_kernel(&init_mm, pmd, pte);
- BUG_ON(pte != pte_offset_kernel(pmd, 0));
- }
+ pte = page_table_kmap_check(one_page_table_init(pmd),
+ pmd, vaddr, pte);
vaddr += PMD_SIZE;
}
k = 0;
diff --git a/arch/sh/mm/tlbflush_32.c b/arch/sh/mm/tlbflush_32.c
index 3fbe03ce8fe3..a6a20d6de4c0 100644
--- a/arch/sh/mm/tlbflush_32.c
+++ b/arch/sh/mm/tlbflush_32.c
@@ -119,3 +119,19 @@ void local_flush_tlb_mm(struct mm_struct *mm)
local_irq_restore(flags);
}
}
+
+void __flush_tlb_global(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ /*
+ * This is the most destructive of the TLB flushing options,
+ * and will tear down all of the UTLB/ITLB mappings, including
+ * wired entries.
+ */
+ __raw_writel(__raw_readl(MMUCR) | MMUCR_TI, MMUCR);
+
+ local_irq_restore(flags);
+}
diff --git a/arch/sh/mm/tlbflush_64.c b/arch/sh/mm/tlbflush_64.c
index 03db41cc1268..7f5810f5dfdc 100644
--- a/arch/sh/mm/tlbflush_64.c
+++ b/arch/sh/mm/tlbflush_64.c
@@ -455,6 +455,11 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
flush_tlb_all();
}
+void __flush_tlb_global(void)
+{
+ flush_tlb_all();
+}
+
void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
}
diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types
index b25aa554ee5e..9f56eb978024 100644
--- a/arch/sh/tools/mach-types
+++ b/arch/sh/tools/mach-types
@@ -52,6 +52,8 @@ MIGOR SH_MIGOR
RSK7201 SH_RSK7201
RSK7203 SH_RSK7203
AP325RXA SH_AP325RXA
+SH2007 SH_SH2007
+SH7757LCR SH_SH7757LCR
SH7763RDP SH_SH7763RDP
SH7785LCR SH_SH7785LCR
SH7785LCR_PT SH_SH7785LCR_PT
diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig
index 259e3fd50993..1dc07a0014c1 100644
--- a/arch/sparc/configs/sparc64_defconfig
+++ b/arch/sparc/configs/sparc64_defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.34-rc3
-# Sat Apr 3 15:49:56 2010
+# Linux kernel version: 2.6.34
+# Wed May 26 21:14:01 2010
#
CONFIG_64BIT=y
CONFIG_SPARC=y
@@ -107,10 +107,9 @@ CONFIG_PERF_COUNTERS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_PCI_QUIRKS=y
-CONFIG_SLUB_DEBUG=y
# CONFIG_COMPAT_BRK is not set
-# CONFIG_SLAB is not set
-CONFIG_SLUB=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
CONFIG_PROFILING=y
CONFIG_TRACEPOINTS=y
@@ -239,6 +238,7 @@ CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
CONFIG_SPARSEMEM_VMEMMAP=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
CONFIG_MIGRATION=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
@@ -351,6 +351,7 @@ CONFIG_IPV6_TUNNEL=m
# CONFIG_RDS is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set
CONFIG_VLAN_8021Q=m
@@ -367,6 +368,7 @@ CONFIG_VLAN_8021Q=m
# CONFIG_IEEE802154 is not set
# CONFIG_NET_SCHED is not set
# CONFIG_DCB is not set
+CONFIG_RPS=y
#
# Network testing
@@ -386,9 +388,14 @@ CONFIG_WIRELESS=y
#
# CFG80211 needs to be enabled for MAC80211
#
+
+#
+# Some wireless drivers require a rate control algorithm
+#
# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
#
# Device Drivers
@@ -658,6 +665,7 @@ CONFIG_PHYLIB=m
# CONFIG_NATIONAL_PHY is not set
# CONFIG_STE10XP is not set
# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
# CONFIG_MDIO_BITBANG is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=m
@@ -734,6 +742,8 @@ CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
+CONFIG_CHELSIO_T4_DEPENDS=y
+# CONFIG_CHELSIO_T4 is not set
# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGBEVF is not set
@@ -766,6 +776,7 @@ CONFIG_NIU=m
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -778,7 +789,6 @@ CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_MPPE=m
CONFIG_PPPOE=m
-# CONFIG_PPPOL2TP is not set
# CONFIG_SLIP is not set
CONFIG_SLHC=m
# CONFIG_NET_FC is not set
@@ -816,6 +826,7 @@ CONFIG_INPUT_KEYBOARD=y
CONFIG_KEYBOARD_ATKBD=y
# CONFIG_QT2160 is not set
CONFIG_KEYBOARD_LKKBD=m
+# CONFIG_KEYBOARD_TCA6416 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
@@ -840,6 +851,7 @@ CONFIG_MOUSE_SERIAL=y
# CONFIG_INPUT_TABLET is not set
# CONFIG_INPUT_TOUCHSCREEN is not set
CONFIG_INPUT_MISC=y
+# CONFIG_INPUT_AD714X is not set
CONFIG_INPUT_SPARCSPKR=y
# CONFIG_INPUT_ATI_REMOTE is not set
# CONFIG_INPUT_ATI_REMOTE2 is not set
@@ -848,6 +860,7 @@ CONFIG_INPUT_SPARCSPKR=y
# CONFIG_INPUT_YEALINK is not set
# CONFIG_INPUT_CM109 is not set
# CONFIG_INPUT_UINPUT is not set
+# CONFIG_INPUT_PCF8574 is not set
#
# Hardware I/O ports
@@ -871,6 +884,7 @@ CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
# CONFIG_DEVKMEM is not set
# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
# CONFIG_NOZOMI is not set
#
@@ -893,6 +907,8 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
# CONFIG_SERIAL_TIMBERDALE is not set
# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
CONFIG_UNIX98_PTYS=y
# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
# CONFIG_LEGACY_PTYS is not set
@@ -1306,11 +1322,14 @@ CONFIG_USB_HIDDEV=y
CONFIG_HID_A4TECH=y
CONFIG_HID_APPLE=y
CONFIG_HID_BELKIN=y
+# CONFIG_HID_CANDO is not set
CONFIG_HID_CHERRY=y
CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
CONFIG_HID_CYPRESS=y
CONFIG_HID_DRAGONRISE=y
# CONFIG_DRAGONRISE_FF is not set
+# CONFIG_HID_EGALAX is not set
CONFIG_HID_EZKEY=y
CONFIG_HID_KYE=y
CONFIG_HID_GYRATION=y
@@ -1328,7 +1347,9 @@ CONFIG_HID_ORTEK=y
CONFIG_HID_PANTHERLORD=y
# CONFIG_PANTHERLORD_FF is not set
CONFIG_HID_PETALYNX=y
+# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT_KONE is not set
CONFIG_HID_SAMSUNG=y
CONFIG_HID_SONY=y
# CONFIG_HID_STANTUM is not set
@@ -1342,6 +1363,7 @@ CONFIG_HID_THRUSTMASTER=y
# CONFIG_THRUSTMASTER_FF is not set
CONFIG_HID_ZEROPLUS=y
# CONFIG_ZEROPLUS_FF is not set
+# CONFIG_HID_ZYDACRON is not set
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -1356,7 +1378,6 @@ CONFIG_USB=y
# CONFIG_USB_DEVICEFS is not set
# CONFIG_USB_DEVICE_CLASS is not set
# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
# CONFIG_USB_MON is not set
# CONFIG_USB_WUSB is not set
# CONFIG_USB_WUSB_CBAF is not set
@@ -1521,10 +1542,6 @@ CONFIG_RTC_DRV_STARFIRE=y
# CONFIG_DMADEVICES is not set
# CONFIG_AUXDISPLAY is not set
# CONFIG_UIO is not set
-
-#
-# TI VLYNQ
-#
# CONFIG_STAGING is not set
#
@@ -1706,8 +1723,8 @@ CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
CONFIG_SCHEDSTATS=y
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_SLUB_DEBUG_ON is not set
-# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
# CONFIG_DEBUG_SPINLOCK is not set
@@ -1742,6 +1759,9 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
# CONFIG_DEBUG_PAGEALLOC is not set
CONFIG_NOP_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
@@ -1769,12 +1789,12 @@ CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_RING_BUFFER_BENCHMARK is not set
# CONFIG_DYNAMIC_DEBUG is not set
# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_DEBUG_DCFLUSH is not set
-# CONFIG_STACK_DEBUG is not set
# CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set
#
@@ -1895,6 +1915,7 @@ CONFIG_CRYPTO_DEFLATE=y
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_NIAGARA2 is not set
# CONFIG_CRYPTO_DEV_HIFN_795X is not set
CONFIG_BINARY_PRINTF=y
diff --git a/arch/sparc/include/asm/pgtable_32.h b/arch/sparc/include/asm/pgtable_32.h
index 77f906d8cc21..0ece77f47753 100644
--- a/arch/sparc/include/asm/pgtable_32.h
+++ b/arch/sparc/include/asm/pgtable_32.h
@@ -142,13 +142,12 @@ BTFIXUPDEF_CALL_CONST(unsigned long, pgd_page_vaddr, pgd_t)
#define pmd_page(pmd) BTFIXUP_CALL(pmd_page)(pmd)
#define pgd_page_vaddr(pgd) BTFIXUP_CALL(pgd_page_vaddr)(pgd)
-BTFIXUPDEF_SETHI(none_mask)
BTFIXUPDEF_CALL_CONST(int, pte_present, pte_t)
BTFIXUPDEF_CALL(void, pte_clear, pte_t *)
static inline int pte_none(pte_t pte)
{
- return !(pte_val(pte) & ~BTFIXUP_SETHI(none_mask));
+ return !pte_val(pte);
}
#define pte_present(pte) BTFIXUP_CALL(pte_present)(pte)
@@ -160,7 +159,7 @@ BTFIXUPDEF_CALL(void, pmd_clear, pmd_t *)
static inline int pmd_none(pmd_t pmd)
{
- return !(pmd_val(pmd) & ~BTFIXUP_SETHI(none_mask));
+ return !pmd_val(pmd);
}
#define pmd_bad(pmd) BTFIXUP_CALL(pmd_bad)(pmd)
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c
index 0ec92c8861dd..44faabc3c02c 100644
--- a/arch/sparc/kernel/perf_event.c
+++ b/arch/sparc/kernel/perf_event.c
@@ -657,6 +657,7 @@ static u64 maybe_change_configuration(struct cpu_hw_events *cpuc, u64 pcr)
cpuc->current_idx[i] = idx;
enc = perf_event_get_enc(cpuc->events[i]);
+ pcr &= ~mask_for_index(idx);
pcr |= event_encoding(enc, idx);
}
out:
diff --git a/arch/sparc/kernel/sun4d_irq.c b/arch/sparc/kernel/sun4d_irq.c
index ab036a72de5a..e11b4612dabb 100644
--- a/arch/sparc/kernel/sun4d_irq.c
+++ b/arch/sparc/kernel/sun4d_irq.c
@@ -183,7 +183,7 @@ void sun4d_free_irq(unsigned int irq, void *dev_id)
goto out_unlock;
}
- if (action && tmp)
+ if (tmp)
tmp->next = action->next;
else
*actionp = action->next;
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index f5f75a58e0b3..b0b43aa5e45a 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -2215,8 +2215,6 @@ void __init ld_mmu_srmmu(void)
BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pgd_page_vaddr, srmmu_pgd_page, BTFIXUPCALL_NORM);
- BTFIXUPSET_SETHI(none_mask, 0xF0000000);
-
BTFIXUPSET_CALL(pte_present, srmmu_pte_present, BTFIXUPCALL_NORM);
BTFIXUPSET_CALL(pte_clear, srmmu_pte_clear, BTFIXUPCALL_SWAPO0G0);
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index cf38846753dd..4289f90f8697 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -2087,9 +2087,6 @@ void __init ld_mmu_sun4c(void)
BTFIXUPSET_CALL(set_pte, sun4c_set_pte, BTFIXUPCALL_STO1O0);
- /* The 2.4.18 code does not set this on sun4c, how does it work? XXX */
- /* BTFIXUPSET_SETHI(none_mask, 0x00000000); */ /* Defaults to zero? */
-
BTFIXUPSET_CALL(pte_pfn, sun4c_pte_pfn, BTFIXUPCALL_NORM);
#if 0 /* PAGE_SHIFT <= 12 */ /* Eek. Investigate. XXX */
BTFIXUPSET_CALL(pmd_page, sun4c_pmd_page, BTFIXUPCALL_ANDNINT(PAGE_SIZE - 1));
diff --git a/arch/tile/Kbuild b/arch/tile/Kbuild
new file mode 100644
index 000000000000..a9b922716092
--- /dev/null
+++ b/arch/tile/Kbuild
@@ -0,0 +1,3 @@
+
+obj-y += kernel/
+obj-y += mm/
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
new file mode 100644
index 000000000000..1eb308cb711a
--- /dev/null
+++ b/arch/tile/Kconfig
@@ -0,0 +1,356 @@
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/config-language.txt.
+
+config MMU
+ def_bool y
+
+config GENERIC_CSUM
+ def_bool y
+
+config GENERIC_HARDIRQS
+ def_bool y
+
+config GENERIC_HARDIRQS_NO__DO_IRQ
+ def_bool y
+
+config GENERIC_IRQ_PROBE
+ def_bool y
+
+config GENERIC_PENDING_IRQ
+ def_bool y
+ depends on GENERIC_HARDIRQS && SMP
+
+config SEMAPHORE_SLEEPERS
+ def_bool y
+
+config HAVE_ARCH_ALLOC_REMAP
+ def_bool y
+
+config HAVE_SETUP_PER_CPU_AREA
+ def_bool y
+
+config NEED_PER_CPU_PAGE_FIRST_CHUNK
+ def_bool y
+
+config SYS_SUPPORTS_HUGETLBFS
+ def_bool y
+
+config GENERIC_TIME
+ def_bool y
+
+config GENERIC_CLOCKEVENTS
+ def_bool y
+
+# FIXME: tilegx can implement a more efficent rwsem.
+config RWSEM_GENERIC_SPINLOCK
+ def_bool y
+
+# We have a very flat architecture from a migration point of view,
+# so save boot time by presetting this (particularly useful on tile-sim).
+config DEFAULT_MIGRATION_COST
+ int
+ default "10000000"
+
+# We only support gcc 4.4 and above, so this should work.
+config ARCH_SUPPORTS_OPTIMIZED_INLINING
+ def_bool y
+
+config ARCH_PHYS_ADDR_T_64BIT
+ def_bool y
+
+config LOCKDEP_SUPPORT
+ def_bool y
+
+config STACKTRACE_SUPPORT
+ def_bool y
+ select STACKTRACE
+
+# We use discontigmem for now; at some point we may want to switch
+# to sparsemem (Tilera bug 7996).
+config ARCH_DISCONTIGMEM_ENABLE
+ def_bool y
+
+config ARCH_DISCONTIGMEM_DEFAULT
+ def_bool y
+
+config TRACE_IRQFLAGS_SUPPORT
+ def_bool y
+
+config STRICT_DEVMEM
+ def_bool y
+
+# SMP is required for Tilera Linux.
+config SMP
+ def_bool y
+
+# Allow checking for compile-time determined overflow errors in
+# copy_from_user(). There are still unprovable places in the
+# generic code as of 2.6.34, so this option is not really compatible
+# with -Werror, which is more useful in general.
+config DEBUG_COPY_FROM_USER
+ def_bool n
+
+config HVC_TILE
+ select HVC_DRIVER
+ def_bool y
+
+config TILE
+ def_bool y
+ select GENERIC_FIND_FIRST_BIT
+ select GENERIC_FIND_NEXT_BIT
+ select USE_GENERIC_SMP_HELPERS
+ select CC_OPTIMIZE_FOR_SIZE
+
+# FIXME: investigate whether we need/want these options.
+# select HAVE_IOREMAP_PROT
+# select HAVE_OPTPROBES
+# select HAVE_REGS_AND_STACK_ACCESS_API
+# select HAVE_HW_BREAKPOINT
+# select PERF_EVENTS
+# select HAVE_USER_RETURN_NOTIFIER
+# config NO_BOOTMEM
+# config ARCH_SUPPORTS_DEBUG_PAGEALLOC
+# config HUGETLB_PAGE_SIZE_VARIABLE
+
+
+mainmenu "Linux/TILE Kernel Configuration"
+
+# Please note: TILE-Gx support is not yet finalized; this is
+# the preliminary support. TILE-Gx drivers are only provided
+# with the alpha or beta test versions for Tilera customers.
+config TILEGX
+ depends on EXPERIMENTAL
+ bool "Building with TILE-Gx (64-bit) compiler and toolchain"
+
+config 64BIT
+ depends on TILEGX
+ def_bool y
+
+config ARCH_DEFCONFIG
+ string
+ default "arch/tile/configs/tile_defconfig" if !TILEGX
+ default "arch/tile/configs/tilegx_defconfig" if TILEGX
+
+source "init/Kconfig"
+
+menu "Tilera-specific configuration"
+
+config NR_CPUS
+ int "Maximum number of tiles (2-255)"
+ range 2 255
+ depends on SMP
+ default "64"
+ ---help---
+ Building with 64 is the recommended value, but a slightly
+ smaller kernel memory footprint results from using a smaller
+ value on chips with fewer tiles.
+
+source "kernel/time/Kconfig"
+
+source "kernel/Kconfig.hz"
+
+config KEXEC
+ bool "kexec system call"
+ ---help---
+ kexec is a system call that implements the ability to shutdown your
+ current kernel, and to start another kernel. It is like a reboot
+ but it is independent of the system firmware. It is used
+ to implement the "mboot" Tilera booter.
+
+ The name comes from the similarity to the exec system call.
+
+config COMPAT
+ bool "Support 32-bit TILE-Gx binaries in addition to 64-bit"
+ depends on TILEGX
+ select COMPAT_BINFMT_ELF
+ default y
+ ---help---
+ If enabled, the kernel will support running TILE-Gx binaries
+ that were built with the -m32 option.
+
+config SYSVIPC_COMPAT
+ def_bool y
+ depends on COMPAT && SYSVIPC
+
+# We do not currently support disabling HIGHMEM on tile64 and tilepro.
+config HIGHMEM
+ bool # "Support for more than 512 MB of RAM"
+ default !TILEGX
+ ---help---
+ Linux can use the full amount of RAM in the system by
+ default. However, the address space of TILE processors is
+ only 4 Gigabytes large. That means that, if you have a large
+ amount of physical memory, not all of it can be "permanently
+ mapped" by the kernel. The physical memory that's not
+ permanently mapped is called "high memory".
+
+ If you are compiling a kernel which will never run on a
+ machine with more than 512 MB total physical RAM, answer
+ "false" here. This will result in the kernel mapping all of
+ physical memory into the top 1 GB of virtual memory space.
+
+ If unsure, say "true".
+
+# We do not currently support disabling NUMA.
+config NUMA
+ bool # "NUMA Memory Allocation and Scheduler Support"
+ depends on SMP && DISCONTIGMEM
+ default y
+ ---help---
+ NUMA memory allocation is required for TILE processors
+ unless booting with memory striping enabled in the
+ hypervisor, or with only a single memory controller.
+ It is recommended that this option always be enabled.
+
+config NODES_SHIFT
+ int "Log base 2 of the max number of memory controllers"
+ default 2
+ depends on NEED_MULTIPLE_NODES
+ ---help---
+ By default, 2, i.e. 2^2 == 4 DDR2 controllers.
+ In a system with more controllers, this value should be raised.
+
+# Need 16MB areas to enable hugetlb
+# See build-time check in arch/tile/mm/init.c.
+config FORCE_MAX_ZONEORDER
+ int
+ default 9
+
+choice
+ depends on !TILEGX
+ prompt "Memory split" if EMBEDDED
+ default VMSPLIT_3G
+ ---help---
+ Select the desired split between kernel and user memory.
+
+ If the address range available to the kernel is less than the
+ physical memory installed, the remaining memory will be available
+ as "high memory". Accessing high memory is a little more costly
+ than low memory, as it needs to be mapped into the kernel first.
+ Note that increasing the kernel address space limits the range
+ available to user programs, making the address space there
+ tighter. Selecting anything other than the default 3G/1G split
+ will also likely make your kernel incompatible with binary-only
+ kernel modules.
+
+ If you are not absolutely sure what you are doing, leave this
+ option alone!
+
+ config VMSPLIT_375G
+ bool "3.75G/0.25G user/kernel split (no kernel networking)"
+ config VMSPLIT_35G
+ bool "3.5G/0.5G user/kernel split"
+ config VMSPLIT_3G
+ bool "3G/1G user/kernel split"
+ config VMSPLIT_3G_OPT
+ bool "3G/1G user/kernel split (for full 1G low memory)"
+ config VMSPLIT_2G
+ bool "2G/2G user/kernel split"
+ config VMSPLIT_1G
+ bool "1G/3G user/kernel split"
+endchoice
+
+config PAGE_OFFSET
+ hex
+ default 0xF0000000 if VMSPLIT_375G
+ default 0xE0000000 if VMSPLIT_35G
+ default 0xB0000000 if VMSPLIT_3G_OPT
+ default 0x80000000 if VMSPLIT_2G
+ default 0x40000000 if VMSPLIT_1G
+ default 0xC0000000
+
+source "mm/Kconfig"
+
+config CMDLINE_BOOL
+ bool "Built-in kernel command line"
+ default n
+ ---help---
+ Allow for specifying boot arguments to the kernel at
+ build time. On some systems (e.g. embedded ones), it is
+ necessary or convenient to provide some or all of the
+ kernel boot arguments with the kernel itself (that is,
+ to not rely on the boot loader to provide them.)
+
+ To compile command line arguments into the kernel,
+ set this option to 'Y', then fill in the
+ the boot arguments in CONFIG_CMDLINE.
+
+ Systems with fully functional boot loaders (e.g. mboot, or
+ if booting over PCI) should leave this option set to 'N'.
+
+config CMDLINE
+ string "Built-in kernel command string"
+ depends on CMDLINE_BOOL
+ default ""
+ ---help---
+ Enter arguments here that should be compiled into the kernel
+ image and used at boot time. If the boot loader provides a
+ command line at boot time, it is appended to this string to
+ form the full kernel command line, when the system boots.
+
+ However, you can use the CONFIG_CMDLINE_OVERRIDE option to
+ change this behavior.
+
+ In most cases, the command line (whether built-in or provided
+ by the boot loader) should specify the device for the root
+ file system.
+
+config CMDLINE_OVERRIDE
+ bool "Built-in command line overrides boot loader arguments"
+ default n
+ depends on CMDLINE_BOOL
+ ---help---
+ Set this option to 'Y' to have the kernel ignore the boot loader
+ command line, and use ONLY the built-in command line.
+
+ This is used to work around broken boot loaders. This should
+ be set to 'N' under normal conditions.
+
+config VMALLOC_RESERVE
+ hex
+ default 0x1000000
+
+config HARDWALL
+ bool "Hardwall support to allow access to user dynamic network"
+ default y
+
+endmenu # Tilera-specific configuration
+
+menu "Bus options"
+
+config NO_IOMEM
+ def_bool !PCI
+
+config NO_IOPORT
+ def_bool !PCI
+
+source "drivers/pci/Kconfig"
+
+source "drivers/pci/hotplug/Kconfig"
+
+endmenu
+
+menu "Executable file formats"
+
+# only elf supported
+config KCORE_ELF
+ def_bool y
+ depends on PROC_FS
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "arch/tile/Kconfig.debug"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
diff --git a/arch/tile/Kconfig.debug b/arch/tile/Kconfig.debug
new file mode 100644
index 000000000000..a81f0fbf7e60
--- /dev/null
+++ b/arch/tile/Kconfig.debug
@@ -0,0 +1,43 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+ bool "Early printk" if EMBEDDED && DEBUG_KERNEL
+ default y
+ help
+ Write kernel log output directly via the hypervisor console.
+
+ This is useful for kernel debugging when your machine crashes very
+ early before the console code is initialized. For normal operation
+ it is not recommended because it looks ugly and doesn't cooperate
+ with klogd/syslogd. You should normally N here,
+ unless you want to debug such a crash.
+
+config DEBUG_STACKOVERFLOW
+ bool "Check for stack overflows"
+ depends on DEBUG_KERNEL
+ help
+ This option will cause messages to be printed if free stack space
+ drops below a certain limit.
+
+config DEBUG_STACK_USAGE
+ bool "Stack utilization instrumentation"
+ depends on DEBUG_KERNEL
+ help
+ Enables the display of the minimum amount of free stack which each
+ task has ever had available in the sysrq-T and sysrq-P debug output.
+
+ This option will slow down process creation somewhat.
+
+config DEBUG_EXTRA_FLAGS
+ string "Additional compiler arguments when building with '-g'"
+ depends on DEBUG_INFO
+ default ""
+ help
+ Debug info can be large, and flags like
+ `-femit-struct-debug-baseonly' can reduce the kernel file
+ size and build time noticeably. Such flags are often
+ helpful if the main use of debug info is line number info.
+
+endmenu
diff --git a/arch/tile/Makefile b/arch/tile/Makefile
new file mode 100644
index 000000000000..07c4318c0629
--- /dev/null
+++ b/arch/tile/Makefile
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+
+ifeq ($(CROSS_COMPILE),)
+# If building with TILERA_ROOT set (i.e. using the Tilera Multicore
+# Development Environment) we can set CROSS_COMPILE based on that.
+ifdef TILERA_ROOT
+CROSS_COMPILE = $(TILERA_ROOT)/bin/tile-
+endif
+endif
+
+# If we're not cross-compiling, make sure we're on the right architecture.
+ifeq ($(CROSS_COMPILE),)
+HOST_ARCH = $(shell uname -m)
+ifneq ($(HOST_ARCH),$(ARCH))
+$(error Set TILERA_ROOT or CROSS_COMPILE when building $(ARCH) on $(HOST_ARCH))
+endif
+endif
+
+
+KBUILD_CFLAGS += $(CONFIG_DEBUG_EXTRA_FLAGS)
+
+LIBGCC_PATH := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
+
+# Provide the path to use for "make defconfig".
+KBUILD_DEFCONFIG := $(ARCH)_defconfig
+
+# Used as a file extension when useful, e.g. head_$(BITS).o
+# Not needed for (e.g.) "$(CC) -m32" since the compiler automatically
+# uses the right default anyway.
+export BITS
+ifeq ($(CONFIG_TILEGX),y)
+BITS := 64
+else
+BITS := 32
+endif
+
+head-y := arch/tile/kernel/head_$(BITS).o
+
+libs-y += arch/tile/lib/
+libs-y += $(LIBGCC_PATH)
+
+
+# See arch/tile/Kbuild for content of core part of the kernel
+core-y += arch/tile/
diff --git a/arch/tile/configs/tile_defconfig b/arch/tile/configs/tile_defconfig
new file mode 100644
index 000000000000..f34c70b46c64
--- /dev/null
+++ b/arch/tile/configs/tile_defconfig
@@ -0,0 +1,1290 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Thu Jun 3 13:20:05 2010
+#
+CONFIG_MMU=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_PENDING_IRQ=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_HAVE_ARCH_ALLOC_REMAP=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_DEFAULT_MIGRATION_COST=10000000
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_SMP=y
+CONFIG_WERROR=y
+# CONFIG_DEBUG_COPY_FROM_USER is not set
+CONFIG_HVC_TILE=y
+CONFIG_TILE=y
+# CONFIG_TILEGX is not set
+CONFIG_ARCH_DEFCONFIG="arch/tile/configs/tile_defconfig"
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=17
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS 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
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+# CONFIG_DEFAULT_CFQ is not set
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+
+#
+# Tilera-specific configuration
+#
+CONFIG_NR_CPUS=64
+CONFIG_HOMECACHE=y
+CONFIG_DATAPLANE=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+CONFIG_HIGHMEM=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=2
+CONFIG_FORCE_MAX_ZONEORDER=9
+# CONFIG_VMSPLIT_375G is not set
+# CONFIG_VMSPLIT_35G is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_3G_OPT is not set
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM_MANUAL=y
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CMDLINE_BOOL is not set
+# CONFIG_FEEDBACK_COLLECT is not set
+CONFIG_FEEDBACK_USE=""
+# CONFIG_HUGEVMAP is not set
+CONFIG_VMALLOC_RESERVE=0x1000000
+CONFIG_HARDWALL=y
+CONFIG_MEMPROF=y
+CONFIG_XGBE=y
+CONFIG_NET_TILE=y
+CONFIG_PSEUDO_NAPI=y
+CONFIG_TILEPCI_ENDP=y
+CONFIG_TILEPCI_HOST_SUBSET=m
+CONFIG_TILE_IDE_GPIO=y
+CONFIG_TILE_SOFTUART=y
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_NO_IOMEM is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=y
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=y
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+# CONFIG_PHANTOM is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+
+#
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+# CONFIG_IDE_GD_ATAPI is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+CONFIG_IDE_PROC_FS=y
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_PLATFORM is not set
+
+#
+# PCI IDE chipsets support
+#
+# CONFIG_BLK_DEV_GENERIC is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_JMICRON is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_IT8172 is not set
+# CONFIG_BLK_DEV_IT8213 is not set
+# CONFIG_BLK_DEV_IT821X is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_TC86C001 is not set
+# CONFIG_BLK_DEV_IDEDMA is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_BE2ISCSI is not set
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_HPSA is not set
+# CONFIG_SCSI_3W_9XXX is not set
+# CONFIG_SCSI_3W_SAS is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AACRAID is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_AIC79XX is not set
+# CONFIG_SCSI_AIC94XX is not set
+# CONFIG_SCSI_MVSAS is not set
+# CONFIG_SCSI_DPT_I2O is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_ARCMSR is not set
+# CONFIG_MEGARAID_NEWGEN is not set
+# CONFIG_MEGARAID_LEGACY is not set
+# CONFIG_MEGARAID_SAS is not set
+# CONFIG_SCSI_MPT2SAS is not set
+# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_FCOE is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_IPS is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_IPR is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=y
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+# CONFIG_SATA_AHCI is not set
+CONFIG_SATA_SIL24=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_SVW is not set
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SX4 is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR is not set
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_HPT366 is not set
+# CONFIG_PATA_HPT37X is not set
+# CONFIG_PATA_HPT3X2N is not set
+# CONFIG_PATA_HPT3X3 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_IT8213 is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_LEGACY is not set
+# CONFIG_PATA_TRIFLEX is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_OLDPIIX is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_OPTIDMA is not set
+# CONFIG_PATA_PDC2027X is not set
+# CONFIG_PATA_PDC_OLD is not set
+# CONFIG_PATA_RADISYS is not set
+# CONFIG_PATA_RDC is not set
+# CONFIG_PATA_RZ1000 is not set
+# CONFIG_PATA_SC1200 is not set
+# CONFIG_PATA_SERVERWORKS is not set
+# CONFIG_PATA_SIL680 is not set
+# CONFIG_PATA_SIS is not set
+# CONFIG_PATA_TOSHIBA is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# You can enable one or both FireWire driver stacks.
+#
+
+#
+# The newer stack is recommended.
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=y
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NET_FC is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_VMXNET3 is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_HVC_DRIVER=y
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_88PM860X is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+# CONFIG_RTC_INTF_SYSFS is not set
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+# CONFIG_INOTIFY is not set
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=m
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_RING_BUFFER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_SAMPLES is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
diff --git a/arch/tile/include/arch/abi.h b/arch/tile/include/arch/abi.h
new file mode 100644
index 000000000000..da8df5b9d914
--- /dev/null
+++ b/arch/tile/include/arch/abi.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/**
+ * @file
+ *
+ * ABI-related register definitions helpful when writing assembly code.
+ */
+
+#ifndef __ARCH_ABI_H__
+#define __ARCH_ABI_H__
+
+#include <arch/chip.h>
+
+/* Registers 0 - 55 are "normal", but some perform special roles. */
+
+#define TREG_FP 52 /**< Frame pointer. */
+#define TREG_TP 53 /**< Thread pointer. */
+#define TREG_SP 54 /**< Stack pointer. */
+#define TREG_LR 55 /**< Link to calling function PC. */
+
+/** Index of last normal general-purpose register. */
+#define TREG_LAST_GPR 55
+
+/* Registers 56 - 62 are "special" network registers. */
+
+#define TREG_SN 56 /**< Static network access. */
+#define TREG_IDN0 57 /**< IDN demux 0 access. */
+#define TREG_IDN1 58 /**< IDN demux 1 access. */
+#define TREG_UDN0 59 /**< UDN demux 0 access. */
+#define TREG_UDN1 60 /**< UDN demux 1 access. */
+#define TREG_UDN2 61 /**< UDN demux 2 access. */
+#define TREG_UDN3 62 /**< UDN demux 3 access. */
+
+/* Register 63 is the "special" zero register. */
+
+#define TREG_ZERO 63 /**< "Zero" register; always reads as "0". */
+
+
+/** By convention, this register is used to hold the syscall number. */
+#define TREG_SYSCALL_NR 10
+
+/** Name of register that holds the syscall number, for use in assembly. */
+#define TREG_SYSCALL_NR_NAME r10
+
+
+/**
+ * The ABI requires callers to allocate a caller state save area of
+ * this many bytes at the bottom of each stack frame.
+ */
+#ifdef __tile__
+#define C_ABI_SAVE_AREA_SIZE (2 * __SIZEOF_POINTER__)
+#endif
+
+/**
+ * The operand to an 'info' opcode directing the backtracer to not
+ * try to find the calling frame.
+ */
+#define INFO_OP_CANNOT_BACKTRACE 2
+
+#ifndef __ASSEMBLER__
+#if CHIP_WORD_SIZE() > 32
+
+/** Unsigned type that can hold a register. */
+typedef unsigned long long uint_reg_t;
+
+/** Signed type that can hold a register. */
+typedef long long int_reg_t;
+
+/** String prefix to use for printf(). */
+#define INT_REG_FMT "ll"
+
+#elif !defined(__LP64__) /* avoid confusion with LP64 cross-build tools */
+
+/** Unsigned type that can hold a register. */
+typedef unsigned long uint_reg_t;
+
+/** Signed type that can hold a register. */
+typedef long int_reg_t;
+
+/** String prefix to use for printf(). */
+#define INT_REG_FMT "l"
+
+#endif
+#endif /* __ASSEMBLER__ */
+
+#endif /* !__ARCH_ABI_H__ */
diff --git a/arch/tile/include/arch/chip.h b/arch/tile/include/arch/chip.h
new file mode 100644
index 000000000000..926d3db0e91e
--- /dev/null
+++ b/arch/tile/include/arch/chip.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#if __tile_chip__ == 0
+#include <arch/chip_tile64.h>
+#elif __tile_chip__ == 1
+#include <arch/chip_tilepro.h>
+#elif defined(__tilegx__)
+#include <arch/chip_tilegx.h>
+#else
+#error Unexpected Tilera chip type
+#endif
diff --git a/arch/tile/include/arch/chip_tile64.h b/arch/tile/include/arch/chip_tile64.h
new file mode 100644
index 000000000000..1246573be59e
--- /dev/null
+++ b/arch/tile/include/arch/chip_tile64.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/*
+ * @file
+ * Global header file.
+ * This header file specifies defines for TILE64.
+ */
+
+#ifndef __ARCH_CHIP_H__
+#define __ARCH_CHIP_H__
+
+/** Specify chip version.
+ * When possible, prefer the CHIP_xxx symbols below for future-proofing.
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip__ symbol.
+ */
+#define TILE_CHIP 0
+
+/** Specify chip revision.
+ * This provides for the case of a respin of a particular chip type;
+ * the normal value for this symbol is "0".
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip_rev__ symbol.
+ */
+#define TILE_CHIP_REV 0
+
+/** The name of this architecture. */
+#define CHIP_ARCH_NAME "tile64"
+
+/** The ELF e_machine type for binaries for this chip. */
+#define CHIP_ELF_TYPE() EM_TILE64
+
+/** The alternate ELF e_machine type for binaries for this chip. */
+#define CHIP_COMPAT_ELF_TYPE() 0x2506
+
+/** What is the native word size of the machine? */
+#define CHIP_WORD_SIZE() 32
+
+/** How many bits of a virtual address are used. Extra bits must be
+ * the sign extension of the low bits.
+ */
+#define CHIP_VA_WIDTH() 32
+
+/** How many bits are in a physical address? */
+#define CHIP_PA_WIDTH() 36
+
+/** Size of the L2 cache, in bytes. */
+#define CHIP_L2_CACHE_SIZE() 65536
+
+/** Log size of an L2 cache line in bytes. */
+#define CHIP_L2_LOG_LINE_SIZE() 6
+
+/** Size of an L2 cache line, in bytes. */
+#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
+
+/** Associativity of the L2 cache. */
+#define CHIP_L2_ASSOC() 2
+
+/** Size of the L1 data cache, in bytes. */
+#define CHIP_L1D_CACHE_SIZE() 8192
+
+/** Log size of an L1 data cache line in bytes. */
+#define CHIP_L1D_LOG_LINE_SIZE() 4
+
+/** Size of an L1 data cache line, in bytes. */
+#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
+
+/** Associativity of the L1 data cache. */
+#define CHIP_L1D_ASSOC() 2
+
+/** Size of the L1 instruction cache, in bytes. */
+#define CHIP_L1I_CACHE_SIZE() 8192
+
+/** Log size of an L1 instruction cache line in bytes. */
+#define CHIP_L1I_LOG_LINE_SIZE() 6
+
+/** Size of an L1 instruction cache line, in bytes. */
+#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
+
+/** Associativity of the L1 instruction cache. */
+#define CHIP_L1I_ASSOC() 1
+
+/** Stride with which flush instructions must be issued. */
+#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Stride with which inv instructions must be issued. */
+#define CHIP_INV_STRIDE() CHIP_L1D_LINE_SIZE()
+
+/** Stride with which finv instructions must be issued. */
+#define CHIP_FINV_STRIDE() CHIP_L1D_LINE_SIZE()
+
+/** Can the local cache coherently cache data that is homed elsewhere? */
+#define CHIP_HAS_COHERENT_LOCAL_CACHE() 0
+
+/** How many simultaneous outstanding victims can the L2 cache have? */
+#define CHIP_MAX_OUTSTANDING_VICTIMS() 2
+
+/** Does the TLB support the NC and NOALLOC bits? */
+#define CHIP_HAS_NC_AND_NOALLOC_BITS() 0
+
+/** Does the chip support hash-for-home caching? */
+#define CHIP_HAS_CBOX_HOME_MAP() 0
+
+/** Number of entries in the chip's home map tables. */
+/* #define CHIP_CBOX_HOME_MAP_SIZE() -- does not apply to chip 0 */
+
+/** Do uncacheable requests miss in the cache regardless of whether
+ * there is matching data? */
+#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 0
+
+/** Does the mf instruction wait for victims? */
+#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 1
+
+/** Does the chip have an "inv" instruction that doesn't also flush? */
+#define CHIP_HAS_INV() 0
+
+/** Does the chip have a "wh64" instruction? */
+#define CHIP_HAS_WH64() 0
+
+/** Does this chip have a 'dword_align' instruction? */
+#define CHIP_HAS_DWORD_ALIGN() 0
+
+/** Number of performance counters. */
+#define CHIP_PERFORMANCE_COUNTERS() 2
+
+/** Does this chip have auxiliary performance counters? */
+#define CHIP_HAS_AUX_PERF_COUNTERS() 0
+
+/** Is the CBOX_MSR1 SPR supported? */
+#define CHIP_HAS_CBOX_MSR1() 0
+
+/** Is the TILE_RTF_HWM SPR supported? */
+#define CHIP_HAS_TILE_RTF_HWM() 0
+
+/** Is the TILE_WRITE_PENDING SPR supported? */
+#define CHIP_HAS_TILE_WRITE_PENDING() 0
+
+/** Is the PROC_STATUS SPR supported? */
+#define CHIP_HAS_PROC_STATUS_SPR() 0
+
+/** Log of the number of mshims we have. */
+#define CHIP_LOG_NUM_MSHIMS() 2
+
+/** Are the bases of the interrupt vector areas fixed? */
+#define CHIP_HAS_FIXED_INTVEC_BASE() 1
+
+/** Are the interrupt masks split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_INTR_MASK() 1
+
+/** Is the cycle count split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_CYCLE() 1
+
+/** Does the chip have a static network? */
+#define CHIP_HAS_SN() 1
+
+/** Does the chip have a static network processor? */
+#define CHIP_HAS_SN_PROC() 1
+
+/** Size of the L1 static network processor instruction cache, in bytes. */
+#define CHIP_L1SNI_CACHE_SIZE() 2048
+
+/** Does the chip have DMA support in each tile? */
+#define CHIP_HAS_TILE_DMA() 1
+
+/** Does the chip have the second revision of the directly accessible
+ * dynamic networks? This encapsulates a number of characteristics,
+ * including the absence of the catch-all, the absence of inline message
+ * tags, the absence of support for network context-switching, and so on.
+ */
+#define CHIP_HAS_REV1_XDN() 0
+
+/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
+#define CHIP_HAS_CMPEXCH() 0
+
+/** Does the chip have memory-mapped I/O support? */
+#define CHIP_HAS_MMIO() 0
+
+/** Does the chip have post-completion interrupts? */
+#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 0
+
+/** Does the chip have native single step support? */
+#define CHIP_HAS_SINGLE_STEP() 0
+
+#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
+
+/** How many entries are present in the instruction TLB? */
+#define CHIP_ITLB_ENTRIES() 8
+
+/** How many entries are present in the data TLB? */
+#define CHIP_DTLB_ENTRIES() 16
+
+/** How many MAF entries does the XAUI shim have? */
+#define CHIP_XAUI_MAF_ENTRIES() 16
+
+/** Does the memory shim have a source-id table? */
+#define CHIP_HAS_MSHIM_SRCID_TABLE() 1
+
+/** Does the L1 instruction cache clear on reset? */
+#define CHIP_HAS_L1I_CLEAR_ON_RESET() 0
+
+/** Does the chip come out of reset with valid coordinates on all tiles?
+ * Note that if defined, this also implies that the upper left is 1,1.
+ */
+#define CHIP_HAS_VALID_TILE_COORD_RESET() 0
+
+/** Does the chip have unified packet formats? */
+#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 0
+
+/** Does the chip support write reordering? */
+#define CHIP_HAS_WRITE_REORDERING() 0
+
+/** Does the chip support Y-X routing as well as X-Y? */
+#define CHIP_HAS_Y_X_ROUTING() 0
+
+/** Is INTCTRL_3 managed with the correct MPL? */
+#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 0
+
+/** Is it possible to configure the chip to be big-endian? */
+#define CHIP_HAS_BIG_ENDIAN_CONFIG() 0
+
+/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
+#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
+
+/** Is the DIAG_TRACE_WAY SPR supported? */
+#define CHIP_HAS_DIAG_TRACE_WAY() 0
+
+/** Is the MEM_STRIPE_CONFIG SPR supported? */
+#define CHIP_HAS_MEM_STRIPE_CONFIG() 0
+
+/** Are the TLB_PERF SPRs supported? */
+#define CHIP_HAS_TLB_PERF() 0
+
+/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
+#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
+
+/** Does the chip support rev1 DMA packets? */
+#define CHIP_HAS_REV1_DMA_PACKETS() 0
+
+/** Does the chip have an IPI shim? */
+#define CHIP_HAS_IPI() 0
+
+#endif /* !__OPEN_SOURCE__ */
+#endif /* __ARCH_CHIP_H__ */
diff --git a/arch/tile/include/arch/chip_tilepro.h b/arch/tile/include/arch/chip_tilepro.h
new file mode 100644
index 000000000000..e864c47fc89c
--- /dev/null
+++ b/arch/tile/include/arch/chip_tilepro.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/*
+ * @file
+ * Global header file.
+ * This header file specifies defines for TILEPro.
+ */
+
+#ifndef __ARCH_CHIP_H__
+#define __ARCH_CHIP_H__
+
+/** Specify chip version.
+ * When possible, prefer the CHIP_xxx symbols below for future-proofing.
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip__ symbol.
+ */
+#define TILE_CHIP 1
+
+/** Specify chip revision.
+ * This provides for the case of a respin of a particular chip type;
+ * the normal value for this symbol is "0".
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip_rev__ symbol.
+ */
+#define TILE_CHIP_REV 0
+
+/** The name of this architecture. */
+#define CHIP_ARCH_NAME "tilepro"
+
+/** The ELF e_machine type for binaries for this chip. */
+#define CHIP_ELF_TYPE() EM_TILEPRO
+
+/** The alternate ELF e_machine type for binaries for this chip. */
+#define CHIP_COMPAT_ELF_TYPE() 0x2507
+
+/** What is the native word size of the machine? */
+#define CHIP_WORD_SIZE() 32
+
+/** How many bits of a virtual address are used. Extra bits must be
+ * the sign extension of the low bits.
+ */
+#define CHIP_VA_WIDTH() 32
+
+/** How many bits are in a physical address? */
+#define CHIP_PA_WIDTH() 36
+
+/** Size of the L2 cache, in bytes. */
+#define CHIP_L2_CACHE_SIZE() 65536
+
+/** Log size of an L2 cache line in bytes. */
+#define CHIP_L2_LOG_LINE_SIZE() 6
+
+/** Size of an L2 cache line, in bytes. */
+#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
+
+/** Associativity of the L2 cache. */
+#define CHIP_L2_ASSOC() 4
+
+/** Size of the L1 data cache, in bytes. */
+#define CHIP_L1D_CACHE_SIZE() 8192
+
+/** Log size of an L1 data cache line in bytes. */
+#define CHIP_L1D_LOG_LINE_SIZE() 4
+
+/** Size of an L1 data cache line, in bytes. */
+#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
+
+/** Associativity of the L1 data cache. */
+#define CHIP_L1D_ASSOC() 2
+
+/** Size of the L1 instruction cache, in bytes. */
+#define CHIP_L1I_CACHE_SIZE() 16384
+
+/** Log size of an L1 instruction cache line in bytes. */
+#define CHIP_L1I_LOG_LINE_SIZE() 6
+
+/** Size of an L1 instruction cache line, in bytes. */
+#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
+
+/** Associativity of the L1 instruction cache. */
+#define CHIP_L1I_ASSOC() 1
+
+/** Stride with which flush instructions must be issued. */
+#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Stride with which inv instructions must be issued. */
+#define CHIP_INV_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Stride with which finv instructions must be issued. */
+#define CHIP_FINV_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Can the local cache coherently cache data that is homed elsewhere? */
+#define CHIP_HAS_COHERENT_LOCAL_CACHE() 1
+
+/** How many simultaneous outstanding victims can the L2 cache have? */
+#define CHIP_MAX_OUTSTANDING_VICTIMS() 4
+
+/** Does the TLB support the NC and NOALLOC bits? */
+#define CHIP_HAS_NC_AND_NOALLOC_BITS() 1
+
+/** Does the chip support hash-for-home caching? */
+#define CHIP_HAS_CBOX_HOME_MAP() 1
+
+/** Number of entries in the chip's home map tables. */
+#define CHIP_CBOX_HOME_MAP_SIZE() 64
+
+/** Do uncacheable requests miss in the cache regardless of whether
+ * there is matching data? */
+#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 1
+
+/** Does the mf instruction wait for victims? */
+#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 0
+
+/** Does the chip have an "inv" instruction that doesn't also flush? */
+#define CHIP_HAS_INV() 1
+
+/** Does the chip have a "wh64" instruction? */
+#define CHIP_HAS_WH64() 1
+
+/** Does this chip have a 'dword_align' instruction? */
+#define CHIP_HAS_DWORD_ALIGN() 1
+
+/** Number of performance counters. */
+#define CHIP_PERFORMANCE_COUNTERS() 4
+
+/** Does this chip have auxiliary performance counters? */
+#define CHIP_HAS_AUX_PERF_COUNTERS() 1
+
+/** Is the CBOX_MSR1 SPR supported? */
+#define CHIP_HAS_CBOX_MSR1() 1
+
+/** Is the TILE_RTF_HWM SPR supported? */
+#define CHIP_HAS_TILE_RTF_HWM() 1
+
+/** Is the TILE_WRITE_PENDING SPR supported? */
+#define CHIP_HAS_TILE_WRITE_PENDING() 1
+
+/** Is the PROC_STATUS SPR supported? */
+#define CHIP_HAS_PROC_STATUS_SPR() 1
+
+/** Log of the number of mshims we have. */
+#define CHIP_LOG_NUM_MSHIMS() 2
+
+/** Are the bases of the interrupt vector areas fixed? */
+#define CHIP_HAS_FIXED_INTVEC_BASE() 1
+
+/** Are the interrupt masks split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_INTR_MASK() 1
+
+/** Is the cycle count split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_CYCLE() 1
+
+/** Does the chip have a static network? */
+#define CHIP_HAS_SN() 1
+
+/** Does the chip have a static network processor? */
+#define CHIP_HAS_SN_PROC() 0
+
+/** Size of the L1 static network processor instruction cache, in bytes. */
+/* #define CHIP_L1SNI_CACHE_SIZE() -- does not apply to chip 1 */
+
+/** Does the chip have DMA support in each tile? */
+#define CHIP_HAS_TILE_DMA() 1
+
+/** Does the chip have the second revision of the directly accessible
+ * dynamic networks? This encapsulates a number of characteristics,
+ * including the absence of the catch-all, the absence of inline message
+ * tags, the absence of support for network context-switching, and so on.
+ */
+#define CHIP_HAS_REV1_XDN() 0
+
+/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
+#define CHIP_HAS_CMPEXCH() 0
+
+/** Does the chip have memory-mapped I/O support? */
+#define CHIP_HAS_MMIO() 0
+
+/** Does the chip have post-completion interrupts? */
+#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 0
+
+/** Does the chip have native single step support? */
+#define CHIP_HAS_SINGLE_STEP() 0
+
+#ifndef __OPEN_SOURCE__ /* features only relevant to hypervisor-level code */
+
+/** How many entries are present in the instruction TLB? */
+#define CHIP_ITLB_ENTRIES() 16
+
+/** How many entries are present in the data TLB? */
+#define CHIP_DTLB_ENTRIES() 16
+
+/** How many MAF entries does the XAUI shim have? */
+#define CHIP_XAUI_MAF_ENTRIES() 32
+
+/** Does the memory shim have a source-id table? */
+#define CHIP_HAS_MSHIM_SRCID_TABLE() 0
+
+/** Does the L1 instruction cache clear on reset? */
+#define CHIP_HAS_L1I_CLEAR_ON_RESET() 1
+
+/** Does the chip come out of reset with valid coordinates on all tiles?
+ * Note that if defined, this also implies that the upper left is 1,1.
+ */
+#define CHIP_HAS_VALID_TILE_COORD_RESET() 1
+
+/** Does the chip have unified packet formats? */
+#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 1
+
+/** Does the chip support write reordering? */
+#define CHIP_HAS_WRITE_REORDERING() 1
+
+/** Does the chip support Y-X routing as well as X-Y? */
+#define CHIP_HAS_Y_X_ROUTING() 1
+
+/** Is INTCTRL_3 managed with the correct MPL? */
+#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 1
+
+/** Is it possible to configure the chip to be big-endian? */
+#define CHIP_HAS_BIG_ENDIAN_CONFIG() 1
+
+/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
+#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 1
+
+/** Is the DIAG_TRACE_WAY SPR supported? */
+#define CHIP_HAS_DIAG_TRACE_WAY() 1
+
+/** Is the MEM_STRIPE_CONFIG SPR supported? */
+#define CHIP_HAS_MEM_STRIPE_CONFIG() 1
+
+/** Are the TLB_PERF SPRs supported? */
+#define CHIP_HAS_TLB_PERF() 1
+
+/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
+#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 1
+
+/** Does the chip support rev1 DMA packets? */
+#define CHIP_HAS_REV1_DMA_PACKETS() 1
+
+/** Does the chip have an IPI shim? */
+#define CHIP_HAS_IPI() 0
+
+#endif /* !__OPEN_SOURCE__ */
+#endif /* __ARCH_CHIP_H__ */
diff --git a/arch/tile/include/arch/icache.h b/arch/tile/include/arch/icache.h
new file mode 100644
index 000000000000..5c87c9016338
--- /dev/null
+++ b/arch/tile/include/arch/icache.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+/**
+ * @file
+ *
+ * Support for invalidating bytes in the instruction
+ */
+
+#ifndef __ARCH_ICACHE_H__
+#define __ARCH_ICACHE_H__
+
+#include <arch/chip.h>
+
+
+/**
+ * Invalidate the instruction cache for the given range of memory.
+ *
+ * @param addr The start of memory to be invalidated.
+ * @param size The number of bytes to be invalidated.
+ * @param page_size The system's page size, typically the PAGE_SIZE constant
+ * in sys/page.h. This value must be a power of two no larger
+ * than the page containing the code to be invalidated. If the value
+ * is smaller than the actual page size, this function will still
+ * work, but may run slower than necessary.
+ */
+static __inline void
+invalidate_icache(const void* addr, unsigned long size,
+ unsigned long page_size)
+{
+ const unsigned long cache_way_size =
+ CHIP_L1I_CACHE_SIZE() / CHIP_L1I_ASSOC();
+ unsigned long max_useful_size;
+ const char* start, *end;
+ long num_passes;
+
+ if (__builtin_expect(size == 0, 0))
+ return;
+
+#ifdef __tilegx__
+ /* Limit the number of bytes visited to avoid redundant iterations. */
+ max_useful_size = (page_size < cache_way_size) ? page_size : cache_way_size;
+
+ /* No PA aliasing is possible, so one pass always suffices. */
+ num_passes = 1;
+#else
+ /* Limit the number of bytes visited to avoid redundant iterations. */
+ max_useful_size = cache_way_size;
+
+ /*
+ * Compute how many passes we need (we'll treat 0 as if it were 1).
+ * This works because we know the page size is a power of two.
+ */
+ num_passes = cache_way_size >> __builtin_ctzl(page_size);
+#endif
+
+ if (__builtin_expect(size > max_useful_size, 0))
+ size = max_useful_size;
+
+ /* Locate the first and last bytes to be invalidated. */
+ start = (const char *)((unsigned long)addr & -CHIP_L1I_LINE_SIZE());
+ end = (const char*)addr + size - 1;
+
+ __insn_mf();
+
+ do
+ {
+ const char* p;
+
+ for (p = start; p <= end; p += CHIP_L1I_LINE_SIZE())
+ __insn_icoh(p);
+
+ start += page_size;
+ end += page_size;
+ }
+ while (--num_passes > 0);
+
+ __insn_drain();
+}
+
+
+#endif /* __ARCH_ICACHE_H__ */
diff --git a/arch/tile/include/arch/interrupts.h b/arch/tile/include/arch/interrupts.h
new file mode 100644
index 000000000000..20f8f07d2de9
--- /dev/null
+++ b/arch/tile/include/arch/interrupts.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifdef __tilegx__
+#include <arch/interrupts_64.h>
+#else
+#include <arch/interrupts_32.h>
+#endif
diff --git a/arch/tile/include/arch/interrupts_32.h b/arch/tile/include/arch/interrupts_32.h
new file mode 100644
index 000000000000..9d0bfa7e59be
--- /dev/null
+++ b/arch/tile/include/arch/interrupts_32.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __ARCH_INTERRUPTS_H__
+#define __ARCH_INTERRUPTS_H__
+
+/** Mask for an interrupt. */
+#ifdef __ASSEMBLER__
+/* Note: must handle breaking interrupts into high and low words manually. */
+#define INT_MASK(intno) (1 << (intno))
+#else
+#define INT_MASK(intno) (1ULL << (intno))
+#endif
+
+
+/** Where a given interrupt executes */
+#define INTERRUPT_VECTOR(i, pl) (0xFC000000 + ((pl) << 24) + ((i) << 8))
+
+/** Where to store a vector for a given interrupt. */
+#define USER_INTERRUPT_VECTOR(i) INTERRUPT_VECTOR(i, 0)
+
+/** The base address of user-level interrupts. */
+#define USER_INTERRUPT_VECTOR_BASE INTERRUPT_VECTOR(0, 0)
+
+
+/** Additional synthetic interrupt. */
+#define INT_BREAKPOINT (63)
+
+#define INT_ITLB_MISS 0
+#define INT_MEM_ERROR 1
+#define INT_ILL 2
+#define INT_GPV 3
+#define INT_SN_ACCESS 4
+#define INT_IDN_ACCESS 5
+#define INT_UDN_ACCESS 6
+#define INT_IDN_REFILL 7
+#define INT_UDN_REFILL 8
+#define INT_IDN_COMPLETE 9
+#define INT_UDN_COMPLETE 10
+#define INT_SWINT_3 11
+#define INT_SWINT_2 12
+#define INT_SWINT_1 13
+#define INT_SWINT_0 14
+#define INT_UNALIGN_DATA 15
+#define INT_DTLB_MISS 16
+#define INT_DTLB_ACCESS 17
+#define INT_DMATLB_MISS 18
+#define INT_DMATLB_ACCESS 19
+#define INT_SNITLB_MISS 20
+#define INT_SN_NOTIFY 21
+#define INT_SN_FIREWALL 22
+#define INT_IDN_FIREWALL 23
+#define INT_UDN_FIREWALL 24
+#define INT_TILE_TIMER 25
+#define INT_IDN_TIMER 26
+#define INT_UDN_TIMER 27
+#define INT_DMA_NOTIFY 28
+#define INT_IDN_CA 29
+#define INT_UDN_CA 30
+#define INT_IDN_AVAIL 31
+#define INT_UDN_AVAIL 32
+#define INT_PERF_COUNT 33
+#define INT_INTCTRL_3 34
+#define INT_INTCTRL_2 35
+#define INT_INTCTRL_1 36
+#define INT_INTCTRL_0 37
+#define INT_BOOT_ACCESS 38
+#define INT_WORLD_ACCESS 39
+#define INT_I_ASID 40
+#define INT_D_ASID 41
+#define INT_DMA_ASID 42
+#define INT_SNI_ASID 43
+#define INT_DMA_CPL 44
+#define INT_SN_CPL 45
+#define INT_DOUBLE_FAULT 46
+#define INT_SN_STATIC_ACCESS 47
+#define INT_AUX_PERF_COUNT 48
+
+#define NUM_INTERRUPTS 49
+
+#define QUEUED_INTERRUPTS ( \
+ INT_MASK(INT_MEM_ERROR) | \
+ INT_MASK(INT_DMATLB_MISS) | \
+ INT_MASK(INT_DMATLB_ACCESS) | \
+ INT_MASK(INT_SNITLB_MISS) | \
+ INT_MASK(INT_SN_NOTIFY) | \
+ INT_MASK(INT_SN_FIREWALL) | \
+ INT_MASK(INT_IDN_FIREWALL) | \
+ INT_MASK(INT_UDN_FIREWALL) | \
+ INT_MASK(INT_TILE_TIMER) | \
+ INT_MASK(INT_IDN_TIMER) | \
+ INT_MASK(INT_UDN_TIMER) | \
+ INT_MASK(INT_DMA_NOTIFY) | \
+ INT_MASK(INT_IDN_CA) | \
+ INT_MASK(INT_UDN_CA) | \
+ INT_MASK(INT_IDN_AVAIL) | \
+ INT_MASK(INT_UDN_AVAIL) | \
+ INT_MASK(INT_PERF_COUNT) | \
+ INT_MASK(INT_INTCTRL_3) | \
+ INT_MASK(INT_INTCTRL_2) | \
+ INT_MASK(INT_INTCTRL_1) | \
+ INT_MASK(INT_INTCTRL_0) | \
+ INT_MASK(INT_BOOT_ACCESS) | \
+ INT_MASK(INT_WORLD_ACCESS) | \
+ INT_MASK(INT_I_ASID) | \
+ INT_MASK(INT_D_ASID) | \
+ INT_MASK(INT_DMA_ASID) | \
+ INT_MASK(INT_SNI_ASID) | \
+ INT_MASK(INT_DMA_CPL) | \
+ INT_MASK(INT_SN_CPL) | \
+ INT_MASK(INT_DOUBLE_FAULT) | \
+ INT_MASK(INT_AUX_PERF_COUNT) | \
+ 0)
+#define NONQUEUED_INTERRUPTS ( \
+ INT_MASK(INT_ITLB_MISS) | \
+ INT_MASK(INT_ILL) | \
+ INT_MASK(INT_GPV) | \
+ INT_MASK(INT_SN_ACCESS) | \
+ INT_MASK(INT_IDN_ACCESS) | \
+ INT_MASK(INT_UDN_ACCESS) | \
+ INT_MASK(INT_IDN_REFILL) | \
+ INT_MASK(INT_UDN_REFILL) | \
+ INT_MASK(INT_IDN_COMPLETE) | \
+ INT_MASK(INT_UDN_COMPLETE) | \
+ INT_MASK(INT_SWINT_3) | \
+ INT_MASK(INT_SWINT_2) | \
+ INT_MASK(INT_SWINT_1) | \
+ INT_MASK(INT_SWINT_0) | \
+ INT_MASK(INT_UNALIGN_DATA) | \
+ INT_MASK(INT_DTLB_MISS) | \
+ INT_MASK(INT_DTLB_ACCESS) | \
+ INT_MASK(INT_SN_STATIC_ACCESS) | \
+ 0)
+#define CRITICAL_MASKED_INTERRUPTS ( \
+ INT_MASK(INT_MEM_ERROR) | \
+ INT_MASK(INT_DMATLB_MISS) | \
+ INT_MASK(INT_DMATLB_ACCESS) | \
+ INT_MASK(INT_SNITLB_MISS) | \
+ INT_MASK(INT_SN_NOTIFY) | \
+ INT_MASK(INT_SN_FIREWALL) | \
+ INT_MASK(INT_IDN_FIREWALL) | \
+ INT_MASK(INT_UDN_FIREWALL) | \
+ INT_MASK(INT_TILE_TIMER) | \
+ INT_MASK(INT_IDN_TIMER) | \
+ INT_MASK(INT_UDN_TIMER) | \
+ INT_MASK(INT_DMA_NOTIFY) | \
+ INT_MASK(INT_IDN_CA) | \
+ INT_MASK(INT_UDN_CA) | \
+ INT_MASK(INT_IDN_AVAIL) | \
+ INT_MASK(INT_UDN_AVAIL) | \
+ INT_MASK(INT_PERF_COUNT) | \
+ INT_MASK(INT_INTCTRL_3) | \
+ INT_MASK(INT_INTCTRL_2) | \
+ INT_MASK(INT_INTCTRL_1) | \
+ INT_MASK(INT_INTCTRL_0) | \
+ INT_MASK(INT_AUX_PERF_COUNT) | \
+ 0)
+#define CRITICAL_UNMASKED_INTERRUPTS ( \
+ INT_MASK(INT_ITLB_MISS) | \
+ INT_MASK(INT_ILL) | \
+ INT_MASK(INT_GPV) | \
+ INT_MASK(INT_SN_ACCESS) | \
+ INT_MASK(INT_IDN_ACCESS) | \
+ INT_MASK(INT_UDN_ACCESS) | \
+ INT_MASK(INT_IDN_REFILL) | \
+ INT_MASK(INT_UDN_REFILL) | \
+ INT_MASK(INT_IDN_COMPLETE) | \
+ INT_MASK(INT_UDN_COMPLETE) | \
+ INT_MASK(INT_SWINT_3) | \
+ INT_MASK(INT_SWINT_2) | \
+ INT_MASK(INT_SWINT_1) | \
+ INT_MASK(INT_SWINT_0) | \
+ INT_MASK(INT_UNALIGN_DATA) | \
+ INT_MASK(INT_DTLB_MISS) | \
+ INT_MASK(INT_DTLB_ACCESS) | \
+ INT_MASK(INT_BOOT_ACCESS) | \
+ INT_MASK(INT_WORLD_ACCESS) | \
+ INT_MASK(INT_I_ASID) | \
+ INT_MASK(INT_D_ASID) | \
+ INT_MASK(INT_DMA_ASID) | \
+ INT_MASK(INT_SNI_ASID) | \
+ INT_MASK(INT_DMA_CPL) | \
+ INT_MASK(INT_SN_CPL) | \
+ INT_MASK(INT_DOUBLE_FAULT) | \
+ INT_MASK(INT_SN_STATIC_ACCESS) | \
+ 0)
+#define MASKABLE_INTERRUPTS ( \
+ INT_MASK(INT_MEM_ERROR) | \
+ INT_MASK(INT_IDN_REFILL) | \
+ INT_MASK(INT_UDN_REFILL) | \
+ INT_MASK(INT_IDN_COMPLETE) | \
+ INT_MASK(INT_UDN_COMPLETE) | \
+ INT_MASK(INT_DMATLB_MISS) | \
+ INT_MASK(INT_DMATLB_ACCESS) | \
+ INT_MASK(INT_SNITLB_MISS) | \
+ INT_MASK(INT_SN_NOTIFY) | \
+ INT_MASK(INT_SN_FIREWALL) | \
+ INT_MASK(INT_IDN_FIREWALL) | \
+ INT_MASK(INT_UDN_FIREWALL) | \
+ INT_MASK(INT_TILE_TIMER) | \
+ INT_MASK(INT_IDN_TIMER) | \
+ INT_MASK(INT_UDN_TIMER) | \
+ INT_MASK(INT_DMA_NOTIFY) | \
+ INT_MASK(INT_IDN_CA) | \
+ INT_MASK(INT_UDN_CA) | \
+ INT_MASK(INT_IDN_AVAIL) | \
+ INT_MASK(INT_UDN_AVAIL) | \
+ INT_MASK(INT_PERF_COUNT) | \
+ INT_MASK(INT_INTCTRL_3) | \
+ INT_MASK(INT_INTCTRL_2) | \
+ INT_MASK(INT_INTCTRL_1) | \
+ INT_MASK(INT_INTCTRL_0) | \
+ INT_MASK(INT_AUX_PERF_COUNT) | \
+ 0)
+#define UNMASKABLE_INTERRUPTS ( \
+ INT_MASK(INT_ITLB_MISS) | \
+ INT_MASK(INT_ILL) | \
+ INT_MASK(INT_GPV) | \
+ INT_MASK(INT_SN_ACCESS) | \
+ INT_MASK(INT_IDN_ACCESS) | \
+ INT_MASK(INT_UDN_ACCESS) | \
+ INT_MASK(INT_SWINT_3) | \
+ INT_MASK(INT_SWINT_2) | \
+ INT_MASK(INT_SWINT_1) | \
+ INT_MASK(INT_SWINT_0) | \
+ INT_MASK(INT_UNALIGN_DATA) | \
+ INT_MASK(INT_DTLB_MISS) | \
+ INT_MASK(INT_DTLB_ACCESS) | \
+ INT_MASK(INT_BOOT_ACCESS) | \
+ INT_MASK(INT_WORLD_ACCESS) | \
+ INT_MASK(INT_I_ASID) | \
+ INT_MASK(INT_D_ASID) | \
+ INT_MASK(INT_DMA_ASID) | \
+ INT_MASK(INT_SNI_ASID) | \
+ INT_MASK(INT_DMA_CPL) | \
+ INT_MASK(INT_SN_CPL) | \
+ INT_MASK(INT_DOUBLE_FAULT) | \
+ INT_MASK(INT_SN_STATIC_ACCESS) | \
+ 0)
+#define SYNC_INTERRUPTS ( \
+ INT_MASK(INT_ITLB_MISS) | \
+ INT_MASK(INT_ILL) | \
+ INT_MASK(INT_GPV) | \
+ INT_MASK(INT_SN_ACCESS) | \
+ INT_MASK(INT_IDN_ACCESS) | \
+ INT_MASK(INT_UDN_ACCESS) | \
+ INT_MASK(INT_IDN_REFILL) | \
+ INT_MASK(INT_UDN_REFILL) | \
+ INT_MASK(INT_IDN_COMPLETE) | \
+ INT_MASK(INT_UDN_COMPLETE) | \
+ INT_MASK(INT_SWINT_3) | \
+ INT_MASK(INT_SWINT_2) | \
+ INT_MASK(INT_SWINT_1) | \
+ INT_MASK(INT_SWINT_0) | \
+ INT_MASK(INT_UNALIGN_DATA) | \
+ INT_MASK(INT_DTLB_MISS) | \
+ INT_MASK(INT_DTLB_ACCESS) | \
+ INT_MASK(INT_SN_STATIC_ACCESS) | \
+ 0)
+#define NON_SYNC_INTERRUPTS ( \
+ INT_MASK(INT_MEM_ERROR) | \
+ INT_MASK(INT_DMATLB_MISS) | \
+ INT_MASK(INT_DMATLB_ACCESS) | \
+ INT_MASK(INT_SNITLB_MISS) | \
+ INT_MASK(INT_SN_NOTIFY) | \
+ INT_MASK(INT_SN_FIREWALL) | \
+ INT_MASK(INT_IDN_FIREWALL) | \
+ INT_MASK(INT_UDN_FIREWALL) | \
+ INT_MASK(INT_TILE_TIMER) | \
+ INT_MASK(INT_IDN_TIMER) | \
+ INT_MASK(INT_UDN_TIMER) | \
+ INT_MASK(INT_DMA_NOTIFY) | \
+ INT_MASK(INT_IDN_CA) | \
+ INT_MASK(INT_UDN_CA) | \
+ INT_MASK(INT_IDN_AVAIL) | \
+ INT_MASK(INT_UDN_AVAIL) | \
+ INT_MASK(INT_PERF_COUNT) | \
+ INT_MASK(INT_INTCTRL_3) | \
+ INT_MASK(INT_INTCTRL_2) | \
+ INT_MASK(INT_INTCTRL_1) | \
+ INT_MASK(INT_INTCTRL_0) | \
+ INT_MASK(INT_BOOT_ACCESS) | \
+ INT_MASK(INT_WORLD_ACCESS) | \
+ INT_MASK(INT_I_ASID) | \
+ INT_MASK(INT_D_ASID) | \
+ INT_MASK(INT_DMA_ASID) | \
+ INT_MASK(INT_SNI_ASID) | \
+ INT_MASK(INT_DMA_CPL) | \
+ INT_MASK(INT_SN_CPL) | \
+ INT_MASK(INT_DOUBLE_FAULT) | \
+ INT_MASK(INT_AUX_PERF_COUNT) | \
+ 0)
+#endif /* !__ARCH_INTERRUPTS_H__ */
diff --git a/arch/tile/include/arch/sim_def.h b/arch/tile/include/arch/sim_def.h
new file mode 100644
index 000000000000..6418fbde063e
--- /dev/null
+++ b/arch/tile/include/arch/sim_def.h
@@ -0,0 +1,512 @@
+// Copyright 2010 Tilera Corporation. All Rights Reserved.
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation, version 2.
+//
+// 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, GOOD TITLE or
+// NON INFRINGEMENT. See the GNU General Public License for
+// more details.
+
+//! @file
+//!
+//! Some low-level simulator definitions.
+//!
+
+#ifndef __ARCH_SIM_DEF_H__
+#define __ARCH_SIM_DEF_H__
+
+
+//! Internal: the low bits of the SIM_CONTROL_* SPR values specify
+//! the operation to perform, and the remaining bits are
+//! an operation-specific parameter (often unused).
+//!
+#define _SIM_CONTROL_OPERATOR_BITS 8
+
+
+//== Values which can be written to SPR_SIM_CONTROL.
+
+//! If written to SPR_SIM_CONTROL, stops profiling.
+//!
+#define SIM_CONTROL_PROFILER_DISABLE 0
+
+//! If written to SPR_SIM_CONTROL, starts profiling.
+//!
+#define SIM_CONTROL_PROFILER_ENABLE 1
+
+//! If written to SPR_SIM_CONTROL, clears profiling counters.
+//!
+#define SIM_CONTROL_PROFILER_CLEAR 2
+
+//! If written to SPR_SIM_CONTROL, checkpoints the simulator.
+//!
+#define SIM_CONTROL_CHECKPOINT 3
+
+//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
+//! sets the tracing mask to the given mask. See "sim_set_tracing()".
+//!
+#define SIM_CONTROL_SET_TRACING 4
+
+//! If written to SPR_SIM_CONTROL, combined with a mask (shifted by 8),
+//! dumps the requested items of machine state to the log.
+//!
+#define SIM_CONTROL_DUMP 5
+
+//! If written to SPR_SIM_CONTROL, clears chip-level profiling counters.
+//!
+#define SIM_CONTROL_PROFILER_CHIP_CLEAR 6
+
+//! If written to SPR_SIM_CONTROL, disables chip-level profiling.
+//!
+#define SIM_CONTROL_PROFILER_CHIP_DISABLE 7
+
+//! If written to SPR_SIM_CONTROL, enables chip-level profiling.
+//!
+#define SIM_CONTROL_PROFILER_CHIP_ENABLE 8
+
+//! If written to SPR_SIM_CONTROL, enables chip-level functional mode
+//!
+#define SIM_CONTROL_ENABLE_FUNCTIONAL 9
+
+//! If written to SPR_SIM_CONTROL, disables chip-level functional mode.
+//!
+#define SIM_CONTROL_DISABLE_FUNCTIONAL 10
+
+//! If written to SPR_SIM_CONTROL, enables chip-level functional mode.
+//! All tiles must perform this write for functional mode to be enabled.
+//! Ignored in naked boot mode unless --functional is specified.
+//! WARNING: Only the hypervisor startup code should use this!
+//!
+#define SIM_CONTROL_ENABLE_FUNCTIONAL_BARRIER 11
+
+//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+//! writes a string directly to the simulator output. Written to once for
+//! each character in the string, plus a final NUL. Instead of NUL,
+//! you can also use "SIM_PUTC_FLUSH_STRING" or "SIM_PUTC_FLUSH_BINARY".
+//!
+// ISSUE: Document the meaning of "newline", and the handling of NUL.
+//
+#define SIM_CONTROL_PUTC 12
+
+//! If written to SPR_SIM_CONTROL, clears the --grind-coherence state for
+//! this core. This is intended to be used before a loop that will
+//! invalidate the cache by loading new data and evicting all current data.
+//! Generally speaking, this API should only be used by system code.
+//!
+#define SIM_CONTROL_GRINDER_CLEAR 13
+
+//! If written to SPR_SIM_CONTROL, shuts down the simulator.
+//!
+#define SIM_CONTROL_SHUTDOWN 14
+
+//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+//! indicates that a fork syscall just created the given process.
+//!
+#define SIM_CONTROL_OS_FORK 15
+
+//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+//! indicates that an exit syscall was just executed by the given process.
+//!
+#define SIM_CONTROL_OS_EXIT 16
+
+//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+//! indicates that the OS just switched to the given process.
+//!
+#define SIM_CONTROL_OS_SWITCH 17
+
+//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+//! indicates that an exec syscall was just executed. Written to once for
+//! each character in the executable name, plus a final NUL.
+//!
+#define SIM_CONTROL_OS_EXEC 18
+
+//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+//! indicates that an interpreter (PT_INTERP) was loaded. Written to once
+//! for each character in "ADDR:PATH", plus a final NUL, where "ADDR" is a
+//! hex load address starting with "0x", and "PATH" is the executable name.
+//!
+#define SIM_CONTROL_OS_INTERP 19
+
+//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+//! indicates that a dll was loaded. Written to once for each character
+//! in "ADDR:PATH", plus a final NUL, where "ADDR" is a hexadecimal load
+//! address starting with "0x", and "PATH" is the executable name.
+//!
+#define SIM_CONTROL_DLOPEN 20
+
+//! If written to SPR_SIM_CONTROL, combined with a character (shifted by 8),
+//! indicates that a dll was unloaded. Written to once for each character
+//! in "ADDR", plus a final NUL, where "ADDR" is a hexadecimal load
+//! address starting with "0x".
+//!
+#define SIM_CONTROL_DLCLOSE 21
+
+//! If written to SPR_SIM_CONTROL, combined with a flag (shifted by 8),
+//! indicates whether to allow data reads to remotely-cached
+//! dirty cache lines to be cached locally without grinder warnings or
+//! assertions (used by Linux kernel fast memcpy).
+//!
+#define SIM_CONTROL_ALLOW_MULTIPLE_CACHING 22
+
+//! If written to SPR_SIM_CONTROL, enables memory tracing.
+//!
+#define SIM_CONTROL_ENABLE_MEM_LOGGING 23
+
+//! If written to SPR_SIM_CONTROL, disables memory tracing.
+//!
+#define SIM_CONTROL_DISABLE_MEM_LOGGING 24
+
+//! If written to SPR_SIM_CONTROL, changes the shaping parameters of one of
+//! the gbe or xgbe shims. Must specify the shim id, the type, the units, and
+//! the rate, as defined in SIM_SHAPING_SPR_ARG.
+//!
+#define SIM_CONTROL_SHAPING 25
+
+//! If written to SPR_SIM_CONTROL, combined with character (shifted by 8),
+//! requests that a simulator command be executed. Written to once for each
+//! character in the command, plus a final NUL.
+//!
+#define SIM_CONTROL_COMMAND 26
+
+//! If written to SPR_SIM_CONTROL, indicates that the simulated system
+//! is panicking, to allow debugging via --debug-on-panic.
+//!
+#define SIM_CONTROL_PANIC 27
+
+//! If written to SPR_SIM_CONTROL, triggers a simulator syscall.
+//! See "sim_syscall()" for more info.
+//!
+#define SIM_CONTROL_SYSCALL 32
+
+//! If written to SPR_SIM_CONTROL, combined with a pid (shifted by 8),
+//! provides the pid that subsequent SIM_CONTROL_OS_FORK writes should
+//! use as the pid, rather than the default previous SIM_CONTROL_OS_SWITCH.
+//!
+#define SIM_CONTROL_OS_FORK_PARENT 33
+
+//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+//! (shifted by 8), clears the pending magic data section. The cleared
+//! pending magic data section and any subsequently appended magic bytes
+//! will only take effect when the classifier blast programmer is run.
+#define SIM_CONTROL_CLEAR_MPIPE_MAGIC_BYTES 34
+
+//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+//! (shifted by 8) and a byte of data (shifted by 16), appends that byte
+//! to the shim's pending magic data section. The pending magic data
+//! section takes effect when the classifier blast programmer is run.
+#define SIM_CONTROL_APPEND_MPIPE_MAGIC_BYTE 35
+
+//! If written to SPR_SIM_CONTROL, combined with a mPIPE shim number
+//! (shifted by 8), an enable=1/disable=0 bit (shifted by 16), and a
+//! mask of links (shifted by 32), enable or disable the corresponding
+//! mPIPE links.
+#define SIM_CONTROL_ENABLE_MPIPE_LINK_MAGIC_BYTE 36
+
+//== Syscall numbers for use with "sim_syscall()".
+
+//! Syscall number for sim_add_watchpoint().
+//!
+#define SIM_SYSCALL_ADD_WATCHPOINT 2
+
+//! Syscall number for sim_remove_watchpoint().
+//!
+#define SIM_SYSCALL_REMOVE_WATCHPOINT 3
+
+//! Syscall number for sim_query_watchpoint().
+//!
+#define SIM_SYSCALL_QUERY_WATCHPOINT 4
+
+//! Syscall number that asserts that the cache lines whose 64-bit PA
+//! is passed as the second argument to sim_syscall(), and over a
+//! range passed as the third argument, are no longer in cache.
+//! The simulator raises an error if this is not the case.
+//!
+#define SIM_SYSCALL_VALIDATE_LINES_EVICTED 5
+
+
+//== Bit masks which can be shifted by 8, combined with
+//== SIM_CONTROL_SET_TRACING, and written to SPR_SIM_CONTROL.
+
+//! @addtogroup arch_sim
+//! @{
+
+//! Enable --trace-cycle when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_CYCLES 0x01
+
+//! Enable --trace-router when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_ROUTER 0x02
+
+//! Enable --trace-register-writes when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_REGISTER_WRITES 0x04
+
+//! Enable --trace-disasm when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_DISASM 0x08
+
+//! Enable --trace-stall-info when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_STALL_INFO 0x10
+
+//! Enable --trace-memory-controller when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_MEMORY_CONTROLLER 0x20
+
+//! Enable --trace-l2 when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_L2_CACHE 0x40
+
+//! Enable --trace-lines when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_LINES 0x80
+
+//! Turn off all tracing when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_NONE 0
+
+//! Turn on all tracing when passed to simulator_set_tracing().
+//!
+#define SIM_TRACE_ALL (-1)
+
+//! @}
+
+//! Computes the value to write to SPR_SIM_CONTROL to set tracing flags.
+//!
+#define SIM_TRACE_SPR_ARG(mask) \
+ (SIM_CONTROL_SET_TRACING | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
+
+
+//== Bit masks which can be shifted by 8, combined with
+//== SIM_CONTROL_DUMP, and written to SPR_SIM_CONTROL.
+
+//! @addtogroup arch_sim
+//! @{
+
+//! Dump the general-purpose registers.
+//!
+#define SIM_DUMP_REGS 0x001
+
+//! Dump the SPRs.
+//!
+#define SIM_DUMP_SPRS 0x002
+
+//! Dump the ITLB.
+//!
+#define SIM_DUMP_ITLB 0x004
+
+//! Dump the DTLB.
+//!
+#define SIM_DUMP_DTLB 0x008
+
+//! Dump the L1 I-cache.
+//!
+#define SIM_DUMP_L1I 0x010
+
+//! Dump the L1 D-cache.
+//!
+#define SIM_DUMP_L1D 0x020
+
+//! Dump the L2 cache.
+//!
+#define SIM_DUMP_L2 0x040
+
+//! Dump the switch registers.
+//!
+#define SIM_DUMP_SNREGS 0x080
+
+//! Dump the switch ITLB.
+//!
+#define SIM_DUMP_SNITLB 0x100
+
+//! Dump the switch L1 I-cache.
+//!
+#define SIM_DUMP_SNL1I 0x200
+
+//! Dump the current backtrace.
+//!
+#define SIM_DUMP_BACKTRACE 0x400
+
+//! Only dump valid lines in caches.
+//!
+#define SIM_DUMP_VALID_LINES 0x800
+
+//! Dump everything that is dumpable.
+//!
+#define SIM_DUMP_ALL (-1 & ~SIM_DUMP_VALID_LINES)
+
+// @}
+
+//! Computes the value to write to SPR_SIM_CONTROL to dump machine state.
+//!
+#define SIM_DUMP_SPR_ARG(mask) \
+ (SIM_CONTROL_DUMP | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
+
+
+//== Bit masks which can be shifted by 8, combined with
+//== SIM_CONTROL_PROFILER_CHIP_xxx, and written to SPR_SIM_CONTROL.
+
+//! @addtogroup arch_sim
+//! @{
+
+//! Use with with SIM_PROFILER_CHIP_xxx to control the memory controllers.
+//!
+#define SIM_CHIP_MEMCTL 0x001
+
+//! Use with with SIM_PROFILER_CHIP_xxx to control the XAUI interface.
+//!
+#define SIM_CHIP_XAUI 0x002
+
+//! Use with with SIM_PROFILER_CHIP_xxx to control the PCIe interface.
+//!
+#define SIM_CHIP_PCIE 0x004
+
+//! Use with with SIM_PROFILER_CHIP_xxx to control the MPIPE interface.
+//!
+#define SIM_CHIP_MPIPE 0x008
+
+//! Reference all chip devices.
+//!
+#define SIM_CHIP_ALL (-1)
+
+//! @}
+
+//! Computes the value to write to SPR_SIM_CONTROL to clear chip statistics.
+//!
+#define SIM_PROFILER_CHIP_CLEAR_SPR_ARG(mask) \
+ (SIM_CONTROL_PROFILER_CHIP_CLEAR | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
+
+//! Computes the value to write to SPR_SIM_CONTROL to disable chip statistics.
+//!
+#define SIM_PROFILER_CHIP_DISABLE_SPR_ARG(mask) \
+ (SIM_CONTROL_PROFILER_CHIP_DISABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
+
+//! Computes the value to write to SPR_SIM_CONTROL to enable chip statistics.
+//!
+#define SIM_PROFILER_CHIP_ENABLE_SPR_ARG(mask) \
+ (SIM_CONTROL_PROFILER_CHIP_ENABLE | ((mask) << _SIM_CONTROL_OPERATOR_BITS))
+
+
+
+// Shim bitrate controls.
+
+//! The number of bits used to store the shim id.
+//!
+#define SIM_CONTROL_SHAPING_SHIM_ID_BITS 3
+
+//! @addtogroup arch_sim
+//! @{
+
+//! Change the gbe 0 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_GBE_0 0x0
+
+//! Change the gbe 1 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_GBE_1 0x1
+
+//! Change the gbe 2 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_GBE_2 0x2
+
+//! Change the gbe 3 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_GBE_3 0x3
+
+//! Change the xgbe 0 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_XGBE_0 0x4
+
+//! Change the xgbe 1 bitrate.
+//!
+#define SIM_CONTROL_SHAPING_XGBE_1 0x5
+
+//! The type of shaping to do.
+//!
+#define SIM_CONTROL_SHAPING_TYPE_BITS 2
+
+//! Control the multiplier.
+//!
+#define SIM_CONTROL_SHAPING_MULTIPLIER 0
+
+//! Control the PPS.
+//!
+#define SIM_CONTROL_SHAPING_PPS 1
+
+//! Control the BPS.
+//!
+#define SIM_CONTROL_SHAPING_BPS 2
+
+//! The number of bits for the units for the shaping parameter.
+//!
+#define SIM_CONTROL_SHAPING_UNITS_BITS 2
+
+//! Provide a number in single units.
+//!
+#define SIM_CONTROL_SHAPING_UNITS_SINGLE 0
+
+//! Provide a number in kilo units.
+//!
+#define SIM_CONTROL_SHAPING_UNITS_KILO 1
+
+//! Provide a number in mega units.
+//!
+#define SIM_CONTROL_SHAPING_UNITS_MEGA 2
+
+//! Provide a number in giga units.
+//!
+#define SIM_CONTROL_SHAPING_UNITS_GIGA 3
+
+// @}
+
+//! How many bits are available for the rate.
+//!
+#define SIM_CONTROL_SHAPING_RATE_BITS \
+ (32 - (_SIM_CONTROL_OPERATOR_BITS + \
+ SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
+ SIM_CONTROL_SHAPING_TYPE_BITS + \
+ SIM_CONTROL_SHAPING_UNITS_BITS))
+
+//! Computes the value to write to SPR_SIM_CONTROL to change a bitrate.
+//!
+#define SIM_SHAPING_SPR_ARG(shim, type, units, rate) \
+ (SIM_CONTROL_SHAPING | \
+ ((shim) | \
+ ((type) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS)) | \
+ ((units) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
+ SIM_CONTROL_SHAPING_TYPE_BITS)) | \
+ ((rate) << (SIM_CONTROL_SHAPING_SHIM_ID_BITS + \
+ SIM_CONTROL_SHAPING_TYPE_BITS + \
+ SIM_CONTROL_SHAPING_UNITS_BITS))) << _SIM_CONTROL_OPERATOR_BITS)
+
+
+//== Values returned when reading SPR_SIM_CONTROL.
+// ISSUE: These names should share a longer common prefix.
+
+//! When reading SPR_SIM_CONTROL, the mask of simulator tracing bits
+//! (SIM_TRACE_xxx values).
+//!
+#define SIM_TRACE_FLAG_MASK 0xFFFF
+
+//! When reading SPR_SIM_CONTROL, the mask for whether profiling is enabled.
+//!
+#define SIM_PROFILER_ENABLED_MASK 0x10000
+
+
+//== Special arguments for "SIM_CONTROL_PUTC".
+
+//! Flag value for forcing a PUTC string-flush, including
+//! coordinate/cycle prefix and newline.
+//!
+#define SIM_PUTC_FLUSH_STRING 0x100
+
+//! Flag value for forcing a PUTC binary-data-flush, which skips the
+//! prefix and does not append a newline.
+//!
+#define SIM_PUTC_FLUSH_BINARY 0x101
+
+
+#endif //__ARCH_SIM_DEF_H__
diff --git a/arch/tile/include/arch/spr_def.h b/arch/tile/include/arch/spr_def.h
new file mode 100644
index 000000000000..c8fdbd9a45e6
--- /dev/null
+++ b/arch/tile/include/arch/spr_def.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifdef __tilegx__
+#include <arch/spr_def_64.h>
+#else
+#include <arch/spr_def_32.h>
+#endif
diff --git a/arch/tile/include/arch/spr_def_32.h b/arch/tile/include/arch/spr_def_32.h
new file mode 100644
index 000000000000..b4fc06864df6
--- /dev/null
+++ b/arch/tile/include/arch/spr_def_32.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __DOXYGEN__
+
+#ifndef __ARCH_SPR_DEF_H__
+#define __ARCH_SPR_DEF_H__
+
+#define SPR_AUX_PERF_COUNT_0 0x6005
+#define SPR_AUX_PERF_COUNT_1 0x6006
+#define SPR_AUX_PERF_COUNT_CTL 0x6007
+#define SPR_AUX_PERF_COUNT_STS 0x6008
+#define SPR_CYCLE_HIGH 0x4e06
+#define SPR_CYCLE_LOW 0x4e07
+#define SPR_DMA_BYTE 0x3900
+#define SPR_DMA_CHUNK_SIZE 0x3901
+#define SPR_DMA_CTR 0x3902
+#define SPR_DMA_CTR__REQUEST_MASK 0x1
+#define SPR_DMA_CTR__SUSPEND_MASK 0x2
+#define SPR_DMA_DST_ADDR 0x3903
+#define SPR_DMA_DST_CHUNK_ADDR 0x3904
+#define SPR_DMA_SRC_ADDR 0x3905
+#define SPR_DMA_SRC_CHUNK_ADDR 0x3906
+#define SPR_DMA_STATUS__DONE_MASK 0x1
+#define SPR_DMA_STATUS__BUSY_MASK 0x2
+#define SPR_DMA_STATUS__RUNNING_MASK 0x10
+#define SPR_DMA_STRIDE 0x3907
+#define SPR_DMA_USER_STATUS 0x3908
+#define SPR_DONE 0x4e08
+#define SPR_EVENT_BEGIN 0x4e0d
+#define SPR_EVENT_END 0x4e0e
+#define SPR_EX_CONTEXT_0_0 0x4a05
+#define SPR_EX_CONTEXT_0_1 0x4a06
+#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_0_1__PL_MASK 0x3
+#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_0_1__ICS_MASK 0x4
+#define SPR_EX_CONTEXT_1_0 0x4805
+#define SPR_EX_CONTEXT_1_1 0x4806
+#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_1_1__PL_MASK 0x3
+#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_1_1__ICS_MASK 0x4
+#define SPR_FAIL 0x4e09
+#define SPR_INTCTRL_0_STATUS 0x4a07
+#define SPR_INTCTRL_1_STATUS 0x4807
+#define SPR_INTERRUPT_CRITICAL_SECTION 0x4e0a
+#define SPR_INTERRUPT_MASK_0_0 0x4a08
+#define SPR_INTERRUPT_MASK_0_1 0x4a09
+#define SPR_INTERRUPT_MASK_1_0 0x4809
+#define SPR_INTERRUPT_MASK_1_1 0x480a
+#define SPR_INTERRUPT_MASK_RESET_0_0 0x4a0a
+#define SPR_INTERRUPT_MASK_RESET_0_1 0x4a0b
+#define SPR_INTERRUPT_MASK_RESET_1_0 0x480b
+#define SPR_INTERRUPT_MASK_RESET_1_1 0x480c
+#define SPR_INTERRUPT_MASK_SET_0_0 0x4a0c
+#define SPR_INTERRUPT_MASK_SET_0_1 0x4a0d
+#define SPR_INTERRUPT_MASK_SET_1_0 0x480d
+#define SPR_INTERRUPT_MASK_SET_1_1 0x480e
+#define SPR_MPL_DMA_CPL_SET_0 0x5800
+#define SPR_MPL_DMA_CPL_SET_1 0x5801
+#define SPR_MPL_DMA_NOTIFY_SET_0 0x3800
+#define SPR_MPL_DMA_NOTIFY_SET_1 0x3801
+#define SPR_MPL_INTCTRL_0_SET_0 0x4a00
+#define SPR_MPL_INTCTRL_0_SET_1 0x4a01
+#define SPR_MPL_INTCTRL_1_SET_0 0x4800
+#define SPR_MPL_INTCTRL_1_SET_1 0x4801
+#define SPR_MPL_SN_ACCESS_SET_0 0x0800
+#define SPR_MPL_SN_ACCESS_SET_1 0x0801
+#define SPR_MPL_SN_CPL_SET_0 0x5a00
+#define SPR_MPL_SN_CPL_SET_1 0x5a01
+#define SPR_MPL_SN_FIREWALL_SET_0 0x2c00
+#define SPR_MPL_SN_FIREWALL_SET_1 0x2c01
+#define SPR_MPL_SN_NOTIFY_SET_0 0x2a00
+#define SPR_MPL_SN_NOTIFY_SET_1 0x2a01
+#define SPR_MPL_UDN_ACCESS_SET_0 0x0c00
+#define SPR_MPL_UDN_ACCESS_SET_1 0x0c01
+#define SPR_MPL_UDN_AVAIL_SET_0 0x4000
+#define SPR_MPL_UDN_AVAIL_SET_1 0x4001
+#define SPR_MPL_UDN_CA_SET_0 0x3c00
+#define SPR_MPL_UDN_CA_SET_1 0x3c01
+#define SPR_MPL_UDN_COMPLETE_SET_0 0x1400
+#define SPR_MPL_UDN_COMPLETE_SET_1 0x1401
+#define SPR_MPL_UDN_FIREWALL_SET_0 0x3000
+#define SPR_MPL_UDN_FIREWALL_SET_1 0x3001
+#define SPR_MPL_UDN_REFILL_SET_0 0x1000
+#define SPR_MPL_UDN_REFILL_SET_1 0x1001
+#define SPR_MPL_UDN_TIMER_SET_0 0x3600
+#define SPR_MPL_UDN_TIMER_SET_1 0x3601
+#define SPR_MPL_WORLD_ACCESS_SET_0 0x4e00
+#define SPR_MPL_WORLD_ACCESS_SET_1 0x4e01
+#define SPR_PASS 0x4e0b
+#define SPR_PERF_COUNT_0 0x4205
+#define SPR_PERF_COUNT_1 0x4206
+#define SPR_PERF_COUNT_CTL 0x4207
+#define SPR_PERF_COUNT_STS 0x4208
+#define SPR_PROC_STATUS 0x4f00
+#define SPR_SIM_CONTROL 0x4e0c
+#define SPR_SNCTL 0x0805
+#define SPR_SNCTL__FRZFABRIC_MASK 0x1
+#define SPR_SNCTL__FRZPROC_MASK 0x2
+#define SPR_SNPC 0x080b
+#define SPR_SNSTATIC 0x080c
+#define SPR_SYSTEM_SAVE_0_0 0x4b00
+#define SPR_SYSTEM_SAVE_0_1 0x4b01
+#define SPR_SYSTEM_SAVE_0_2 0x4b02
+#define SPR_SYSTEM_SAVE_0_3 0x4b03
+#define SPR_SYSTEM_SAVE_1_0 0x4900
+#define SPR_SYSTEM_SAVE_1_1 0x4901
+#define SPR_SYSTEM_SAVE_1_2 0x4902
+#define SPR_SYSTEM_SAVE_1_3 0x4903
+#define SPR_TILE_COORD 0x4c17
+#define SPR_TILE_RTF_HWM 0x4e10
+#define SPR_TILE_TIMER_CONTROL 0x3205
+#define SPR_TILE_WRITE_PENDING 0x4e0f
+#define SPR_UDN_AVAIL_EN 0x4005
+#define SPR_UDN_CA_DATA 0x0d00
+#define SPR_UDN_DATA_AVAIL 0x0d03
+#define SPR_UDN_DEADLOCK_TIMEOUT 0x3606
+#define SPR_UDN_DEMUX_CA_COUNT 0x0c05
+#define SPR_UDN_DEMUX_COUNT_0 0x0c06
+#define SPR_UDN_DEMUX_COUNT_1 0x0c07
+#define SPR_UDN_DEMUX_COUNT_2 0x0c08
+#define SPR_UDN_DEMUX_COUNT_3 0x0c09
+#define SPR_UDN_DEMUX_CTL 0x0c0a
+#define SPR_UDN_DEMUX_QUEUE_SEL 0x0c0c
+#define SPR_UDN_DEMUX_STATUS 0x0c0d
+#define SPR_UDN_DEMUX_WRITE_FIFO 0x0c0e
+#define SPR_UDN_DIRECTION_PROTECT 0x3005
+#define SPR_UDN_REFILL_EN 0x1005
+#define SPR_UDN_SP_FIFO_DATA 0x0c11
+#define SPR_UDN_SP_FIFO_SEL 0x0c12
+#define SPR_UDN_SP_FREEZE 0x0c13
+#define SPR_UDN_SP_FREEZE__SP_FRZ_MASK 0x1
+#define SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK 0x2
+#define SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK 0x4
+#define SPR_UDN_SP_STATE 0x0c14
+#define SPR_UDN_TAG_0 0x0c15
+#define SPR_UDN_TAG_1 0x0c16
+#define SPR_UDN_TAG_2 0x0c17
+#define SPR_UDN_TAG_3 0x0c18
+#define SPR_UDN_TAG_VALID 0x0c19
+#define SPR_UDN_TILE_COORD 0x0c1a
+
+#endif /* !defined(__ARCH_SPR_DEF_H__) */
+
+#endif /* !defined(__DOXYGEN__) */
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
new file mode 100644
index 000000000000..3b8f55b82dee
--- /dev/null
+++ b/arch/tile/include/asm/Kbuild
@@ -0,0 +1,3 @@
+include include/asm-generic/Kbuild.asm
+
+header-y += ucontext.h
diff --git a/arch/tile/include/asm/asm-offsets.h b/arch/tile/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/arch/tile/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/tile/include/asm/atomic.h b/arch/tile/include/asm/atomic.h
new file mode 100644
index 000000000000..b8c49f98a44c
--- /dev/null
+++ b/arch/tile/include/asm/atomic.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Atomic primitives.
+ */
+
+#ifndef _ASM_TILE_ATOMIC_H
+#define _ASM_TILE_ATOMIC_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/compiler.h>
+#include <asm/system.h>
+
+#define ATOMIC_INIT(i) { (i) }
+
+/**
+ * atomic_read - read atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically reads the value of @v.
+ */
+static inline int atomic_read(const atomic_t *v)
+{
+ return v->counter;
+}
+
+/**
+ * atomic_sub_return - subtract integer and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to subtract
+ *
+ * Atomically subtracts @i from @v and returns @v - @i
+ */
+#define atomic_sub_return(i, v) atomic_add_return((int)(-(i)), (v))
+
+/**
+ * atomic_sub - subtract integer from atomic variable
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v.
+ */
+#define atomic_sub(i, v) atomic_add((int)(-(i)), (v))
+
+/**
+ * atomic_sub_and_test - subtract value from variable and test result
+ * @i: integer value to subtract
+ * @v: pointer of type atomic_t
+ *
+ * Atomically subtracts @i from @v and returns true if the result is
+ * zero, or false for all other cases.
+ */
+#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
+
+/**
+ * atomic_inc_return - increment memory and return
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1 and returns the new value.
+ */
+#define atomic_inc_return(v) atomic_add_return(1, (v))
+
+/**
+ * atomic_dec_return - decrement memory and return
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and returns the new value.
+ */
+#define atomic_dec_return(v) atomic_sub_return(1, (v))
+
+/**
+ * atomic_inc - increment atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1.
+ */
+#define atomic_inc(v) atomic_add(1, (v))
+
+/**
+ * atomic_dec - decrement atomic variable
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1.
+ */
+#define atomic_dec(v) atomic_sub(1, (v))
+
+/**
+ * atomic_dec_and_test - decrement and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically decrements @v by 1 and returns true if the result is 0.
+ */
+#define atomic_dec_and_test(v) (atomic_dec_return(v) == 0)
+
+/**
+ * atomic_inc_and_test - increment and test
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1 and returns true if the result is 0.
+ */
+#define atomic_inc_and_test(v) (atomic_inc_return(v) == 0)
+
+/**
+ * atomic_add_negative - add and test if negative
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns true if the result is
+ * negative, or false when result is greater than or equal to zero.
+ */
+#define atomic_add_negative(i, v) (atomic_add_return((i), (v)) < 0)
+
+/**
+ * atomic_inc_not_zero - increment unless the number is zero
+ * @v: pointer of type atomic_t
+ *
+ * Atomically increments @v by 1, so long as @v is non-zero.
+ * Returns non-zero if @v was non-zero, and zero otherwise.
+ */
+#define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
+
+
+/*
+ * We define xchg() and cmpxchg() in the included headers.
+ * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply
+ * that cmpxchg() is an efficient operation, which is not particularly true.
+ */
+
+/* Nonexistent functions intended to cause link errors. */
+extern unsigned long __xchg_called_with_bad_pointer(void);
+extern unsigned long __cmpxchg_called_with_bad_pointer(void);
+
+#define tas(ptr) (xchg((ptr), 1))
+
+#endif /* __ASSEMBLY__ */
+
+#ifndef __tilegx__
+#include <asm/atomic_32.h>
+#else
+#include <asm/atomic_64.h>
+#endif
+
+/* Provide the appropriate atomic_long_t definitions. */
+#ifndef __ASSEMBLY__
+#include <asm-generic/atomic-long.h>
+#endif
+
+#endif /* _ASM_TILE_ATOMIC_H */
diff --git a/arch/tile/include/asm/atomic_32.h b/arch/tile/include/asm/atomic_32.h
new file mode 100644
index 000000000000..40a5a3a876d9
--- /dev/null
+++ b/arch/tile/include/asm/atomic_32.h
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Do not include directly; use <asm/atomic.h>.
+ */
+
+#ifndef _ASM_TILE_ATOMIC_32_H
+#define _ASM_TILE_ATOMIC_32_H
+
+#include <arch/chip.h>
+
+#ifndef __ASSEMBLY__
+
+/* Tile-specific routines to support <asm/atomic.h>. */
+int _atomic_xchg(atomic_t *v, int n);
+int _atomic_xchg_add(atomic_t *v, int i);
+int _atomic_xchg_add_unless(atomic_t *v, int a, int u);
+int _atomic_cmpxchg(atomic_t *v, int o, int n);
+
+/**
+ * atomic_xchg - atomically exchange contents of memory with a new value
+ * @v: pointer of type atomic_t
+ * @i: integer value to store in memory
+ *
+ * Atomically sets @v to @i and returns old @v
+ */
+static inline int atomic_xchg(atomic_t *v, int n)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic_xchg(v, n);
+}
+
+/**
+ * atomic_cmpxchg - atomically exchange contents of memory if it matches
+ * @v: pointer of type atomic_t
+ * @o: old value that memory should have
+ * @n: new value to write to memory if it matches
+ *
+ * Atomically checks if @v holds @o and replaces it with @n if so.
+ * Returns the old value at @v.
+ */
+static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic_cmpxchg(v, o, n);
+}
+
+/**
+ * atomic_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic_t
+ *
+ * Atomically adds @i to @v.
+ */
+static inline void atomic_add(int i, atomic_t *v)
+{
+ _atomic_xchg_add(v, i);
+}
+
+/**
+ * atomic_add_return - add integer and return
+ * @v: pointer of type atomic_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic_xchg_add(v, i) + i;
+}
+
+/**
+ * atomic_add_unless - add unless the number is already a given value
+ * @v: pointer of type atomic_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as @v was not already @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic_xchg_add_unless(v, a, u) != u;
+}
+
+/**
+ * atomic_set - set atomic variable
+ * @v: pointer of type atomic_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ *
+ * atomic_set() can't be just a raw store, since it would be lost if it
+ * fell between the load and store of one of the other atomic ops.
+ */
+static inline void atomic_set(atomic_t *v, int n)
+{
+ _atomic_xchg(v, n);
+}
+
+#define xchg(ptr, x) ((typeof(*(ptr))) \
+ ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
+ atomic_xchg((atomic_t *)(ptr), (long)(x)) : \
+ __xchg_called_with_bad_pointer()))
+
+#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \
+ ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
+ atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \
+ __cmpxchg_called_with_bad_pointer()))
+
+/* A 64bit atomic type */
+
+typedef struct {
+ u64 __aligned(8) counter;
+} atomic64_t;
+
+#define ATOMIC64_INIT(val) { (val) }
+
+u64 _atomic64_xchg(atomic64_t *v, u64 n);
+u64 _atomic64_xchg_add(atomic64_t *v, u64 i);
+u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u);
+u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n);
+
+/**
+ * atomic64_read - read atomic variable
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically reads the value of @v.
+ */
+static inline u64 atomic64_read(const atomic64_t *v)
+{
+ /*
+ * Requires an atomic op to read both 32-bit parts consistently.
+ * Casting away const is safe since the atomic support routines
+ * do not write to memory if the value has not been modified.
+ */
+ return _atomic64_xchg_add((atomic64_t *)v, 0);
+}
+
+/**
+ * atomic64_xchg - atomically exchange contents of memory with a new value
+ * @v: pointer of type atomic64_t
+ * @i: integer value to store in memory
+ *
+ * Atomically sets @v to @i and returns old @v
+ */
+static inline u64 atomic64_xchg(atomic64_t *v, u64 n)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic64_xchg(v, n);
+}
+
+/**
+ * atomic64_cmpxchg - atomically exchange contents of memory if it matches
+ * @v: pointer of type atomic64_t
+ * @o: old value that memory should have
+ * @n: new value to write to memory if it matches
+ *
+ * Atomically checks if @v holds @o and replaces it with @n if so.
+ * Returns the old value at @v.
+ */
+static inline u64 atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic64_cmpxchg(v, o, n);
+}
+
+/**
+ * atomic64_add - add integer to atomic variable
+ * @i: integer value to add
+ * @v: pointer of type atomic64_t
+ *
+ * Atomically adds @i to @v.
+ */
+static inline void atomic64_add(u64 i, atomic64_t *v)
+{
+ _atomic64_xchg_add(v, i);
+}
+
+/**
+ * atomic64_add_return - add integer and return
+ * @v: pointer of type atomic64_t
+ * @i: integer value to add
+ *
+ * Atomically adds @i to @v and returns @i + @v
+ */
+static inline u64 atomic64_add_return(u64 i, atomic64_t *v)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic64_xchg_add(v, i) + i;
+}
+
+/**
+ * atomic64_add_unless - add unless the number is already a given value
+ * @v: pointer of type atomic64_t
+ * @a: the amount to add to v...
+ * @u: ...unless v is equal to u.
+ *
+ * Atomically adds @a to @v, so long as @v was not already @u.
+ * Returns non-zero if @v was not @u, and zero otherwise.
+ */
+static inline u64 atomic64_add_unless(atomic64_t *v, u64 a, u64 u)
+{
+ smp_mb(); /* barrier for proper semantics */
+ return _atomic64_xchg_add_unless(v, a, u) != u;
+}
+
+/**
+ * atomic64_set - set atomic variable
+ * @v: pointer of type atomic64_t
+ * @i: required value
+ *
+ * Atomically sets the value of @v to @i.
+ *
+ * atomic64_set() can't be just a raw store, since it would be lost if it
+ * fell between the load and store of one of the other atomic ops.
+ */
+static inline void atomic64_set(atomic64_t *v, u64 n)
+{
+ _atomic64_xchg(v, n);
+}
+
+#define atomic64_add_negative(a, v) (atomic64_add_return((a), (v)) < 0)
+#define atomic64_inc(v) atomic64_add(1LL, (v))
+#define atomic64_inc_return(v) atomic64_add_return(1LL, (v))
+#define atomic64_inc_and_test(v) (atomic64_inc_return(v) == 0)
+#define atomic64_sub_return(i, v) atomic64_add_return(-(i), (v))
+#define atomic64_sub_and_test(a, v) (atomic64_sub_return((a), (v)) == 0)
+#define atomic64_sub(i, v) atomic64_add(-(i), (v))
+#define atomic64_dec(v) atomic64_sub(1LL, (v))
+#define atomic64_dec_return(v) atomic64_sub_return(1LL, (v))
+#define atomic64_dec_and_test(v) (atomic64_dec_return((v)) == 0)
+#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1LL, 0LL)
+
+/*
+ * We need to barrier before modifying the word, since the _atomic_xxx()
+ * routines just tns the lock and then read/modify/write of the word.
+ * But after the word is updated, the routine issues an "mf" before returning,
+ * and since it's a function call, we don't even need a compiler barrier.
+ */
+#define smp_mb__before_atomic_dec() smp_mb()
+#define smp_mb__before_atomic_inc() smp_mb()
+#define smp_mb__after_atomic_dec() do { } while (0)
+#define smp_mb__after_atomic_inc() do { } while (0)
+
+
+/*
+ * Support "tns" atomic integers. These are atomic integers that can
+ * hold any value but "1". They are more efficient than regular atomic
+ * operations because the "lock" (aka acquire) step is a single "tns"
+ * in the uncontended case, and the "unlock" (aka release) step is a
+ * single "store" without an mf. (However, note that on tilepro the
+ * "tns" will evict the local cache line, so it's not all upside.)
+ *
+ * Note that you can ONLY observe the value stored in the pointer
+ * using these operations; a direct read of the value may confusingly
+ * return the special value "1".
+ */
+
+int __tns_atomic_acquire(atomic_t *);
+void __tns_atomic_release(atomic_t *p, int v);
+
+static inline void tns_atomic_set(atomic_t *v, int i)
+{
+ __tns_atomic_acquire(v);
+ __tns_atomic_release(v, i);
+}
+
+static inline int tns_atomic_cmpxchg(atomic_t *v, int o, int n)
+{
+ int ret = __tns_atomic_acquire(v);
+ __tns_atomic_release(v, (ret == o) ? n : ret);
+ return ret;
+}
+
+static inline int tns_atomic_xchg(atomic_t *v, int n)
+{
+ int ret = __tns_atomic_acquire(v);
+ __tns_atomic_release(v, n);
+ return ret;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Internal definitions only beyond this point.
+ */
+
+#define ATOMIC_LOCKS_FOUND_VIA_TABLE() \
+ (!CHIP_HAS_CBOX_HOME_MAP() && defined(CONFIG_SMP))
+
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+
+/* Number of entries in atomic_lock_ptr[]. */
+#define ATOMIC_HASH_L1_SHIFT 6
+#define ATOMIC_HASH_L1_SIZE (1 << ATOMIC_HASH_L1_SHIFT)
+
+/* Number of locks in each struct pointed to by atomic_lock_ptr[]. */
+#define ATOMIC_HASH_L2_SHIFT (CHIP_L2_LOG_LINE_SIZE() - 2)
+#define ATOMIC_HASH_L2_SIZE (1 << ATOMIC_HASH_L2_SHIFT)
+
+#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+/*
+ * Number of atomic locks in atomic_locks[]. Must be a power of two.
+ * There is no reason for more than PAGE_SIZE / 8 entries, since that
+ * is the maximum number of pointer bits we can use to index this.
+ * And we cannot have more than PAGE_SIZE / 4, since this has to
+ * fit on a single page and each entry takes 4 bytes.
+ */
+#define ATOMIC_HASH_SHIFT (PAGE_SHIFT - 3)
+#define ATOMIC_HASH_SIZE (1 << ATOMIC_HASH_SHIFT)
+
+#ifndef __ASSEMBLY__
+extern int atomic_locks[];
+#endif
+
+#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+/*
+ * All the code that may fault while holding an atomic lock must
+ * place the pointer to the lock in ATOMIC_LOCK_REG so the fault code
+ * can correctly release and reacquire the lock. Note that we
+ * mention the register number in a comment in "lib/atomic_asm.S" to help
+ * assembly coders from using this register by mistake, so if it
+ * is changed here, change that comment as well.
+ */
+#define ATOMIC_LOCK_REG 20
+#define ATOMIC_LOCK_REG_NAME r20
+
+#ifndef __ASSEMBLY__
+/* Called from setup to initialize a hash table to point to per_cpu locks. */
+void __init_atomic_per_cpu(void);
+
+#ifdef CONFIG_SMP
+/* Support releasing the atomic lock in do_page_fault_ics(). */
+void __atomic_fault_unlock(int *lock_ptr);
+#endif
+
+/* Private helper routines in lib/atomic_asm_32.S */
+extern struct __get_user __atomic_cmpxchg(volatile int *p,
+ int *lock, int o, int n);
+extern struct __get_user __atomic_xchg(volatile int *p, int *lock, int n);
+extern struct __get_user __atomic_xchg_add(volatile int *p, int *lock, int n);
+extern struct __get_user __atomic_xchg_add_unless(volatile int *p,
+ int *lock, int o, int n);
+extern struct __get_user __atomic_or(volatile int *p, int *lock, int n);
+extern struct __get_user __atomic_andn(volatile int *p, int *lock, int n);
+extern struct __get_user __atomic_xor(volatile int *p, int *lock, int n);
+extern u64 __atomic64_cmpxchg(volatile u64 *p, int *lock, u64 o, u64 n);
+extern u64 __atomic64_xchg(volatile u64 *p, int *lock, u64 n);
+extern u64 __atomic64_xchg_add(volatile u64 *p, int *lock, u64 n);
+extern u64 __atomic64_xchg_add_unless(volatile u64 *p,
+ int *lock, u64 o, u64 n);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_ATOMIC_32_H */
diff --git a/arch/tile/include/asm/auxvec.h b/arch/tile/include/asm/auxvec.h
new file mode 100644
index 000000000000..1d393edb0641
--- /dev/null
+++ b/arch/tile/include/asm/auxvec.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_AUXVEC_H
+#define _ASM_TILE_AUXVEC_H
+
+/* No extensions to auxvec */
+
+#endif /* _ASM_TILE_AUXVEC_H */
diff --git a/arch/tile/include/asm/backtrace.h b/arch/tile/include/asm/backtrace.h
new file mode 100644
index 000000000000..6970bfcad549
--- /dev/null
+++ b/arch/tile/include/asm/backtrace.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _TILE_BACKTRACE_H
+#define _TILE_BACKTRACE_H
+
+
+
+#include <linux/types.h>
+
+#include <arch/chip.h>
+
+#if CHIP_VA_WIDTH() > 32
+typedef unsigned long long VirtualAddress;
+#else
+typedef unsigned int VirtualAddress;
+#endif
+
+
+/** Reads 'size' bytes from 'address' and writes the data to 'result'.
+ * Returns true if successful, else false (e.g. memory not readable).
+ */
+typedef bool (*BacktraceMemoryReader)(void *result,
+ VirtualAddress address,
+ unsigned int size,
+ void *extra);
+
+typedef struct {
+ /** Current PC. */
+ VirtualAddress pc;
+
+ /** Current stack pointer value. */
+ VirtualAddress sp;
+
+ /** Current frame pointer value (i.e. caller's stack pointer) */
+ VirtualAddress fp;
+
+ /** Internal use only: caller's PC for first frame. */
+ VirtualAddress initial_frame_caller_pc;
+
+ /** Internal use only: callback to read memory. */
+ BacktraceMemoryReader read_memory_func;
+
+ /** Internal use only: arbitrary argument to read_memory_func. */
+ void *read_memory_func_extra;
+
+} BacktraceIterator;
+
+
+/** Initializes a backtracer to start from the given location.
+ *
+ * If the frame pointer cannot be determined it is set to -1.
+ *
+ * @param state The state to be filled in.
+ * @param read_memory_func A callback that reads memory. If NULL, a default
+ * value is provided.
+ * @param read_memory_func_extra An arbitrary argument to read_memory_func.
+ * @param pc The current PC.
+ * @param lr The current value of the 'lr' register.
+ * @param sp The current value of the 'sp' register.
+ * @param r52 The current value of the 'r52' register.
+ */
+extern void backtrace_init(BacktraceIterator *state,
+ BacktraceMemoryReader read_memory_func,
+ void *read_memory_func_extra,
+ VirtualAddress pc, VirtualAddress lr,
+ VirtualAddress sp, VirtualAddress r52);
+
+
+/** Advances the backtracing state to the calling frame, returning
+ * true iff successful.
+ */
+extern bool backtrace_next(BacktraceIterator *state);
+
+
+typedef enum {
+
+ /* We have no idea what the caller's pc is. */
+ PC_LOC_UNKNOWN,
+
+ /* The caller's pc is currently in lr. */
+ PC_LOC_IN_LR,
+
+ /* The caller's pc can be found by dereferencing the caller's sp. */
+ PC_LOC_ON_STACK
+
+} CallerPCLocation;
+
+
+typedef enum {
+
+ /* We have no idea what the caller's sp is. */
+ SP_LOC_UNKNOWN,
+
+ /* The caller's sp is currently in r52. */
+ SP_LOC_IN_R52,
+
+ /* The caller's sp can be found by adding a certain constant
+ * to the current value of sp.
+ */
+ SP_LOC_OFFSET
+
+} CallerSPLocation;
+
+
+/* Bit values ORed into CALLER_* values for info ops. */
+enum {
+ /* Setting the low bit on any of these values means the info op
+ * applies only to one bundle ago.
+ */
+ ONE_BUNDLE_AGO_FLAG = 1,
+
+ /* Setting this bit on a CALLER_SP_* value means the PC is in LR.
+ * If not set, PC is on the stack.
+ */
+ PC_IN_LR_FLAG = 2,
+
+ /* This many of the low bits of a CALLER_SP_* value are for the
+ * flag bits above.
+ */
+ NUM_INFO_OP_FLAGS = 2,
+
+ /* We cannot have one in the memory pipe so this is the maximum. */
+ MAX_INFO_OPS_PER_BUNDLE = 2
+};
+
+
+/** Internal constants used to define 'info' operands. */
+enum {
+ /* 0 and 1 are reserved, as are all negative numbers. */
+
+ CALLER_UNKNOWN_BASE = 2,
+
+ CALLER_SP_IN_R52_BASE = 4,
+
+ CALLER_SP_OFFSET_BASE = 8
+};
+
+
+/** Current backtracer state describing where it thinks the caller is. */
+typedef struct {
+ /*
+ * Public fields
+ */
+
+ /* How do we find the caller's PC? */
+ CallerPCLocation pc_location : 8;
+
+ /* How do we find the caller's SP? */
+ CallerSPLocation sp_location : 8;
+
+ /* If sp_location == SP_LOC_OFFSET, then caller_sp == sp +
+ * loc->sp_offset. Else this field is undefined.
+ */
+ uint16_t sp_offset;
+
+ /* In the most recently visited bundle a terminating bundle? */
+ bool at_terminating_bundle;
+
+ /*
+ * Private fields
+ */
+
+ /* Will the forward scanner see someone clobbering sp
+ * (i.e. changing it with something other than addi sp, sp, N?)
+ */
+ bool sp_clobber_follows;
+
+ /* Operand to next "visible" info op (no more than one bundle past
+ * the next terminating bundle), or -32768 if none.
+ */
+ int16_t next_info_operand;
+
+ /* Is the info of in next_info_op in the very next bundle? */
+ bool is_next_info_operand_adjacent;
+
+} CallerLocation;
+
+
+
+
+#endif /* _TILE_BACKTRACE_H */
diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
new file mode 100644
index 000000000000..84600f3514da
--- /dev/null
+++ b/arch/tile/include/asm/bitops.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright 1992, Linus Torvalds.
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_BITOPS_H
+#define _ASM_TILE_BITOPS_H
+
+#include <linux/types.h>
+
+#ifndef _LINUX_BITOPS_H
+#error only <linux/bitops.h> can be included directly
+#endif
+
+#ifdef __tilegx__
+#include <asm/bitops_64.h>
+#else
+#include <asm/bitops_32.h>
+#endif
+
+/**
+ * __ffs - find first set bit in word
+ * @word: The word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __ffs(unsigned long word)
+{
+ return __builtin_ctzl(word);
+}
+
+/**
+ * ffz - find first zero bit in word
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+static inline unsigned long ffz(unsigned long word)
+{
+ return __builtin_ctzl(~word);
+}
+
+/**
+ * __fls - find last set bit in word
+ * @word: The word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ return (sizeof(word) * 8) - 1 - __builtin_clzl(word);
+}
+
+/**
+ * ffs - find first set bit in word
+ * @x: the word to search
+ *
+ * This is defined the same way as the libc and compiler builtin ffs
+ * routines, therefore differs in spirit from the other bitops.
+ *
+ * ffs(value) returns 0 if value is 0 or the position of the first
+ * set bit if value is nonzero. The first (least significant) bit
+ * is at position 1.
+ */
+static inline int ffs(int x)
+{
+ return __builtin_ffs(x);
+}
+
+/**
+ * fls - find last set bit in word
+ * @x: the word to search
+ *
+ * This is defined in a similar way as the libc and compiler builtin
+ * ffs, but returns the position of the most significant set bit.
+ *
+ * fls(value) returns 0 if value is 0 or the position of the last
+ * set bit if value is nonzero. The last (most significant) bit is
+ * at position 32.
+ */
+static inline int fls(int x)
+{
+ return (sizeof(int) * 8) - __builtin_clz(x);
+}
+
+static inline int fls64(__u64 w)
+{
+ return (sizeof(__u64) * 8) - __builtin_clzll(w);
+}
+
+static inline unsigned int hweight32(unsigned int w)
+{
+ return __builtin_popcount(w);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+ return __builtin_popcount(w & 0xffff);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+ return __builtin_popcount(w & 0xff);
+}
+
+static inline unsigned long hweight64(__u64 w)
+{
+ return __builtin_popcountll(w);
+}
+
+#include <asm-generic/bitops/lock.h>
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/ext2-non-atomic.h>
+#include <asm-generic/bitops/minix.h>
+
+#endif /* _ASM_TILE_BITOPS_H */
diff --git a/arch/tile/include/asm/bitops_32.h b/arch/tile/include/asm/bitops_32.h
new file mode 100644
index 000000000000..7a93c001ac19
--- /dev/null
+++ b/arch/tile/include/asm/bitops_32.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_BITOPS_32_H
+#define _ASM_TILE_BITOPS_32_H
+
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/* Tile-specific routines to support <asm/bitops.h>. */
+unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask);
+unsigned long _atomic_andn(volatile unsigned long *p, unsigned long mask);
+unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask);
+
+/**
+ * set_bit - Atomically set a bit in memory
+ * @nr: the bit to set
+ * @addr: the address to start counting from
+ *
+ * This function is atomic and may not be reordered.
+ * See __set_bit() if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void set_bit(unsigned nr, volatile unsigned long *addr)
+{
+ _atomic_or(addr + BIT_WORD(nr), BIT_MASK(nr));
+}
+
+/**
+ * clear_bit - Clears a bit in memory
+ * @nr: Bit to clear
+ * @addr: Address to start counting from
+ *
+ * clear_bit() is atomic and may not be reordered.
+ * See __clear_bit() if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ *
+ * clear_bit() may not contain a memory barrier, so if it is used for
+ * locking purposes, you should call smp_mb__before_clear_bit() and/or
+ * smp_mb__after_clear_bit() to ensure changes are visible on other cpus.
+ */
+static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
+{
+ _atomic_andn(addr + BIT_WORD(nr), BIT_MASK(nr));
+}
+
+/**
+ * change_bit - Toggle a bit in memory
+ * @nr: Bit to change
+ * @addr: Address to start counting from
+ *
+ * change_bit() is atomic and may not be reordered.
+ * See __change_bit() if you do not require the atomic guarantees.
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ */
+static inline void change_bit(unsigned nr, volatile unsigned long *addr)
+{
+ _atomic_xor(addr + BIT_WORD(nr), BIT_MASK(nr));
+}
+
+/**
+ * test_and_set_bit - Set a bit and return its old value
+ * @nr: Bit to set
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ addr += BIT_WORD(nr);
+ smp_mb(); /* barrier for proper semantics */
+ return (_atomic_or(addr, mask) & mask) != 0;
+}
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ addr += BIT_WORD(nr);
+ smp_mb(); /* barrier for proper semantics */
+ return (_atomic_andn(addr, mask) & mask) != 0;
+}
+
+/**
+ * test_and_change_bit - Change a bit and return its old value
+ * @nr: Bit to change
+ * @addr: Address to count from
+ *
+ * This operation is atomic and cannot be reordered.
+ * It also implies a memory barrier.
+ */
+static inline int test_and_change_bit(unsigned nr,
+ volatile unsigned long *addr)
+{
+ unsigned long mask = BIT_MASK(nr);
+ addr += BIT_WORD(nr);
+ smp_mb(); /* barrier for proper semantics */
+ return (_atomic_xor(addr, mask) & mask) != 0;
+}
+
+/* See discussion at smp_mb__before_atomic_dec() in <asm/atomic.h>. */
+#define smp_mb__before_clear_bit() smp_mb()
+#define smp_mb__after_clear_bit() do {} while (0)
+
+#include <asm-generic/bitops/non-atomic.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* _ASM_TILE_BITOPS_32_H */
diff --git a/arch/tile/include/asm/bitsperlong.h b/arch/tile/include/asm/bitsperlong.h
new file mode 100644
index 000000000000..58c771f2af2f
--- /dev/null
+++ b/arch/tile/include/asm/bitsperlong.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_BITSPERLONG_H
+#define _ASM_TILE_BITSPERLONG_H
+
+#ifdef __LP64__
+# define __BITS_PER_LONG 64
+#else
+# define __BITS_PER_LONG 32
+#endif
+
+#include <asm-generic/bitsperlong.h>
+
+#endif /* _ASM_TILE_BITSPERLONG_H */
diff --git a/arch/tile/include/asm/bug.h b/arch/tile/include/asm/bug.h
new file mode 100644
index 000000000000..b12fd89e42e9
--- /dev/null
+++ b/arch/tile/include/asm/bug.h
@@ -0,0 +1 @@
+#include <asm-generic/bug.h>
diff --git a/arch/tile/include/asm/bugs.h b/arch/tile/include/asm/bugs.h
new file mode 100644
index 000000000000..61791e1ad9f5
--- /dev/null
+++ b/arch/tile/include/asm/bugs.h
@@ -0,0 +1 @@
+#include <asm-generic/bugs.h>
diff --git a/arch/tile/include/asm/byteorder.h b/arch/tile/include/asm/byteorder.h
new file mode 100644
index 000000000000..9558416d578b
--- /dev/null
+++ b/arch/tile/include/asm/byteorder.h
@@ -0,0 +1 @@
+#include <linux/byteorder/little_endian.h>
diff --git a/arch/tile/include/asm/cache.h b/arch/tile/include/asm/cache.h
new file mode 100644
index 000000000000..f6101840c9e7
--- /dev/null
+++ b/arch/tile/include/asm/cache.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_CACHE_H
+#define _ASM_TILE_CACHE_H
+
+#include <arch/chip.h>
+
+/* bytes per L1 data cache line */
+#define L1_CACHE_SHIFT CHIP_L1D_LOG_LINE_SIZE()
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+/* bytes per L2 cache line */
+#define L2_CACHE_SHIFT CHIP_L2_LOG_LINE_SIZE()
+#define L2_CACHE_BYTES (1 << L2_CACHE_SHIFT)
+#define L2_CACHE_ALIGN(x) (((x)+(L2_CACHE_BYTES-1)) & -L2_CACHE_BYTES)
+
+/*
+ * TILE-Gx is fully coherents so we don't need to define
+ * ARCH_KMALLOC_MINALIGN.
+ */
+#ifndef __tilegx__
+#define ARCH_KMALLOC_MINALIGN L2_CACHE_BYTES
+#endif
+
+/* use the cache line size for the L2, which is where it counts */
+#define SMP_CACHE_BYTES_SHIFT L2_CACHE_SHIFT
+#define SMP_CACHE_BYTES L2_CACHE_BYTES
+#define INTERNODE_CACHE_SHIFT L2_CACHE_SHIFT
+#define INTERNODE_CACHE_BYTES L2_CACHE_BYTES
+
+/* Group together read-mostly things to avoid cache false sharing */
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
+/*
+ * Attribute for data that is kept read/write coherent until the end of
+ * initialization, then bumped to read/only incoherent for performance.
+ */
+#define __write_once __attribute__((__section__(".w1data")))
+
+#endif /* _ASM_TILE_CACHE_H */
diff --git a/arch/tile/include/asm/cacheflush.h b/arch/tile/include/asm/cacheflush.h
new file mode 100644
index 000000000000..c5741da4eeac
--- /dev/null
+++ b/arch/tile/include/asm/cacheflush.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_CACHEFLUSH_H
+#define _ASM_TILE_CACHEFLUSH_H
+
+#include <arch/chip.h>
+
+/* Keep includes the same across arches. */
+#include <linux/mm.h>
+#include <linux/cache.h>
+#include <asm/system.h>
+#include <arch/icache.h>
+
+/* Caches are physically-indexed and so don't need special treatment */
+#define flush_cache_all() do { } while (0)
+#define flush_cache_mm(mm) do { } while (0)
+#define flush_cache_dup_mm(mm) do { } while (0)
+#define flush_cache_range(vma, start, end) do { } while (0)
+#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
+#define flush_dcache_page(page) do { } while (0)
+#define flush_dcache_mmap_lock(mapping) do { } while (0)
+#define flush_dcache_mmap_unlock(mapping) do { } while (0)
+#define flush_cache_vmap(start, end) do { } while (0)
+#define flush_cache_vunmap(start, end) do { } while (0)
+#define flush_icache_page(vma, pg) do { } while (0)
+#define flush_icache_user_range(vma, pg, adr, len) do { } while (0)
+
+/* Flush the icache just on this cpu */
+extern void __flush_icache_range(unsigned long start, unsigned long end);
+
+/* Flush the entire icache on this cpu. */
+#define __flush_icache() __flush_icache_range(0, CHIP_L1I_CACHE_SIZE())
+
+#ifdef CONFIG_SMP
+/*
+ * When the kernel writes to its own text we need to do an SMP
+ * broadcast to make the L1I coherent everywhere. This includes
+ * module load and single step.
+ */
+extern void flush_icache_range(unsigned long start, unsigned long end);
+#else
+#define flush_icache_range __flush_icache_range
+#endif
+
+/*
+ * An update to an executable user page requires icache flushing.
+ * We could carefully update only tiles that are running this process,
+ * and rely on the fact that we flush the icache on every context
+ * switch to avoid doing extra work here. But for now, I'll be
+ * conservative and just do a global icache flush.
+ */
+static inline void copy_to_user_page(struct vm_area_struct *vma,
+ struct page *page, unsigned long vaddr,
+ void *dst, void *src, int len)
+{
+ memcpy(dst, src, len);
+ if (vma->vm_flags & VM_EXEC) {
+ flush_icache_range((unsigned long) dst,
+ (unsigned long) dst + len);
+ }
+}
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy((dst), (src), (len))
+
+/*
+ * Invalidate a VA range; pads to L2 cacheline boundaries.
+ *
+ * Note that on TILE64, __inv_buffer() actually flushes modified
+ * cache lines in addition to invalidating them, i.e., it's the
+ * same as __finv_buffer().
+ */
+static inline void __inv_buffer(void *buffer, size_t size)
+{
+ char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
+ char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
+ while (next < finish) {
+ __insn_inv(next);
+ next += CHIP_INV_STRIDE();
+ }
+}
+
+/* Flush a VA range; pads to L2 cacheline boundaries. */
+static inline void __flush_buffer(void *buffer, size_t size)
+{
+ char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
+ char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
+ while (next < finish) {
+ __insn_flush(next);
+ next += CHIP_FLUSH_STRIDE();
+ }
+}
+
+/* Flush & invalidate a VA range; pads to L2 cacheline boundaries. */
+static inline void __finv_buffer(void *buffer, size_t size)
+{
+ char *next = (char *)((long)buffer & -L2_CACHE_BYTES);
+ char *finish = (char *)L2_CACHE_ALIGN((long)buffer + size);
+ while (next < finish) {
+ __insn_finv(next);
+ next += CHIP_FINV_STRIDE();
+ }
+}
+
+
+/* Invalidate a VA range, then memory fence. */
+static inline void inv_buffer(void *buffer, size_t size)
+{
+ __inv_buffer(buffer, size);
+ mb_incoherent();
+}
+
+/* Flush a VA range, then memory fence. */
+static inline void flush_buffer(void *buffer, size_t size)
+{
+ __flush_buffer(buffer, size);
+ mb_incoherent();
+}
+
+/* Flush & invalidate a VA range, then memory fence. */
+static inline void finv_buffer(void *buffer, size_t size)
+{
+ __finv_buffer(buffer, size);
+ mb_incoherent();
+}
+
+#endif /* _ASM_TILE_CACHEFLUSH_H */
diff --git a/arch/tile/include/asm/checksum.h b/arch/tile/include/asm/checksum.h
new file mode 100644
index 000000000000..a120766c7264
--- /dev/null
+++ b/arch/tile/include/asm/checksum.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_CHECKSUM_H
+#define _ASM_TILE_CHECKSUM_H
+
+#include <asm-generic/checksum.h>
+
+/* Allow us to provide a more optimized do_csum(). */
+__wsum do_csum(const unsigned char *buff, int len);
+#define do_csum do_csum
+
+#endif /* _ASM_TILE_CHECKSUM_H */
diff --git a/arch/tile/include/asm/compat.h b/arch/tile/include/asm/compat.h
new file mode 100644
index 000000000000..5a34da6cdd79
--- /dev/null
+++ b/arch/tile/include/asm/compat.h
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_COMPAT_H
+#define _ASM_TILE_COMPAT_H
+
+/*
+ * Architecture specific compatibility types
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+
+#define COMPAT_USER_HZ 100
+
+/* "long" and pointer-based types are different. */
+typedef s32 compat_long_t;
+typedef u32 compat_ulong_t;
+typedef u32 compat_size_t;
+typedef s32 compat_ssize_t;
+typedef s32 compat_off_t;
+typedef s32 compat_time_t;
+typedef s32 compat_clock_t;
+typedef u32 compat_ino_t;
+typedef u32 compat_caddr_t;
+typedef u32 compat_uptr_t;
+
+/* Many types are "int" or otherwise the same. */
+typedef __kernel_pid_t compat_pid_t;
+typedef __kernel_uid_t __compat_uid_t;
+typedef __kernel_gid_t __compat_gid_t;
+typedef __kernel_uid32_t __compat_uid32_t;
+typedef __kernel_uid32_t __compat_gid32_t;
+typedef __kernel_mode_t compat_mode_t;
+typedef __kernel_dev_t compat_dev_t;
+typedef __kernel_loff_t compat_loff_t;
+typedef __kernel_nlink_t compat_nlink_t;
+typedef __kernel_ipc_pid_t compat_ipc_pid_t;
+typedef __kernel_daddr_t compat_daddr_t;
+typedef __kernel_fsid_t compat_fsid_t;
+typedef __kernel_timer_t compat_timer_t;
+typedef __kernel_key_t compat_key_t;
+typedef int compat_int_t;
+typedef s64 compat_s64;
+typedef uint compat_uint_t;
+typedef u64 compat_u64;
+
+/* We use the same register dump format in 32-bit images. */
+typedef unsigned long compat_elf_greg_t;
+#define COMPAT_ELF_NGREG (sizeof(struct pt_regs) / sizeof(compat_elf_greg_t))
+typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG];
+
+struct compat_timespec {
+ compat_time_t tv_sec;
+ s32 tv_nsec;
+};
+
+struct compat_timeval {
+ compat_time_t tv_sec;
+ s32 tv_usec;
+};
+
+#define compat_stat stat
+#define compat_statfs statfs
+
+struct compat_sysctl {
+ unsigned int name;
+ int nlen;
+ unsigned int oldval;
+ unsigned int oldlenp;
+ unsigned int newval;
+ unsigned int newlen;
+ unsigned int __unused[4];
+};
+
+
+struct compat_flock {
+ short l_type;
+ short l_whence;
+ compat_off_t l_start;
+ compat_off_t l_len;
+ compat_pid_t l_pid;
+};
+
+#define F_GETLK64 12 /* using 'struct flock64' */
+#define F_SETLK64 13
+#define F_SETLKW64 14
+
+struct compat_flock64 {
+ short l_type;
+ short l_whence;
+ compat_loff_t l_start;
+ compat_loff_t l_len;
+ compat_pid_t l_pid;
+};
+
+#define COMPAT_RLIM_INFINITY 0xffffffff
+
+#define _COMPAT_NSIG 64
+#define _COMPAT_NSIG_BPW 32
+
+typedef u32 compat_sigset_word;
+
+#define COMPAT_OFF_T_MAX 0x7fffffff
+#define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL
+
+struct compat_ipc64_perm {
+ compat_key_t key;
+ __compat_uid32_t uid;
+ __compat_gid32_t gid;
+ __compat_uid32_t cuid;
+ __compat_gid32_t cgid;
+ unsigned short mode;
+ unsigned short __pad1;
+ unsigned short seq;
+ unsigned short __pad2;
+ compat_ulong_t unused1;
+ compat_ulong_t unused2;
+};
+
+struct compat_semid64_ds {
+ struct compat_ipc64_perm sem_perm;
+ compat_time_t sem_otime;
+ compat_ulong_t __unused1;
+ compat_time_t sem_ctime;
+ compat_ulong_t __unused2;
+ compat_ulong_t sem_nsems;
+ compat_ulong_t __unused3;
+ compat_ulong_t __unused4;
+};
+
+struct compat_msqid64_ds {
+ struct compat_ipc64_perm msg_perm;
+ compat_time_t msg_stime;
+ compat_ulong_t __unused1;
+ compat_time_t msg_rtime;
+ compat_ulong_t __unused2;
+ compat_time_t msg_ctime;
+ compat_ulong_t __unused3;
+ compat_ulong_t msg_cbytes;
+ compat_ulong_t msg_qnum;
+ compat_ulong_t msg_qbytes;
+ compat_pid_t msg_lspid;
+ compat_pid_t msg_lrpid;
+ compat_ulong_t __unused4;
+ compat_ulong_t __unused5;
+};
+
+struct compat_shmid64_ds {
+ struct compat_ipc64_perm shm_perm;
+ compat_size_t shm_segsz;
+ compat_time_t shm_atime;
+ compat_ulong_t __unused1;
+ compat_time_t shm_dtime;
+ compat_ulong_t __unused2;
+ compat_time_t shm_ctime;
+ compat_ulong_t __unused3;
+ compat_pid_t shm_cpid;
+ compat_pid_t shm_lpid;
+ compat_ulong_t shm_nattch;
+ compat_ulong_t __unused4;
+ compat_ulong_t __unused5;
+};
+
+/*
+ * A pointer passed in from user mode. This should not
+ * be used for syscall parameters, just declare them
+ * as pointers because the syscall entry code will have
+ * appropriately converted them already.
+ */
+
+static inline void __user *compat_ptr(compat_uptr_t uptr)
+{
+ return (void __user *)(long)(s32)uptr;
+}
+
+static inline compat_uptr_t ptr_to_compat(void __user *uptr)
+{
+ return (u32)(unsigned long)uptr;
+}
+
+/* Sign-extend when storing a kernel pointer to a user's ptregs. */
+static inline unsigned long ptr_to_compat_reg(void __user *uptr)
+{
+ return (long)(int)(long __force)uptr;
+}
+
+static inline void __user *compat_alloc_user_space(long len)
+{
+ struct pt_regs *regs = task_pt_regs(current);
+ return (void __user *)regs->sp - len;
+}
+
+static inline int is_compat_task(void)
+{
+ return current_thread_info()->status & TS_COMPAT;
+}
+
+extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
+ siginfo_t *info, sigset_t *set,
+ struct pt_regs *regs);
+
+/* Compat syscalls. */
+struct compat_sigaction;
+struct compat_siginfo;
+struct compat_sigaltstack;
+long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
+ compat_uptr_t __user *envp);
+long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
+ struct compat_sigaction __user *oact,
+ size_t sigsetsize);
+long compat_sys_rt_sigqueueinfo(int pid, int sig,
+ struct compat_siginfo __user *uinfo);
+long compat_sys_rt_sigreturn(void);
+long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr);
+long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high);
+long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high);
+long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
+ u32 dummy, u32 low, u32 high);
+long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
+ u32 dummy, u32 low, u32 high);
+long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len);
+long compat_sys_sync_file_range2(int fd, unsigned int flags,
+ u32 offset_lo, u32 offset_hi,
+ u32 nbytes_lo, u32 nbytes_hi);
+long compat_sys_fallocate(int fd, int mode,
+ u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi);
+long compat_sys_sched_rr_get_interval(compat_pid_t pid,
+ struct compat_timespec __user *interval);
+
+/* Versions of compat functions that differ from generic Linux. */
+struct compat_msgbuf;
+long tile_compat_sys_msgsnd(int msqid,
+ struct compat_msgbuf __user *msgp,
+ size_t msgsz, int msgflg);
+long tile_compat_sys_msgrcv(int msqid,
+ struct compat_msgbuf __user *msgp,
+ size_t msgsz, long msgtyp, int msgflg);
+long tile_compat_sys_ptrace(compat_long_t request, compat_long_t pid,
+ compat_long_t addr, compat_long_t data);
+
+/* Tilera Linux syscalls that don't have "compat" versions. */
+#define compat_sys_flush_cache sys_flush_cache
+
+#endif /* _ASM_TILE_COMPAT_H */
diff --git a/arch/tile/include/asm/cputime.h b/arch/tile/include/asm/cputime.h
new file mode 100644
index 000000000000..6d68ad7e0ea3
--- /dev/null
+++ b/arch/tile/include/asm/cputime.h
@@ -0,0 +1 @@
+#include <asm-generic/cputime.h>
diff --git a/arch/tile/include/asm/current.h b/arch/tile/include/asm/current.h
new file mode 100644
index 000000000000..da21acf020d3
--- /dev/null
+++ b/arch/tile/include/asm/current.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_CURRENT_H
+#define _ASM_TILE_CURRENT_H
+
+#include <linux/thread_info.h>
+
+struct task_struct;
+
+static inline struct task_struct *get_current(void)
+{
+ return current_thread_info()->task;
+}
+#define current get_current()
+
+/* Return a usable "task_struct" pointer even if the real one is corrupt. */
+struct task_struct *validate_current(void);
+
+#endif /* _ASM_TILE_CURRENT_H */
diff --git a/arch/tile/include/asm/delay.h b/arch/tile/include/asm/delay.h
new file mode 100644
index 000000000000..97b0e69e704e
--- /dev/null
+++ b/arch/tile/include/asm/delay.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_DELAY_H
+#define _ASM_TILE_DELAY_H
+
+/* Undefined functions to get compile-time errors. */
+extern void __bad_udelay(void);
+extern void __bad_ndelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __ndelay(unsigned long nsecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) (__builtin_constant_p(n) ? \
+ ((n) > 20000 ? __bad_udelay() : __ndelay((n) * 1000)) : \
+ __udelay(n))
+
+#define ndelay(n) (__builtin_constant_p(n) ? \
+ ((n) > 20000 ? __bad_ndelay() : __ndelay(n)) : \
+ __ndelay(n))
+
+#endif /* _ASM_TILE_DELAY_H */
diff --git a/arch/tile/include/asm/device.h b/arch/tile/include/asm/device.h
new file mode 100644
index 000000000000..f0a4c256403b
--- /dev/null
+++ b/arch/tile/include/asm/device.h
@@ -0,0 +1 @@
+#include <asm-generic/device.h>
diff --git a/arch/tile/include/asm/div64.h b/arch/tile/include/asm/div64.h
new file mode 100644
index 000000000000..6cd978cefb28
--- /dev/null
+++ b/arch/tile/include/asm/div64.h
@@ -0,0 +1 @@
+#include <asm-generic/div64.h>
diff --git a/arch/tile/include/asm/dma-mapping.h b/arch/tile/include/asm/dma-mapping.h
new file mode 100644
index 000000000000..cf466b39aa13
--- /dev/null
+++ b/arch/tile/include/asm/dma-mapping.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_DMA_MAPPING_H
+#define _ASM_TILE_DMA_MAPPING_H
+
+#include <linux/mm.h>
+#include <linux/scatterlist.h>
+#include <linux/cache.h>
+#include <linux/io.h>
+
+/*
+ * Note that on x86 and powerpc, there is a "struct dma_mapping_ops"
+ * that is used for all the DMA operations. For now, we don't have an
+ * equivalent on tile, because we only have a single way of doing DMA.
+ * (Tilera bug 7994 to use dma_mapping_ops.)
+ */
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+
+extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction);
+extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
+ size_t size, enum dma_data_direction);
+extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction);
+extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nhwentries, enum dma_data_direction);
+extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction);
+extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
+ size_t size, enum dma_data_direction);
+extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+ int nelems, enum dma_data_direction);
+extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
+ int nelems, enum dma_data_direction);
+
+
+void *dma_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag);
+
+void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+
+extern void dma_sync_single_for_cpu(struct device *, dma_addr_t, size_t,
+ enum dma_data_direction);
+extern void dma_sync_single_for_device(struct device *, dma_addr_t,
+ size_t, enum dma_data_direction);
+extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
+ unsigned long offset, size_t,
+ enum dma_data_direction);
+extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
+ unsigned long offset, size_t,
+ enum dma_data_direction);
+extern void dma_cache_sync(void *vaddr, size_t, enum dma_data_direction);
+
+static inline int
+dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return 0;
+}
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 mask)
+{
+ if (!dev->dma_mask || !dma_supported(dev, mask))
+ return -EIO;
+
+ *dev->dma_mask = mask;
+
+ return 0;
+}
+
+static inline int
+dma_get_cache_alignment(void)
+{
+ return L2_CACHE_BYTES;
+}
+
+#define dma_is_consistent(d, h) (1)
+
+
+#endif /* _ASM_TILE_DMA_MAPPING_H */
diff --git a/arch/tile/include/asm/dma.h b/arch/tile/include/asm/dma.h
new file mode 100644
index 000000000000..12a7ca16d164
--- /dev/null
+++ b/arch/tile/include/asm/dma.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_DMA_H
+#define _ASM_TILE_DMA_H
+
+#include <asm-generic/dma.h>
+
+/* Needed by drivers/pci/quirks.c */
+#ifdef CONFIG_PCI
+extern int isa_dma_bridge_buggy;
+#endif
+
+#endif /* _ASM_TILE_DMA_H */
diff --git a/arch/tile/include/asm/elf.h b/arch/tile/include/asm/elf.h
new file mode 100644
index 000000000000..623a6bb741c1
--- /dev/null
+++ b/arch/tile/include/asm/elf.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_ELF_H
+#define _ASM_TILE_ELF_H
+
+/*
+ * ELF register definitions.
+ */
+
+#include <arch/chip.h>
+
+#include <linux/ptrace.h>
+#include <asm/byteorder.h>
+#include <asm/page.h>
+
+typedef unsigned long elf_greg_t;
+
+#define ELF_NGREG (sizeof(struct pt_regs) / sizeof(elf_greg_t))
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+#define EM_TILE64 187
+#define EM_TILEPRO 188
+#define EM_TILEGX 191
+
+/* Provide a nominal data structure. */
+#define ELF_NFPREG 0
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#ifdef __tilegx__
+#define ELF_CLASS ELFCLASS64
+#else
+#define ELF_CLASS ELFCLASS32
+#endif
+#define ELF_DATA ELFDATA2LSB
+
+/*
+ * There seems to be a bug in how compat_binfmt_elf.c works: it
+ * #undefs ELF_ARCH, but it is then used in binfmt_elf.c for fill_note_info().
+ * Hack around this by providing an enum value of ELF_ARCH.
+ */
+enum { ELF_ARCH = CHIP_ELF_TYPE() };
+#define ELF_ARCH ELF_ARCH
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) \
+ ((x)->e_ident[EI_CLASS] == ELF_CLASS && \
+ (x)->e_machine == CHIP_ELF_TYPE())
+
+/* The module loader only handles a few relocation types. */
+#ifndef __tilegx__
+#define R_TILE_32 1
+#define R_TILE_JOFFLONG_X1 15
+#define R_TILE_IMM16_X0_LO 25
+#define R_TILE_IMM16_X1_LO 26
+#define R_TILE_IMM16_X0_HA 29
+#define R_TILE_IMM16_X1_HA 30
+#else
+#define R_TILEGX_64 1
+#define R_TILEGX_JUMPOFF_X1 21
+#define R_TILEGX_IMM16_X0_HW0 36
+#define R_TILEGX_IMM16_X1_HW0 37
+#define R_TILEGX_IMM16_X0_HW1 38
+#define R_TILEGX_IMM16_X1_HW1 39
+#define R_TILEGX_IMM16_X0_HW2_LAST 48
+#define R_TILEGX_IMM16_X1_HW2_LAST 49
+#endif
+
+/* Use standard page size for core dumps. */
+#define ELF_EXEC_PAGESIZE PAGE_SIZE
+
+/*
+ * This is the location that an ET_DYN program is loaded if exec'ed. Typical
+ * use of this is to invoke "./ld.so someprog" to test out a new version of
+ * the loader. We need to make sure that it is out of the way of the program
+ * that it will "exec", and that there is sufficient room for the brk.
+ */
+#define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2)
+
+#define ELF_CORE_COPY_REGS(_dest, _regs) \
+ memcpy((char *) &_dest, (char *) _regs, \
+ sizeof(struct pt_regs));
+
+/* No additional FP registers to copy. */
+#define ELF_CORE_COPY_FPREGS(t, fpu) 0
+
+/*
+ * This yields a mask that user programs can use to figure out what
+ * instruction set this CPU supports. This could be done in user space,
+ * but it's not easy, and we've already done it here.
+ */
+#define ELF_HWCAP (0)
+
+/*
+ * This yields a string that ld.so will use to load implementation
+ * specific libraries for optimization. This is more specific in
+ * intent than poking at uname or /proc/cpuinfo.
+ */
+#define ELF_PLATFORM (NULL)
+
+extern void elf_plat_init(struct pt_regs *regs, unsigned long load_addr);
+
+#define ELF_PLAT_INIT(_r, load_addr) elf_plat_init(_r, load_addr)
+
+extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
+#define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs)
+
+/* Tilera Linux has no personalities currently, so no need to do anything. */
+#define SET_PERSONALITY(ex) do { } while (0)
+
+#define ARCH_HAS_SETUP_ADDITIONAL_PAGES
+/* Support auto-mapping of the user interrupt vectors. */
+struct linux_binprm;
+extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int executable_stack);
+#ifdef CONFIG_COMPAT
+
+#define COMPAT_ELF_PLATFORM "tilegx-m32"
+
+/*
+ * "Compat" binaries have the same machine type, but 32-bit class,
+ * since they're not a separate machine type, but just a 32-bit
+ * variant of the standard 64-bit architecture.
+ */
+#define compat_elf_check_arch(x) \
+ ((x)->e_ident[EI_CLASS] == ELFCLASS32 && \
+ (x)->e_machine == CHIP_ELF_TYPE())
+
+#define compat_start_thread(regs, ip, usp) do { \
+ regs->pc = ptr_to_compat_reg((void *)(ip)); \
+ regs->sp = ptr_to_compat_reg((void *)(usp)); \
+ } while (0)
+
+/*
+ * Use SET_PERSONALITY to indicate compatibility via TS_COMPAT.
+ */
+#undef SET_PERSONALITY
+#define SET_PERSONALITY(ex) \
+do { \
+ current->personality = PER_LINUX; \
+ current_thread_info()->status &= ~TS_COMPAT; \
+} while (0)
+#define COMPAT_SET_PERSONALITY(ex) \
+do { \
+ current->personality = PER_LINUX_32BIT; \
+ current_thread_info()->status |= TS_COMPAT; \
+} while (0)
+
+#define COMPAT_ELF_ET_DYN_BASE (0xffffffff / 3 * 2)
+
+#endif /* CONFIG_COMPAT */
+
+#endif /* _ASM_TILE_ELF_H */
diff --git a/arch/tile/include/asm/emergency-restart.h b/arch/tile/include/asm/emergency-restart.h
new file mode 100644
index 000000000000..3711bd9d50bd
--- /dev/null
+++ b/arch/tile/include/asm/emergency-restart.h
@@ -0,0 +1 @@
+#include <asm-generic/emergency-restart.h>
diff --git a/arch/tile/include/asm/errno.h b/arch/tile/include/asm/errno.h
new file mode 100644
index 000000000000..4c82b503d92f
--- /dev/null
+++ b/arch/tile/include/asm/errno.h
@@ -0,0 +1 @@
+#include <asm-generic/errno.h>
diff --git a/arch/tile/include/asm/fcntl.h b/arch/tile/include/asm/fcntl.h
new file mode 100644
index 000000000000..46ab12db5739
--- /dev/null
+++ b/arch/tile/include/asm/fcntl.h
@@ -0,0 +1 @@
+#include <asm-generic/fcntl.h>
diff --git a/arch/tile/include/asm/fixmap.h b/arch/tile/include/asm/fixmap.h
new file mode 100644
index 000000000000..51537ff9265a
--- /dev/null
+++ b/arch/tile/include/asm/fixmap.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1998 Ingo Molnar
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_FIXMAP_H
+#define _ASM_TILE_FIXMAP_H
+
+#include <asm/page.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/kernel.h>
+#ifdef CONFIG_HIGHMEM
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#endif
+
+#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special addresses
+ * from the end of supervisor virtual memory backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * higher than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ *
+ * We don't bother with a FIX_HOLE since above the fixmaps
+ * is unmapped memory in any case.
+ */
+enum fixed_addresses {
+#ifdef CONFIG_HIGHMEM
+ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+ __end_of_permanent_fixed_addresses,
+
+ /*
+ * Temporary boot-time mappings, used before ioremap() is functional.
+ * Not currently needed by the Tile architecture.
+ */
+#define NR_FIX_BTMAPS 0
+#if NR_FIX_BTMAPS
+ FIX_BTMAP_END = __end_of_permanent_fixed_addresses,
+ FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,
+ __end_of_fixed_addresses
+#else
+ __end_of_fixed_addresses = __end_of_permanent_fixed_addresses
+#endif
+};
+
+extern void __set_fixmap(enum fixed_addresses idx,
+ unsigned long phys, pgprot_t flags);
+
+#define set_fixmap(idx, phys) \
+ __set_fixmap(idx, phys, PAGE_KERNEL)
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+ __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+
+#define clear_fixmap(idx) \
+ __set_fixmap(idx, 0, __pgprot(0))
+
+#define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT)
+#define __FIXADDR_BOOT_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_SIZE)
+#define FIXADDR_BOOT_START (FIXADDR_TOP + PAGE_SIZE - __FIXADDR_BOOT_SIZE)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static __always_inline unsigned long fix_to_virt(const unsigned int idx)
+{
+ /*
+ * this branch gets completely eliminated after inlining,
+ * except when someone tries to use fixaddr indices in an
+ * illegal way. (such as mixing up address types or using
+ * out-of-range indices).
+ *
+ * If it doesn't get removed, the linker will complain
+ * loudly with a reasonably clear error message..
+ */
+ if (idx >= __end_of_fixed_addresses)
+ __this_fixmap_does_not_exist();
+
+ return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+ return __virt_to_fix(vaddr);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_FIXMAP_H */
diff --git a/arch/tile/include/asm/ftrace.h b/arch/tile/include/asm/ftrace.h
new file mode 100644
index 000000000000..461459b06d98
--- /dev/null
+++ b/arch/tile/include/asm/ftrace.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_FTRACE_H
+#define _ASM_TILE_FTRACE_H
+
+/* empty */
+
+#endif /* _ASM_TILE_FTRACE_H */
diff --git a/arch/tile/include/asm/futex.h b/arch/tile/include/asm/futex.h
new file mode 100644
index 000000000000..fe0d10dcae57
--- /dev/null
+++ b/arch/tile/include/asm/futex.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * These routines make two important assumptions:
+ *
+ * 1. atomic_t is really an int and can be freely cast back and forth
+ * (validated in __init_atomic_per_cpu).
+ *
+ * 2. userspace uses sys_cmpxchg() for all atomic operations, thus using
+ * the same locking convention that all the kernel atomic routines use.
+ */
+
+#ifndef _ASM_TILE_FUTEX_H
+#define _ASM_TILE_FUTEX_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <linux/errno.h>
+
+extern struct __get_user futex_set(int __user *v, int i);
+extern struct __get_user futex_add(int __user *v, int n);
+extern struct __get_user futex_or(int __user *v, int n);
+extern struct __get_user futex_andn(int __user *v, int n);
+extern struct __get_user futex_cmpxchg(int __user *v, int o, int n);
+
+#ifndef __tilegx__
+extern struct __get_user futex_xor(int __user *v, int n);
+#else
+static inline struct __get_user futex_xor(int __user *uaddr, int n)
+{
+ struct __get_user asm_ret = __get_user_4(uaddr);
+ if (!asm_ret.err) {
+ int oldval, newval;
+ do {
+ oldval = asm_ret.val;
+ newval = oldval ^ n;
+ asm_ret = futex_cmpxchg(uaddr, oldval, newval);
+ } while (asm_ret.err == 0 && oldval != asm_ret.val);
+ }
+ return asm_ret;
+}
+#endif
+
+static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
+{
+ int op = (encoded_op >> 28) & 7;
+ int cmp = (encoded_op >> 24) & 15;
+ int oparg = (encoded_op << 8) >> 20;
+ int cmparg = (encoded_op << 20) >> 20;
+ int ret;
+ struct __get_user asm_ret;
+
+ if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
+ oparg = 1 << oparg;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+ return -EFAULT;
+
+ pagefault_disable();
+ switch (op) {
+ case FUTEX_OP_SET:
+ asm_ret = futex_set(uaddr, oparg);
+ break;
+ case FUTEX_OP_ADD:
+ asm_ret = futex_add(uaddr, oparg);
+ break;
+ case FUTEX_OP_OR:
+ asm_ret = futex_or(uaddr, oparg);
+ break;
+ case FUTEX_OP_ANDN:
+ asm_ret = futex_andn(uaddr, oparg);
+ break;
+ case FUTEX_OP_XOR:
+ asm_ret = futex_xor(uaddr, oparg);
+ break;
+ default:
+ asm_ret.err = -ENOSYS;
+ }
+ pagefault_enable();
+
+ ret = asm_ret.err;
+
+ if (!ret) {
+ switch (cmp) {
+ case FUTEX_OP_CMP_EQ:
+ ret = (asm_ret.val == cmparg);
+ break;
+ case FUTEX_OP_CMP_NE:
+ ret = (asm_ret.val != cmparg);
+ break;
+ case FUTEX_OP_CMP_LT:
+ ret = (asm_ret.val < cmparg);
+ break;
+ case FUTEX_OP_CMP_GE:
+ ret = (asm_ret.val >= cmparg);
+ break;
+ case FUTEX_OP_CMP_LE:
+ ret = (asm_ret.val <= cmparg);
+ break;
+ case FUTEX_OP_CMP_GT:
+ ret = (asm_ret.val > cmparg);
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+ }
+ return ret;
+}
+
+static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval,
+ int newval)
+{
+ struct __get_user asm_ret;
+
+ if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
+ return -EFAULT;
+
+ asm_ret = futex_cmpxchg(uaddr, oldval, newval);
+ return asm_ret.err ? asm_ret.err : asm_ret.val;
+}
+
+#ifndef __tilegx__
+/* Return failure from the atomic wrappers. */
+struct __get_user __atomic_bad_address(int __user *addr);
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_FUTEX_H */
diff --git a/arch/tile/include/asm/hardirq.h b/arch/tile/include/asm/hardirq.h
new file mode 100644
index 000000000000..822390f9a154
--- /dev/null
+++ b/arch/tile/include/asm/hardirq.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_HARDIRQ_H
+#define _ASM_TILE_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/cache.h>
+
+#include <asm/irq.h>
+
+typedef struct {
+ unsigned int __softirq_pending;
+ long idle_timestamp;
+
+ /* Hard interrupt statistics. */
+ unsigned int irq_timer_count;
+ unsigned int irq_syscall_count;
+ unsigned int irq_resched_count;
+ unsigned int irq_hv_flush_count;
+ unsigned int irq_call_count;
+ unsigned int irq_hv_msg_count;
+ unsigned int irq_dev_intr_count;
+
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
+
+#define __ARCH_IRQ_STAT
+#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
+
+#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */
+
+#define HARDIRQ_BITS 8
+
+#endif /* _ASM_TILE_HARDIRQ_H */
diff --git a/arch/tile/include/asm/hardwall.h b/arch/tile/include/asm/hardwall.h
new file mode 100644
index 000000000000..0bed3ec7b42c
--- /dev/null
+++ b/arch/tile/include/asm/hardwall.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Provide methods for the HARDWALL_FILE for accessing the UDN.
+ */
+
+#ifndef _ASM_TILE_HARDWALL_H
+#define _ASM_TILE_HARDWALL_H
+
+#include <linux/ioctl.h>
+
+#define HARDWALL_IOCTL_BASE 0xa2
+
+/*
+ * The HARDWALL_CREATE() ioctl is a macro with a "size" argument.
+ * The resulting ioctl value is passed to the kernel in conjunction
+ * with a pointer to a little-endian bitmask of cpus, which must be
+ * physically in a rectangular configuration on the chip.
+ * The "size" is the number of bytes of cpu mask data.
+ */
+#define _HARDWALL_CREATE 1
+#define HARDWALL_CREATE(size) \
+ _IOC(_IOC_READ, HARDWALL_IOCTL_BASE, _HARDWALL_CREATE, (size))
+
+#define _HARDWALL_ACTIVATE 2
+#define HARDWALL_ACTIVATE \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_ACTIVATE)
+
+#define _HARDWALL_DEACTIVATE 3
+#define HARDWALL_DEACTIVATE \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
+
+#ifndef __KERNEL__
+
+/* This is the canonical name expected by userspace. */
+#define HARDWALL_FILE "/dev/hardwall"
+
+#else
+
+/* Hook for /proc/tile/hardwall. */
+struct seq_file;
+int proc_tile_hardwall_show(struct seq_file *sf, void *v);
+
+#endif
+
+#endif /* _ASM_TILE_HARDWALL_H */
diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h
new file mode 100644
index 000000000000..efdd12e91020
--- /dev/null
+++ b/arch/tile/include/asm/highmem.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1999 Gerhard Wichert, Siemens AG
+ * Gerhard.Wichert@pdb.siemens.de
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Used in CONFIG_HIGHMEM systems for memory pages which
+ * are not addressable by direct kernel virtual addresses.
+ *
+ */
+
+#ifndef _ASM_TILE_HIGHMEM_H
+#define _ASM_TILE_HIGHMEM_H
+
+#include <linux/interrupt.h>
+#include <linux/threads.h>
+#include <asm/kmap_types.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
+
+/* declarations for highmem.c */
+extern unsigned long highstart_pfn, highend_pfn;
+
+extern pte_t *pkmap_page_table;
+
+/*
+ * Ordering is:
+ *
+ * FIXADDR_TOP
+ * fixed_addresses
+ * FIXADDR_START
+ * temp fixed addresses
+ * FIXADDR_BOOT_START
+ * Persistent kmap area
+ * PKMAP_BASE
+ * VMALLOC_END
+ * Vmalloc area
+ * VMALLOC_START
+ * high_memory
+ */
+#define LAST_PKMAP_MASK (LAST_PKMAP-1)
+#define PKMAP_NR(virt) ((virt-PKMAP_BASE) >> PAGE_SHIFT)
+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT))
+
+void *kmap_high(struct page *page);
+void kunmap_high(struct page *page);
+void *kmap(struct page *page);
+void kunmap(struct page *page);
+void *kmap_fix_kpte(struct page *page, int finished);
+
+/* This macro is used only in map_new_virtual() to map "page". */
+#define kmap_prot page_to_kpgprot(page)
+
+void kunmap_atomic(void *kvaddr, enum km_type type);
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type);
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot);
+struct page *kmap_atomic_to_page(void *ptr);
+void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot);
+void *kmap_atomic(struct page *page, enum km_type type);
+void kmap_atomic_fix_kpte(struct page *page, int finished);
+
+#define flush_cache_kmaps() do { } while (0)
+
+#endif /* _ASM_TILE_HIGHMEM_H */
diff --git a/arch/tile/include/asm/homecache.h b/arch/tile/include/asm/homecache.h
new file mode 100644
index 000000000000..a8243865d49e
--- /dev/null
+++ b/arch/tile/include/asm/homecache.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Handle issues around the Tile "home cache" model of coherence.
+ */
+
+#ifndef _ASM_TILE_HOMECACHE_H
+#define _ASM_TILE_HOMECACHE_H
+
+#include <asm/page.h>
+#include <linux/cpumask.h>
+
+struct page;
+struct task_struct;
+struct vm_area_struct;
+struct zone;
+
+/*
+ * Coherence point for the page is its memory controller.
+ * It is not present in any cache (L1 or L2).
+ */
+#define PAGE_HOME_UNCACHED -1
+
+/*
+ * Is this page immutable (unwritable) and thus able to be cached more
+ * widely than would otherwise be possible? On tile64 this means we
+ * mark the PTE to cache locally; on tilepro it means we have "nc" set.
+ */
+#define PAGE_HOME_IMMUTABLE -2
+
+/*
+ * Each cpu considers its own cache to be the home for the page,
+ * which makes it incoherent.
+ */
+#define PAGE_HOME_INCOHERENT -3
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+/* Home for the page is distributed via hash-for-home. */
+#define PAGE_HOME_HASH -4
+#endif
+
+/* Homing is unknown or unspecified. Not valid for page_home(). */
+#define PAGE_HOME_UNKNOWN -5
+
+/* Home on the current cpu. Not valid for page_home(). */
+#define PAGE_HOME_HERE -6
+
+/* Support wrapper to use instead of explicit hv_flush_remote(). */
+extern void flush_remote(unsigned long cache_pfn, unsigned long cache_length,
+ const struct cpumask *cache_cpumask,
+ HV_VirtAddr tlb_va, unsigned long tlb_length,
+ unsigned long tlb_pgsize,
+ const struct cpumask *tlb_cpumask,
+ HV_Remote_ASID *asids, int asidcount);
+
+/* Set homing-related bits in a PTE (can also pass a pgprot_t). */
+extern pte_t pte_set_home(pte_t pte, int home);
+
+/* Do a cache eviction on the specified cpus. */
+extern void homecache_evict(const struct cpumask *mask);
+
+/*
+ * Change a kernel page's homecache. It must not be mapped in user space.
+ * If !CONFIG_HOMECACHE, only usable on LOWMEM, and can only be called when
+ * no other cpu can reference the page, and causes a full-chip cache/TLB flush.
+ */
+extern void homecache_change_page_home(struct page *, int order, int home);
+
+/*
+ * Flush a page out of whatever cache(s) it is in.
+ * This is more than just finv, since it properly handles waiting
+ * for the data to reach memory on tilepro, but it can be quite
+ * heavyweight, particularly on hash-for-home memory.
+ */
+extern void homecache_flush_cache(struct page *, int order);
+
+/*
+ * Allocate a page with the given GFP flags, home, and optionally
+ * node. These routines are actually just wrappers around the normal
+ * alloc_pages() / alloc_pages_node() functions, which set and clear
+ * a per-cpu variable to communicate with homecache_new_kernel_page().
+ * If !CONFIG_HOMECACHE, uses homecache_change_page_home().
+ */
+extern struct page *homecache_alloc_pages(gfp_t gfp_mask,
+ unsigned int order, int home);
+extern struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
+ unsigned int order, int home);
+#define homecache_alloc_page(gfp_mask, home) \
+ homecache_alloc_pages(gfp_mask, 0, home)
+
+/*
+ * These routines are just pass-throughs to free_pages() when
+ * we support full homecaching. If !CONFIG_HOMECACHE, then these
+ * routines use homecache_change_page_home() to reset the home
+ * back to the default before returning the page to the allocator.
+ */
+void homecache_free_pages(unsigned long addr, unsigned int order);
+#define homecache_free_page(page) \
+ homecache_free_pages((page), 0)
+
+
+
+/*
+ * Report the page home for LOWMEM pages by examining their kernel PTE,
+ * or for highmem pages as the default home.
+ */
+extern int page_home(struct page *);
+
+#define homecache_migrate_kthread() do {} while (0)
+
+#define homecache_kpte_lock() 0
+#define homecache_kpte_unlock(flags) do {} while (0)
+
+
+#endif /* _ASM_TILE_HOMECACHE_H */
diff --git a/arch/tile/include/asm/hugetlb.h b/arch/tile/include/asm/hugetlb.h
new file mode 100644
index 000000000000..0521c277bbde
--- /dev/null
+++ b/arch/tile/include/asm/hugetlb.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_HUGETLB_H
+#define _ASM_TILE_HUGETLB_H
+
+#include <asm/page.h>
+
+
+static inline int is_hugepage_only_range(struct mm_struct *mm,
+ unsigned long addr,
+ unsigned long len) {
+ return 0;
+}
+
+/*
+ * If the arch doesn't supply something else, assume that hugepage
+ * size aligned regions are ok without further preparation.
+ */
+static inline int prepare_hugepage_range(struct file *file,
+ unsigned long addr, unsigned long len)
+{
+ struct hstate *h = hstate_file(file);
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (addr & ~huge_page_mask(h))
+ return -EINVAL;
+ return 0;
+}
+
+static inline void hugetlb_prefault_arch_hook(struct mm_struct *mm)
+{
+}
+
+static inline void hugetlb_free_pgd_range(struct mmu_gather *tlb,
+ unsigned long addr, unsigned long end,
+ unsigned long floor,
+ unsigned long ceiling)
+{
+ free_pgd_range(tlb, addr, end, floor, ceiling);
+}
+
+static inline void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ pte_t *ptep, pte_t pte)
+{
+ set_pte_order(ptep, pte, HUGETLB_PAGE_ORDER);
+}
+
+static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ return ptep_get_and_clear(mm, addr, ptep);
+}
+
+static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_clear_flush(vma, addr, ptep);
+}
+
+static inline int huge_pte_none(pte_t pte)
+{
+ return pte_none(pte);
+}
+
+static inline pte_t huge_pte_wrprotect(pte_t pte)
+{
+ return pte_wrprotect(pte);
+}
+
+static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ ptep_set_wrprotect(mm, addr, ptep);
+}
+
+static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep,
+ pte_t pte, int dirty)
+{
+ return ptep_set_access_flags(vma, addr, ptep, pte, dirty);
+}
+
+static inline pte_t huge_ptep_get(pte_t *ptep)
+{
+ return *ptep;
+}
+
+static inline int arch_prepare_hugepage(struct page *page)
+{
+ return 0;
+}
+
+static inline void arch_release_hugepage(struct page *page)
+{
+}
+
+#endif /* _ASM_TILE_HUGETLB_H */
diff --git a/arch/tile/include/asm/hv_driver.h b/arch/tile/include/asm/hv_driver.h
new file mode 100644
index 000000000000..ad614de899b3
--- /dev/null
+++ b/arch/tile/include/asm/hv_driver.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This header defines a wrapper interface for managing hypervisor
+ * device calls that will result in an interrupt at some later time.
+ * In particular, this provides wrappers for hv_preada() and
+ * hv_pwritea().
+ */
+
+#ifndef _ASM_TILE_HV_DRIVER_H
+#define _ASM_TILE_HV_DRIVER_H
+
+#include <hv/hypervisor.h>
+
+struct hv_driver_cb;
+
+/* A callback to be invoked when an operation completes. */
+typedef void hv_driver_callback_t(struct hv_driver_cb *cb, __hv32 result);
+
+/*
+ * A structure to hold information about an outstanding call.
+ * The driver must allocate a separate structure for each call.
+ */
+struct hv_driver_cb {
+ hv_driver_callback_t *callback; /* Function to call on interrupt. */
+ void *dev; /* Driver-specific state variable. */
+};
+
+/* Wrapper for invoking hv_dev_preada(). */
+static inline int
+tile_hv_dev_preada(int devhdl, __hv32 flags, __hv32 sgl_len,
+ HV_SGL sgl[/* sgl_len */], __hv64 offset,
+ struct hv_driver_cb *callback)
+{
+ return hv_dev_preada(devhdl, flags, sgl_len, sgl,
+ offset, (HV_IntArg)callback);
+}
+
+/* Wrapper for invoking hv_dev_pwritea(). */
+static inline int
+tile_hv_dev_pwritea(int devhdl, __hv32 flags, __hv32 sgl_len,
+ HV_SGL sgl[/* sgl_len */], __hv64 offset,
+ struct hv_driver_cb *callback)
+{
+ return hv_dev_pwritea(devhdl, flags, sgl_len, sgl,
+ offset, (HV_IntArg)callback);
+}
+
+
+#endif /* _ASM_TILE_HV_DRIVER_H */
diff --git a/arch/tile/include/asm/hw_irq.h b/arch/tile/include/asm/hw_irq.h
new file mode 100644
index 000000000000..4fac5fbf333e
--- /dev/null
+++ b/arch/tile/include/asm/hw_irq.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_HW_IRQ_H
+#define _ASM_TILE_HW_IRQ_H
+
+#endif /* _ASM_TILE_HW_IRQ_H */
diff --git a/arch/tile/include/asm/ide.h b/arch/tile/include/asm/ide.h
new file mode 100644
index 000000000000..3c6f2ed894ce
--- /dev/null
+++ b/arch/tile/include/asm/ide.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_IDE_H
+#define _ASM_TILE_IDE_H
+
+/* For IDE on PCI */
+#define MAX_HWIFS 10
+
+#define ide_default_io_ctl(base) (0)
+
+#include <asm-generic/ide_iops.h>
+
+#endif /* _ASM_TILE_IDE_H */
diff --git a/arch/tile/include/asm/io.h b/arch/tile/include/asm/io.h
new file mode 100644
index 000000000000..8c95bef3fa45
--- /dev/null
+++ b/arch/tile/include/asm/io.h
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_IO_H
+#define _ASM_TILE_IO_H
+
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <asm/page.h>
+
+#define IO_SPACE_LIMIT 0xfffffffful
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access.
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer.
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+/*
+ * Change "struct page" to physical address.
+ */
+#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
+
+/*
+ * Some places try to pass in an loff_t for PHYSADDR (?!), so we cast it to
+ * long before casting it to a pointer to avoid compiler warnings.
+ */
+#if CHIP_HAS_MMIO()
+extern void __iomem *ioremap(resource_size_t offset, unsigned long size);
+extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size,
+ pgprot_t pgprot);
+extern void iounmap(volatile void __iomem *addr);
+#else
+#define ioremap(physaddr, size) ((void __iomem *)(unsigned long)(physaddr))
+#define iounmap(addr) ((void)0)
+#endif
+
+#define ioremap_nocache(physaddr, size) ioremap(physaddr, size)
+#define ioremap_writethrough(physaddr, size) ioremap(physaddr, size)
+#define ioremap_fullcache(physaddr, size) ioremap(physaddr, size)
+
+void __iomem *ioport_map(unsigned long port, unsigned int len);
+extern inline void ioport_unmap(void __iomem *addr) {}
+
+#define mmiowb()
+
+/* Conversion between virtual and physical mappings. */
+#define mm_ptov(addr) ((void *)phys_to_virt(addr))
+#define mm_vtop(addr) ((unsigned long)virt_to_phys(addr))
+
+#ifdef CONFIG_PCI
+
+extern u8 _tile_readb(unsigned long addr);
+extern u16 _tile_readw(unsigned long addr);
+extern u32 _tile_readl(unsigned long addr);
+extern u64 _tile_readq(unsigned long addr);
+extern void _tile_writeb(u8 val, unsigned long addr);
+extern void _tile_writew(u16 val, unsigned long addr);
+extern void _tile_writel(u32 val, unsigned long addr);
+extern void _tile_writeq(u64 val, unsigned long addr);
+
+#else
+
+/*
+ * The Tile architecture does not support IOMEM unless PCI is enabled.
+ * Unfortunately we can't yet simply not declare these methods,
+ * since some generic code that compiles into the kernel, but
+ * we never run, uses them unconditionally.
+ */
+
+static inline int iomem_panic(void)
+{
+ panic("readb/writeb and friends do not exist on tile without PCI");
+ return 0;
+}
+
+static inline u8 _tile_readb(unsigned long addr)
+{
+ return iomem_panic();
+}
+
+static inline u16 _tile_readw(unsigned long addr)
+{
+ return iomem_panic();
+}
+
+static inline u32 _tile_readl(unsigned long addr)
+{
+ return iomem_panic();
+}
+
+static inline u64 _tile_readq(unsigned long addr)
+{
+ return iomem_panic();
+}
+
+static inline void _tile_writeb(u8 val, unsigned long addr)
+{
+ iomem_panic();
+}
+
+static inline void _tile_writew(u16 val, unsigned long addr)
+{
+ iomem_panic();
+}
+
+static inline void _tile_writel(u32 val, unsigned long addr)
+{
+ iomem_panic();
+}
+
+static inline void _tile_writeq(u64 val, unsigned long addr)
+{
+ iomem_panic();
+}
+
+#endif
+
+#define readb(addr) _tile_readb((unsigned long)addr)
+#define readw(addr) _tile_readw((unsigned long)addr)
+#define readl(addr) _tile_readl((unsigned long)addr)
+#define readq(addr) _tile_readq((unsigned long)addr)
+#define writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
+#define writew(val, addr) _tile_writew(val, (unsigned long)addr)
+#define writel(val, addr) _tile_writel(val, (unsigned long)addr)
+#define writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_readq readq
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+#define __raw_writeq writeq
+
+#define readb_relaxed readb
+#define readw_relaxed readw
+#define readl_relaxed readl
+#define readq_relaxed readq
+
+#define ioread8 readb
+#define ioread16 readw
+#define ioread32 readl
+#define ioread64 readq
+#define iowrite8 writeb
+#define iowrite16 writew
+#define iowrite32 writel
+#define iowrite64 writeq
+
+static inline void *memcpy_fromio(void *dst, void *src, int len)
+{
+ int x;
+ BUG_ON((unsigned long)src & 0x3);
+ for (x = 0; x < len; x += 4)
+ *(u32 *)(dst + x) = readl(src + x);
+ return dst;
+}
+
+static inline void *memcpy_toio(void *dst, void *src, int len)
+{
+ int x;
+ BUG_ON((unsigned long)dst & 0x3);
+ for (x = 0; x < len; x += 4)
+ writel(*(u32 *)(src + x), dst + x);
+ return dst;
+}
+
+/*
+ * The Tile architecture does not support IOPORT, even with PCI.
+ * Unfortunately we can't yet simply not declare these methods,
+ * since some generic code that compiles into the kernel, but
+ * we never run, uses them unconditionally.
+ */
+
+static inline int ioport_panic(void)
+{
+ panic("inb/outb and friends do not exist on tile");
+ return 0;
+}
+
+static inline u8 inb(unsigned long addr)
+{
+ return ioport_panic();
+}
+
+static inline u16 inw(unsigned long addr)
+{
+ return ioport_panic();
+}
+
+static inline u32 inl(unsigned long addr)
+{
+ return ioport_panic();
+}
+
+static inline void outb(u8 b, unsigned long addr)
+{
+ ioport_panic();
+}
+
+static inline void outw(u16 b, unsigned long addr)
+{
+ ioport_panic();
+}
+
+static inline void outl(u32 b, unsigned long addr)
+{
+ ioport_panic();
+}
+
+#define inb_p(addr) inb(addr)
+#define inw_p(addr) inw(addr)
+#define inl_p(addr) inl(addr)
+#define outb_p(x, addr) outb((x), (addr))
+#define outw_p(x, addr) outw((x), (addr))
+#define outl_p(x, addr) outl((x), (addr))
+
+static inline void insb(unsigned long addr, void *buffer, int count)
+{
+ ioport_panic();
+}
+
+static inline void insw(unsigned long addr, void *buffer, int count)
+{
+ ioport_panic();
+}
+
+static inline void insl(unsigned long addr, void *buffer, int count)
+{
+ ioport_panic();
+}
+
+static inline void outsb(unsigned long addr, const void *buffer, int count)
+{
+ ioport_panic();
+}
+
+static inline void outsw(unsigned long addr, const void *buffer, int count)
+{
+ ioport_panic();
+}
+
+static inline void outsl(unsigned long addr, const void *buffer, int count)
+{
+ ioport_panic();
+}
+
+#define ioread8_rep(p, dst, count) \
+ insb((unsigned long) (p), (dst), (count))
+#define ioread16_rep(p, dst, count) \
+ insw((unsigned long) (p), (dst), (count))
+#define ioread32_rep(p, dst, count) \
+ insl((unsigned long) (p), (dst), (count))
+
+#define iowrite8_rep(p, src, count) \
+ outsb((unsigned long) (p), (src), (count))
+#define iowrite16_rep(p, src, count) \
+ outsw((unsigned long) (p), (src), (count))
+#define iowrite32_rep(p, src, count) \
+ outsl((unsigned long) (p), (src), (count))
+
+#endif /* _ASM_TILE_IO_H */
diff --git a/arch/tile/include/asm/ioctl.h b/arch/tile/include/asm/ioctl.h
new file mode 100644
index 000000000000..b279fe06dfe5
--- /dev/null
+++ b/arch/tile/include/asm/ioctl.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctl.h>
diff --git a/arch/tile/include/asm/ioctls.h b/arch/tile/include/asm/ioctls.h
new file mode 100644
index 000000000000..ec34c760665e
--- /dev/null
+++ b/arch/tile/include/asm/ioctls.h
@@ -0,0 +1 @@
+#include <asm-generic/ioctls.h>
diff --git a/arch/tile/include/asm/ipc.h b/arch/tile/include/asm/ipc.h
new file mode 100644
index 000000000000..a46e3d9c2a3f
--- /dev/null
+++ b/arch/tile/include/asm/ipc.h
@@ -0,0 +1 @@
+#include <asm-generic/ipc.h>
diff --git a/arch/tile/include/asm/ipcbuf.h b/arch/tile/include/asm/ipcbuf.h
new file mode 100644
index 000000000000..84c7e51cb6d0
--- /dev/null
+++ b/arch/tile/include/asm/ipcbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/ipcbuf.h>
diff --git a/arch/tile/include/asm/irq.h b/arch/tile/include/asm/irq.h
new file mode 100644
index 000000000000..572fd3ef1d73
--- /dev/null
+++ b/arch/tile/include/asm/irq.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_IRQ_H
+#define _ASM_TILE_IRQ_H
+
+#include <linux/hardirq.h>
+
+/* The hypervisor interface provides 32 IRQs. */
+#define NR_IRQS 32
+
+/* IRQ numbers used for linux IPIs. */
+#define IRQ_RESCHEDULE 1
+
+void ack_bad_irq(unsigned int irq);
+
+/*
+ * Different ways of handling interrupts. Tile interrupts are always
+ * per-cpu; there is no global interrupt controller to implement
+ * enable/disable. Most onboard devices can send their interrupts to
+ * many tiles at the same time, and Tile-specific drivers know how to
+ * deal with this.
+ *
+ * However, generic devices (usually PCIE based, sometimes GPIO)
+ * expect that interrupts will fire on a single core at a time and
+ * that the irq can be enabled or disabled from any core at any time.
+ * We implement this by directing such interrupts to a single core.
+ *
+ * One added wrinkle is that PCI interrupts can be either
+ * hardware-cleared (legacy interrupts) or software cleared (MSI).
+ * Other generic device systems (GPIO) are always software-cleared.
+ *
+ * The enums below are used by drivers for onboard devices, including
+ * the internals of PCI root complex and GPIO. They allow the driver
+ * to tell the generic irq code what kind of interrupt is mapped to a
+ * particular IRQ number.
+ */
+enum {
+ /* per-cpu interrupt; use enable/disable_percpu_irq() to mask */
+ TILE_IRQ_PERCPU,
+ /* global interrupt, hardware responsible for clearing. */
+ TILE_IRQ_HW_CLEAR,
+ /* global interrupt, software responsible for clearing. */
+ TILE_IRQ_SW_CLEAR,
+};
+
+
+/*
+ * Paravirtualized drivers should call this when they dynamically
+ * allocate a new IRQ or discover an IRQ that was pre-allocated by the
+ * hypervisor for use with their particular device. This gives the
+ * IRQ subsystem an opportunity to do interrupt-type-specific
+ * initialization.
+ *
+ * ISSUE: We should modify this API so that registering anything
+ * except percpu interrupts also requires providing callback methods
+ * for enabling and disabling the interrupt. This would allow the
+ * generic IRQ code to proxy enable/disable_irq() calls back into the
+ * PCI subsystem, which in turn could enable or disable the interrupt
+ * at the PCI shim.
+ */
+void tile_irq_activate(unsigned int irq, int tile_irq_type);
+
+/*
+ * For onboard, non-PCI (e.g. TILE_IRQ_PERCPU) devices, drivers know
+ * how to use enable/disable_percpu_irq() to manage interrupts on each
+ * core. We can't use the generic enable/disable_irq() because they
+ * use a single reference count per irq, rather than per cpu per irq.
+ */
+void enable_percpu_irq(unsigned int irq);
+void disable_percpu_irq(unsigned int irq);
+
+
+void setup_irq_regs(void);
+
+#endif /* _ASM_TILE_IRQ_H */
diff --git a/arch/tile/include/asm/irq_regs.h b/arch/tile/include/asm/irq_regs.h
new file mode 100644
index 000000000000..3dd9c0b70270
--- /dev/null
+++ b/arch/tile/include/asm/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/tile/include/asm/irqflags.h b/arch/tile/include/asm/irqflags.h
new file mode 100644
index 000000000000..45cf67c2f286
--- /dev/null
+++ b/arch/tile/include/asm/irqflags.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_IRQFLAGS_H
+#define _ASM_TILE_IRQFLAGS_H
+
+#include <arch/interrupts.h>
+#include <arch/chip.h>
+
+/*
+ * The set of interrupts we want to allow when interrupts are nominally
+ * disabled. The remainder are effectively "NMI" interrupts from
+ * the point of view of the generic Linux code. Note that synchronous
+ * interrupts (aka "non-queued") are not blocked by the mask in any case.
+ */
+#if CHIP_HAS_AUX_PERF_COUNTERS()
+#define LINUX_MASKABLE_INTERRUPTS \
+ (~(INT_MASK(INT_PERF_COUNT) | INT_MASK(INT_AUX_PERF_COUNT)))
+#else
+#define LINUX_MASKABLE_INTERRUPTS \
+ (~(INT_MASK(INT_PERF_COUNT)))
+#endif
+
+#ifndef __ASSEMBLY__
+
+/* NOTE: we can't include <linux/percpu.h> due to #include dependencies. */
+#include <asm/percpu.h>
+#include <arch/spr_def.h>
+
+/* Set and clear kernel interrupt masks. */
+#if CHIP_HAS_SPLIT_INTR_MASK()
+#if INT_PERF_COUNT < 32 || INT_AUX_PERF_COUNT < 32 || INT_MEM_ERROR >= 32
+# error Fix assumptions about which word various interrupts are in
+#endif
+#define interrupt_mask_set(n) do { \
+ int __n = (n); \
+ int __mask = 1 << (__n & 0x1f); \
+ if (__n < 32) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, __mask); \
+ else \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, __mask); \
+} while (0)
+#define interrupt_mask_reset(n) do { \
+ int __n = (n); \
+ int __mask = 1 << (__n & 0x1f); \
+ if (__n < 32) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, __mask); \
+ else \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, __mask); \
+} while (0)
+#define interrupt_mask_check(n) ({ \
+ int __n = (n); \
+ (((__n < 32) ? \
+ __insn_mfspr(SPR_INTERRUPT_MASK_1_0) : \
+ __insn_mfspr(SPR_INTERRUPT_MASK_1_1)) \
+ >> (__n & 0x1f)) & 1; \
+})
+#define interrupt_mask_set_mask(mask) do { \
+ unsigned long long __m = (mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_0, (unsigned long)(__m)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1_1, (unsigned long)(__m>>32)); \
+} while (0)
+#define interrupt_mask_reset_mask(mask) do { \
+ unsigned long long __m = (mask); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_0, (unsigned long)(__m)); \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1_1, (unsigned long)(__m>>32)); \
+} while (0)
+#else
+#define interrupt_mask_set(n) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (1UL << (n)))
+#define interrupt_mask_reset(n) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (1UL << (n)))
+#define interrupt_mask_check(n) \
+ ((__insn_mfspr(SPR_INTERRUPT_MASK_1) >> (n)) & 1)
+#define interrupt_mask_set_mask(mask) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_SET_1, (mask))
+#define interrupt_mask_reset_mask(mask) \
+ __insn_mtspr(SPR_INTERRUPT_MASK_RESET_1, (mask))
+#endif
+
+/*
+ * The set of interrupts we want active if irqs are enabled.
+ * Note that in particular, the tile timer interrupt comes and goes
+ * from this set, since we have no other way to turn off the timer.
+ * Likewise, INTCTRL_1 is removed and re-added during device
+ * interrupts, as is the the hardwall UDN_FIREWALL interrupt.
+ * We use a low bit (MEM_ERROR) as our sentinel value and make sure it
+ * is always claimed as an "active interrupt" so we can query that bit
+ * to know our current state.
+ */
+DECLARE_PER_CPU(unsigned long long, interrupts_enabled_mask);
+#define INITIAL_INTERRUPTS_ENABLED INT_MASK(INT_MEM_ERROR)
+
+/* Disable interrupts. */
+#define raw_local_irq_disable() \
+ interrupt_mask_set_mask(LINUX_MASKABLE_INTERRUPTS)
+
+/* Disable all interrupts, including NMIs. */
+#define raw_local_irq_disable_all() \
+ interrupt_mask_set_mask(-1UL)
+
+/* Re-enable all maskable interrupts. */
+#define raw_local_irq_enable() \
+ interrupt_mask_reset_mask(__get_cpu_var(interrupts_enabled_mask))
+
+/* Disable or enable interrupts based on flag argument. */
+#define raw_local_irq_restore(disabled) do { \
+ if (disabled) \
+ raw_local_irq_disable(); \
+ else \
+ raw_local_irq_enable(); \
+} while (0)
+
+/* Return true if "flags" argument means interrupts are disabled. */
+#define raw_irqs_disabled_flags(flags) ((flags) != 0)
+
+/* Return true if interrupts are currently disabled. */
+#define raw_irqs_disabled() interrupt_mask_check(INT_MEM_ERROR)
+
+/* Save whether interrupts are currently disabled. */
+#define raw_local_save_flags(flags) ((flags) = raw_irqs_disabled())
+
+/* Save whether interrupts are currently disabled, then disable them. */
+#define raw_local_irq_save(flags) \
+ do { raw_local_save_flags(flags); raw_local_irq_disable(); } while (0)
+
+/* Prevent the given interrupt from being enabled next time we enable irqs. */
+#define raw_local_irq_mask(interrupt) \
+ (__get_cpu_var(interrupts_enabled_mask) &= ~INT_MASK(interrupt))
+
+/* Prevent the given interrupt from being enabled immediately. */
+#define raw_local_irq_mask_now(interrupt) do { \
+ raw_local_irq_mask(interrupt); \
+ interrupt_mask_set(interrupt); \
+} while (0)
+
+/* Allow the given interrupt to be enabled next time we enable irqs. */
+#define raw_local_irq_unmask(interrupt) \
+ (__get_cpu_var(interrupts_enabled_mask) |= INT_MASK(interrupt))
+
+/* Allow the given interrupt to be enabled immediately, if !irqs_disabled. */
+#define raw_local_irq_unmask_now(interrupt) do { \
+ raw_local_irq_unmask(interrupt); \
+ if (!irqs_disabled()) \
+ interrupt_mask_reset(interrupt); \
+} while (0)
+
+#else /* __ASSEMBLY__ */
+
+/* We provide a somewhat more restricted set for assembly. */
+
+#ifdef __tilegx__
+
+#if INT_MEM_ERROR != 0
+# error Fix IRQ_DISABLED() macro
+#endif
+
+/* Return 0 or 1 to indicate whether interrupts are currently disabled. */
+#define IRQS_DISABLED(tmp) \
+ mfspr tmp, INTERRUPT_MASK_1; \
+ andi tmp, tmp, 1
+
+/* Load up a pointer to &interrupts_enabled_mask. */
+#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
+ moveli reg, hw2_last(interrupts_enabled_mask); \
+ shl16insli reg, reg, hw1(interrupts_enabled_mask); \
+ shl16insli reg, reg, hw0(interrupts_enabled_mask); \
+ add reg, reg, tp
+
+/* Disable interrupts. */
+#define IRQ_DISABLE(tmp0, tmp1) \
+ moveli tmp0, hw2_last(LINUX_MASKABLE_INTERRUPTS); \
+ shl16insli tmp0, tmp0, hw1(LINUX_MASKABLE_INTERRUPTS); \
+ shl16insli tmp0, tmp0, hw0(LINUX_MASKABLE_INTERRUPTS); \
+ mtspr INTERRUPT_MASK_SET_1, tmp0
+
+/* Disable ALL synchronous interrupts (used by NMI entry). */
+#define IRQ_DISABLE_ALL(tmp) \
+ movei tmp, -1; \
+ mtspr INTERRUPT_MASK_SET_1, tmp
+
+/* Enable interrupts. */
+#define IRQ_ENABLE(tmp0, tmp1) \
+ GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
+ ld tmp0, tmp0; \
+ mtspr INTERRUPT_MASK_RESET_1, tmp0
+
+#else /* !__tilegx__ */
+
+/*
+ * Return 0 or 1 to indicate whether interrupts are currently disabled.
+ * Note that it's important that we use a bit from the "low" mask word,
+ * since when we are enabling, that is the word we write first, so if we
+ * are interrupted after only writing half of the mask, the interrupt
+ * handler will correctly observe that we have interrupts enabled, and
+ * will enable interrupts itself on return from the interrupt handler
+ * (making the original code's write of the "high" mask word idempotent).
+ */
+#define IRQS_DISABLED(tmp) \
+ mfspr tmp, INTERRUPT_MASK_1_0; \
+ shri tmp, tmp, INT_MEM_ERROR; \
+ andi tmp, tmp, 1
+
+/* Load up a pointer to &interrupts_enabled_mask. */
+#define GET_INTERRUPTS_ENABLED_MASK_PTR(reg) \
+ moveli reg, lo16(interrupts_enabled_mask); \
+ auli reg, reg, ha16(interrupts_enabled_mask);\
+ add reg, reg, tp
+
+/* Disable interrupts. */
+#define IRQ_DISABLE(tmp0, tmp1) \
+ { \
+ movei tmp0, -1; \
+ moveli tmp1, lo16(LINUX_MASKABLE_INTERRUPTS) \
+ }; \
+ { \
+ mtspr INTERRUPT_MASK_SET_1_0, tmp0; \
+ auli tmp1, tmp1, ha16(LINUX_MASKABLE_INTERRUPTS) \
+ }; \
+ mtspr INTERRUPT_MASK_SET_1_1, tmp1
+
+/* Disable ALL synchronous interrupts (used by NMI entry). */
+#define IRQ_DISABLE_ALL(tmp) \
+ movei tmp, -1; \
+ mtspr INTERRUPT_MASK_SET_1_0, tmp; \
+ mtspr INTERRUPT_MASK_SET_1_1, tmp
+
+/* Enable interrupts. */
+#define IRQ_ENABLE(tmp0, tmp1) \
+ GET_INTERRUPTS_ENABLED_MASK_PTR(tmp0); \
+ { \
+ lw tmp0, tmp0; \
+ addi tmp1, tmp0, 4 \
+ }; \
+ lw tmp1, tmp1; \
+ mtspr INTERRUPT_MASK_RESET_1_0, tmp0; \
+ mtspr INTERRUPT_MASK_RESET_1_1, tmp1
+#endif
+
+/*
+ * Do the CPU's IRQ-state tracing from assembly code. We call a
+ * C function, but almost everywhere we do, we don't mind clobbering
+ * all the caller-saved registers.
+ */
+#ifdef CONFIG_TRACE_IRQFLAGS
+# define TRACE_IRQS_ON jal trace_hardirqs_on
+# define TRACE_IRQS_OFF jal trace_hardirqs_off
+#else
+# define TRACE_IRQS_ON
+# define TRACE_IRQS_OFF
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_TILE_IRQFLAGS_H */
diff --git a/arch/tile/include/asm/kdebug.h b/arch/tile/include/asm/kdebug.h
new file mode 100644
index 000000000000..6ece1b037665
--- /dev/null
+++ b/arch/tile/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/tile/include/asm/kexec.h b/arch/tile/include/asm/kexec.h
new file mode 100644
index 000000000000..c11a6cc73bb8
--- /dev/null
+++ b/arch/tile/include/asm/kexec.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * based on kexec.h from other architectures in linux-2.6.18
+ */
+
+#ifndef _ASM_TILE_KEXEC_H
+#define _ASM_TILE_KEXEC_H
+
+#include <asm/page.h>
+
+/* Maximum physical address we can use pages from. */
+#define KEXEC_SOURCE_MEMORY_LIMIT TASK_SIZE
+/* Maximum address we can reach in physical address mode. */
+#define KEXEC_DESTINATION_MEMORY_LIMIT TASK_SIZE
+/* Maximum address we can use for the control code buffer. */
+#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
+
+#define KEXEC_CONTROL_PAGE_SIZE PAGE_SIZE
+
+/*
+ * We don't bother to provide a unique identifier, since we can only
+ * reboot with a single type of kernel image anyway.
+ */
+#define KEXEC_ARCH KEXEC_ARCH_DEFAULT
+
+/* Use the tile override for the page allocator. */
+struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order);
+#define kimage_alloc_pages_arch kimage_alloc_pages_arch
+
+#define MAX_NOTE_BYTES 1024
+
+/* Defined in arch/tile/kernel/relocate_kernel.S */
+extern const unsigned char relocate_new_kernel[];
+extern const unsigned long relocate_new_kernel_size;
+extern void relocate_new_kernel_end(void);
+
+/* Provide a dummy definition to avoid build failures. */
+static inline void crash_setup_regs(struct pt_regs *n, struct pt_regs *o)
+{
+}
+
+#endif /* _ASM_TILE_KEXEC_H */
diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h
new file mode 100644
index 000000000000..1480106d1c05
--- /dev/null
+++ b/arch/tile/include/asm/kmap_types.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_KMAP_TYPES_H
+#define _ASM_TILE_KMAP_TYPES_H
+
+/*
+ * In TILE Linux each set of four of these uses another 16MB chunk of
+ * address space, given 64 tiles and 64KB pages, so we only enable
+ * ones that are required by the kernel configuration.
+ */
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_BIO_SRC_IRQ,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_MEMCPY0,
+ KM_MEMCPY1,
+#if defined(CONFIG_HIGHPTE)
+ KM_PTE0,
+ KM_PTE1,
+#endif
+ KM_TYPE_NR
+};
+
+#endif /* _ASM_TILE_KMAP_TYPES_H */
diff --git a/arch/tile/include/asm/linkage.h b/arch/tile/include/asm/linkage.h
new file mode 100644
index 000000000000..e121c39751a7
--- /dev/null
+++ b/arch/tile/include/asm/linkage.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_LINKAGE_H
+#define _ASM_TILE_LINKAGE_H
+
+#include <feedback.h>
+
+#define __ALIGN .align 8
+
+/*
+ * The STD_ENTRY and STD_ENDPROC macros put the function in a
+ * self-named .text.foo section, and if linker feedback collection
+ * is enabled, add a suitable call to the feedback collection code.
+ * STD_ENTRY_SECTION lets you specify a non-standard section name.
+ */
+
+#define STD_ENTRY(name) \
+ .pushsection .text.##name, "ax"; \
+ ENTRY(name); \
+ FEEDBACK_ENTER(name)
+
+#define STD_ENTRY_SECTION(name, section) \
+ .pushsection section, "ax"; \
+ ENTRY(name); \
+ FEEDBACK_ENTER_EXPLICIT(name, section, .Lend_##name - name)
+
+#define STD_ENDPROC(name) \
+ ENDPROC(name); \
+ .Lend_##name:; \
+ .popsection
+
+/* Create a file-static function entry set up for feedback gathering. */
+#define STD_ENTRY_LOCAL(name) \
+ .pushsection .text.##name, "ax"; \
+ ALIGN; \
+ name:; \
+ FEEDBACK_ENTER(name)
+
+#endif /* _ASM_TILE_LINKAGE_H */
diff --git a/arch/tile/include/asm/local.h b/arch/tile/include/asm/local.h
new file mode 100644
index 000000000000..c11c530f74d0
--- /dev/null
+++ b/arch/tile/include/asm/local.h
@@ -0,0 +1 @@
+#include <asm-generic/local.h>
diff --git a/arch/tile/include/asm/memprof.h b/arch/tile/include/asm/memprof.h
new file mode 100644
index 000000000000..359949be28c1
--- /dev/null
+++ b/arch/tile/include/asm/memprof.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * The hypervisor's memory controller profiling infrastructure allows
+ * the programmer to find out what fraction of the available memory
+ * bandwidth is being consumed at each memory controller. The
+ * profiler provides start, stop, and clear operations to allows
+ * profiling over a specific time window, as well as an interface for
+ * reading the most recent profile values.
+ *
+ * This header declares IOCTL codes necessary to control memprof.
+ */
+#ifndef _ASM_TILE_MEMPROF_H
+#define _ASM_TILE_MEMPROF_H
+
+#include <linux/ioctl.h>
+
+#define MEMPROF_IOCTL_TYPE 0xB4
+#define MEMPROF_IOCTL_START _IO(MEMPROF_IOCTL_TYPE, 0)
+#define MEMPROF_IOCTL_STOP _IO(MEMPROF_IOCTL_TYPE, 1)
+#define MEMPROF_IOCTL_CLEAR _IO(MEMPROF_IOCTL_TYPE, 2)
+
+#endif /* _ASM_TILE_MEMPROF_H */
diff --git a/arch/tile/include/asm/mman.h b/arch/tile/include/asm/mman.h
new file mode 100644
index 000000000000..4c6811e3e8dc
--- /dev/null
+++ b/arch/tile/include/asm/mman.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_MMAN_H
+#define _ASM_TILE_MMAN_H
+
+#include <asm-generic/mman-common.h>
+#include <arch/chip.h>
+
+/* Standard Linux flags */
+
+#define MAP_POPULATE 0x0040 /* populate (prefault) pagetables */
+#define MAP_NONBLOCK 0x0080 /* do not block on IO */
+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */
+#define MAP_LOCKED 0x0200 /* pages are locked */
+#define MAP_NORESERVE 0x0400 /* don't check for reservations */
+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */
+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */
+#define MAP_HUGETLB 0x4000 /* create a huge page mapping */
+
+
+/*
+ * Flags for mlockall
+ */
+#define MCL_CURRENT 1 /* lock all current mappings */
+#define MCL_FUTURE 2 /* lock all future mappings */
+
+
+#endif /* _ASM_TILE_MMAN_H */
diff --git a/arch/tile/include/asm/mmu.h b/arch/tile/include/asm/mmu.h
new file mode 100644
index 000000000000..92f94c77b6e4
--- /dev/null
+++ b/arch/tile/include/asm/mmu.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_MMU_H
+#define _ASM_TILE_MMU_H
+
+/* Capture any arch- and mm-specific information. */
+struct mm_context {
+ /*
+ * Written under the mmap_sem semaphore; read without the
+ * semaphore but atomically, but it is conservatively set.
+ */
+ unsigned int priority_cached;
+};
+
+typedef struct mm_context mm_context_t;
+
+void leave_mm(int cpu);
+
+#endif /* _ASM_TILE_MMU_H */
diff --git a/arch/tile/include/asm/mmu_context.h b/arch/tile/include/asm/mmu_context.h
new file mode 100644
index 000000000000..9bc0d0725c28
--- /dev/null
+++ b/arch/tile/include/asm/mmu_context.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_MMU_CONTEXT_H
+#define _ASM_TILE_MMU_CONTEXT_H
+
+#include <linux/smp.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
+#include <asm-generic/mm_hooks.h>
+
+static inline int
+init_new_context(struct task_struct *tsk, struct mm_struct *mm)
+{
+ return 0;
+}
+
+/* Note that arch/tile/kernel/head.S also calls hv_install_context() */
+static inline void __install_page_table(pgd_t *pgdir, int asid, pgprot_t prot)
+{
+ /* FIXME: DIRECTIO should not always be set. FIXME. */
+ int rc = hv_install_context(__pa(pgdir), prot, asid, HV_CTX_DIRECTIO);
+ if (rc < 0)
+ panic("hv_install_context failed: %d", rc);
+}
+
+static inline void install_page_table(pgd_t *pgdir, int asid)
+{
+ pte_t *ptep = virt_to_pte(NULL, (unsigned long)pgdir);
+ __install_page_table(pgdir, asid, *ptep);
+}
+
+/*
+ * "Lazy" TLB mode is entered when we are switching to a kernel task,
+ * which borrows the mm of the previous task. The goal of this
+ * optimization is to avoid having to install a new page table. On
+ * early x86 machines (where the concept originated) you couldn't do
+ * anything short of a full page table install for invalidation, so
+ * handling a remote TLB invalidate required doing a page table
+ * re-install. Someone clearly decided that it was silly to keep
+ * doing this while in "lazy" TLB mode, so the optimization involves
+ * installing the swapper page table instead the first time one
+ * occurs, and clearing the cpu out of cpu_vm_mask, so the cpu running
+ * the kernel task doesn't need to take any more interrupts. At that
+ * point it's then necessary to explicitly reinstall it when context
+ * switching back to the original mm.
+ *
+ * On Tile, we have to do a page-table install whenever DMA is enabled,
+ * so in that case lazy mode doesn't help anyway. And more generally,
+ * we have efficient per-page TLB shootdown, and don't expect to spend
+ * that much time in kernel tasks in general, so just leaving the
+ * kernel task borrowing the old page table, but handling TLB
+ * shootdowns, is a reasonable thing to do. And importantly, this
+ * lets us use the hypervisor's internal APIs for TLB shootdown, which
+ * means we don't have to worry about having TLB shootdowns blocked
+ * when Linux is disabling interrupts; see the page migration code for
+ * an example of where it's important for TLB shootdowns to complete
+ * even when interrupts are disabled at the Linux level.
+ */
+static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *t)
+{
+#if CHIP_HAS_TILE_DMA()
+ /*
+ * We have to do an "identity" page table switch in order to
+ * clear any pending DMA interrupts.
+ */
+ if (current->thread.tile_dma_state.enabled)
+ install_page_table(mm->pgd, __get_cpu_var(current_asid));
+#endif
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ if (likely(prev != next)) {
+
+ int cpu = smp_processor_id();
+
+ /* Pick new ASID. */
+ int asid = __get_cpu_var(current_asid) + 1;
+ if (asid > max_asid) {
+ asid = min_asid;
+ local_flush_tlb();
+ }
+ __get_cpu_var(current_asid) = asid;
+
+ /* Clear cpu from the old mm, and set it in the new one. */
+ cpumask_clear_cpu(cpu, &prev->cpu_vm_mask);
+ cpumask_set_cpu(cpu, &next->cpu_vm_mask);
+
+ /* Re-load page tables */
+ install_page_table(next->pgd, asid);
+
+ /* See how we should set the red/black cache info */
+ check_mm_caching(prev, next);
+
+ /*
+ * Since we're changing to a new mm, we have to flush
+ * the icache in case some physical page now being mapped
+ * has subsequently been repurposed and has new code.
+ */
+ __flush_icache();
+
+ }
+}
+
+static inline void activate_mm(struct mm_struct *prev_mm,
+ struct mm_struct *next_mm)
+{
+ switch_mm(prev_mm, next_mm, NULL);
+}
+
+#define destroy_context(mm) do { } while (0)
+#define deactivate_mm(tsk, mm) do { } while (0)
+
+#endif /* _ASM_TILE_MMU_CONTEXT_H */
diff --git a/arch/tile/include/asm/mmzone.h b/arch/tile/include/asm/mmzone.h
new file mode 100644
index 000000000000..c6344c4f32ac
--- /dev/null
+++ b/arch/tile/include/asm/mmzone.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_MMZONE_H
+#define _ASM_TILE_MMZONE_H
+
+extern struct pglist_data node_data[];
+#define NODE_DATA(nid) (&node_data[nid])
+
+extern void get_memcfg_numa(void);
+
+#ifdef CONFIG_DISCONTIGMEM
+
+#include <asm/page.h>
+
+/*
+ * Generally, memory ranges are always doled out by the hypervisor in
+ * fixed-size, power-of-two increments. That would make computing the node
+ * very easy. We could just take a couple high bits of the PA, which
+ * denote the memory shim, and we'd be done. However, when we're doing
+ * memory striping, this may not be true; PAs with different high bit
+ * values might be in the same node. Thus, we keep a lookup table to
+ * translate the high bits of the PFN to the node number.
+ */
+extern int highbits_to_node[];
+
+static inline int pfn_to_nid(unsigned long pfn)
+{
+ return highbits_to_node[__pfn_to_highbits(pfn)];
+}
+
+/*
+ * Following are macros that each numa implmentation must define.
+ */
+
+#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid) \
+({ \
+ pg_data_t *__pgdat = NODE_DATA(nid); \
+ __pgdat->node_start_pfn + __pgdat->node_spanned_pages; \
+})
+
+#define kern_addr_valid(kaddr) virt_addr_valid((void *)kaddr)
+
+static inline int pfn_valid(int pfn)
+{
+ int nid = pfn_to_nid(pfn);
+
+ if (nid >= 0)
+ return (pfn < node_end_pfn(nid));
+ return 0;
+}
+
+/* Information on the NUMA nodes that we compute early */
+extern unsigned long node_start_pfn[];
+extern unsigned long node_end_pfn[];
+extern unsigned long node_memmap_pfn[];
+extern unsigned long node_percpu_pfn[];
+extern unsigned long node_free_pfn[];
+#ifdef CONFIG_HIGHMEM
+extern unsigned long node_lowmem_end_pfn[];
+#endif
+#ifdef CONFIG_PCI
+extern unsigned long pci_reserve_start_pfn;
+extern unsigned long pci_reserve_end_pfn;
+#endif
+
+#endif /* CONFIG_DISCONTIGMEM */
+
+#endif /* _ASM_TILE_MMZONE_H */
diff --git a/arch/tile/include/asm/module.h b/arch/tile/include/asm/module.h
new file mode 100644
index 000000000000..1e4b79fe8584
--- /dev/null
+++ b/arch/tile/include/asm/module.h
@@ -0,0 +1 @@
+#include <asm-generic/module.h>
diff --git a/arch/tile/include/asm/msgbuf.h b/arch/tile/include/asm/msgbuf.h
new file mode 100644
index 000000000000..809134c644a6
--- /dev/null
+++ b/arch/tile/include/asm/msgbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/msgbuf.h>
diff --git a/arch/tile/include/asm/mutex.h b/arch/tile/include/asm/mutex.h
new file mode 100644
index 000000000000..ff6101aa2c71
--- /dev/null
+++ b/arch/tile/include/asm/mutex.h
@@ -0,0 +1 @@
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/tile/include/asm/opcode-tile.h b/arch/tile/include/asm/opcode-tile.h
new file mode 100644
index 000000000000..ba38959137d7
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_OPCODE_TILE_H
+#define _ASM_TILE_OPCODE_TILE_H
+
+#include <arch/chip.h>
+
+#if CHIP_WORD_SIZE() == 64
+#include <asm/opcode-tile_64.h>
+#else
+#include <asm/opcode-tile_32.h>
+#endif
+
+/* These definitions are not correct for TILE64, so just avoid them. */
+#undef TILE_ELF_MACHINE_CODE
+#undef TILE_ELF_NAME
+
+#endif /* _ASM_TILE_OPCODE_TILE_H */
diff --git a/arch/tile/include/asm/opcode-tile_32.h b/arch/tile/include/asm/opcode-tile_32.h
new file mode 100644
index 000000000000..eda60ecbae3d
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile_32.h
@@ -0,0 +1,1506 @@
+/* tile.h -- Header file for TILE opcode table
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Contributed by Tilera Corp. */
+
+#ifndef opcode_tile_h
+#define opcode_tile_h
+
+typedef unsigned long long tile_bundle_bits;
+
+
+enum
+{
+ TILE_MAX_OPERANDS = 5 /* mm */
+};
+
+typedef enum
+{
+ TILE_OPC_BPT,
+ TILE_OPC_INFO,
+ TILE_OPC_INFOL,
+ TILE_OPC_J,
+ TILE_OPC_JAL,
+ TILE_OPC_MOVE,
+ TILE_OPC_MOVE_SN,
+ TILE_OPC_MOVEI,
+ TILE_OPC_MOVEI_SN,
+ TILE_OPC_MOVELI,
+ TILE_OPC_MOVELI_SN,
+ TILE_OPC_MOVELIS,
+ TILE_OPC_PREFETCH,
+ TILE_OPC_RAISE,
+ TILE_OPC_ADD,
+ TILE_OPC_ADD_SN,
+ TILE_OPC_ADDB,
+ TILE_OPC_ADDB_SN,
+ TILE_OPC_ADDBS_U,
+ TILE_OPC_ADDBS_U_SN,
+ TILE_OPC_ADDH,
+ TILE_OPC_ADDH_SN,
+ TILE_OPC_ADDHS,
+ TILE_OPC_ADDHS_SN,
+ TILE_OPC_ADDI,
+ TILE_OPC_ADDI_SN,
+ TILE_OPC_ADDIB,
+ TILE_OPC_ADDIB_SN,
+ TILE_OPC_ADDIH,
+ TILE_OPC_ADDIH_SN,
+ TILE_OPC_ADDLI,
+ TILE_OPC_ADDLI_SN,
+ TILE_OPC_ADDLIS,
+ TILE_OPC_ADDS,
+ TILE_OPC_ADDS_SN,
+ TILE_OPC_ADIFFB_U,
+ TILE_OPC_ADIFFB_U_SN,
+ TILE_OPC_ADIFFH,
+ TILE_OPC_ADIFFH_SN,
+ TILE_OPC_AND,
+ TILE_OPC_AND_SN,
+ TILE_OPC_ANDI,
+ TILE_OPC_ANDI_SN,
+ TILE_OPC_AULI,
+ TILE_OPC_AVGB_U,
+ TILE_OPC_AVGB_U_SN,
+ TILE_OPC_AVGH,
+ TILE_OPC_AVGH_SN,
+ TILE_OPC_BBNS,
+ TILE_OPC_BBNS_SN,
+ TILE_OPC_BBNST,
+ TILE_OPC_BBNST_SN,
+ TILE_OPC_BBS,
+ TILE_OPC_BBS_SN,
+ TILE_OPC_BBST,
+ TILE_OPC_BBST_SN,
+ TILE_OPC_BGEZ,
+ TILE_OPC_BGEZ_SN,
+ TILE_OPC_BGEZT,
+ TILE_OPC_BGEZT_SN,
+ TILE_OPC_BGZ,
+ TILE_OPC_BGZ_SN,
+ TILE_OPC_BGZT,
+ TILE_OPC_BGZT_SN,
+ TILE_OPC_BITX,
+ TILE_OPC_BITX_SN,
+ TILE_OPC_BLEZ,
+ TILE_OPC_BLEZ_SN,
+ TILE_OPC_BLEZT,
+ TILE_OPC_BLEZT_SN,
+ TILE_OPC_BLZ,
+ TILE_OPC_BLZ_SN,
+ TILE_OPC_BLZT,
+ TILE_OPC_BLZT_SN,
+ TILE_OPC_BNZ,
+ TILE_OPC_BNZ_SN,
+ TILE_OPC_BNZT,
+ TILE_OPC_BNZT_SN,
+ TILE_OPC_BYTEX,
+ TILE_OPC_BYTEX_SN,
+ TILE_OPC_BZ,
+ TILE_OPC_BZ_SN,
+ TILE_OPC_BZT,
+ TILE_OPC_BZT_SN,
+ TILE_OPC_CLZ,
+ TILE_OPC_CLZ_SN,
+ TILE_OPC_CRC32_32,
+ TILE_OPC_CRC32_32_SN,
+ TILE_OPC_CRC32_8,
+ TILE_OPC_CRC32_8_SN,
+ TILE_OPC_CTZ,
+ TILE_OPC_CTZ_SN,
+ TILE_OPC_DRAIN,
+ TILE_OPC_DTLBPR,
+ TILE_OPC_DWORD_ALIGN,
+ TILE_OPC_DWORD_ALIGN_SN,
+ TILE_OPC_FINV,
+ TILE_OPC_FLUSH,
+ TILE_OPC_FNOP,
+ TILE_OPC_ICOH,
+ TILE_OPC_ILL,
+ TILE_OPC_INTHB,
+ TILE_OPC_INTHB_SN,
+ TILE_OPC_INTHH,
+ TILE_OPC_INTHH_SN,
+ TILE_OPC_INTLB,
+ TILE_OPC_INTLB_SN,
+ TILE_OPC_INTLH,
+ TILE_OPC_INTLH_SN,
+ TILE_OPC_INV,
+ TILE_OPC_IRET,
+ TILE_OPC_JALB,
+ TILE_OPC_JALF,
+ TILE_OPC_JALR,
+ TILE_OPC_JALRP,
+ TILE_OPC_JB,
+ TILE_OPC_JF,
+ TILE_OPC_JR,
+ TILE_OPC_JRP,
+ TILE_OPC_LB,
+ TILE_OPC_LB_SN,
+ TILE_OPC_LB_U,
+ TILE_OPC_LB_U_SN,
+ TILE_OPC_LBADD,
+ TILE_OPC_LBADD_SN,
+ TILE_OPC_LBADD_U,
+ TILE_OPC_LBADD_U_SN,
+ TILE_OPC_LH,
+ TILE_OPC_LH_SN,
+ TILE_OPC_LH_U,
+ TILE_OPC_LH_U_SN,
+ TILE_OPC_LHADD,
+ TILE_OPC_LHADD_SN,
+ TILE_OPC_LHADD_U,
+ TILE_OPC_LHADD_U_SN,
+ TILE_OPC_LNK,
+ TILE_OPC_LNK_SN,
+ TILE_OPC_LW,
+ TILE_OPC_LW_SN,
+ TILE_OPC_LW_NA,
+ TILE_OPC_LW_NA_SN,
+ TILE_OPC_LWADD,
+ TILE_OPC_LWADD_SN,
+ TILE_OPC_LWADD_NA,
+ TILE_OPC_LWADD_NA_SN,
+ TILE_OPC_MAXB_U,
+ TILE_OPC_MAXB_U_SN,
+ TILE_OPC_MAXH,
+ TILE_OPC_MAXH_SN,
+ TILE_OPC_MAXIB_U,
+ TILE_OPC_MAXIB_U_SN,
+ TILE_OPC_MAXIH,
+ TILE_OPC_MAXIH_SN,
+ TILE_OPC_MF,
+ TILE_OPC_MFSPR,
+ TILE_OPC_MINB_U,
+ TILE_OPC_MINB_U_SN,
+ TILE_OPC_MINH,
+ TILE_OPC_MINH_SN,
+ TILE_OPC_MINIB_U,
+ TILE_OPC_MINIB_U_SN,
+ TILE_OPC_MINIH,
+ TILE_OPC_MINIH_SN,
+ TILE_OPC_MM,
+ TILE_OPC_MNZ,
+ TILE_OPC_MNZ_SN,
+ TILE_OPC_MNZB,
+ TILE_OPC_MNZB_SN,
+ TILE_OPC_MNZH,
+ TILE_OPC_MNZH_SN,
+ TILE_OPC_MTSPR,
+ TILE_OPC_MULHH_SS,
+ TILE_OPC_MULHH_SS_SN,
+ TILE_OPC_MULHH_SU,
+ TILE_OPC_MULHH_SU_SN,
+ TILE_OPC_MULHH_UU,
+ TILE_OPC_MULHH_UU_SN,
+ TILE_OPC_MULHHA_SS,
+ TILE_OPC_MULHHA_SS_SN,
+ TILE_OPC_MULHHA_SU,
+ TILE_OPC_MULHHA_SU_SN,
+ TILE_OPC_MULHHA_UU,
+ TILE_OPC_MULHHA_UU_SN,
+ TILE_OPC_MULHHSA_UU,
+ TILE_OPC_MULHHSA_UU_SN,
+ TILE_OPC_MULHL_SS,
+ TILE_OPC_MULHL_SS_SN,
+ TILE_OPC_MULHL_SU,
+ TILE_OPC_MULHL_SU_SN,
+ TILE_OPC_MULHL_US,
+ TILE_OPC_MULHL_US_SN,
+ TILE_OPC_MULHL_UU,
+ TILE_OPC_MULHL_UU_SN,
+ TILE_OPC_MULHLA_SS,
+ TILE_OPC_MULHLA_SS_SN,
+ TILE_OPC_MULHLA_SU,
+ TILE_OPC_MULHLA_SU_SN,
+ TILE_OPC_MULHLA_US,
+ TILE_OPC_MULHLA_US_SN,
+ TILE_OPC_MULHLA_UU,
+ TILE_OPC_MULHLA_UU_SN,
+ TILE_OPC_MULHLSA_UU,
+ TILE_OPC_MULHLSA_UU_SN,
+ TILE_OPC_MULLL_SS,
+ TILE_OPC_MULLL_SS_SN,
+ TILE_OPC_MULLL_SU,
+ TILE_OPC_MULLL_SU_SN,
+ TILE_OPC_MULLL_UU,
+ TILE_OPC_MULLL_UU_SN,
+ TILE_OPC_MULLLA_SS,
+ TILE_OPC_MULLLA_SS_SN,
+ TILE_OPC_MULLLA_SU,
+ TILE_OPC_MULLLA_SU_SN,
+ TILE_OPC_MULLLA_UU,
+ TILE_OPC_MULLLA_UU_SN,
+ TILE_OPC_MULLLSA_UU,
+ TILE_OPC_MULLLSA_UU_SN,
+ TILE_OPC_MVNZ,
+ TILE_OPC_MVNZ_SN,
+ TILE_OPC_MVZ,
+ TILE_OPC_MVZ_SN,
+ TILE_OPC_MZ,
+ TILE_OPC_MZ_SN,
+ TILE_OPC_MZB,
+ TILE_OPC_MZB_SN,
+ TILE_OPC_MZH,
+ TILE_OPC_MZH_SN,
+ TILE_OPC_NAP,
+ TILE_OPC_NOP,
+ TILE_OPC_NOR,
+ TILE_OPC_NOR_SN,
+ TILE_OPC_OR,
+ TILE_OPC_OR_SN,
+ TILE_OPC_ORI,
+ TILE_OPC_ORI_SN,
+ TILE_OPC_PACKBS_U,
+ TILE_OPC_PACKBS_U_SN,
+ TILE_OPC_PACKHB,
+ TILE_OPC_PACKHB_SN,
+ TILE_OPC_PACKHS,
+ TILE_OPC_PACKHS_SN,
+ TILE_OPC_PACKLB,
+ TILE_OPC_PACKLB_SN,
+ TILE_OPC_PCNT,
+ TILE_OPC_PCNT_SN,
+ TILE_OPC_RL,
+ TILE_OPC_RL_SN,
+ TILE_OPC_RLI,
+ TILE_OPC_RLI_SN,
+ TILE_OPC_S1A,
+ TILE_OPC_S1A_SN,
+ TILE_OPC_S2A,
+ TILE_OPC_S2A_SN,
+ TILE_OPC_S3A,
+ TILE_OPC_S3A_SN,
+ TILE_OPC_SADAB_U,
+ TILE_OPC_SADAB_U_SN,
+ TILE_OPC_SADAH,
+ TILE_OPC_SADAH_SN,
+ TILE_OPC_SADAH_U,
+ TILE_OPC_SADAH_U_SN,
+ TILE_OPC_SADB_U,
+ TILE_OPC_SADB_U_SN,
+ TILE_OPC_SADH,
+ TILE_OPC_SADH_SN,
+ TILE_OPC_SADH_U,
+ TILE_OPC_SADH_U_SN,
+ TILE_OPC_SB,
+ TILE_OPC_SBADD,
+ TILE_OPC_SEQ,
+ TILE_OPC_SEQ_SN,
+ TILE_OPC_SEQB,
+ TILE_OPC_SEQB_SN,
+ TILE_OPC_SEQH,
+ TILE_OPC_SEQH_SN,
+ TILE_OPC_SEQI,
+ TILE_OPC_SEQI_SN,
+ TILE_OPC_SEQIB,
+ TILE_OPC_SEQIB_SN,
+ TILE_OPC_SEQIH,
+ TILE_OPC_SEQIH_SN,
+ TILE_OPC_SH,
+ TILE_OPC_SHADD,
+ TILE_OPC_SHL,
+ TILE_OPC_SHL_SN,
+ TILE_OPC_SHLB,
+ TILE_OPC_SHLB_SN,
+ TILE_OPC_SHLH,
+ TILE_OPC_SHLH_SN,
+ TILE_OPC_SHLI,
+ TILE_OPC_SHLI_SN,
+ TILE_OPC_SHLIB,
+ TILE_OPC_SHLIB_SN,
+ TILE_OPC_SHLIH,
+ TILE_OPC_SHLIH_SN,
+ TILE_OPC_SHR,
+ TILE_OPC_SHR_SN,
+ TILE_OPC_SHRB,
+ TILE_OPC_SHRB_SN,
+ TILE_OPC_SHRH,
+ TILE_OPC_SHRH_SN,
+ TILE_OPC_SHRI,
+ TILE_OPC_SHRI_SN,
+ TILE_OPC_SHRIB,
+ TILE_OPC_SHRIB_SN,
+ TILE_OPC_SHRIH,
+ TILE_OPC_SHRIH_SN,
+ TILE_OPC_SLT,
+ TILE_OPC_SLT_SN,
+ TILE_OPC_SLT_U,
+ TILE_OPC_SLT_U_SN,
+ TILE_OPC_SLTB,
+ TILE_OPC_SLTB_SN,
+ TILE_OPC_SLTB_U,
+ TILE_OPC_SLTB_U_SN,
+ TILE_OPC_SLTE,
+ TILE_OPC_SLTE_SN,
+ TILE_OPC_SLTE_U,
+ TILE_OPC_SLTE_U_SN,
+ TILE_OPC_SLTEB,
+ TILE_OPC_SLTEB_SN,
+ TILE_OPC_SLTEB_U,
+ TILE_OPC_SLTEB_U_SN,
+ TILE_OPC_SLTEH,
+ TILE_OPC_SLTEH_SN,
+ TILE_OPC_SLTEH_U,
+ TILE_OPC_SLTEH_U_SN,
+ TILE_OPC_SLTH,
+ TILE_OPC_SLTH_SN,
+ TILE_OPC_SLTH_U,
+ TILE_OPC_SLTH_U_SN,
+ TILE_OPC_SLTI,
+ TILE_OPC_SLTI_SN,
+ TILE_OPC_SLTI_U,
+ TILE_OPC_SLTI_U_SN,
+ TILE_OPC_SLTIB,
+ TILE_OPC_SLTIB_SN,
+ TILE_OPC_SLTIB_U,
+ TILE_OPC_SLTIB_U_SN,
+ TILE_OPC_SLTIH,
+ TILE_OPC_SLTIH_SN,
+ TILE_OPC_SLTIH_U,
+ TILE_OPC_SLTIH_U_SN,
+ TILE_OPC_SNE,
+ TILE_OPC_SNE_SN,
+ TILE_OPC_SNEB,
+ TILE_OPC_SNEB_SN,
+ TILE_OPC_SNEH,
+ TILE_OPC_SNEH_SN,
+ TILE_OPC_SRA,
+ TILE_OPC_SRA_SN,
+ TILE_OPC_SRAB,
+ TILE_OPC_SRAB_SN,
+ TILE_OPC_SRAH,
+ TILE_OPC_SRAH_SN,
+ TILE_OPC_SRAI,
+ TILE_OPC_SRAI_SN,
+ TILE_OPC_SRAIB,
+ TILE_OPC_SRAIB_SN,
+ TILE_OPC_SRAIH,
+ TILE_OPC_SRAIH_SN,
+ TILE_OPC_SUB,
+ TILE_OPC_SUB_SN,
+ TILE_OPC_SUBB,
+ TILE_OPC_SUBB_SN,
+ TILE_OPC_SUBBS_U,
+ TILE_OPC_SUBBS_U_SN,
+ TILE_OPC_SUBH,
+ TILE_OPC_SUBH_SN,
+ TILE_OPC_SUBHS,
+ TILE_OPC_SUBHS_SN,
+ TILE_OPC_SUBS,
+ TILE_OPC_SUBS_SN,
+ TILE_OPC_SW,
+ TILE_OPC_SWADD,
+ TILE_OPC_SWINT0,
+ TILE_OPC_SWINT1,
+ TILE_OPC_SWINT2,
+ TILE_OPC_SWINT3,
+ TILE_OPC_TBLIDXB0,
+ TILE_OPC_TBLIDXB0_SN,
+ TILE_OPC_TBLIDXB1,
+ TILE_OPC_TBLIDXB1_SN,
+ TILE_OPC_TBLIDXB2,
+ TILE_OPC_TBLIDXB2_SN,
+ TILE_OPC_TBLIDXB3,
+ TILE_OPC_TBLIDXB3_SN,
+ TILE_OPC_TNS,
+ TILE_OPC_TNS_SN,
+ TILE_OPC_WH64,
+ TILE_OPC_XOR,
+ TILE_OPC_XOR_SN,
+ TILE_OPC_XORI,
+ TILE_OPC_XORI_SN,
+ TILE_OPC_NONE
+} tile_mnemonic;
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
+
+
+#define TILE_ELF_MACHINE_CODE EM_TILEPRO
+
+#define TILE_ELF_NAME "elf32-tilepro"
+
+
+static __inline unsigned int
+get_BrOff_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000);
+}
+
+static __inline unsigned int
+get_BrType_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0xf);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 2)) & 0x3);
+}
+
+static __inline unsigned int
+get_Dest_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm8_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 51)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 8)) & 0x3);
+}
+
+static __inline unsigned int
+get_JOffLong_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000) |
+ (((unsigned int)(n >> 14)) & 0x001e0000) |
+ (((unsigned int)(n >> 16)) & 0x07e00000) |
+ (((unsigned int)(n >> 31)) & 0x18000000);
+}
+
+static __inline unsigned int
+get_JOff_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000) |
+ (((unsigned int)(n >> 14)) & 0x001e0000) |
+ (((unsigned int)(n >> 16)) & 0x07e00000) |
+ (((unsigned int)(n >> 31)) & 0x08000000);
+}
+
+static __inline unsigned int
+get_MF_Imm15_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x00003fff) |
+ (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_MMEnd_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMEnd_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 23)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MT_Imm15_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 37)) & 0x00003fc0) |
+ (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_Mode(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 63)) & 0x1);
+}
+
+static __inline unsigned int
+get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 10)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Opcode_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 28)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 27)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y2(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 56)) & 0x7);
+}
+
+static __inline unsigned int
+get_RROpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 4)) & 0xf);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_RouteOpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_S_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 27)) & 0x1);
+}
+
+static __inline unsigned int
+get_S_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 58)) & 0x1);
+}
+
+static __inline unsigned int
+get_ShAmt_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_SrcA_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y2(tile_bundle_bits n)
+{
+ return (((n >> 26)) & 0x00000001) |
+ (((unsigned int)(n >> 50)) & 0x0000003e);
+}
+
+static __inline unsigned int
+get_SrcBDest_Y2(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Src_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 17)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 48)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 17)) & 0x7);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 48)) & 0x7);
+}
+
+
+static __inline int
+sign_extend(int n, int num_bits)
+{
+ int shift = (int)(sizeof(int) * 8 - num_bits);
+ return (n << shift) >> shift;
+}
+
+
+
+static __inline tile_bundle_bits
+create_BrOff_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_BrOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20);
+}
+
+static __inline tile_bundle_bits
+create_BrType_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tile_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Dest_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 2);
+}
+
+static __inline tile_bundle_bits
+create_Dest_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Dest_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Imm16_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xffff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm16_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xffff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_ImmOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7f) << 20);
+}
+
+static __inline tile_bundle_bits
+create_ImmOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7f)) << 51);
+}
+
+static __inline tile_bundle_bits
+create_ImmRROpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 8);
+}
+
+static __inline tile_bundle_bits
+create_JOffLong_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20) |
+ (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
+ (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
+ (((tile_bundle_bits)(n & 0x18000000)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_JOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20) |
+ (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
+ (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
+ (((tile_bundle_bits)(n & 0x08000000)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_MF_Imm15_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
+ (((tile_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tile_bundle_bits
+create_MMEnd_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 18);
+}
+
+static __inline tile_bundle_bits
+create_MMEnd_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_MMStart_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 23);
+}
+
+static __inline tile_bundle_bits
+create_MMStart_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 54);
+}
+
+static __inline tile_bundle_bits
+create_MT_Imm15_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
+ (((tile_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tile_bundle_bits
+create_Mode(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1)) << 63);
+}
+
+static __inline tile_bundle_bits
+create_NoRegOpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 10);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7) << 28);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 27);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7)) << 56);
+}
+
+static __inline tile_bundle_bits
+create_RROpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 4);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1ff) << 18);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1ff)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 18);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_RouteOpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_S_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1) << 27);
+}
+
+static __inline tile_bundle_bits
+create_S_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1)) << 58);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x00000001) << 26) |
+ (((tile_bundle_bits)(n & 0x0000003e)) << 50);
+}
+
+static __inline tile_bundle_bits
+create_SrcBDest_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 20);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Src_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 0);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 17);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3ff)) << 48);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7) << 17);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7)) << 48);
+}
+
+
+
+typedef enum
+{
+ TILE_PIPELINE_X0,
+ TILE_PIPELINE_X1,
+ TILE_PIPELINE_Y0,
+ TILE_PIPELINE_Y1,
+ TILE_PIPELINE_Y2,
+} tile_pipeline;
+
+#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
+
+typedef enum
+{
+ TILE_OP_TYPE_REGISTER,
+ TILE_OP_TYPE_IMMEDIATE,
+ TILE_OP_TYPE_ADDRESS,
+ TILE_OP_TYPE_SPR
+} tile_operand_type;
+
+/* This is the bit that determines if a bundle is in the Y encoding. */
+#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
+
+enum
+{
+ /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+ TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+ /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+ TILE_NUM_PIPELINE_ENCODINGS = 5,
+
+ /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
+ TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+ /* Instructions take this many bytes. */
+ TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+ /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
+ TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+ /* Bundles should be aligned modulo this number of bytes. */
+ TILE_BUNDLE_ALIGNMENT_IN_BYTES =
+ (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+ /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
+ TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
+
+ /* Static network instructions take this many bytes. */
+ TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
+ (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
+
+ /* Number of registers (some are magic, such as network I/O). */
+ TILE_NUM_REGISTERS = 64,
+
+ /* Number of static network registers. */
+ TILE_NUM_SN_REGISTERS = 4
+};
+
+
+struct tile_operand
+{
+ /* Is this operand a register, immediate or address? */
+ tile_operand_type type;
+
+ /* The default relocation type for this operand. */
+ signed int default_reloc : 16;
+
+ /* How many bits is this value? (used for range checking) */
+ unsigned int num_bits : 5;
+
+ /* Is the value signed? (used for range checking) */
+ unsigned int is_signed : 1;
+
+ /* Is this operand a source register? */
+ unsigned int is_src_reg : 1;
+
+ /* Is this operand written? (i.e. is it a destination register) */
+ unsigned int is_dest_reg : 1;
+
+ /* Is this operand PC-relative? */
+ unsigned int is_pc_relative : 1;
+
+ /* By how many bits do we right shift the value before inserting? */
+ unsigned int rightshift : 2;
+
+ /* Return the bits for this operand to be ORed into an existing bundle. */
+ tile_bundle_bits (*insert) (int op);
+
+ /* Extract this operand and return it. */
+ unsigned int (*extract) (tile_bundle_bits bundle);
+};
+
+
+extern const struct tile_operand tile_operands[];
+
+/* One finite-state machine per pipe for rapid instruction decoding. */
+extern const unsigned short * const
+tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
+
+
+struct tile_opcode
+{
+ /* The opcode mnemonic, e.g. "add" */
+ const char *name;
+
+ /* The enum value for this mnemonic. */
+ tile_mnemonic mnemonic;
+
+ /* A bit mask of which of the five pipes this instruction
+ is compatible with:
+ X0 0x01
+ X1 0x02
+ Y0 0x04
+ Y1 0x08
+ Y2 0x10 */
+ unsigned char pipes;
+
+ /* How many operands are there? */
+ unsigned char num_operands;
+
+ /* Which register does this write implicitly, or TREG_ZERO if none? */
+ unsigned char implicitly_written_register;
+
+ /* Can this be bundled with other instructions (almost always true). */
+ unsigned char can_bundle;
+
+ /* The description of the operands. Each of these is an
+ * index into the tile_operands[] table. */
+ unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
+
+};
+
+extern const struct tile_opcode tile_opcodes[];
+
+
+/* Used for non-textual disassembly into structs. */
+struct tile_decoded_instruction
+{
+ const struct tile_opcode *opcode;
+ const struct tile_operand *operands[TILE_MAX_OPERANDS];
+ int operand_values[TILE_MAX_OPERANDS];
+};
+
+
+/* Disassemble a bundle into a struct for machine processing. */
+extern int parse_insn_tile(tile_bundle_bits bits,
+ unsigned int pc,
+ struct tile_decoded_instruction
+ decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
+
+
+
+#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode-tile_64.h b/arch/tile/include/asm/opcode-tile_64.h
new file mode 100644
index 000000000000..eda60ecbae3d
--- /dev/null
+++ b/arch/tile/include/asm/opcode-tile_64.h
@@ -0,0 +1,1506 @@
+/* tile.h -- Header file for TILE opcode table
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Contributed by Tilera Corp. */
+
+#ifndef opcode_tile_h
+#define opcode_tile_h
+
+typedef unsigned long long tile_bundle_bits;
+
+
+enum
+{
+ TILE_MAX_OPERANDS = 5 /* mm */
+};
+
+typedef enum
+{
+ TILE_OPC_BPT,
+ TILE_OPC_INFO,
+ TILE_OPC_INFOL,
+ TILE_OPC_J,
+ TILE_OPC_JAL,
+ TILE_OPC_MOVE,
+ TILE_OPC_MOVE_SN,
+ TILE_OPC_MOVEI,
+ TILE_OPC_MOVEI_SN,
+ TILE_OPC_MOVELI,
+ TILE_OPC_MOVELI_SN,
+ TILE_OPC_MOVELIS,
+ TILE_OPC_PREFETCH,
+ TILE_OPC_RAISE,
+ TILE_OPC_ADD,
+ TILE_OPC_ADD_SN,
+ TILE_OPC_ADDB,
+ TILE_OPC_ADDB_SN,
+ TILE_OPC_ADDBS_U,
+ TILE_OPC_ADDBS_U_SN,
+ TILE_OPC_ADDH,
+ TILE_OPC_ADDH_SN,
+ TILE_OPC_ADDHS,
+ TILE_OPC_ADDHS_SN,
+ TILE_OPC_ADDI,
+ TILE_OPC_ADDI_SN,
+ TILE_OPC_ADDIB,
+ TILE_OPC_ADDIB_SN,
+ TILE_OPC_ADDIH,
+ TILE_OPC_ADDIH_SN,
+ TILE_OPC_ADDLI,
+ TILE_OPC_ADDLI_SN,
+ TILE_OPC_ADDLIS,
+ TILE_OPC_ADDS,
+ TILE_OPC_ADDS_SN,
+ TILE_OPC_ADIFFB_U,
+ TILE_OPC_ADIFFB_U_SN,
+ TILE_OPC_ADIFFH,
+ TILE_OPC_ADIFFH_SN,
+ TILE_OPC_AND,
+ TILE_OPC_AND_SN,
+ TILE_OPC_ANDI,
+ TILE_OPC_ANDI_SN,
+ TILE_OPC_AULI,
+ TILE_OPC_AVGB_U,
+ TILE_OPC_AVGB_U_SN,
+ TILE_OPC_AVGH,
+ TILE_OPC_AVGH_SN,
+ TILE_OPC_BBNS,
+ TILE_OPC_BBNS_SN,
+ TILE_OPC_BBNST,
+ TILE_OPC_BBNST_SN,
+ TILE_OPC_BBS,
+ TILE_OPC_BBS_SN,
+ TILE_OPC_BBST,
+ TILE_OPC_BBST_SN,
+ TILE_OPC_BGEZ,
+ TILE_OPC_BGEZ_SN,
+ TILE_OPC_BGEZT,
+ TILE_OPC_BGEZT_SN,
+ TILE_OPC_BGZ,
+ TILE_OPC_BGZ_SN,
+ TILE_OPC_BGZT,
+ TILE_OPC_BGZT_SN,
+ TILE_OPC_BITX,
+ TILE_OPC_BITX_SN,
+ TILE_OPC_BLEZ,
+ TILE_OPC_BLEZ_SN,
+ TILE_OPC_BLEZT,
+ TILE_OPC_BLEZT_SN,
+ TILE_OPC_BLZ,
+ TILE_OPC_BLZ_SN,
+ TILE_OPC_BLZT,
+ TILE_OPC_BLZT_SN,
+ TILE_OPC_BNZ,
+ TILE_OPC_BNZ_SN,
+ TILE_OPC_BNZT,
+ TILE_OPC_BNZT_SN,
+ TILE_OPC_BYTEX,
+ TILE_OPC_BYTEX_SN,
+ TILE_OPC_BZ,
+ TILE_OPC_BZ_SN,
+ TILE_OPC_BZT,
+ TILE_OPC_BZT_SN,
+ TILE_OPC_CLZ,
+ TILE_OPC_CLZ_SN,
+ TILE_OPC_CRC32_32,
+ TILE_OPC_CRC32_32_SN,
+ TILE_OPC_CRC32_8,
+ TILE_OPC_CRC32_8_SN,
+ TILE_OPC_CTZ,
+ TILE_OPC_CTZ_SN,
+ TILE_OPC_DRAIN,
+ TILE_OPC_DTLBPR,
+ TILE_OPC_DWORD_ALIGN,
+ TILE_OPC_DWORD_ALIGN_SN,
+ TILE_OPC_FINV,
+ TILE_OPC_FLUSH,
+ TILE_OPC_FNOP,
+ TILE_OPC_ICOH,
+ TILE_OPC_ILL,
+ TILE_OPC_INTHB,
+ TILE_OPC_INTHB_SN,
+ TILE_OPC_INTHH,
+ TILE_OPC_INTHH_SN,
+ TILE_OPC_INTLB,
+ TILE_OPC_INTLB_SN,
+ TILE_OPC_INTLH,
+ TILE_OPC_INTLH_SN,
+ TILE_OPC_INV,
+ TILE_OPC_IRET,
+ TILE_OPC_JALB,
+ TILE_OPC_JALF,
+ TILE_OPC_JALR,
+ TILE_OPC_JALRP,
+ TILE_OPC_JB,
+ TILE_OPC_JF,
+ TILE_OPC_JR,
+ TILE_OPC_JRP,
+ TILE_OPC_LB,
+ TILE_OPC_LB_SN,
+ TILE_OPC_LB_U,
+ TILE_OPC_LB_U_SN,
+ TILE_OPC_LBADD,
+ TILE_OPC_LBADD_SN,
+ TILE_OPC_LBADD_U,
+ TILE_OPC_LBADD_U_SN,
+ TILE_OPC_LH,
+ TILE_OPC_LH_SN,
+ TILE_OPC_LH_U,
+ TILE_OPC_LH_U_SN,
+ TILE_OPC_LHADD,
+ TILE_OPC_LHADD_SN,
+ TILE_OPC_LHADD_U,
+ TILE_OPC_LHADD_U_SN,
+ TILE_OPC_LNK,
+ TILE_OPC_LNK_SN,
+ TILE_OPC_LW,
+ TILE_OPC_LW_SN,
+ TILE_OPC_LW_NA,
+ TILE_OPC_LW_NA_SN,
+ TILE_OPC_LWADD,
+ TILE_OPC_LWADD_SN,
+ TILE_OPC_LWADD_NA,
+ TILE_OPC_LWADD_NA_SN,
+ TILE_OPC_MAXB_U,
+ TILE_OPC_MAXB_U_SN,
+ TILE_OPC_MAXH,
+ TILE_OPC_MAXH_SN,
+ TILE_OPC_MAXIB_U,
+ TILE_OPC_MAXIB_U_SN,
+ TILE_OPC_MAXIH,
+ TILE_OPC_MAXIH_SN,
+ TILE_OPC_MF,
+ TILE_OPC_MFSPR,
+ TILE_OPC_MINB_U,
+ TILE_OPC_MINB_U_SN,
+ TILE_OPC_MINH,
+ TILE_OPC_MINH_SN,
+ TILE_OPC_MINIB_U,
+ TILE_OPC_MINIB_U_SN,
+ TILE_OPC_MINIH,
+ TILE_OPC_MINIH_SN,
+ TILE_OPC_MM,
+ TILE_OPC_MNZ,
+ TILE_OPC_MNZ_SN,
+ TILE_OPC_MNZB,
+ TILE_OPC_MNZB_SN,
+ TILE_OPC_MNZH,
+ TILE_OPC_MNZH_SN,
+ TILE_OPC_MTSPR,
+ TILE_OPC_MULHH_SS,
+ TILE_OPC_MULHH_SS_SN,
+ TILE_OPC_MULHH_SU,
+ TILE_OPC_MULHH_SU_SN,
+ TILE_OPC_MULHH_UU,
+ TILE_OPC_MULHH_UU_SN,
+ TILE_OPC_MULHHA_SS,
+ TILE_OPC_MULHHA_SS_SN,
+ TILE_OPC_MULHHA_SU,
+ TILE_OPC_MULHHA_SU_SN,
+ TILE_OPC_MULHHA_UU,
+ TILE_OPC_MULHHA_UU_SN,
+ TILE_OPC_MULHHSA_UU,
+ TILE_OPC_MULHHSA_UU_SN,
+ TILE_OPC_MULHL_SS,
+ TILE_OPC_MULHL_SS_SN,
+ TILE_OPC_MULHL_SU,
+ TILE_OPC_MULHL_SU_SN,
+ TILE_OPC_MULHL_US,
+ TILE_OPC_MULHL_US_SN,
+ TILE_OPC_MULHL_UU,
+ TILE_OPC_MULHL_UU_SN,
+ TILE_OPC_MULHLA_SS,
+ TILE_OPC_MULHLA_SS_SN,
+ TILE_OPC_MULHLA_SU,
+ TILE_OPC_MULHLA_SU_SN,
+ TILE_OPC_MULHLA_US,
+ TILE_OPC_MULHLA_US_SN,
+ TILE_OPC_MULHLA_UU,
+ TILE_OPC_MULHLA_UU_SN,
+ TILE_OPC_MULHLSA_UU,
+ TILE_OPC_MULHLSA_UU_SN,
+ TILE_OPC_MULLL_SS,
+ TILE_OPC_MULLL_SS_SN,
+ TILE_OPC_MULLL_SU,
+ TILE_OPC_MULLL_SU_SN,
+ TILE_OPC_MULLL_UU,
+ TILE_OPC_MULLL_UU_SN,
+ TILE_OPC_MULLLA_SS,
+ TILE_OPC_MULLLA_SS_SN,
+ TILE_OPC_MULLLA_SU,
+ TILE_OPC_MULLLA_SU_SN,
+ TILE_OPC_MULLLA_UU,
+ TILE_OPC_MULLLA_UU_SN,
+ TILE_OPC_MULLLSA_UU,
+ TILE_OPC_MULLLSA_UU_SN,
+ TILE_OPC_MVNZ,
+ TILE_OPC_MVNZ_SN,
+ TILE_OPC_MVZ,
+ TILE_OPC_MVZ_SN,
+ TILE_OPC_MZ,
+ TILE_OPC_MZ_SN,
+ TILE_OPC_MZB,
+ TILE_OPC_MZB_SN,
+ TILE_OPC_MZH,
+ TILE_OPC_MZH_SN,
+ TILE_OPC_NAP,
+ TILE_OPC_NOP,
+ TILE_OPC_NOR,
+ TILE_OPC_NOR_SN,
+ TILE_OPC_OR,
+ TILE_OPC_OR_SN,
+ TILE_OPC_ORI,
+ TILE_OPC_ORI_SN,
+ TILE_OPC_PACKBS_U,
+ TILE_OPC_PACKBS_U_SN,
+ TILE_OPC_PACKHB,
+ TILE_OPC_PACKHB_SN,
+ TILE_OPC_PACKHS,
+ TILE_OPC_PACKHS_SN,
+ TILE_OPC_PACKLB,
+ TILE_OPC_PACKLB_SN,
+ TILE_OPC_PCNT,
+ TILE_OPC_PCNT_SN,
+ TILE_OPC_RL,
+ TILE_OPC_RL_SN,
+ TILE_OPC_RLI,
+ TILE_OPC_RLI_SN,
+ TILE_OPC_S1A,
+ TILE_OPC_S1A_SN,
+ TILE_OPC_S2A,
+ TILE_OPC_S2A_SN,
+ TILE_OPC_S3A,
+ TILE_OPC_S3A_SN,
+ TILE_OPC_SADAB_U,
+ TILE_OPC_SADAB_U_SN,
+ TILE_OPC_SADAH,
+ TILE_OPC_SADAH_SN,
+ TILE_OPC_SADAH_U,
+ TILE_OPC_SADAH_U_SN,
+ TILE_OPC_SADB_U,
+ TILE_OPC_SADB_U_SN,
+ TILE_OPC_SADH,
+ TILE_OPC_SADH_SN,
+ TILE_OPC_SADH_U,
+ TILE_OPC_SADH_U_SN,
+ TILE_OPC_SB,
+ TILE_OPC_SBADD,
+ TILE_OPC_SEQ,
+ TILE_OPC_SEQ_SN,
+ TILE_OPC_SEQB,
+ TILE_OPC_SEQB_SN,
+ TILE_OPC_SEQH,
+ TILE_OPC_SEQH_SN,
+ TILE_OPC_SEQI,
+ TILE_OPC_SEQI_SN,
+ TILE_OPC_SEQIB,
+ TILE_OPC_SEQIB_SN,
+ TILE_OPC_SEQIH,
+ TILE_OPC_SEQIH_SN,
+ TILE_OPC_SH,
+ TILE_OPC_SHADD,
+ TILE_OPC_SHL,
+ TILE_OPC_SHL_SN,
+ TILE_OPC_SHLB,
+ TILE_OPC_SHLB_SN,
+ TILE_OPC_SHLH,
+ TILE_OPC_SHLH_SN,
+ TILE_OPC_SHLI,
+ TILE_OPC_SHLI_SN,
+ TILE_OPC_SHLIB,
+ TILE_OPC_SHLIB_SN,
+ TILE_OPC_SHLIH,
+ TILE_OPC_SHLIH_SN,
+ TILE_OPC_SHR,
+ TILE_OPC_SHR_SN,
+ TILE_OPC_SHRB,
+ TILE_OPC_SHRB_SN,
+ TILE_OPC_SHRH,
+ TILE_OPC_SHRH_SN,
+ TILE_OPC_SHRI,
+ TILE_OPC_SHRI_SN,
+ TILE_OPC_SHRIB,
+ TILE_OPC_SHRIB_SN,
+ TILE_OPC_SHRIH,
+ TILE_OPC_SHRIH_SN,
+ TILE_OPC_SLT,
+ TILE_OPC_SLT_SN,
+ TILE_OPC_SLT_U,
+ TILE_OPC_SLT_U_SN,
+ TILE_OPC_SLTB,
+ TILE_OPC_SLTB_SN,
+ TILE_OPC_SLTB_U,
+ TILE_OPC_SLTB_U_SN,
+ TILE_OPC_SLTE,
+ TILE_OPC_SLTE_SN,
+ TILE_OPC_SLTE_U,
+ TILE_OPC_SLTE_U_SN,
+ TILE_OPC_SLTEB,
+ TILE_OPC_SLTEB_SN,
+ TILE_OPC_SLTEB_U,
+ TILE_OPC_SLTEB_U_SN,
+ TILE_OPC_SLTEH,
+ TILE_OPC_SLTEH_SN,
+ TILE_OPC_SLTEH_U,
+ TILE_OPC_SLTEH_U_SN,
+ TILE_OPC_SLTH,
+ TILE_OPC_SLTH_SN,
+ TILE_OPC_SLTH_U,
+ TILE_OPC_SLTH_U_SN,
+ TILE_OPC_SLTI,
+ TILE_OPC_SLTI_SN,
+ TILE_OPC_SLTI_U,
+ TILE_OPC_SLTI_U_SN,
+ TILE_OPC_SLTIB,
+ TILE_OPC_SLTIB_SN,
+ TILE_OPC_SLTIB_U,
+ TILE_OPC_SLTIB_U_SN,
+ TILE_OPC_SLTIH,
+ TILE_OPC_SLTIH_SN,
+ TILE_OPC_SLTIH_U,
+ TILE_OPC_SLTIH_U_SN,
+ TILE_OPC_SNE,
+ TILE_OPC_SNE_SN,
+ TILE_OPC_SNEB,
+ TILE_OPC_SNEB_SN,
+ TILE_OPC_SNEH,
+ TILE_OPC_SNEH_SN,
+ TILE_OPC_SRA,
+ TILE_OPC_SRA_SN,
+ TILE_OPC_SRAB,
+ TILE_OPC_SRAB_SN,
+ TILE_OPC_SRAH,
+ TILE_OPC_SRAH_SN,
+ TILE_OPC_SRAI,
+ TILE_OPC_SRAI_SN,
+ TILE_OPC_SRAIB,
+ TILE_OPC_SRAIB_SN,
+ TILE_OPC_SRAIH,
+ TILE_OPC_SRAIH_SN,
+ TILE_OPC_SUB,
+ TILE_OPC_SUB_SN,
+ TILE_OPC_SUBB,
+ TILE_OPC_SUBB_SN,
+ TILE_OPC_SUBBS_U,
+ TILE_OPC_SUBBS_U_SN,
+ TILE_OPC_SUBH,
+ TILE_OPC_SUBH_SN,
+ TILE_OPC_SUBHS,
+ TILE_OPC_SUBHS_SN,
+ TILE_OPC_SUBS,
+ TILE_OPC_SUBS_SN,
+ TILE_OPC_SW,
+ TILE_OPC_SWADD,
+ TILE_OPC_SWINT0,
+ TILE_OPC_SWINT1,
+ TILE_OPC_SWINT2,
+ TILE_OPC_SWINT3,
+ TILE_OPC_TBLIDXB0,
+ TILE_OPC_TBLIDXB0_SN,
+ TILE_OPC_TBLIDXB1,
+ TILE_OPC_TBLIDXB1_SN,
+ TILE_OPC_TBLIDXB2,
+ TILE_OPC_TBLIDXB2_SN,
+ TILE_OPC_TBLIDXB3,
+ TILE_OPC_TBLIDXB3_SN,
+ TILE_OPC_TNS,
+ TILE_OPC_TNS_SN,
+ TILE_OPC_WH64,
+ TILE_OPC_XOR,
+ TILE_OPC_XOR_SN,
+ TILE_OPC_XORI,
+ TILE_OPC_XORI_SN,
+ TILE_OPC_NONE
+} tile_mnemonic;
+
+/* 64-bit pattern for a { bpt ; nop } bundle. */
+#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
+
+
+#define TILE_ELF_MACHINE_CODE EM_TILEPRO
+
+#define TILE_ELF_NAME "elf32-tilepro"
+
+
+static __inline unsigned int
+get_BrOff_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_BrOff_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000);
+}
+
+static __inline unsigned int
+get_BrType_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0xf);
+}
+
+static __inline unsigned int
+get_Dest_Imm8_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 2)) & 0x3);
+}
+
+static __inline unsigned int
+get_Dest_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Dest_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Imm16_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm16_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xffff);
+}
+
+static __inline unsigned int
+get_Imm8_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0xff);
+}
+
+static __inline unsigned int
+get_Imm8_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0xff);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 51)) & 0x7f);
+}
+
+static __inline unsigned int
+get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 8)) & 0x3);
+}
+
+static __inline unsigned int
+get_JOffLong_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000) |
+ (((unsigned int)(n >> 14)) & 0x001e0000) |
+ (((unsigned int)(n >> 16)) & 0x07e00000) |
+ (((unsigned int)(n >> 31)) & 0x18000000);
+}
+
+static __inline unsigned int
+get_JOff_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x00007fff) |
+ (((unsigned int)(n >> 20)) & 0x00018000) |
+ (((unsigned int)(n >> 14)) & 0x001e0000) |
+ (((unsigned int)(n >> 16)) & 0x07e00000) |
+ (((unsigned int)(n >> 31)) & 0x08000000);
+}
+
+static __inline unsigned int
+get_MF_Imm15_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x00003fff) |
+ (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_MMEnd_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMEnd_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 23)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MMStart_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 54)) & 0x1f);
+}
+
+static __inline unsigned int
+get_MT_Imm15_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 31)) & 0x0000003f) |
+ (((unsigned int)(n >> 37)) & 0x00003fc0) |
+ (((unsigned int)(n >> 44)) & 0x00004000);
+}
+
+static __inline unsigned int
+get_Mode(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 63)) & 0x1);
+}
+
+static __inline unsigned int
+get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 10)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Opcode_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 28)) & 0x7);
+}
+
+static __inline unsigned int
+get_Opcode_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 27)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 59)) & 0xf);
+}
+
+static __inline unsigned int
+get_Opcode_Y2(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 56)) & 0x7);
+}
+
+static __inline unsigned int
+get_RROpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 4)) & 0xf);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x1ff);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 18)) & 0x3);
+}
+
+static __inline unsigned int
+get_RRROpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 49)) & 0x3);
+}
+
+static __inline unsigned int
+get_RouteOpcodeExtension_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_S_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 27)) & 0x1);
+}
+
+static __inline unsigned int
+get_S_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 58)) & 0x1);
+}
+
+static __inline unsigned int
+get_ShAmt_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_ShAmt_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_SrcA_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 6)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 37)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcA_Y2(tile_bundle_bits n)
+{
+ return (((n >> 26)) & 0x00000001) |
+ (((unsigned int)(n >> 50)) & 0x0000003e);
+}
+
+static __inline unsigned int
+get_SrcBDest_Y2(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 20)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x3f);
+}
+
+static __inline unsigned int
+get_SrcB_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x3f);
+}
+
+static __inline unsigned int
+get_Src_SN(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 0)) & 0x3);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 12)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnOpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 43)) & 0x1f);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 17)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_X1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 48)) & 0x3ff);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((n >> 17)) & 0x7);
+}
+
+static __inline unsigned int
+get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
+{
+ return (((unsigned int)(n >> 48)) & 0x7);
+}
+
+
+static __inline int
+sign_extend(int n, int num_bits)
+{
+ int shift = (int)(sizeof(int) * 8 - num_bits);
+ return (n << shift) >> shift;
+}
+
+
+
+static __inline tile_bundle_bits
+create_BrOff_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_BrOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20);
+}
+
+static __inline tile_bundle_bits
+create_BrType_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tile_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Dest_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 2);
+}
+
+static __inline tile_bundle_bits
+create_Dest_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Dest_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Dest_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_Imm16_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xffff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm16_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xffff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xff) << 12);
+}
+
+static __inline tile_bundle_bits
+create_Imm8_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xff)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_ImmOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7f) << 20);
+}
+
+static __inline tile_bundle_bits
+create_ImmOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7f)) << 51);
+}
+
+static __inline tile_bundle_bits
+create_ImmRROpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 8);
+}
+
+static __inline tile_bundle_bits
+create_JOffLong_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20) |
+ (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
+ (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
+ (((tile_bundle_bits)(n & 0x18000000)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_JOff_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
+ (((tile_bundle_bits)(n & 0x00018000)) << 20) |
+ (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
+ (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
+ (((tile_bundle_bits)(n & 0x08000000)) << 31);
+}
+
+static __inline tile_bundle_bits
+create_MF_Imm15_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
+ (((tile_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tile_bundle_bits
+create_MMEnd_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 18);
+}
+
+static __inline tile_bundle_bits
+create_MMEnd_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_MMStart_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 23);
+}
+
+static __inline tile_bundle_bits
+create_MMStart_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 54);
+}
+
+static __inline tile_bundle_bits
+create_MT_Imm15_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
+ (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
+ (((tile_bundle_bits)(n & 0x00004000)) << 44);
+}
+
+static __inline tile_bundle_bits
+create_Mode(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1)) << 63);
+}
+
+static __inline tile_bundle_bits
+create_NoRegOpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 0);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 10);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7) << 28);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 27);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0xf)) << 59);
+}
+
+static __inline tile_bundle_bits
+create_Opcode_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7)) << 56);
+}
+
+static __inline tile_bundle_bits
+create_RROpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0xf) << 4);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1ff) << 18);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1ff)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 18);
+}
+
+static __inline tile_bundle_bits
+create_RRROpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tile_bundle_bits
+create_RouteOpcodeExtension_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 0);
+}
+
+static __inline tile_bundle_bits
+create_S_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1) << 27);
+}
+
+static __inline tile_bundle_bits
+create_S_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1)) << 58);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_ShAmt_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 6);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 37);
+}
+
+static __inline tile_bundle_bits
+create_SrcA_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x00000001) << 26) |
+ (((tile_bundle_bits)(n & 0x0000003e)) << 50);
+}
+
+static __inline tile_bundle_bits
+create_SrcBDest_Y2(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 20);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_SrcB_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_Src_SN(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3) << 0);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x1f) << 12);
+}
+
+static __inline tile_bundle_bits
+create_UnOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x1f)) << 43);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_X0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x3ff) << 17);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_X1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x3ff)) << 48);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_Y0(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return ((n & 0x7) << 17);
+}
+
+static __inline tile_bundle_bits
+create_UnShOpcodeExtension_Y1(int num)
+{
+ const unsigned int n = (unsigned int)num;
+ return (((tile_bundle_bits)(n & 0x7)) << 48);
+}
+
+
+
+typedef enum
+{
+ TILE_PIPELINE_X0,
+ TILE_PIPELINE_X1,
+ TILE_PIPELINE_Y0,
+ TILE_PIPELINE_Y1,
+ TILE_PIPELINE_Y2,
+} tile_pipeline;
+
+#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
+
+typedef enum
+{
+ TILE_OP_TYPE_REGISTER,
+ TILE_OP_TYPE_IMMEDIATE,
+ TILE_OP_TYPE_ADDRESS,
+ TILE_OP_TYPE_SPR
+} tile_operand_type;
+
+/* This is the bit that determines if a bundle is in the Y encoding. */
+#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
+
+enum
+{
+ /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
+ TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+
+ /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
+ TILE_NUM_PIPELINE_ENCODINGS = 5,
+
+ /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
+ TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+
+ /* Instructions take this many bytes. */
+ TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
+
+ /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
+ TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+
+ /* Bundles should be aligned modulo this number of bytes. */
+ TILE_BUNDLE_ALIGNMENT_IN_BYTES =
+ (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
+
+ /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
+ TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
+
+ /* Static network instructions take this many bytes. */
+ TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
+ (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
+
+ /* Number of registers (some are magic, such as network I/O). */
+ TILE_NUM_REGISTERS = 64,
+
+ /* Number of static network registers. */
+ TILE_NUM_SN_REGISTERS = 4
+};
+
+
+struct tile_operand
+{
+ /* Is this operand a register, immediate or address? */
+ tile_operand_type type;
+
+ /* The default relocation type for this operand. */
+ signed int default_reloc : 16;
+
+ /* How many bits is this value? (used for range checking) */
+ unsigned int num_bits : 5;
+
+ /* Is the value signed? (used for range checking) */
+ unsigned int is_signed : 1;
+
+ /* Is this operand a source register? */
+ unsigned int is_src_reg : 1;
+
+ /* Is this operand written? (i.e. is it a destination register) */
+ unsigned int is_dest_reg : 1;
+
+ /* Is this operand PC-relative? */
+ unsigned int is_pc_relative : 1;
+
+ /* By how many bits do we right shift the value before inserting? */
+ unsigned int rightshift : 2;
+
+ /* Return the bits for this operand to be ORed into an existing bundle. */
+ tile_bundle_bits (*insert) (int op);
+
+ /* Extract this operand and return it. */
+ unsigned int (*extract) (tile_bundle_bits bundle);
+};
+
+
+extern const struct tile_operand tile_operands[];
+
+/* One finite-state machine per pipe for rapid instruction decoding. */
+extern const unsigned short * const
+tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
+
+
+struct tile_opcode
+{
+ /* The opcode mnemonic, e.g. "add" */
+ const char *name;
+
+ /* The enum value for this mnemonic. */
+ tile_mnemonic mnemonic;
+
+ /* A bit mask of which of the five pipes this instruction
+ is compatible with:
+ X0 0x01
+ X1 0x02
+ Y0 0x04
+ Y1 0x08
+ Y2 0x10 */
+ unsigned char pipes;
+
+ /* How many operands are there? */
+ unsigned char num_operands;
+
+ /* Which register does this write implicitly, or TREG_ZERO if none? */
+ unsigned char implicitly_written_register;
+
+ /* Can this be bundled with other instructions (almost always true). */
+ unsigned char can_bundle;
+
+ /* The description of the operands. Each of these is an
+ * index into the tile_operands[] table. */
+ unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
+
+};
+
+extern const struct tile_opcode tile_opcodes[];
+
+
+/* Used for non-textual disassembly into structs. */
+struct tile_decoded_instruction
+{
+ const struct tile_opcode *opcode;
+ const struct tile_operand *operands[TILE_MAX_OPERANDS];
+ int operand_values[TILE_MAX_OPERANDS];
+};
+
+
+/* Disassemble a bundle into a struct for machine processing. */
+extern int parse_insn_tile(tile_bundle_bits bits,
+ unsigned int pc,
+ struct tile_decoded_instruction
+ decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
+
+
+
+#endif /* opcode_tile_h */
diff --git a/arch/tile/include/asm/opcode_constants.h b/arch/tile/include/asm/opcode_constants.h
new file mode 100644
index 000000000000..37a9f2958cb1
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_OPCODE_CONSTANTS_H
+#define _ASM_TILE_OPCODE_CONSTANTS_H
+
+#include <arch/chip.h>
+
+#if CHIP_WORD_SIZE() == 64
+#include <asm/opcode_constants_64.h>
+#else
+#include <asm/opcode_constants_32.h>
+#endif
+
+#endif /* _ASM_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/opcode_constants_32.h b/arch/tile/include/asm/opcode_constants_32.h
new file mode 100644
index 000000000000..227d033b180c
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants_32.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/* This file is machine-generated; DO NOT EDIT! */
+
+
+#ifndef _TILE_OPCODE_CONSTANTS_H
+#define _TILE_OPCODE_CONSTANTS_H
+enum
+{
+ ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
+ ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
+ ADDB_SPECIAL_0_OPCODE_X0 = 1,
+ ADDB_SPECIAL_0_OPCODE_X1 = 1,
+ ADDHS_SPECIAL_0_OPCODE_X0 = 99,
+ ADDHS_SPECIAL_0_OPCODE_X1 = 69,
+ ADDH_SPECIAL_0_OPCODE_X0 = 2,
+ ADDH_SPECIAL_0_OPCODE_X1 = 2,
+ ADDIB_IMM_0_OPCODE_X0 = 1,
+ ADDIB_IMM_0_OPCODE_X1 = 1,
+ ADDIH_IMM_0_OPCODE_X0 = 2,
+ ADDIH_IMM_0_OPCODE_X1 = 2,
+ ADDI_IMM_0_OPCODE_X0 = 3,
+ ADDI_IMM_0_OPCODE_X1 = 3,
+ ADDI_IMM_1_OPCODE_SN = 1,
+ ADDI_OPCODE_Y0 = 9,
+ ADDI_OPCODE_Y1 = 7,
+ ADDLIS_OPCODE_X0 = 1,
+ ADDLIS_OPCODE_X1 = 2,
+ ADDLI_OPCODE_X0 = 2,
+ ADDLI_OPCODE_X1 = 3,
+ ADDS_SPECIAL_0_OPCODE_X0 = 96,
+ ADDS_SPECIAL_0_OPCODE_X1 = 66,
+ ADD_SPECIAL_0_OPCODE_X0 = 3,
+ ADD_SPECIAL_0_OPCODE_X1 = 3,
+ ADD_SPECIAL_0_OPCODE_Y0 = 0,
+ ADD_SPECIAL_0_OPCODE_Y1 = 0,
+ ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
+ ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
+ ANDI_IMM_0_OPCODE_X0 = 1,
+ ANDI_IMM_0_OPCODE_X1 = 4,
+ ANDI_OPCODE_Y0 = 10,
+ ANDI_OPCODE_Y1 = 8,
+ AND_SPECIAL_0_OPCODE_X0 = 6,
+ AND_SPECIAL_0_OPCODE_X1 = 4,
+ AND_SPECIAL_2_OPCODE_Y0 = 0,
+ AND_SPECIAL_2_OPCODE_Y1 = 0,
+ AULI_OPCODE_X0 = 3,
+ AULI_OPCODE_X1 = 4,
+ AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
+ AVGH_SPECIAL_0_OPCODE_X0 = 8,
+ BBNST_BRANCH_OPCODE_X1 = 15,
+ BBNS_BRANCH_OPCODE_X1 = 14,
+ BBNS_OPCODE_SN = 63,
+ BBST_BRANCH_OPCODE_X1 = 13,
+ BBS_BRANCH_OPCODE_X1 = 12,
+ BBS_OPCODE_SN = 62,
+ BGEZT_BRANCH_OPCODE_X1 = 7,
+ BGEZ_BRANCH_OPCODE_X1 = 6,
+ BGEZ_OPCODE_SN = 61,
+ BGZT_BRANCH_OPCODE_X1 = 5,
+ BGZ_BRANCH_OPCODE_X1 = 4,
+ BGZ_OPCODE_SN = 58,
+ BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
+ BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
+ BLEZT_BRANCH_OPCODE_X1 = 11,
+ BLEZ_BRANCH_OPCODE_X1 = 10,
+ BLEZ_OPCODE_SN = 59,
+ BLZT_BRANCH_OPCODE_X1 = 9,
+ BLZ_BRANCH_OPCODE_X1 = 8,
+ BLZ_OPCODE_SN = 60,
+ BNZT_BRANCH_OPCODE_X1 = 3,
+ BNZ_BRANCH_OPCODE_X1 = 2,
+ BNZ_OPCODE_SN = 57,
+ BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
+ BRANCH_OPCODE_X1 = 5,
+ BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
+ BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
+ BZT_BRANCH_OPCODE_X1 = 1,
+ BZ_BRANCH_OPCODE_X1 = 0,
+ BZ_OPCODE_SN = 56,
+ CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
+ CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
+ CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
+ CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
+ CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
+ CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
+ DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
+ DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
+ DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
+ FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
+ FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
+ FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
+ FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
+ HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
+ ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
+ ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
+ ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
+ IMM_0_OPCODE_SN = 0,
+ IMM_0_OPCODE_X0 = 4,
+ IMM_0_OPCODE_X1 = 6,
+ IMM_1_OPCODE_SN = 1,
+ IMM_OPCODE_0_X0 = 5,
+ INTHB_SPECIAL_0_OPCODE_X0 = 11,
+ INTHB_SPECIAL_0_OPCODE_X1 = 5,
+ INTHH_SPECIAL_0_OPCODE_X0 = 12,
+ INTHH_SPECIAL_0_OPCODE_X1 = 6,
+ INTLB_SPECIAL_0_OPCODE_X0 = 13,
+ INTLB_SPECIAL_0_OPCODE_X1 = 7,
+ INTLH_SPECIAL_0_OPCODE_X0 = 14,
+ INTLH_SPECIAL_0_OPCODE_X1 = 8,
+ INV_UN_0_SHUN_0_OPCODE_X1 = 8,
+ IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
+ JALB_OPCODE_X1 = 13,
+ JALF_OPCODE_X1 = 12,
+ JALRP_SPECIAL_0_OPCODE_X1 = 9,
+ JALRR_IMM_1_OPCODE_SN = 3,
+ JALR_RR_IMM_0_OPCODE_SN = 5,
+ JALR_SPECIAL_0_OPCODE_X1 = 10,
+ JB_OPCODE_X1 = 11,
+ JF_OPCODE_X1 = 10,
+ JRP_SPECIAL_0_OPCODE_X1 = 11,
+ JRR_IMM_1_OPCODE_SN = 2,
+ JR_RR_IMM_0_OPCODE_SN = 4,
+ JR_SPECIAL_0_OPCODE_X1 = 12,
+ LBADD_IMM_0_OPCODE_X1 = 22,
+ LBADD_U_IMM_0_OPCODE_X1 = 23,
+ LB_OPCODE_Y2 = 0,
+ LB_UN_0_SHUN_0_OPCODE_X1 = 10,
+ LB_U_OPCODE_Y2 = 1,
+ LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
+ LHADD_IMM_0_OPCODE_X1 = 24,
+ LHADD_U_IMM_0_OPCODE_X1 = 25,
+ LH_OPCODE_Y2 = 2,
+ LH_UN_0_SHUN_0_OPCODE_X1 = 12,
+ LH_U_OPCODE_Y2 = 3,
+ LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
+ LNK_SPECIAL_0_OPCODE_X1 = 13,
+ LWADD_IMM_0_OPCODE_X1 = 26,
+ LWADD_NA_IMM_0_OPCODE_X1 = 27,
+ LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
+ LW_OPCODE_Y2 = 4,
+ LW_UN_0_SHUN_0_OPCODE_X1 = 14,
+ MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
+ MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
+ MAXH_SPECIAL_0_OPCODE_X0 = 16,
+ MAXH_SPECIAL_0_OPCODE_X1 = 15,
+ MAXIB_U_IMM_0_OPCODE_X0 = 4,
+ MAXIB_U_IMM_0_OPCODE_X1 = 5,
+ MAXIH_IMM_0_OPCODE_X0 = 5,
+ MAXIH_IMM_0_OPCODE_X1 = 6,
+ MFSPR_IMM_0_OPCODE_X1 = 7,
+ MF_UN_0_SHUN_0_OPCODE_X1 = 15,
+ MINB_U_SPECIAL_0_OPCODE_X0 = 17,
+ MINB_U_SPECIAL_0_OPCODE_X1 = 16,
+ MINH_SPECIAL_0_OPCODE_X0 = 18,
+ MINH_SPECIAL_0_OPCODE_X1 = 17,
+ MINIB_U_IMM_0_OPCODE_X0 = 6,
+ MINIB_U_IMM_0_OPCODE_X1 = 8,
+ MINIH_IMM_0_OPCODE_X0 = 7,
+ MINIH_IMM_0_OPCODE_X1 = 9,
+ MM_OPCODE_X0 = 6,
+ MM_OPCODE_X1 = 7,
+ MNZB_SPECIAL_0_OPCODE_X0 = 19,
+ MNZB_SPECIAL_0_OPCODE_X1 = 18,
+ MNZH_SPECIAL_0_OPCODE_X0 = 20,
+ MNZH_SPECIAL_0_OPCODE_X1 = 19,
+ MNZ_SPECIAL_0_OPCODE_X0 = 21,
+ MNZ_SPECIAL_0_OPCODE_X1 = 20,
+ MNZ_SPECIAL_1_OPCODE_Y0 = 0,
+ MNZ_SPECIAL_1_OPCODE_Y1 = 1,
+ MOVEI_IMM_1_OPCODE_SN = 0,
+ MOVE_RR_IMM_0_OPCODE_SN = 8,
+ MTSPR_IMM_0_OPCODE_X1 = 10,
+ MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
+ MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
+ MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
+ MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
+ MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
+ MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
+ MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
+ MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
+ MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
+ MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
+ MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
+ MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
+ MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
+ MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
+ MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
+ MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
+ MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
+ MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
+ MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
+ MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
+ MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
+ MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
+ MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
+ MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
+ MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
+ MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
+ MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
+ MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
+ MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
+ MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
+ MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
+ MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
+ MVNZ_SPECIAL_0_OPCODE_X0 = 45,
+ MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
+ MVZ_SPECIAL_0_OPCODE_X0 = 46,
+ MVZ_SPECIAL_1_OPCODE_Y0 = 2,
+ MZB_SPECIAL_0_OPCODE_X0 = 47,
+ MZB_SPECIAL_0_OPCODE_X1 = 21,
+ MZH_SPECIAL_0_OPCODE_X0 = 48,
+ MZH_SPECIAL_0_OPCODE_X1 = 22,
+ MZ_SPECIAL_0_OPCODE_X0 = 49,
+ MZ_SPECIAL_0_OPCODE_X1 = 23,
+ MZ_SPECIAL_1_OPCODE_Y0 = 3,
+ MZ_SPECIAL_1_OPCODE_Y1 = 2,
+ NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
+ NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
+ NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
+ NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
+ NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
+ NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
+ NOREG_RR_IMM_0_OPCODE_SN = 0,
+ NOR_SPECIAL_0_OPCODE_X0 = 50,
+ NOR_SPECIAL_0_OPCODE_X1 = 24,
+ NOR_SPECIAL_2_OPCODE_Y0 = 1,
+ NOR_SPECIAL_2_OPCODE_Y1 = 1,
+ ORI_IMM_0_OPCODE_X0 = 8,
+ ORI_IMM_0_OPCODE_X1 = 11,
+ ORI_OPCODE_Y0 = 11,
+ ORI_OPCODE_Y1 = 9,
+ OR_SPECIAL_0_OPCODE_X0 = 51,
+ OR_SPECIAL_0_OPCODE_X1 = 25,
+ OR_SPECIAL_2_OPCODE_Y0 = 2,
+ OR_SPECIAL_2_OPCODE_Y1 = 2,
+ PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
+ PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
+ PACKHB_SPECIAL_0_OPCODE_X0 = 52,
+ PACKHB_SPECIAL_0_OPCODE_X1 = 26,
+ PACKHS_SPECIAL_0_OPCODE_X0 = 102,
+ PACKHS_SPECIAL_0_OPCODE_X1 = 72,
+ PACKLB_SPECIAL_0_OPCODE_X0 = 53,
+ PACKLB_SPECIAL_0_OPCODE_X1 = 27,
+ PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
+ PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
+ RLI_SHUN_0_OPCODE_X0 = 1,
+ RLI_SHUN_0_OPCODE_X1 = 1,
+ RLI_SHUN_0_OPCODE_Y0 = 1,
+ RLI_SHUN_0_OPCODE_Y1 = 1,
+ RL_SPECIAL_0_OPCODE_X0 = 54,
+ RL_SPECIAL_0_OPCODE_X1 = 28,
+ RL_SPECIAL_3_OPCODE_Y0 = 0,
+ RL_SPECIAL_3_OPCODE_Y1 = 0,
+ RR_IMM_0_OPCODE_SN = 0,
+ S1A_SPECIAL_0_OPCODE_X0 = 55,
+ S1A_SPECIAL_0_OPCODE_X1 = 29,
+ S1A_SPECIAL_0_OPCODE_Y0 = 1,
+ S1A_SPECIAL_0_OPCODE_Y1 = 1,
+ S2A_SPECIAL_0_OPCODE_X0 = 56,
+ S2A_SPECIAL_0_OPCODE_X1 = 30,
+ S2A_SPECIAL_0_OPCODE_Y0 = 2,
+ S2A_SPECIAL_0_OPCODE_Y1 = 2,
+ S3A_SPECIAL_0_OPCODE_X0 = 57,
+ S3A_SPECIAL_0_OPCODE_X1 = 31,
+ S3A_SPECIAL_5_OPCODE_Y0 = 1,
+ S3A_SPECIAL_5_OPCODE_Y1 = 1,
+ SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
+ SADAH_SPECIAL_0_OPCODE_X0 = 59,
+ SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
+ SADB_U_SPECIAL_0_OPCODE_X0 = 61,
+ SADH_SPECIAL_0_OPCODE_X0 = 62,
+ SADH_U_SPECIAL_0_OPCODE_X0 = 63,
+ SBADD_IMM_0_OPCODE_X1 = 28,
+ SB_OPCODE_Y2 = 5,
+ SB_SPECIAL_0_OPCODE_X1 = 32,
+ SEQB_SPECIAL_0_OPCODE_X0 = 64,
+ SEQB_SPECIAL_0_OPCODE_X1 = 33,
+ SEQH_SPECIAL_0_OPCODE_X0 = 65,
+ SEQH_SPECIAL_0_OPCODE_X1 = 34,
+ SEQIB_IMM_0_OPCODE_X0 = 9,
+ SEQIB_IMM_0_OPCODE_X1 = 12,
+ SEQIH_IMM_0_OPCODE_X0 = 10,
+ SEQIH_IMM_0_OPCODE_X1 = 13,
+ SEQI_IMM_0_OPCODE_X0 = 11,
+ SEQI_IMM_0_OPCODE_X1 = 14,
+ SEQI_OPCODE_Y0 = 12,
+ SEQI_OPCODE_Y1 = 10,
+ SEQ_SPECIAL_0_OPCODE_X0 = 66,
+ SEQ_SPECIAL_0_OPCODE_X1 = 35,
+ SEQ_SPECIAL_5_OPCODE_Y0 = 2,
+ SEQ_SPECIAL_5_OPCODE_Y1 = 2,
+ SHADD_IMM_0_OPCODE_X1 = 29,
+ SHL8II_IMM_0_OPCODE_SN = 3,
+ SHLB_SPECIAL_0_OPCODE_X0 = 67,
+ SHLB_SPECIAL_0_OPCODE_X1 = 36,
+ SHLH_SPECIAL_0_OPCODE_X0 = 68,
+ SHLH_SPECIAL_0_OPCODE_X1 = 37,
+ SHLIB_SHUN_0_OPCODE_X0 = 2,
+ SHLIB_SHUN_0_OPCODE_X1 = 2,
+ SHLIH_SHUN_0_OPCODE_X0 = 3,
+ SHLIH_SHUN_0_OPCODE_X1 = 3,
+ SHLI_SHUN_0_OPCODE_X0 = 4,
+ SHLI_SHUN_0_OPCODE_X1 = 4,
+ SHLI_SHUN_0_OPCODE_Y0 = 2,
+ SHLI_SHUN_0_OPCODE_Y1 = 2,
+ SHL_SPECIAL_0_OPCODE_X0 = 69,
+ SHL_SPECIAL_0_OPCODE_X1 = 38,
+ SHL_SPECIAL_3_OPCODE_Y0 = 1,
+ SHL_SPECIAL_3_OPCODE_Y1 = 1,
+ SHR1_RR_IMM_0_OPCODE_SN = 9,
+ SHRB_SPECIAL_0_OPCODE_X0 = 70,
+ SHRB_SPECIAL_0_OPCODE_X1 = 39,
+ SHRH_SPECIAL_0_OPCODE_X0 = 71,
+ SHRH_SPECIAL_0_OPCODE_X1 = 40,
+ SHRIB_SHUN_0_OPCODE_X0 = 5,
+ SHRIB_SHUN_0_OPCODE_X1 = 5,
+ SHRIH_SHUN_0_OPCODE_X0 = 6,
+ SHRIH_SHUN_0_OPCODE_X1 = 6,
+ SHRI_SHUN_0_OPCODE_X0 = 7,
+ SHRI_SHUN_0_OPCODE_X1 = 7,
+ SHRI_SHUN_0_OPCODE_Y0 = 3,
+ SHRI_SHUN_0_OPCODE_Y1 = 3,
+ SHR_SPECIAL_0_OPCODE_X0 = 72,
+ SHR_SPECIAL_0_OPCODE_X1 = 41,
+ SHR_SPECIAL_3_OPCODE_Y0 = 2,
+ SHR_SPECIAL_3_OPCODE_Y1 = 2,
+ SHUN_0_OPCODE_X0 = 7,
+ SHUN_0_OPCODE_X1 = 8,
+ SHUN_0_OPCODE_Y0 = 13,
+ SHUN_0_OPCODE_Y1 = 11,
+ SH_OPCODE_Y2 = 6,
+ SH_SPECIAL_0_OPCODE_X1 = 42,
+ SLTB_SPECIAL_0_OPCODE_X0 = 73,
+ SLTB_SPECIAL_0_OPCODE_X1 = 43,
+ SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
+ SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
+ SLTEB_SPECIAL_0_OPCODE_X0 = 75,
+ SLTEB_SPECIAL_0_OPCODE_X1 = 45,
+ SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
+ SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
+ SLTEH_SPECIAL_0_OPCODE_X0 = 77,
+ SLTEH_SPECIAL_0_OPCODE_X1 = 47,
+ SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
+ SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
+ SLTE_SPECIAL_0_OPCODE_X0 = 79,
+ SLTE_SPECIAL_0_OPCODE_X1 = 49,
+ SLTE_SPECIAL_4_OPCODE_Y0 = 0,
+ SLTE_SPECIAL_4_OPCODE_Y1 = 0,
+ SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
+ SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
+ SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
+ SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
+ SLTH_SPECIAL_0_OPCODE_X0 = 81,
+ SLTH_SPECIAL_0_OPCODE_X1 = 51,
+ SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
+ SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
+ SLTIB_IMM_0_OPCODE_X0 = 12,
+ SLTIB_IMM_0_OPCODE_X1 = 15,
+ SLTIB_U_IMM_0_OPCODE_X0 = 13,
+ SLTIB_U_IMM_0_OPCODE_X1 = 16,
+ SLTIH_IMM_0_OPCODE_X0 = 14,
+ SLTIH_IMM_0_OPCODE_X1 = 17,
+ SLTIH_U_IMM_0_OPCODE_X0 = 15,
+ SLTIH_U_IMM_0_OPCODE_X1 = 18,
+ SLTI_IMM_0_OPCODE_X0 = 16,
+ SLTI_IMM_0_OPCODE_X1 = 19,
+ SLTI_OPCODE_Y0 = 14,
+ SLTI_OPCODE_Y1 = 12,
+ SLTI_U_IMM_0_OPCODE_X0 = 17,
+ SLTI_U_IMM_0_OPCODE_X1 = 20,
+ SLTI_U_OPCODE_Y0 = 15,
+ SLTI_U_OPCODE_Y1 = 13,
+ SLT_SPECIAL_0_OPCODE_X0 = 83,
+ SLT_SPECIAL_0_OPCODE_X1 = 53,
+ SLT_SPECIAL_4_OPCODE_Y0 = 2,
+ SLT_SPECIAL_4_OPCODE_Y1 = 2,
+ SLT_U_SPECIAL_0_OPCODE_X0 = 84,
+ SLT_U_SPECIAL_0_OPCODE_X1 = 54,
+ SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
+ SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
+ SNEB_SPECIAL_0_OPCODE_X0 = 85,
+ SNEB_SPECIAL_0_OPCODE_X1 = 55,
+ SNEH_SPECIAL_0_OPCODE_X0 = 86,
+ SNEH_SPECIAL_0_OPCODE_X1 = 56,
+ SNE_SPECIAL_0_OPCODE_X0 = 87,
+ SNE_SPECIAL_0_OPCODE_X1 = 57,
+ SNE_SPECIAL_5_OPCODE_Y0 = 3,
+ SNE_SPECIAL_5_OPCODE_Y1 = 3,
+ SPECIAL_0_OPCODE_X0 = 0,
+ SPECIAL_0_OPCODE_X1 = 1,
+ SPECIAL_0_OPCODE_Y0 = 1,
+ SPECIAL_0_OPCODE_Y1 = 1,
+ SPECIAL_1_OPCODE_Y0 = 2,
+ SPECIAL_1_OPCODE_Y1 = 2,
+ SPECIAL_2_OPCODE_Y0 = 3,
+ SPECIAL_2_OPCODE_Y1 = 3,
+ SPECIAL_3_OPCODE_Y0 = 4,
+ SPECIAL_3_OPCODE_Y1 = 4,
+ SPECIAL_4_OPCODE_Y0 = 5,
+ SPECIAL_4_OPCODE_Y1 = 5,
+ SPECIAL_5_OPCODE_Y0 = 6,
+ SPECIAL_5_OPCODE_Y1 = 6,
+ SPECIAL_6_OPCODE_Y0 = 7,
+ SPECIAL_7_OPCODE_Y0 = 8,
+ SRAB_SPECIAL_0_OPCODE_X0 = 88,
+ SRAB_SPECIAL_0_OPCODE_X1 = 58,
+ SRAH_SPECIAL_0_OPCODE_X0 = 89,
+ SRAH_SPECIAL_0_OPCODE_X1 = 59,
+ SRAIB_SHUN_0_OPCODE_X0 = 8,
+ SRAIB_SHUN_0_OPCODE_X1 = 8,
+ SRAIH_SHUN_0_OPCODE_X0 = 9,
+ SRAIH_SHUN_0_OPCODE_X1 = 9,
+ SRAI_SHUN_0_OPCODE_X0 = 10,
+ SRAI_SHUN_0_OPCODE_X1 = 10,
+ SRAI_SHUN_0_OPCODE_Y0 = 4,
+ SRAI_SHUN_0_OPCODE_Y1 = 4,
+ SRA_SPECIAL_0_OPCODE_X0 = 90,
+ SRA_SPECIAL_0_OPCODE_X1 = 60,
+ SRA_SPECIAL_3_OPCODE_Y0 = 3,
+ SRA_SPECIAL_3_OPCODE_Y1 = 3,
+ SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
+ SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
+ SUBB_SPECIAL_0_OPCODE_X0 = 91,
+ SUBB_SPECIAL_0_OPCODE_X1 = 61,
+ SUBHS_SPECIAL_0_OPCODE_X0 = 101,
+ SUBHS_SPECIAL_0_OPCODE_X1 = 71,
+ SUBH_SPECIAL_0_OPCODE_X0 = 92,
+ SUBH_SPECIAL_0_OPCODE_X1 = 62,
+ SUBS_SPECIAL_0_OPCODE_X0 = 97,
+ SUBS_SPECIAL_0_OPCODE_X1 = 67,
+ SUB_SPECIAL_0_OPCODE_X0 = 93,
+ SUB_SPECIAL_0_OPCODE_X1 = 63,
+ SUB_SPECIAL_0_OPCODE_Y0 = 3,
+ SUB_SPECIAL_0_OPCODE_Y1 = 3,
+ SWADD_IMM_0_OPCODE_X1 = 30,
+ SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
+ SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
+ SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
+ SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
+ SW_OPCODE_Y2 = 7,
+ SW_SPECIAL_0_OPCODE_X1 = 64,
+ TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
+ TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
+ TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
+ TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
+ TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
+ TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
+ TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
+ TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
+ TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
+ UN_0_SHUN_0_OPCODE_X0 = 11,
+ UN_0_SHUN_0_OPCODE_X1 = 11,
+ UN_0_SHUN_0_OPCODE_Y0 = 5,
+ UN_0_SHUN_0_OPCODE_Y1 = 5,
+ WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
+ XORI_IMM_0_OPCODE_X0 = 2,
+ XORI_IMM_0_OPCODE_X1 = 21,
+ XOR_SPECIAL_0_OPCODE_X0 = 94,
+ XOR_SPECIAL_0_OPCODE_X1 = 65,
+ XOR_SPECIAL_2_OPCODE_Y0 = 3,
+ XOR_SPECIAL_2_OPCODE_Y1 = 3
+};
+
+#endif /* !_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/opcode_constants_64.h b/arch/tile/include/asm/opcode_constants_64.h
new file mode 100644
index 000000000000..227d033b180c
--- /dev/null
+++ b/arch/tile/include/asm/opcode_constants_64.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/* This file is machine-generated; DO NOT EDIT! */
+
+
+#ifndef _TILE_OPCODE_CONSTANTS_H
+#define _TILE_OPCODE_CONSTANTS_H
+enum
+{
+ ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
+ ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
+ ADDB_SPECIAL_0_OPCODE_X0 = 1,
+ ADDB_SPECIAL_0_OPCODE_X1 = 1,
+ ADDHS_SPECIAL_0_OPCODE_X0 = 99,
+ ADDHS_SPECIAL_0_OPCODE_X1 = 69,
+ ADDH_SPECIAL_0_OPCODE_X0 = 2,
+ ADDH_SPECIAL_0_OPCODE_X1 = 2,
+ ADDIB_IMM_0_OPCODE_X0 = 1,
+ ADDIB_IMM_0_OPCODE_X1 = 1,
+ ADDIH_IMM_0_OPCODE_X0 = 2,
+ ADDIH_IMM_0_OPCODE_X1 = 2,
+ ADDI_IMM_0_OPCODE_X0 = 3,
+ ADDI_IMM_0_OPCODE_X1 = 3,
+ ADDI_IMM_1_OPCODE_SN = 1,
+ ADDI_OPCODE_Y0 = 9,
+ ADDI_OPCODE_Y1 = 7,
+ ADDLIS_OPCODE_X0 = 1,
+ ADDLIS_OPCODE_X1 = 2,
+ ADDLI_OPCODE_X0 = 2,
+ ADDLI_OPCODE_X1 = 3,
+ ADDS_SPECIAL_0_OPCODE_X0 = 96,
+ ADDS_SPECIAL_0_OPCODE_X1 = 66,
+ ADD_SPECIAL_0_OPCODE_X0 = 3,
+ ADD_SPECIAL_0_OPCODE_X1 = 3,
+ ADD_SPECIAL_0_OPCODE_Y0 = 0,
+ ADD_SPECIAL_0_OPCODE_Y1 = 0,
+ ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
+ ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
+ ANDI_IMM_0_OPCODE_X0 = 1,
+ ANDI_IMM_0_OPCODE_X1 = 4,
+ ANDI_OPCODE_Y0 = 10,
+ ANDI_OPCODE_Y1 = 8,
+ AND_SPECIAL_0_OPCODE_X0 = 6,
+ AND_SPECIAL_0_OPCODE_X1 = 4,
+ AND_SPECIAL_2_OPCODE_Y0 = 0,
+ AND_SPECIAL_2_OPCODE_Y1 = 0,
+ AULI_OPCODE_X0 = 3,
+ AULI_OPCODE_X1 = 4,
+ AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
+ AVGH_SPECIAL_0_OPCODE_X0 = 8,
+ BBNST_BRANCH_OPCODE_X1 = 15,
+ BBNS_BRANCH_OPCODE_X1 = 14,
+ BBNS_OPCODE_SN = 63,
+ BBST_BRANCH_OPCODE_X1 = 13,
+ BBS_BRANCH_OPCODE_X1 = 12,
+ BBS_OPCODE_SN = 62,
+ BGEZT_BRANCH_OPCODE_X1 = 7,
+ BGEZ_BRANCH_OPCODE_X1 = 6,
+ BGEZ_OPCODE_SN = 61,
+ BGZT_BRANCH_OPCODE_X1 = 5,
+ BGZ_BRANCH_OPCODE_X1 = 4,
+ BGZ_OPCODE_SN = 58,
+ BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
+ BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
+ BLEZT_BRANCH_OPCODE_X1 = 11,
+ BLEZ_BRANCH_OPCODE_X1 = 10,
+ BLEZ_OPCODE_SN = 59,
+ BLZT_BRANCH_OPCODE_X1 = 9,
+ BLZ_BRANCH_OPCODE_X1 = 8,
+ BLZ_OPCODE_SN = 60,
+ BNZT_BRANCH_OPCODE_X1 = 3,
+ BNZ_BRANCH_OPCODE_X1 = 2,
+ BNZ_OPCODE_SN = 57,
+ BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
+ BRANCH_OPCODE_X1 = 5,
+ BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
+ BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
+ BZT_BRANCH_OPCODE_X1 = 1,
+ BZ_BRANCH_OPCODE_X1 = 0,
+ BZ_OPCODE_SN = 56,
+ CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
+ CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
+ CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
+ CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
+ CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
+ CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
+ DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
+ DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
+ DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
+ FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
+ FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
+ FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
+ FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
+ FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
+ HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
+ ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
+ ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
+ ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
+ IMM_0_OPCODE_SN = 0,
+ IMM_0_OPCODE_X0 = 4,
+ IMM_0_OPCODE_X1 = 6,
+ IMM_1_OPCODE_SN = 1,
+ IMM_OPCODE_0_X0 = 5,
+ INTHB_SPECIAL_0_OPCODE_X0 = 11,
+ INTHB_SPECIAL_0_OPCODE_X1 = 5,
+ INTHH_SPECIAL_0_OPCODE_X0 = 12,
+ INTHH_SPECIAL_0_OPCODE_X1 = 6,
+ INTLB_SPECIAL_0_OPCODE_X0 = 13,
+ INTLB_SPECIAL_0_OPCODE_X1 = 7,
+ INTLH_SPECIAL_0_OPCODE_X0 = 14,
+ INTLH_SPECIAL_0_OPCODE_X1 = 8,
+ INV_UN_0_SHUN_0_OPCODE_X1 = 8,
+ IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
+ JALB_OPCODE_X1 = 13,
+ JALF_OPCODE_X1 = 12,
+ JALRP_SPECIAL_0_OPCODE_X1 = 9,
+ JALRR_IMM_1_OPCODE_SN = 3,
+ JALR_RR_IMM_0_OPCODE_SN = 5,
+ JALR_SPECIAL_0_OPCODE_X1 = 10,
+ JB_OPCODE_X1 = 11,
+ JF_OPCODE_X1 = 10,
+ JRP_SPECIAL_0_OPCODE_X1 = 11,
+ JRR_IMM_1_OPCODE_SN = 2,
+ JR_RR_IMM_0_OPCODE_SN = 4,
+ JR_SPECIAL_0_OPCODE_X1 = 12,
+ LBADD_IMM_0_OPCODE_X1 = 22,
+ LBADD_U_IMM_0_OPCODE_X1 = 23,
+ LB_OPCODE_Y2 = 0,
+ LB_UN_0_SHUN_0_OPCODE_X1 = 10,
+ LB_U_OPCODE_Y2 = 1,
+ LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
+ LHADD_IMM_0_OPCODE_X1 = 24,
+ LHADD_U_IMM_0_OPCODE_X1 = 25,
+ LH_OPCODE_Y2 = 2,
+ LH_UN_0_SHUN_0_OPCODE_X1 = 12,
+ LH_U_OPCODE_Y2 = 3,
+ LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
+ LNK_SPECIAL_0_OPCODE_X1 = 13,
+ LWADD_IMM_0_OPCODE_X1 = 26,
+ LWADD_NA_IMM_0_OPCODE_X1 = 27,
+ LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
+ LW_OPCODE_Y2 = 4,
+ LW_UN_0_SHUN_0_OPCODE_X1 = 14,
+ MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
+ MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
+ MAXH_SPECIAL_0_OPCODE_X0 = 16,
+ MAXH_SPECIAL_0_OPCODE_X1 = 15,
+ MAXIB_U_IMM_0_OPCODE_X0 = 4,
+ MAXIB_U_IMM_0_OPCODE_X1 = 5,
+ MAXIH_IMM_0_OPCODE_X0 = 5,
+ MAXIH_IMM_0_OPCODE_X1 = 6,
+ MFSPR_IMM_0_OPCODE_X1 = 7,
+ MF_UN_0_SHUN_0_OPCODE_X1 = 15,
+ MINB_U_SPECIAL_0_OPCODE_X0 = 17,
+ MINB_U_SPECIAL_0_OPCODE_X1 = 16,
+ MINH_SPECIAL_0_OPCODE_X0 = 18,
+ MINH_SPECIAL_0_OPCODE_X1 = 17,
+ MINIB_U_IMM_0_OPCODE_X0 = 6,
+ MINIB_U_IMM_0_OPCODE_X1 = 8,
+ MINIH_IMM_0_OPCODE_X0 = 7,
+ MINIH_IMM_0_OPCODE_X1 = 9,
+ MM_OPCODE_X0 = 6,
+ MM_OPCODE_X1 = 7,
+ MNZB_SPECIAL_0_OPCODE_X0 = 19,
+ MNZB_SPECIAL_0_OPCODE_X1 = 18,
+ MNZH_SPECIAL_0_OPCODE_X0 = 20,
+ MNZH_SPECIAL_0_OPCODE_X1 = 19,
+ MNZ_SPECIAL_0_OPCODE_X0 = 21,
+ MNZ_SPECIAL_0_OPCODE_X1 = 20,
+ MNZ_SPECIAL_1_OPCODE_Y0 = 0,
+ MNZ_SPECIAL_1_OPCODE_Y1 = 1,
+ MOVEI_IMM_1_OPCODE_SN = 0,
+ MOVE_RR_IMM_0_OPCODE_SN = 8,
+ MTSPR_IMM_0_OPCODE_X1 = 10,
+ MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
+ MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
+ MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
+ MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
+ MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
+ MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
+ MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
+ MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
+ MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
+ MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
+ MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
+ MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
+ MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
+ MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
+ MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
+ MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
+ MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
+ MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
+ MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
+ MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
+ MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
+ MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
+ MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
+ MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
+ MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
+ MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
+ MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
+ MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
+ MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
+ MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
+ MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
+ MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
+ MVNZ_SPECIAL_0_OPCODE_X0 = 45,
+ MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
+ MVZ_SPECIAL_0_OPCODE_X0 = 46,
+ MVZ_SPECIAL_1_OPCODE_Y0 = 2,
+ MZB_SPECIAL_0_OPCODE_X0 = 47,
+ MZB_SPECIAL_0_OPCODE_X1 = 21,
+ MZH_SPECIAL_0_OPCODE_X0 = 48,
+ MZH_SPECIAL_0_OPCODE_X1 = 22,
+ MZ_SPECIAL_0_OPCODE_X0 = 49,
+ MZ_SPECIAL_0_OPCODE_X1 = 23,
+ MZ_SPECIAL_1_OPCODE_Y0 = 3,
+ MZ_SPECIAL_1_OPCODE_Y1 = 2,
+ NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
+ NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
+ NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
+ NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
+ NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
+ NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
+ NOREG_RR_IMM_0_OPCODE_SN = 0,
+ NOR_SPECIAL_0_OPCODE_X0 = 50,
+ NOR_SPECIAL_0_OPCODE_X1 = 24,
+ NOR_SPECIAL_2_OPCODE_Y0 = 1,
+ NOR_SPECIAL_2_OPCODE_Y1 = 1,
+ ORI_IMM_0_OPCODE_X0 = 8,
+ ORI_IMM_0_OPCODE_X1 = 11,
+ ORI_OPCODE_Y0 = 11,
+ ORI_OPCODE_Y1 = 9,
+ OR_SPECIAL_0_OPCODE_X0 = 51,
+ OR_SPECIAL_0_OPCODE_X1 = 25,
+ OR_SPECIAL_2_OPCODE_Y0 = 2,
+ OR_SPECIAL_2_OPCODE_Y1 = 2,
+ PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
+ PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
+ PACKHB_SPECIAL_0_OPCODE_X0 = 52,
+ PACKHB_SPECIAL_0_OPCODE_X1 = 26,
+ PACKHS_SPECIAL_0_OPCODE_X0 = 102,
+ PACKHS_SPECIAL_0_OPCODE_X1 = 72,
+ PACKLB_SPECIAL_0_OPCODE_X0 = 53,
+ PACKLB_SPECIAL_0_OPCODE_X1 = 27,
+ PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
+ PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
+ RLI_SHUN_0_OPCODE_X0 = 1,
+ RLI_SHUN_0_OPCODE_X1 = 1,
+ RLI_SHUN_0_OPCODE_Y0 = 1,
+ RLI_SHUN_0_OPCODE_Y1 = 1,
+ RL_SPECIAL_0_OPCODE_X0 = 54,
+ RL_SPECIAL_0_OPCODE_X1 = 28,
+ RL_SPECIAL_3_OPCODE_Y0 = 0,
+ RL_SPECIAL_3_OPCODE_Y1 = 0,
+ RR_IMM_0_OPCODE_SN = 0,
+ S1A_SPECIAL_0_OPCODE_X0 = 55,
+ S1A_SPECIAL_0_OPCODE_X1 = 29,
+ S1A_SPECIAL_0_OPCODE_Y0 = 1,
+ S1A_SPECIAL_0_OPCODE_Y1 = 1,
+ S2A_SPECIAL_0_OPCODE_X0 = 56,
+ S2A_SPECIAL_0_OPCODE_X1 = 30,
+ S2A_SPECIAL_0_OPCODE_Y0 = 2,
+ S2A_SPECIAL_0_OPCODE_Y1 = 2,
+ S3A_SPECIAL_0_OPCODE_X0 = 57,
+ S3A_SPECIAL_0_OPCODE_X1 = 31,
+ S3A_SPECIAL_5_OPCODE_Y0 = 1,
+ S3A_SPECIAL_5_OPCODE_Y1 = 1,
+ SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
+ SADAH_SPECIAL_0_OPCODE_X0 = 59,
+ SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
+ SADB_U_SPECIAL_0_OPCODE_X0 = 61,
+ SADH_SPECIAL_0_OPCODE_X0 = 62,
+ SADH_U_SPECIAL_0_OPCODE_X0 = 63,
+ SBADD_IMM_0_OPCODE_X1 = 28,
+ SB_OPCODE_Y2 = 5,
+ SB_SPECIAL_0_OPCODE_X1 = 32,
+ SEQB_SPECIAL_0_OPCODE_X0 = 64,
+ SEQB_SPECIAL_0_OPCODE_X1 = 33,
+ SEQH_SPECIAL_0_OPCODE_X0 = 65,
+ SEQH_SPECIAL_0_OPCODE_X1 = 34,
+ SEQIB_IMM_0_OPCODE_X0 = 9,
+ SEQIB_IMM_0_OPCODE_X1 = 12,
+ SEQIH_IMM_0_OPCODE_X0 = 10,
+ SEQIH_IMM_0_OPCODE_X1 = 13,
+ SEQI_IMM_0_OPCODE_X0 = 11,
+ SEQI_IMM_0_OPCODE_X1 = 14,
+ SEQI_OPCODE_Y0 = 12,
+ SEQI_OPCODE_Y1 = 10,
+ SEQ_SPECIAL_0_OPCODE_X0 = 66,
+ SEQ_SPECIAL_0_OPCODE_X1 = 35,
+ SEQ_SPECIAL_5_OPCODE_Y0 = 2,
+ SEQ_SPECIAL_5_OPCODE_Y1 = 2,
+ SHADD_IMM_0_OPCODE_X1 = 29,
+ SHL8II_IMM_0_OPCODE_SN = 3,
+ SHLB_SPECIAL_0_OPCODE_X0 = 67,
+ SHLB_SPECIAL_0_OPCODE_X1 = 36,
+ SHLH_SPECIAL_0_OPCODE_X0 = 68,
+ SHLH_SPECIAL_0_OPCODE_X1 = 37,
+ SHLIB_SHUN_0_OPCODE_X0 = 2,
+ SHLIB_SHUN_0_OPCODE_X1 = 2,
+ SHLIH_SHUN_0_OPCODE_X0 = 3,
+ SHLIH_SHUN_0_OPCODE_X1 = 3,
+ SHLI_SHUN_0_OPCODE_X0 = 4,
+ SHLI_SHUN_0_OPCODE_X1 = 4,
+ SHLI_SHUN_0_OPCODE_Y0 = 2,
+ SHLI_SHUN_0_OPCODE_Y1 = 2,
+ SHL_SPECIAL_0_OPCODE_X0 = 69,
+ SHL_SPECIAL_0_OPCODE_X1 = 38,
+ SHL_SPECIAL_3_OPCODE_Y0 = 1,
+ SHL_SPECIAL_3_OPCODE_Y1 = 1,
+ SHR1_RR_IMM_0_OPCODE_SN = 9,
+ SHRB_SPECIAL_0_OPCODE_X0 = 70,
+ SHRB_SPECIAL_0_OPCODE_X1 = 39,
+ SHRH_SPECIAL_0_OPCODE_X0 = 71,
+ SHRH_SPECIAL_0_OPCODE_X1 = 40,
+ SHRIB_SHUN_0_OPCODE_X0 = 5,
+ SHRIB_SHUN_0_OPCODE_X1 = 5,
+ SHRIH_SHUN_0_OPCODE_X0 = 6,
+ SHRIH_SHUN_0_OPCODE_X1 = 6,
+ SHRI_SHUN_0_OPCODE_X0 = 7,
+ SHRI_SHUN_0_OPCODE_X1 = 7,
+ SHRI_SHUN_0_OPCODE_Y0 = 3,
+ SHRI_SHUN_0_OPCODE_Y1 = 3,
+ SHR_SPECIAL_0_OPCODE_X0 = 72,
+ SHR_SPECIAL_0_OPCODE_X1 = 41,
+ SHR_SPECIAL_3_OPCODE_Y0 = 2,
+ SHR_SPECIAL_3_OPCODE_Y1 = 2,
+ SHUN_0_OPCODE_X0 = 7,
+ SHUN_0_OPCODE_X1 = 8,
+ SHUN_0_OPCODE_Y0 = 13,
+ SHUN_0_OPCODE_Y1 = 11,
+ SH_OPCODE_Y2 = 6,
+ SH_SPECIAL_0_OPCODE_X1 = 42,
+ SLTB_SPECIAL_0_OPCODE_X0 = 73,
+ SLTB_SPECIAL_0_OPCODE_X1 = 43,
+ SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
+ SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
+ SLTEB_SPECIAL_0_OPCODE_X0 = 75,
+ SLTEB_SPECIAL_0_OPCODE_X1 = 45,
+ SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
+ SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
+ SLTEH_SPECIAL_0_OPCODE_X0 = 77,
+ SLTEH_SPECIAL_0_OPCODE_X1 = 47,
+ SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
+ SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
+ SLTE_SPECIAL_0_OPCODE_X0 = 79,
+ SLTE_SPECIAL_0_OPCODE_X1 = 49,
+ SLTE_SPECIAL_4_OPCODE_Y0 = 0,
+ SLTE_SPECIAL_4_OPCODE_Y1 = 0,
+ SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
+ SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
+ SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
+ SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
+ SLTH_SPECIAL_0_OPCODE_X0 = 81,
+ SLTH_SPECIAL_0_OPCODE_X1 = 51,
+ SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
+ SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
+ SLTIB_IMM_0_OPCODE_X0 = 12,
+ SLTIB_IMM_0_OPCODE_X1 = 15,
+ SLTIB_U_IMM_0_OPCODE_X0 = 13,
+ SLTIB_U_IMM_0_OPCODE_X1 = 16,
+ SLTIH_IMM_0_OPCODE_X0 = 14,
+ SLTIH_IMM_0_OPCODE_X1 = 17,
+ SLTIH_U_IMM_0_OPCODE_X0 = 15,
+ SLTIH_U_IMM_0_OPCODE_X1 = 18,
+ SLTI_IMM_0_OPCODE_X0 = 16,
+ SLTI_IMM_0_OPCODE_X1 = 19,
+ SLTI_OPCODE_Y0 = 14,
+ SLTI_OPCODE_Y1 = 12,
+ SLTI_U_IMM_0_OPCODE_X0 = 17,
+ SLTI_U_IMM_0_OPCODE_X1 = 20,
+ SLTI_U_OPCODE_Y0 = 15,
+ SLTI_U_OPCODE_Y1 = 13,
+ SLT_SPECIAL_0_OPCODE_X0 = 83,
+ SLT_SPECIAL_0_OPCODE_X1 = 53,
+ SLT_SPECIAL_4_OPCODE_Y0 = 2,
+ SLT_SPECIAL_4_OPCODE_Y1 = 2,
+ SLT_U_SPECIAL_0_OPCODE_X0 = 84,
+ SLT_U_SPECIAL_0_OPCODE_X1 = 54,
+ SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
+ SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
+ SNEB_SPECIAL_0_OPCODE_X0 = 85,
+ SNEB_SPECIAL_0_OPCODE_X1 = 55,
+ SNEH_SPECIAL_0_OPCODE_X0 = 86,
+ SNEH_SPECIAL_0_OPCODE_X1 = 56,
+ SNE_SPECIAL_0_OPCODE_X0 = 87,
+ SNE_SPECIAL_0_OPCODE_X1 = 57,
+ SNE_SPECIAL_5_OPCODE_Y0 = 3,
+ SNE_SPECIAL_5_OPCODE_Y1 = 3,
+ SPECIAL_0_OPCODE_X0 = 0,
+ SPECIAL_0_OPCODE_X1 = 1,
+ SPECIAL_0_OPCODE_Y0 = 1,
+ SPECIAL_0_OPCODE_Y1 = 1,
+ SPECIAL_1_OPCODE_Y0 = 2,
+ SPECIAL_1_OPCODE_Y1 = 2,
+ SPECIAL_2_OPCODE_Y0 = 3,
+ SPECIAL_2_OPCODE_Y1 = 3,
+ SPECIAL_3_OPCODE_Y0 = 4,
+ SPECIAL_3_OPCODE_Y1 = 4,
+ SPECIAL_4_OPCODE_Y0 = 5,
+ SPECIAL_4_OPCODE_Y1 = 5,
+ SPECIAL_5_OPCODE_Y0 = 6,
+ SPECIAL_5_OPCODE_Y1 = 6,
+ SPECIAL_6_OPCODE_Y0 = 7,
+ SPECIAL_7_OPCODE_Y0 = 8,
+ SRAB_SPECIAL_0_OPCODE_X0 = 88,
+ SRAB_SPECIAL_0_OPCODE_X1 = 58,
+ SRAH_SPECIAL_0_OPCODE_X0 = 89,
+ SRAH_SPECIAL_0_OPCODE_X1 = 59,
+ SRAIB_SHUN_0_OPCODE_X0 = 8,
+ SRAIB_SHUN_0_OPCODE_X1 = 8,
+ SRAIH_SHUN_0_OPCODE_X0 = 9,
+ SRAIH_SHUN_0_OPCODE_X1 = 9,
+ SRAI_SHUN_0_OPCODE_X0 = 10,
+ SRAI_SHUN_0_OPCODE_X1 = 10,
+ SRAI_SHUN_0_OPCODE_Y0 = 4,
+ SRAI_SHUN_0_OPCODE_Y1 = 4,
+ SRA_SPECIAL_0_OPCODE_X0 = 90,
+ SRA_SPECIAL_0_OPCODE_X1 = 60,
+ SRA_SPECIAL_3_OPCODE_Y0 = 3,
+ SRA_SPECIAL_3_OPCODE_Y1 = 3,
+ SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
+ SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
+ SUBB_SPECIAL_0_OPCODE_X0 = 91,
+ SUBB_SPECIAL_0_OPCODE_X1 = 61,
+ SUBHS_SPECIAL_0_OPCODE_X0 = 101,
+ SUBHS_SPECIAL_0_OPCODE_X1 = 71,
+ SUBH_SPECIAL_0_OPCODE_X0 = 92,
+ SUBH_SPECIAL_0_OPCODE_X1 = 62,
+ SUBS_SPECIAL_0_OPCODE_X0 = 97,
+ SUBS_SPECIAL_0_OPCODE_X1 = 67,
+ SUB_SPECIAL_0_OPCODE_X0 = 93,
+ SUB_SPECIAL_0_OPCODE_X1 = 63,
+ SUB_SPECIAL_0_OPCODE_Y0 = 3,
+ SUB_SPECIAL_0_OPCODE_Y1 = 3,
+ SWADD_IMM_0_OPCODE_X1 = 30,
+ SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
+ SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
+ SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
+ SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
+ SW_OPCODE_Y2 = 7,
+ SW_SPECIAL_0_OPCODE_X1 = 64,
+ TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
+ TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
+ TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
+ TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
+ TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
+ TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
+ TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
+ TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
+ TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
+ UN_0_SHUN_0_OPCODE_X0 = 11,
+ UN_0_SHUN_0_OPCODE_X1 = 11,
+ UN_0_SHUN_0_OPCODE_Y0 = 5,
+ UN_0_SHUN_0_OPCODE_Y1 = 5,
+ WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
+ XORI_IMM_0_OPCODE_X0 = 2,
+ XORI_IMM_0_OPCODE_X1 = 21,
+ XOR_SPECIAL_0_OPCODE_X0 = 94,
+ XOR_SPECIAL_0_OPCODE_X1 = 65,
+ XOR_SPECIAL_2_OPCODE_Y0 = 3,
+ XOR_SPECIAL_2_OPCODE_Y1 = 3
+};
+
+#endif /* !_TILE_OPCODE_CONSTANTS_H */
diff --git a/arch/tile/include/asm/page.h b/arch/tile/include/asm/page.h
new file mode 100644
index 000000000000..f894a9016da6
--- /dev/null
+++ b/arch/tile/include/asm/page.h
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PAGE_H
+#define _ASM_TILE_PAGE_H
+
+#include <linux/const.h>
+
+/* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
+#define PAGE_SHIFT 16
+#define HPAGE_SHIFT 24
+
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define HPAGE_SIZE (_AC(1, UL) << HPAGE_SHIFT)
+
+#define PAGE_MASK (~(PAGE_SIZE - 1))
+#define HPAGE_MASK (~(HPAGE_SIZE - 1))
+
+#ifdef __KERNEL__
+
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
+
+/*
+ * The {,H}PAGE_SHIFT values must match the HV_LOG2_PAGE_SIZE_xxx
+ * definitions in <hv/hypervisor.h>. We validate this at build time
+ * here, and again at runtime during early boot. We provide a
+ * separate definition since userspace doesn't have <hv/hypervisor.h>.
+ *
+ * Be careful to distinguish PAGE_SHIFT from HV_PTE_INDEX_PFN, since
+ * they are the same on i386 but not TILE.
+ */
+#if HV_LOG2_PAGE_SIZE_SMALL != PAGE_SHIFT
+# error Small page size mismatch in Linux
+#endif
+#if HV_LOG2_PAGE_SIZE_LARGE != HPAGE_SHIFT
+# error Huge page size mismatch in Linux
+#endif
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+struct page;
+
+static inline void clear_page(void *page)
+{
+ memset(page, 0, PAGE_SIZE);
+}
+
+static inline void copy_page(void *to, void *from)
+{
+ memcpy(to, from, PAGE_SIZE);
+}
+
+static inline void clear_user_page(void *page, unsigned long vaddr,
+ struct page *pg)
+{
+ clear_page(page);
+}
+
+static inline void copy_user_page(void *to, void *from, unsigned long vaddr,
+ struct page *topage)
+{
+ copy_page(to, from);
+}
+
+/*
+ * Hypervisor page tables are made of the same basic structure.
+ */
+
+typedef __u64 pteval_t;
+typedef __u64 pmdval_t;
+typedef __u64 pudval_t;
+typedef __u64 pgdval_t;
+typedef __u64 pgprotval_t;
+
+typedef HV_PTE pte_t;
+typedef HV_PTE pgd_t;
+typedef HV_PTE pgprot_t;
+
+/*
+ * User L2 page tables are managed as one L2 page table per page,
+ * because we use the page allocator for them. This keeps the allocation
+ * simple and makes it potentially useful to implement HIGHPTE at some point.
+ * However, it's also inefficient, since L2 page tables are much smaller
+ * than pages (currently 2KB vs 64KB). So we should revisit this.
+ */
+typedef struct page *pgtable_t;
+
+/* Must be a macro since it is used to create constants. */
+#define __pgprot(val) hv_pte(val)
+
+static inline u64 pgprot_val(pgprot_t pgprot)
+{
+ return hv_pte_val(pgprot);
+}
+
+static inline u64 pte_val(pte_t pte)
+{
+ return hv_pte_val(pte);
+}
+
+static inline u64 pgd_val(pgd_t pgd)
+{
+ return hv_pte_val(pgd);
+}
+
+#ifdef __tilegx__
+
+typedef HV_PTE pmd_t;
+
+static inline u64 pmd_val(pmd_t pmd)
+{
+ return hv_pte_val(pmd);
+}
+
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+
+#define HUGE_MAX_HSTATE 2
+
+#ifdef CONFIG_HUGETLB_PAGE
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+#endif
+
+/* Each memory controller has PAs distinct in their high bits. */
+#define NR_PA_HIGHBIT_SHIFT (CHIP_PA_WIDTH() - CHIP_LOG_NUM_MSHIMS())
+#define NR_PA_HIGHBIT_VALUES (1 << CHIP_LOG_NUM_MSHIMS())
+#define __pa_to_highbits(pa) ((phys_addr_t)(pa) >> NR_PA_HIGHBIT_SHIFT)
+#define __pfn_to_highbits(pfn) ((pfn) >> (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT))
+
+#ifdef __tilegx__
+
+/*
+ * We reserve the lower half of memory for user-space programs, and the
+ * upper half for system code. We re-map all of physical memory in the
+ * upper half, which takes a quarter of our VA space. Then we have
+ * the vmalloc regions. The supervisor code lives at 0xfffffff700000000,
+ * with the hypervisor above that.
+ *
+ * Loadable kernel modules are placed immediately after the static
+ * supervisor code, with each being allocated a 256MB region of
+ * address space, so we don't have to worry about the range of "jal"
+ * and other branch instructions.
+ *
+ * For now we keep life simple and just allocate one pmd (4GB) for vmalloc.
+ * Similarly, for now we don't play any struct page mapping games.
+ */
+
+#if CHIP_PA_WIDTH() + 2 > CHIP_VA_WIDTH()
+# error Too much PA to map with the VA available!
+#endif
+#define HALF_VA_SPACE (_AC(1, UL) << (CHIP_VA_WIDTH() - 1))
+
+#define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */
+#define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */
+#define PAGE_OFFSET MEM_HIGH_START
+#define _VMALLOC_START _AC(0xfffffff500000000, UL) /* 4 GB */
+#define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */
+#define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */
+#define MEM_SV_INTRPT MEM_SV_START
+#define MEM_MODULE_START _AC(0xfffffff710000000, UL) /* 256 MB */
+#define MEM_MODULE_END (MEM_MODULE_START + (256*1024*1024))
+#define MEM_HV_START _AC(0xfffffff800000000, UL) /* 32 GB */
+
+/* Highest DTLB address we will use */
+#define KERNEL_HIGH_VADDR MEM_SV_START
+
+/* Since we don't currently provide any fixmaps, we use an impossible VA. */
+#define FIXADDR_TOP MEM_HV_START
+
+#else /* !__tilegx__ */
+
+/*
+ * A PAGE_OFFSET of 0xC0000000 means that the kernel has
+ * a virtual address space of one gigabyte, which limits the
+ * amount of physical memory you can use to about 768MB.
+ * If you want more physical memory than this then see the CONFIG_HIGHMEM
+ * option in the kernel configuration.
+ *
+ * The top two 16MB chunks in the table below (VIRT and HV) are
+ * unavailable to Linux. Since the kernel interrupt vectors must live
+ * at 0xfd000000, we map all of the bottom of RAM at this address with
+ * a huge page table entry to minimize its ITLB footprint (as well as
+ * at PAGE_OFFSET). The last architected requirement is that user
+ * interrupt vectors live at 0xfc000000, so we make that range of
+ * memory available to user processes. The remaining regions are sized
+ * as shown; after the first four addresses, we show "typical" values,
+ * since the actual addresses depend on kernel #defines.
+ *
+ * MEM_VIRT_INTRPT 0xff000000
+ * MEM_HV_INTRPT 0xfe000000
+ * MEM_SV_INTRPT (kernel code) 0xfd000000
+ * MEM_USER_INTRPT (user vector) 0xfc000000
+ * FIX_KMAP_xxx 0xf8000000 (via NR_CPUS * KM_TYPE_NR)
+ * PKMAP_BASE 0xf7000000 (via LAST_PKMAP)
+ * HUGE_VMAP 0xf3000000 (via CONFIG_NR_HUGE_VMAPS)
+ * VMALLOC_START 0xf0000000 (via __VMALLOC_RESERVE)
+ * mapped LOWMEM 0xc0000000
+ */
+
+#define MEM_USER_INTRPT _AC(0xfc000000, UL)
+#define MEM_SV_INTRPT _AC(0xfd000000, UL)
+#define MEM_HV_INTRPT _AC(0xfe000000, UL)
+#define MEM_VIRT_INTRPT _AC(0xff000000, UL)
+
+#define INTRPT_SIZE 0x4000
+
+/* Tolerate page size larger than the architecture interrupt region size. */
+#if PAGE_SIZE > INTRPT_SIZE
+#undef INTRPT_SIZE
+#define INTRPT_SIZE PAGE_SIZE
+#endif
+
+#define KERNEL_HIGH_VADDR MEM_USER_INTRPT
+#define FIXADDR_TOP (KERNEL_HIGH_VADDR - PAGE_SIZE)
+
+#define PAGE_OFFSET _AC(CONFIG_PAGE_OFFSET, UL)
+
+/* On 32-bit architectures we mix kernel modules in with other vmaps. */
+#define MEM_MODULE_START VMALLOC_START
+#define MEM_MODULE_END VMALLOC_END
+
+#endif /* __tilegx__ */
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_HIGHMEM
+
+/* Map kernel virtual addresses to page frames, in HPAGE_SIZE chunks. */
+extern unsigned long pbase_map[];
+extern void *vbase_map[];
+
+static inline unsigned long kaddr_to_pfn(const volatile void *_kaddr)
+{
+ unsigned long kaddr = (unsigned long)_kaddr;
+ return pbase_map[kaddr >> HPAGE_SHIFT] +
+ ((kaddr & (HPAGE_SIZE - 1)) >> PAGE_SHIFT);
+}
+
+static inline void *pfn_to_kaddr(unsigned long pfn)
+{
+ return vbase_map[__pfn_to_highbits(pfn)] + (pfn << PAGE_SHIFT);
+}
+
+static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
+{
+ unsigned long pfn = kaddr_to_pfn(kaddr);
+ return ((phys_addr_t)pfn << PAGE_SHIFT) +
+ ((unsigned long)kaddr & (PAGE_SIZE-1));
+}
+
+static inline void *phys_to_virt(phys_addr_t paddr)
+{
+ return pfn_to_kaddr(paddr >> PAGE_SHIFT) + (paddr & (PAGE_SIZE-1));
+}
+
+/* With HIGHMEM, we pack PAGE_OFFSET through high_memory with all valid VAs. */
+static inline int virt_addr_valid(const volatile void *kaddr)
+{
+ extern void *high_memory; /* copied from <linux/mm.h> */
+ return ((unsigned long)kaddr >= PAGE_OFFSET && kaddr < high_memory);
+}
+
+#else /* !CONFIG_HIGHMEM */
+
+static inline unsigned long kaddr_to_pfn(const volatile void *kaddr)
+{
+ return ((unsigned long)kaddr - PAGE_OFFSET) >> PAGE_SHIFT;
+}
+
+static inline void *pfn_to_kaddr(unsigned long pfn)
+{
+ return (void *)((pfn << PAGE_SHIFT) + PAGE_OFFSET);
+}
+
+static inline phys_addr_t virt_to_phys(const volatile void *kaddr)
+{
+ return (phys_addr_t)((unsigned long)kaddr - PAGE_OFFSET);
+}
+
+static inline void *phys_to_virt(phys_addr_t paddr)
+{
+ return (void *)((unsigned long)paddr + PAGE_OFFSET);
+}
+
+/* Check that the given address is within some mapped range of PAs. */
+#define virt_addr_valid(kaddr) pfn_valid(kaddr_to_pfn(kaddr))
+
+#endif /* !CONFIG_HIGHMEM */
+
+/* All callers are not consistent in how they call these functions. */
+#define __pa(kaddr) virt_to_phys((void *)(unsigned long)(kaddr))
+#define __va(paddr) phys_to_virt((phys_addr_t)(paddr))
+
+extern int devmem_is_allowed(unsigned long pagenr);
+
+#ifdef CONFIG_FLATMEM
+static inline int pfn_valid(unsigned long pfn)
+{
+ return pfn < max_mapnr;
+}
+#endif
+
+/* Provide as macros since these require some other headers included. */
+#define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
+#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn(kaddr))
+#define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
+
+struct mm_struct;
+extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
+
+#endif /* !__ASSEMBLY__ */
+
+#define VM_DATA_DEFAULT_FLAGS \
+ (VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/getorder.h>
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_TILE_PAGE_H */
diff --git a/arch/tile/include/asm/param.h b/arch/tile/include/asm/param.h
new file mode 100644
index 000000000000..965d45427975
--- /dev/null
+++ b/arch/tile/include/asm/param.h
@@ -0,0 +1 @@
+#include <asm-generic/param.h>
diff --git a/arch/tile/include/asm/pci-bridge.h b/arch/tile/include/asm/pci-bridge.h
new file mode 100644
index 000000000000..e853b0e2793b
--- /dev/null
+++ b/arch/tile/include/asm/pci-bridge.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PCI_BRIDGE_H
+#define _ASM_TILE_PCI_BRIDGE_H
+
+#include <linux/ioport.h>
+#include <linux/pci.h>
+
+struct device_node;
+struct pci_controller;
+
+/*
+ * pci_io_base returns the memory address at which you can access
+ * the I/O space for PCI bus number `bus' (or NULL on error).
+ */
+extern void __iomem *pci_bus_io_base(unsigned int bus);
+extern unsigned long pci_bus_io_base_phys(unsigned int bus);
+extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
+
+/* Allocate a new PCI host bridge structure */
+extern struct pci_controller *pcibios_alloc_controller(void);
+
+/* Helper function for setting up resources */
+extern void pci_init_resource(struct resource *res, unsigned long start,
+ unsigned long end, int flags, char *name);
+
+/* Get the PCI host controller for a bus */
+extern struct pci_controller *pci_bus_to_hose(int bus);
+
+/*
+ * Structure of a PCI controller (host bridge)
+ */
+struct pci_controller {
+ int index; /* PCI domain number */
+ struct pci_bus *root_bus;
+
+ int first_busno;
+ int last_busno;
+
+ int hv_cfg_fd[2]; /* config{0,1} fds for this PCIe controller */
+ int hv_mem_fd; /* fd to Hypervisor for MMIO operations */
+
+ struct pci_ops *ops;
+
+ int irq_base; /* Base IRQ from the Hypervisor */
+ int plx_gen1; /* flag for PLX Gen 1 configuration */
+
+ /* Address ranges that are routed to this controller/bridge. */
+ struct resource mem_resources[3];
+};
+
+static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
+{
+ return bus->sysdata;
+}
+
+extern void setup_indirect_pci_nomap(struct pci_controller *hose,
+ void __iomem *cfg_addr, void __iomem *cfg_data);
+extern void setup_indirect_pci(struct pci_controller *hose,
+ u32 cfg_addr, u32 cfg_data);
+extern void setup_grackle(struct pci_controller *hose);
+
+extern unsigned char common_swizzle(struct pci_dev *, unsigned char *);
+
+/*
+ * The following code swizzles for exactly one bridge. The routine
+ * common_swizzle below handles multiple bridges. But there are a
+ * some boards that don't follow the PCI spec's suggestion so we
+ * break this piece out separately.
+ */
+static inline unsigned char bridge_swizzle(unsigned char pin,
+ unsigned char idsel)
+{
+ return (((pin-1) + idsel) % 4) + 1;
+}
+
+/*
+ * The following macro is used to lookup irqs in a standard table
+ * format for those PPC systems that do not already have PCI
+ * interrupts properly routed.
+ */
+/* FIXME - double check this */
+#define PCI_IRQ_TABLE_LOOKUP ({ \
+ long _ctl_ = -1; \
+ if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
+ _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
+ _ctl_; \
+})
+
+/*
+ * Scan the buses below a given PCI host bridge and assign suitable
+ * resources to all devices found.
+ */
+extern int pciauto_bus_scan(struct pci_controller *, int);
+
+#ifdef CONFIG_PCI
+extern unsigned long pci_address_to_pio(phys_addr_t address);
+#else
+static inline unsigned long pci_address_to_pio(phys_addr_t address)
+{
+ return (unsigned long)-1;
+}
+#endif
+
+#endif /* _ASM_TILE_PCI_BRIDGE_H */
diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
new file mode 100644
index 000000000000..b0c15da2d5d5
--- /dev/null
+++ b/arch/tile/include/asm/pci.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PCI_H
+#define _ASM_TILE_PCI_H
+
+#include <asm/pci-bridge.h>
+
+/*
+ * The hypervisor maps the entirety of CPA-space as bus addresses, so
+ * bus addresses are physical addresses. The networking and block
+ * device layers use this boolean for bounce buffer decisions.
+ */
+#define PCI_DMA_BUS_IS_PHYS 1
+
+struct pci_controller *pci_bus_to_hose(int bus);
+unsigned char __init common_swizzle(struct pci_dev *dev, unsigned char *pinp);
+int __init tile_pci_init(void);
+void pci_iounmap(struct pci_dev *dev, void __iomem *addr);
+void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
+void __devinit pcibios_fixup_bus(struct pci_bus *bus);
+
+int __devinit _tile_cfg_read(struct pci_controller *hose,
+ int bus,
+ int slot,
+ int function,
+ int offset,
+ int size,
+ u32 *val);
+int __devinit _tile_cfg_write(struct pci_controller *hose,
+ int bus,
+ int slot,
+ int function,
+ int offset,
+ int size,
+ u32 val);
+
+/*
+ * These are used to to config reads and writes in the early stages of
+ * setup before the driver infrastructure has been set up enough to be
+ * able to do config reads and writes.
+ */
+#define early_cfg_read(where, size, value) \
+ _tile_cfg_read(controller, \
+ current_bus, \
+ pci_slot, \
+ pci_fn, \
+ where, \
+ size, \
+ value)
+
+#define early_cfg_write(where, size, value) \
+ _tile_cfg_write(controller, \
+ current_bus, \
+ pci_slot, \
+ pci_fn, \
+ where, \
+ size, \
+ value)
+
+
+
+#define PCICFG_BYTE 1
+#define PCICFG_WORD 2
+#define PCICFG_DWORD 4
+
+#define TILE_NUM_PCIE 2
+
+#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)
+
+/*
+ * This decides whether to display the domain number in /proc.
+ */
+static inline int pci_proc_domain(struct pci_bus *bus)
+{
+ return 1;
+}
+
+/*
+ * I/O space is currently not supported.
+ */
+
+#define TILE_PCIE_LOWER_IO 0x0
+#define TILE_PCIE_UPPER_IO 0x10000
+#define TILE_PCIE_PCIE_IO_SIZE 0x0000FFFF
+
+#define _PAGE_NO_CACHE 0
+#define _PAGE_GUARDED 0
+
+
+#define pcibios_assign_all_busses() pci_assign_all_buses
+extern int pci_assign_all_buses;
+
+static inline void pcibios_set_master(struct pci_dev *dev)
+{
+ /* No special bus mastering setup handling */
+}
+
+#define PCIBIOS_MIN_MEM 0
+#define PCIBIOS_MIN_IO TILE_PCIE_LOWER_IO
+
+/*
+ * This flag tells if the platform is TILEmpower that needs
+ * special configuration for the PLX switch chip.
+ */
+extern int blade_pci;
+
+/* implement the pci_ DMA API in terms of the generic device dma_ one */
+#include <asm-generic/pci-dma-compat.h>
+
+/* generic pci stuff */
+#include <asm-generic/pci.h>
+
+/* Use any cpu for PCI. */
+#define cpumask_of_pcibus(bus) cpu_online_mask
+
+#endif /* _ASM_TILE_PCI_H */
diff --git a/arch/tile/include/asm/percpu.h b/arch/tile/include/asm/percpu.h
new file mode 100644
index 000000000000..63294f5a8efb
--- /dev/null
+++ b/arch/tile/include/asm/percpu.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PERCPU_H
+#define _ASM_TILE_PERCPU_H
+
+register unsigned long __my_cpu_offset __asm__("tp");
+#define __my_cpu_offset __my_cpu_offset
+#define set_my_cpu_offset(tp) (__my_cpu_offset = (tp))
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_TILE_PERCPU_H */
diff --git a/arch/tile/include/asm/pgalloc.h b/arch/tile/include/asm/pgalloc.h
new file mode 100644
index 000000000000..cf52791a5501
--- /dev/null
+++ b/arch/tile/include/asm/pgalloc.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PGALLOC_H
+#define _ASM_TILE_PGALLOC_H
+
+#include <linux/threads.h>
+#include <linux/mm.h>
+#include <linux/mmzone.h>
+#include <asm/fixmap.h>
+#include <hv/hypervisor.h>
+
+/* Bits for the size of the second-level page table. */
+#define L2_KERNEL_PGTABLE_SHIFT \
+ (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL + HV_LOG2_PTE_SIZE)
+
+/* We currently allocate user L2 page tables by page (unlike kernel L2s). */
+#if L2_KERNEL_PGTABLE_SHIFT < HV_LOG2_PAGE_SIZE_SMALL
+#define L2_USER_PGTABLE_SHIFT HV_LOG2_PAGE_SIZE_SMALL
+#else
+#define L2_USER_PGTABLE_SHIFT L2_KERNEL_PGTABLE_SHIFT
+#endif
+
+/* How many pages do we need, as an "order", for a user L2 page table? */
+#define L2_USER_PGTABLE_ORDER (L2_USER_PGTABLE_SHIFT - HV_LOG2_PAGE_SIZE_SMALL)
+
+/* How big is a kernel L2 page table? */
+#define L2_KERNEL_PGTABLE_SIZE (1 << L2_KERNEL_PGTABLE_SHIFT)
+
+static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
+{
+#ifdef CONFIG_64BIT
+ set_pte_order(pmdp, pmd, L2_USER_PGTABLE_ORDER);
+#else
+ set_pte_order(&pmdp->pud.pgd, pmd.pud.pgd, L2_USER_PGTABLE_ORDER);
+#endif
+}
+
+static inline void pmd_populate_kernel(struct mm_struct *mm,
+ pmd_t *pmd, pte_t *ptep)
+{
+ set_pmd(pmd, ptfn_pmd(__pa(ptep) >> HV_LOG2_PAGE_TABLE_ALIGN,
+ __pgprot(_PAGE_PRESENT)));
+}
+
+static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
+ pgtable_t page)
+{
+ set_pmd(pmd, ptfn_pmd(HV_PFN_TO_PTFN(page_to_pfn(page)),
+ __pgprot(_PAGE_PRESENT)));
+}
+
+/*
+ * Allocate and free page tables.
+ */
+
+extern pgd_t *pgd_alloc(struct mm_struct *mm);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address);
+extern void pte_free(struct mm_struct *mm, struct page *pte);
+
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+static inline pte_t *
+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
+{
+ return pfn_to_kaddr(page_to_pfn(pte_alloc_one(mm, address)));
+}
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ BUG_ON((unsigned long)pte & (PAGE_SIZE-1));
+ pte_free(mm, virt_to_page(pte));
+}
+
+extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address);
+
+#define check_pgt_cache() do { } while (0)
+
+/*
+ * Get the small-page pte_t lowmem entry for a given pfn.
+ * This may or may not be in use, depending on whether the initial
+ * huge-page entry for the page has already been shattered.
+ */
+pte_t *get_prealloc_pte(unsigned long pfn);
+
+/* During init, we can shatter kernel huge pages if needed. */
+void shatter_pmd(pmd_t *pmd);
+
+#ifdef __tilegx__
+/* We share a single page allocator for both L1 and L2 page tables. */
+#if HV_L1_SIZE != HV_L2_SIZE
+# error Rework assumption that L1 and L2 page tables are same size.
+#endif
+#define L1_USER_PGTABLE_ORDER L2_USER_PGTABLE_ORDER
+#define pud_populate(mm, pud, pmd) \
+ pmd_populate_kernel((mm), (pmd_t *)(pud), (pte_t *)(pmd))
+#define pmd_alloc_one(mm, addr) \
+ ((pmd_t *)page_to_virt(pte_alloc_one((mm), (addr))))
+#define pmd_free(mm, pmdp) \
+ pte_free((mm), virt_to_page(pmdp))
+#define __pmd_free_tlb(tlb, pmdp, address) \
+ __pte_free_tlb((tlb), virt_to_page(pmdp), (address))
+#endif
+
+#endif /* _ASM_TILE_PGALLOC_H */
diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h
new file mode 100644
index 000000000000..b3367379d537
--- /dev/null
+++ b/arch/tile/include/asm/pgtable.h
@@ -0,0 +1,480 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the TILE page table tree.
+ */
+
+#ifndef _ASM_TILE_PGTABLE_H
+#define _ASM_TILE_PGTABLE_H
+
+#include <hv/hypervisor.h>
+
+#ifndef __ASSEMBLY__
+
+#include <linux/bitops.h>
+#include <linux/threads.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <asm/processor.h>
+#include <asm/fixmap.h>
+#include <asm/system.h>
+
+struct mm_struct;
+struct vm_area_struct;
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+
+extern pgd_t swapper_pg_dir[];
+extern pgprot_t swapper_pgprot;
+extern struct kmem_cache *pgd_cache;
+extern spinlock_t pgd_lock;
+extern struct list_head pgd_list;
+
+/*
+ * The very last slots in the pgd_t are for addresses unusable by Linux
+ * (pgd_addr_invalid() returns true). So we use them for the list structure.
+ * The x86 code we are modelled on uses the page->private/index fields
+ * (older 2.6 kernels) or the lru list (newer 2.6 kernels), but since
+ * our pgds are so much smaller than a page, it seems a waste to
+ * spend a whole page on each pgd.
+ */
+#define PGD_LIST_OFFSET \
+ ((PTRS_PER_PGD * sizeof(pgd_t)) - sizeof(struct list_head))
+#define pgd_to_list(pgd) \
+ ((struct list_head *)((char *)(pgd) + PGD_LIST_OFFSET))
+#define list_to_pgd(list) \
+ ((pgd_t *)((char *)(list) - PGD_LIST_OFFSET))
+
+extern void pgtable_cache_init(void);
+extern void paging_init(void);
+extern void set_page_homes(void);
+
+#define FIRST_USER_ADDRESS 0
+
+#define _PAGE_PRESENT HV_PTE_PRESENT
+#define _PAGE_HUGE_PAGE HV_PTE_PAGE
+#define _PAGE_READABLE HV_PTE_READABLE
+#define _PAGE_WRITABLE HV_PTE_WRITABLE
+#define _PAGE_EXECUTABLE HV_PTE_EXECUTABLE
+#define _PAGE_ACCESSED HV_PTE_ACCESSED
+#define _PAGE_DIRTY HV_PTE_DIRTY
+#define _PAGE_GLOBAL HV_PTE_GLOBAL
+#define _PAGE_USER HV_PTE_USER
+
+/*
+ * All the "standard" bits. Cache-control bits are managed elsewhere.
+ * This is used to test for valid level-2 page table pointers by checking
+ * all the bits, and to mask away the cache control bits for mprotect.
+ */
+#define _PAGE_ALL (\
+ _PAGE_PRESENT | \
+ _PAGE_HUGE_PAGE | \
+ _PAGE_READABLE | \
+ _PAGE_WRITABLE | \
+ _PAGE_EXECUTABLE | \
+ _PAGE_ACCESSED | \
+ _PAGE_DIRTY | \
+ _PAGE_GLOBAL | \
+ _PAGE_USER \
+)
+
+#define PAGE_NONE \
+ __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_SHARED \
+ __pgprot(_PAGE_PRESENT | _PAGE_READABLE | _PAGE_WRITABLE | \
+ _PAGE_USER | _PAGE_ACCESSED)
+
+#define PAGE_SHARED_EXEC \
+ __pgprot(_PAGE_PRESENT | _PAGE_READABLE | _PAGE_WRITABLE | \
+ _PAGE_EXECUTABLE | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_COPY_NOEXEC \
+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_READABLE)
+#define PAGE_COPY_EXEC \
+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | \
+ _PAGE_READABLE | _PAGE_EXECUTABLE)
+#define PAGE_COPY \
+ PAGE_COPY_NOEXEC
+#define PAGE_READONLY \
+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_READABLE)
+#define PAGE_READONLY_EXEC \
+ __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | \
+ _PAGE_READABLE | _PAGE_EXECUTABLE)
+
+#define _PAGE_KERNEL_RO \
+ (_PAGE_PRESENT | _PAGE_GLOBAL | _PAGE_READABLE | _PAGE_ACCESSED)
+#define _PAGE_KERNEL \
+ (_PAGE_KERNEL_RO | _PAGE_WRITABLE | _PAGE_DIRTY)
+#define _PAGE_KERNEL_EXEC (_PAGE_KERNEL_RO | _PAGE_EXECUTABLE)
+
+#define PAGE_KERNEL __pgprot(_PAGE_KERNEL)
+#define PAGE_KERNEL_RO __pgprot(_PAGE_KERNEL_RO)
+#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL_EXEC)
+
+#define page_to_kpgprot(p) PAGE_KERNEL
+
+/*
+ * We could tighten these up, but for now writable or executable
+ * implies readable.
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY /* this is write-only, which we won't support */
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY_EXEC
+#define __P101 PAGE_READONLY_EXEC
+#define __P110 PAGE_COPY_EXEC
+#define __P111 PAGE_COPY_EXEC
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY_EXEC
+#define __S101 PAGE_READONLY_EXEC
+#define __S110 PAGE_SHARED_EXEC
+#define __S111 PAGE_SHARED_EXEC
+
+/*
+ * All the normal _PAGE_ALL bits are ignored for PMDs, except PAGE_PRESENT
+ * and PAGE_HUGE_PAGE, which must be one and zero, respectively.
+ * We set the ignored bits to zero.
+ */
+#define _PAGE_TABLE _PAGE_PRESENT
+
+/* Inherit the caching flags from the old protection bits. */
+#define pgprot_modify(oldprot, newprot) \
+ (pgprot_t) { ((oldprot).val & ~_PAGE_ALL) | (newprot).val }
+
+/* Just setting the PFN to zero suffices. */
+#define pte_pgprot(x) hv_pte_set_pfn((x), 0)
+
+/*
+ * For PTEs and PDEs, we must clear the Present bit first when
+ * clearing a page table entry, so clear the bottom half first and
+ * enforce ordering with a barrier.
+ */
+static inline void __pte_clear(pte_t *ptep)
+{
+#ifdef __tilegx__
+ ptep->val = 0;
+#else
+ u32 *tmp = (u32 *)ptep;
+ tmp[0] = 0;
+ barrier();
+ tmp[1] = 0;
+#endif
+}
+#define pte_clear(mm, addr, ptep) __pte_clear(ptep)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_present hv_pte_get_present
+#define pte_user hv_pte_get_user
+#define pte_read hv_pte_get_readable
+#define pte_dirty hv_pte_get_dirty
+#define pte_young hv_pte_get_accessed
+#define pte_write hv_pte_get_writable
+#define pte_exec hv_pte_get_executable
+#define pte_huge hv_pte_get_page
+#define pte_rdprotect hv_pte_clear_readable
+#define pte_exprotect hv_pte_clear_executable
+#define pte_mkclean hv_pte_clear_dirty
+#define pte_mkold hv_pte_clear_accessed
+#define pte_wrprotect hv_pte_clear_writable
+#define pte_mksmall hv_pte_clear_page
+#define pte_mkread hv_pte_set_readable
+#define pte_mkexec hv_pte_set_executable
+#define pte_mkdirty hv_pte_set_dirty
+#define pte_mkyoung hv_pte_set_accessed
+#define pte_mkwrite hv_pte_set_writable
+#define pte_mkhuge hv_pte_set_page
+
+#define pte_special(pte) 0
+#define pte_mkspecial(pte) (pte)
+
+/*
+ * Use some spare bits in the PTE for user-caching tags.
+ */
+#define pte_set_forcecache hv_pte_set_client0
+#define pte_get_forcecache hv_pte_get_client0
+#define pte_clear_forcecache hv_pte_clear_client0
+#define pte_set_anyhome hv_pte_set_client1
+#define pte_get_anyhome hv_pte_get_client1
+#define pte_clear_anyhome hv_pte_clear_client1
+
+/*
+ * A migrating PTE has PAGE_PRESENT clear but all the other bits preserved.
+ */
+#define pte_migrating hv_pte_get_migrating
+#define pte_mkmigrate(x) hv_pte_set_migrating(hv_pte_clear_present(x))
+#define pte_donemigrate(x) hv_pte_set_present(hv_pte_clear_migrating(x))
+
+#define pte_ERROR(e) \
+ pr_err("%s:%d: bad pte 0x%016llx.\n", __FILE__, __LINE__, pte_val(e))
+#define pgd_ERROR(e) \
+ pr_err("%s:%d: bad pgd 0x%016llx.\n", __FILE__, __LINE__, pgd_val(e))
+
+/*
+ * set_pte_order() sets the given PTE and also sanity-checks the
+ * requested PTE against the page homecaching. Unspecified parts
+ * of the PTE are filled in when it is written to memory, i.e. all
+ * caching attributes if "!forcecache", or the home cpu if "anyhome".
+ */
+extern void set_pte_order(pte_t *ptep, pte_t pte, int order);
+
+#define set_pte(ptep, pteval) set_pte_order(ptep, pteval, 0)
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+#define set_pte_atomic(pteptr, pteval) set_pte(pteptr, pteval)
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+static inline int pte_none(pte_t pte)
+{
+ return !pte.val;
+}
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ return hv_pte_get_pfn(pte);
+}
+
+/* Set or get the remote cache cpu in a pgprot with remote caching. */
+extern pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu);
+extern int get_remote_cache_cpu(pgprot_t prot);
+
+static inline pte_t pfn_pte(unsigned long pfn, pgprot_t prot)
+{
+ return hv_pte_set_pfn(prot, pfn);
+}
+
+/* Support for priority mappings. */
+extern void start_mm_caching(struct mm_struct *mm);
+extern void check_mm_caching(struct mm_struct *prev, struct mm_struct *next);
+
+/*
+ * Support non-linear file mappings (see sys_remap_file_pages).
+ * This is defined by CLIENT1 set but CLIENT0 and _PAGE_PRESENT clear, and the
+ * file offset in the 32 high bits.
+ */
+#define _PAGE_FILE HV_PTE_CLIENT1
+#define PTE_FILE_MAX_BITS 32
+#define pte_file(pte) (hv_pte_get_client1(pte) && !hv_pte_get_client0(pte))
+#define pte_to_pgoff(pte) ((pte).val >> 32)
+#define pgoff_to_pte(off) ((pte_t) { (((long long)(off)) << 32) | _PAGE_FILE })
+
+/*
+ * Encode and de-code a swap entry (see <linux/swapops.h>).
+ * We put the swap file type+offset in the 32 high bits;
+ * I believe we can just leave the low bits clear.
+ */
+#define __swp_type(swp) ((swp).val & 0x1f)
+#define __swp_offset(swp) ((swp).val >> 5)
+#define __swp_entry(type, off) ((swp_entry_t) { (type) | ((off) << 5) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).val >> 32 })
+#define __swp_entry_to_pte(swp) ((pte_t) { (((long long) ((swp).val)) << 32) })
+
+/*
+ * clone_pgd_range(pgd_t *dst, pgd_t *src, int count);
+ *
+ * dst - pointer to pgd range anwhere on a pgd page
+ * src - ""
+ * count - the number of pgds to copy.
+ *
+ * dst and src can be on the same page, but the range must not overlap,
+ * and must not cross a page boundary.
+ */
+static inline void clone_pgd_range(pgd_t *dst, pgd_t *src, int count)
+{
+ memcpy(dst, src, count * sizeof(pgd_t));
+}
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot))
+
+/*
+ * If we are doing an mprotect(), just accept the new vma->vm_page_prot
+ * value and combine it with the PFN from the old PTE to get a new PTE.
+ */
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ return pfn_pte(hv_pte_get_pfn(pte), newprot);
+}
+
+/*
+ * The pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
+ *
+ * This macro returns the index of the entry in the pgd page which would
+ * control the given virtual address.
+ */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's.
+ */
+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
+
+/*
+ * A shortcut which implies the use of the kernel's pgd, instead
+ * of a process's.
+ */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+#if defined(CONFIG_HIGHPTE)
+extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type);
+#define pte_offset_map(dir, address) \
+ _pte_offset_map(dir, address, KM_PTE0)
+#define pte_offset_map_nested(dir, address) \
+ _pte_offset_map(dir, address, KM_PTE1)
+#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
+#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
+#else
+#define pte_offset_map(dir, address) pte_offset_kernel(dir, address)
+#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+#endif
+
+/* Clear a non-executable kernel PTE and flush it from the TLB. */
+#define kpte_clear_flush(ptep, vaddr) \
+do { \
+ pte_clear(&init_mm, (vaddr), (ptep)); \
+ local_flush_tlb_page(FLUSH_NONEXEC, (vaddr), PAGE_SIZE); \
+} while (0)
+
+/*
+ * The kernel page tables contain what we need, and we flush when we
+ * change specific page table entries.
+ */
+#define update_mmu_cache(vma, address, pte) do { } while (0)
+
+#ifdef CONFIG_FLATMEM
+#define kern_addr_valid(addr) (1)
+#endif /* CONFIG_FLATMEM */
+
+#define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \
+ remap_pfn_range(vma, vaddr, pfn, size, prot)
+
+extern void vmalloc_sync_all(void);
+
+#endif /* !__ASSEMBLY__ */
+
+#ifdef __tilegx__
+#include <asm/pgtable_64.h>
+#else
+#include <asm/pgtable_32.h>
+#endif
+
+#ifndef __ASSEMBLY__
+
+static inline int pmd_none(pmd_t pmd)
+{
+ /*
+ * Only check low word on 32-bit platforms, since it might be
+ * out of sync with upper half.
+ */
+ return (unsigned long)pmd_val(pmd) == 0;
+}
+
+static inline int pmd_present(pmd_t pmd)
+{
+ return pmd_val(pmd) & _PAGE_PRESENT;
+}
+
+static inline int pmd_bad(pmd_t pmd)
+{
+ return ((pmd_val(pmd) & _PAGE_ALL) != _PAGE_TABLE);
+}
+
+static inline unsigned long pages_to_mb(unsigned long npg)
+{
+ return npg >> (20 - PAGE_SHIFT);
+}
+
+/*
+ * The pmd can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * This function returns the index of the entry in the pmd which would
+ * control the given virtual address.
+ */
+static inline unsigned long pmd_index(unsigned long address)
+{
+ return (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1);
+}
+
+/*
+ * A given kernel pmd_t maps to a specific virtual address (either a
+ * kernel huge page or a kernel pte_t table). Since kernel pte_t
+ * tables can be aligned at sub-page granularity, this function can
+ * return non-page-aligned pointers, despite its name.
+ */
+static inline unsigned long pmd_page_vaddr(pmd_t pmd)
+{
+ phys_addr_t pa =
+ (phys_addr_t)pmd_ptfn(pmd) << HV_LOG2_PAGE_TABLE_ALIGN;
+ return (unsigned long)__va(pa);
+}
+
+/*
+ * A pmd_t points to the base of a huge page or to a pte_t array.
+ * If a pte_t array, since we can have multiple per page, we don't
+ * have a one-to-one mapping of pmd_t's to pages. However, this is
+ * OK for pte_lockptr(), since we just end up with potentially one
+ * lock being used for several pte_t arrays.
+ */
+#define pmd_page(pmd) pfn_to_page(HV_PTFN_TO_PFN(pmd_ptfn(pmd)))
+
+/*
+ * The pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * This macro returns the index of the entry in the pte page which would
+ * control the given virtual address.
+ */
+static inline unsigned long pte_index(unsigned long address)
+{
+ return (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+}
+
+static inline pte_t *pte_offset_kernel(pmd_t *pmd, unsigned long address)
+{
+ return (pte_t *)pmd_page_vaddr(*pmd) + pte_index(address);
+}
+
+static inline int pmd_huge_page(pmd_t pmd)
+{
+ return pmd_val(pmd) & _PAGE_HUGE_PAGE;
+}
+
+#include <asm-generic/pgtable.h>
+
+/* Support /proc/NN/pgtable API. */
+struct seq_file;
+int arch_proc_pgtable_show(struct seq_file *m, struct mm_struct *mm,
+ unsigned long vaddr, pte_t *ptep, void **datap);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_PGTABLE_H */
diff --git a/arch/tile/include/asm/pgtable_32.h b/arch/tile/include/asm/pgtable_32.h
new file mode 100644
index 000000000000..53ec34884744
--- /dev/null
+++ b/arch/tile/include/asm/pgtable_32.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _ASM_TILE_PGTABLE_32_H
+#define _ASM_TILE_PGTABLE_32_H
+
+/*
+ * The level-1 index is defined by the huge page size. A PGD is composed
+ * of PTRS_PER_PGD pgd_t's and is the top level of the page table.
+ */
+#define PGDIR_SHIFT HV_LOG2_PAGE_SIZE_LARGE
+#define PGDIR_SIZE HV_PAGE_SIZE_LARGE
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+#define PTRS_PER_PGD (1 << (32 - PGDIR_SHIFT))
+
+/*
+ * The level-2 index is defined by the difference between the huge
+ * page size and the normal page size. A PTE is composed of
+ * PTRS_PER_PTE pte_t's and is the bottom level of the page table.
+ * Note that the hypervisor docs use PTE for what we call pte_t, so
+ * this nomenclature is somewhat confusing.
+ */
+#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Right now we initialize only a single pte table. It can be extended
+ * easily, subsequent pte tables have to be allocated in one physical
+ * chunk of RAM.
+ *
+ * HOWEVER, if we are using an allocation scheme with slop after the
+ * end of the page table (e.g. where our L2 page tables are 2KB but
+ * our pages are 64KB and we are allocating via the page allocator)
+ * we can't extend it easily.
+ */
+#define LAST_PKMAP PTRS_PER_PTE
+
+#define PKMAP_BASE ((FIXADDR_BOOT_START - PAGE_SIZE*LAST_PKMAP) & PGDIR_MASK)
+
+#ifdef CONFIG_HIGHMEM
+# define __VMAPPING_END (PKMAP_BASE & ~(HPAGE_SIZE-1))
+#else
+# define __VMAPPING_END (FIXADDR_START & ~(HPAGE_SIZE-1))
+#endif
+
+#ifdef CONFIG_HUGEVMAP
+#define HUGE_VMAP_END __VMAPPING_END
+#define HUGE_VMAP_BASE (HUGE_VMAP_END - CONFIG_NR_HUGE_VMAPS * HPAGE_SIZE)
+#define _VMALLOC_END HUGE_VMAP_BASE
+#else
+#define _VMALLOC_END __VMAPPING_END
+#endif
+
+/*
+ * Align the vmalloc area to an L2 page table, and leave a guard page
+ * at the beginning and end. The vmalloc code also puts in an internal
+ * guard page between each allocation.
+ */
+#define VMALLOC_END (_VMALLOC_END - PAGE_SIZE)
+extern unsigned long VMALLOC_RESERVE /* = CONFIG_VMALLOC_RESERVE */;
+#define _VMALLOC_START (_VMALLOC_END - VMALLOC_RESERVE)
+#define VMALLOC_START (_VMALLOC_START + PAGE_SIZE)
+
+/* This is the maximum possible amount of lowmem. */
+#define MAXMEM (_VMALLOC_START - PAGE_OFFSET)
+
+/* We have no pmd or pud since we are strictly a two-level page table */
+#include <asm-generic/pgtable-nopmd.h>
+
+/* We don't define any pgds for these addresses. */
+static inline int pgd_addr_invalid(unsigned long addr)
+{
+ return addr >= MEM_HV_INTRPT;
+}
+
+/*
+ * Provide versions of these routines that can be used safely when
+ * the hypervisor may be asynchronously modifying dirty/accessed bits.
+ * ptep_get_and_clear() matches the generic one but we provide it to
+ * be parallel with the 64-bit code.
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+
+extern int ptep_test_and_clear_young(struct vm_area_struct *,
+ unsigned long addr, pte_t *);
+extern void ptep_set_wrprotect(struct mm_struct *,
+ unsigned long addr, pte_t *);
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+ pte_t pte = *ptep;
+ pte_clear(_mm, addr, ptep);
+ return pte;
+}
+
+/* Create a pmd from a PTFN. */
+static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
+{
+ return (pmd_t){ { hv_pte_set_ptfn(prot, ptfn) } };
+}
+
+/* Return the page-table frame number (ptfn) that a pmd_t points at. */
+#define pmd_ptfn(pmd) hv_pte_get_ptfn((pmd).pud.pgd)
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+ __pte_clear(&pmdp->pud.pgd);
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_TILE_PGTABLE_32_H */
diff --git a/arch/tile/include/asm/poll.h b/arch/tile/include/asm/poll.h
new file mode 100644
index 000000000000..c98509d3149e
--- /dev/null
+++ b/arch/tile/include/asm/poll.h
@@ -0,0 +1 @@
+#include <asm-generic/poll.h>
diff --git a/arch/tile/include/asm/posix_types.h b/arch/tile/include/asm/posix_types.h
new file mode 100644
index 000000000000..22cae6230ceb
--- /dev/null
+++ b/arch/tile/include/asm/posix_types.h
@@ -0,0 +1 @@
+#include <asm-generic/posix_types.h>
diff --git a/arch/tile/include/asm/processor.h b/arch/tile/include/asm/processor.h
new file mode 100644
index 000000000000..d942d09b252e
--- /dev/null
+++ b/arch/tile/include/asm/processor.h
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PROCESSOR_H
+#define _ASM_TILE_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+/*
+ * NOTE: we don't include <linux/ptrace.h> or <linux/percpu.h> as one
+ * normally would, due to #include dependencies.
+ */
+#include <linux/types.h>
+#include <asm/ptrace.h>
+#include <asm/percpu.h>
+
+#include <arch/chip.h>
+#include <arch/spr_def.h>
+
+struct task_struct;
+struct thread_struct;
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+void *current_text_addr(void);
+
+#if CHIP_HAS_TILE_DMA()
+/* Capture the state of a suspended DMA. */
+struct tile_dma_state {
+ int enabled;
+ unsigned long src;
+ unsigned long dest;
+ unsigned long strides;
+ unsigned long chunk_size;
+ unsigned long src_chunk;
+ unsigned long dest_chunk;
+ unsigned long byte;
+ unsigned long status;
+};
+
+/*
+ * A mask of the DMA status register for selecting only the 'running'
+ * and 'done' bits.
+ */
+#define DMA_STATUS_MASK \
+ (SPR_DMA_STATUS__RUNNING_MASK | SPR_DMA_STATUS__DONE_MASK)
+#endif
+
+/*
+ * Track asynchronous TLB events (faults and access violations)
+ * that occur while we are in kernel mode from DMA or the SN processor.
+ */
+struct async_tlb {
+ short fault_num; /* original fault number; 0 if none */
+ char is_fault; /* was it a fault (vs an access violation) */
+ char is_write; /* for fault: was it caused by a write? */
+ unsigned long address; /* what address faulted? */
+};
+
+#ifdef CONFIG_HARDWALL
+struct hardwall_info;
+#endif
+
+struct thread_struct {
+ /* kernel stack pointer */
+ unsigned long ksp;
+ /* kernel PC */
+ unsigned long pc;
+ /* starting user stack pointer (for page migration) */
+ unsigned long usp0;
+ /* pid of process that created this one */
+ pid_t creator_pid;
+#if CHIP_HAS_TILE_DMA()
+ /* DMA info for suspended threads (byte == 0 means no DMA state) */
+ struct tile_dma_state tile_dma_state;
+#endif
+ /* User EX_CONTEXT registers */
+ unsigned long ex_context[2];
+ /* User SYSTEM_SAVE registers */
+ unsigned long system_save[4];
+ /* User interrupt mask */
+ unsigned long long interrupt_mask;
+ /* User interrupt-control 0 state */
+ unsigned long intctrl_0;
+#if CHIP_HAS_PROC_STATUS_SPR()
+ /* Any other miscellaneous processor state bits */
+ unsigned long proc_status;
+#endif
+#ifdef CONFIG_HARDWALL
+ /* Is this task tied to an activated hardwall? */
+ struct hardwall_info *hardwall;
+ /* Chains this task into the list at hardwall->list. */
+ struct list_head hardwall_list;
+#endif
+#if CHIP_HAS_TILE_DMA()
+ /* Async DMA TLB fault information */
+ struct async_tlb dma_async_tlb;
+#endif
+#if CHIP_HAS_SN_PROC()
+ /* Was static network processor when we were switched out? */
+ int sn_proc_running;
+ /* Async SNI TLB fault information */
+ struct async_tlb sn_async_tlb;
+#endif
+};
+
+#endif /* !__ASSEMBLY__ */
+
+/*
+ * Start with "sp" this many bytes below the top of the kernel stack.
+ * This preserves the invariant that a called function may write to *sp.
+ */
+#define STACK_TOP_DELTA 8
+
+/*
+ * When entering the kernel via a fault, start with the top of the
+ * pt_regs structure this many bytes below the top of the page.
+ * This aligns the pt_regs structure optimally for cache-line access.
+ */
+#ifdef __tilegx__
+#define KSTK_PTREGS_GAP 48
+#else
+#define KSTK_PTREGS_GAP 56
+#endif
+
+#ifndef __ASSEMBLY__
+
+#ifdef __tilegx__
+#define TASK_SIZE_MAX (MEM_LOW_END + 1)
+#else
+#define TASK_SIZE_MAX PAGE_OFFSET
+#endif
+
+/* TASK_SIZE and related variables are always checked in "current" context. */
+#ifdef CONFIG_COMPAT
+#define COMPAT_TASK_SIZE (1UL << 31)
+#define TASK_SIZE ((current_thread_info()->status & TS_COMPAT) ?\
+ COMPAT_TASK_SIZE : TASK_SIZE_MAX)
+#else
+#define TASK_SIZE TASK_SIZE_MAX
+#endif
+
+/* We provide a minimal "vdso" a la x86; just the sigreturn code for now. */
+#define VDSO_BASE (TASK_SIZE - PAGE_SIZE)
+
+#define STACK_TOP VDSO_BASE
+
+/* STACK_TOP_MAX is used temporarily in execve and should not check COMPAT. */
+#define STACK_TOP_MAX TASK_SIZE_MAX
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's, if it is using bottom-up mapping.
+ */
+#define TASK_UNMAPPED_BASE (PAGE_ALIGN(TASK_SIZE / 3))
+
+#define HAVE_ARCH_PICK_MMAP_LAYOUT
+
+#define INIT_THREAD { \
+ .ksp = (unsigned long)init_stack + THREAD_SIZE - STACK_TOP_DELTA, \
+ .interrupt_mask = -1ULL \
+}
+
+/* Kernel stack top for the task that first boots on this cpu. */
+DECLARE_PER_CPU(unsigned long, boot_sp);
+
+/* PC to boot from on this cpu. */
+DECLARE_PER_CPU(unsigned long, boot_pc);
+
+/* Do necessary setup to start up a newly executed thread. */
+static inline void start_thread(struct pt_regs *regs,
+ unsigned long pc, unsigned long usp)
+{
+ regs->pc = pc;
+ regs->sp = usp;
+}
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+ /* Nothing for now */
+}
+
+/* Prepare to copy thread state - unlazy all lazy status. */
+#define prepare_to_copy(tsk) do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
+
+
+/*
+ * Return saved (kernel) PC of a blocked thread.
+ * Only used in a printk() in kernel/sched.c, so don't work too hard.
+ */
+#define thread_saved_pc(t) ((t)->thread.pc)
+
+unsigned long get_wchan(struct task_struct *p);
+
+/* Return initial ksp value for given task. */
+#define task_ksp0(task) ((unsigned long)(task)->stack + THREAD_SIZE)
+
+/* Return some info about the user process TASK. */
+#define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA)
+#define task_pt_regs(task) \
+ ((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
+#define task_sp(task) (task_pt_regs(task)->sp)
+#define task_pc(task) (task_pt_regs(task)->pc)
+/* Aliases for pc and sp (used in fs/proc/array.c) */
+#define KSTK_EIP(task) task_pc(task)
+#define KSTK_ESP(task) task_sp(task)
+
+/* Standard format for printing registers and other word-size data. */
+#ifdef __tilegx__
+# define REGFMT "0x%016lx"
+#else
+# define REGFMT "0x%08lx"
+#endif
+
+/*
+ * Do some slow action (e.g. read a slow SPR).
+ * Note that this must also have compiler-barrier semantics since
+ * it may be used in a busy loop reading memory.
+ */
+static inline void cpu_relax(void)
+{
+ __insn_mfspr(SPR_PASS);
+ barrier();
+}
+
+struct siginfo;
+extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
+#define arch_coredump_signal arch_coredump_signal
+
+/* Info on this processor (see fs/proc/cpuinfo.c) */
+struct seq_operations;
+extern const struct seq_operations cpuinfo_op;
+
+/* Provide information about the chip model. */
+extern char chip_model[64];
+
+/* Data on which physical memory controller corresponds to which NUMA node. */
+extern int node_controller[];
+
+
+/* Do we dump information to the console when a user application crashes? */
+extern int show_crashinfo;
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+/* Does the heap allocator return hash-for-home pages by default? */
+extern int hash_default;
+
+/* Should kernel stack pages be hash-for-home? */
+extern int kstack_hash;
+
+/* Does MAP_ANONYMOUS return hash-for-home pages by default? */
+#define uheap_hash hash_default
+
+#else
+#define hash_default 0
+#define kstack_hash 0
+#define uheap_hash 0
+#endif
+
+/* Are we using huge pages in the TLB for kernel data? */
+extern int kdata_huge;
+
+#define PREFETCH_STRIDE CHIP_L2_LINE_SIZE()
+
+#else /* __ASSEMBLY__ */
+
+/* Do some slow action (e.g. read a slow SPR). */
+#define CPU_RELAX mfspr zero, SPR_PASS
+
+#endif /* !__ASSEMBLY__ */
+
+/* Assembly code assumes that the PL is in the low bits. */
+#if SPR_EX_CONTEXT_1_1__PL_SHIFT != 0
+# error Fix assembly assumptions about PL
+#endif
+
+/* We sometimes use these macros for EX_CONTEXT_0_1 as well. */
+#if SPR_EX_CONTEXT_1_1__PL_SHIFT != SPR_EX_CONTEXT_0_1__PL_SHIFT || \
+ SPR_EX_CONTEXT_1_1__PL_RMASK != SPR_EX_CONTEXT_0_1__PL_RMASK || \
+ SPR_EX_CONTEXT_1_1__ICS_SHIFT != SPR_EX_CONTEXT_0_1__ICS_SHIFT || \
+ SPR_EX_CONTEXT_1_1__ICS_RMASK != SPR_EX_CONTEXT_0_1__ICS_RMASK
+# error Fix assumptions that EX1 macros work for both PL0 and PL1
+#endif
+
+/* Allow pulling apart and recombining the PL and ICS bits in EX_CONTEXT. */
+#define EX1_PL(ex1) \
+ (((ex1) >> SPR_EX_CONTEXT_1_1__PL_SHIFT) & SPR_EX_CONTEXT_1_1__PL_RMASK)
+#define EX1_ICS(ex1) \
+ (((ex1) >> SPR_EX_CONTEXT_1_1__ICS_SHIFT) & SPR_EX_CONTEXT_1_1__ICS_RMASK)
+#define PL_ICS_EX1(pl, ics) \
+ (((pl) << SPR_EX_CONTEXT_1_1__PL_SHIFT) | \
+ ((ics) << SPR_EX_CONTEXT_1_1__ICS_SHIFT))
+
+/*
+ * Provide symbolic constants for PLs.
+ * Note that assembly code assumes that USER_PL is zero.
+ */
+#define USER_PL 0
+#define KERNEL_PL 1
+
+/* SYSTEM_SAVE_1_0 holds the current cpu number ORed with ksp0. */
+#define CPU_LOG_MASK_VALUE 12
+#define CPU_MASK_VALUE ((1 << CPU_LOG_MASK_VALUE) - 1)
+#if CONFIG_NR_CPUS > CPU_MASK_VALUE
+# error Too many cpus!
+#endif
+#define raw_smp_processor_id() \
+ ((int)__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & CPU_MASK_VALUE)
+#define get_current_ksp0() \
+ (__insn_mfspr(SPR_SYSTEM_SAVE_1_0) & ~CPU_MASK_VALUE)
+#define next_current_ksp0(task) ({ \
+ unsigned long __ksp0 = task_ksp0(task); \
+ int __cpu = raw_smp_processor_id(); \
+ BUG_ON(__ksp0 & CPU_MASK_VALUE); \
+ __ksp0 | __cpu; \
+})
+
+#endif /* _ASM_TILE_PROCESSOR_H */
diff --git a/arch/tile/include/asm/ptrace.h b/arch/tile/include/asm/ptrace.h
new file mode 100644
index 000000000000..acdae814e016
--- /dev/null
+++ b/arch/tile/include/asm/ptrace.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_PTRACE_H
+#define _ASM_TILE_PTRACE_H
+
+#include <arch/chip.h>
+#include <arch/abi.h>
+
+/* These must match struct pt_regs, below. */
+#if CHIP_WORD_SIZE() == 32
+#define PTREGS_OFFSET_REG(n) ((n)*4)
+#else
+#define PTREGS_OFFSET_REG(n) ((n)*8)
+#endif
+#define PTREGS_OFFSET_BASE 0
+#define PTREGS_OFFSET_TP PTREGS_OFFSET_REG(53)
+#define PTREGS_OFFSET_SP PTREGS_OFFSET_REG(54)
+#define PTREGS_OFFSET_LR PTREGS_OFFSET_REG(55)
+#define PTREGS_NR_GPRS 56
+#define PTREGS_OFFSET_PC PTREGS_OFFSET_REG(56)
+#define PTREGS_OFFSET_EX1 PTREGS_OFFSET_REG(57)
+#define PTREGS_OFFSET_FAULTNUM PTREGS_OFFSET_REG(58)
+#define PTREGS_OFFSET_ORIG_R0 PTREGS_OFFSET_REG(59)
+#define PTREGS_OFFSET_FLAGS PTREGS_OFFSET_REG(60)
+#if CHIP_HAS_CMPEXCH()
+#define PTREGS_OFFSET_CMPEXCH PTREGS_OFFSET_REG(61)
+#endif
+#define PTREGS_SIZE PTREGS_OFFSET_REG(64)
+
+#ifndef __ASSEMBLY__
+
+#ifdef __KERNEL__
+/* Benefit from consistent use of "long" on all chips. */
+typedef unsigned long pt_reg_t;
+#else
+/* Provide appropriate length type to userspace regardless of -m32/-m64. */
+typedef uint_reg_t pt_reg_t;
+#endif
+
+/*
+ * This struct defines the way the registers are stored on the stack during a
+ * system call/exception. It should be a multiple of 8 bytes to preserve
+ * normal stack alignment rules.
+ *
+ * Must track <sys/ucontext.h> and <sys/procfs.h>
+ */
+struct pt_regs {
+ /* Saved main processor registers; 56..63 are special. */
+ /* tp, sp, and lr must immediately follow regs[] for aliasing. */
+ pt_reg_t regs[53];
+ pt_reg_t tp; /* aliases regs[TREG_TP] */
+ pt_reg_t sp; /* aliases regs[TREG_SP] */
+ pt_reg_t lr; /* aliases regs[TREG_LR] */
+
+ /* Saved special registers. */
+ pt_reg_t pc; /* stored in EX_CONTEXT_1_0 */
+ pt_reg_t ex1; /* stored in EX_CONTEXT_1_1 (PL and ICS bit) */
+ pt_reg_t faultnum; /* fault number (INT_SWINT_1 for syscall) */
+ pt_reg_t orig_r0; /* r0 at syscall entry, else zero */
+ pt_reg_t flags; /* flags (see below) */
+#if !CHIP_HAS_CMPEXCH()
+ pt_reg_t pad[3];
+#else
+ pt_reg_t cmpexch; /* value of CMPEXCH_VALUE SPR at interrupt */
+ pt_reg_t pad[2];
+#endif
+};
+
+#endif /* __ASSEMBLY__ */
+
+/* Flag bits in pt_regs.flags */
+#define PT_FLAGS_DISABLE_IRQ 1 /* on return to kernel, disable irqs */
+#define PT_FLAGS_CALLER_SAVES 2 /* caller-save registers are valid */
+#define PT_FLAGS_RESTORE_REGS 4 /* restore callee-save regs on return */
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+/* Support TILE-specific ptrace options, with events starting at 16. */
+#define PTRACE_O_TRACEMIGRATE 0x00010000
+#define PTRACE_EVENT_MIGRATE 16
+#ifdef __KERNEL__
+#define PTRACE_O_MASK_TILE (PTRACE_O_TRACEMIGRATE)
+#define PT_TRACE_MIGRATE 0x00080000
+#define PT_TRACE_MASK_TILE (PT_TRACE_MIGRATE)
+#endif
+
+#ifdef __KERNEL__
+
+#ifndef __ASSEMBLY__
+
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+
+/* Does the process account for user or for system time? */
+#define user_mode(regs) (EX1_PL((regs)->ex1) == USER_PL)
+
+/* Fill in a struct pt_regs with the current kernel registers. */
+struct pt_regs *get_pt_regs(struct pt_regs *);
+
+/* Trace the current syscall. */
+extern void do_syscall_trace(void);
+
+extern void show_regs(struct pt_regs *);
+
+#define arch_has_single_step() (1)
+
+/*
+ * A structure for all single-stepper state.
+ *
+ * Also update defines in assembler section if it changes
+ */
+struct single_step_state {
+ /* the page to which we will write hacked-up bundles */
+ void __user *buffer;
+
+ union {
+ int flags;
+ struct {
+ unsigned long is_enabled:1, update:1, update_reg:6;
+ };
+ };
+
+ unsigned long orig_pc; /* the original PC */
+ unsigned long next_pc; /* return PC if no branch (PC + 1) */
+ unsigned long branch_next_pc; /* return PC if we did branch/jump */
+ unsigned long update_value; /* value to restore to update_target */
+};
+
+/* Single-step the instruction at regs->pc */
+extern void single_step_once(struct pt_regs *regs);
+
+struct task_struct;
+
+extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
+ int error_code);
+
+#ifdef __tilegx__
+/* We need this since sigval_t has a user pointer in it, for GETSIGINFO etc. */
+#define __ARCH_WANT_COMPAT_SYS_PTRACE
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#define SINGLESTEP_STATE_MASK_IS_ENABLED 0x1
+#define SINGLESTEP_STATE_MASK_UPDATE 0x2
+#define SINGLESTEP_STATE_TARGET_LB 2
+#define SINGLESTEP_STATE_TARGET_UB 7
+
+#endif /* !__KERNEL__ */
+
+#endif /* _ASM_TILE_PTRACE_H */
diff --git a/arch/tile/include/asm/resource.h b/arch/tile/include/asm/resource.h
new file mode 100644
index 000000000000..04bc4db8921b
--- /dev/null
+++ b/arch/tile/include/asm/resource.h
@@ -0,0 +1 @@
+#include <asm-generic/resource.h>
diff --git a/arch/tile/include/asm/scatterlist.h b/arch/tile/include/asm/scatterlist.h
new file mode 100644
index 000000000000..c5604242c0d5
--- /dev/null
+++ b/arch/tile/include/asm/scatterlist.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SCATTERLIST_H
+#define _ASM_TILE_SCATTERLIST_H
+
+#define ISA_DMA_THRESHOLD (~0UL)
+
+#include <asm-generic/scatterlist.h>
+
+#endif /* _ASM_TILE_SCATTERLIST_H */
diff --git a/arch/tile/include/asm/sections.h b/arch/tile/include/asm/sections.h
new file mode 100644
index 000000000000..d062d463fca9
--- /dev/null
+++ b/arch/tile/include/asm/sections.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SECTIONS_H
+#define _ASM_TILE_SECTIONS_H
+
+#define arch_is_kernel_data arch_is_kernel_data
+
+#include <asm-generic/sections.h>
+
+/* Text and data are at different areas in the kernel VA space. */
+extern char _sinitdata[], _einitdata[];
+
+/* Write-once data is writable only till the end of initialization. */
+extern char __w1data_begin[], __w1data_end[];
+
+
+/* Not exactly sections, but PC comparison points in the code. */
+extern char __rt_sigreturn[], __rt_sigreturn_end[];
+#ifndef __tilegx__
+extern char sys_cmpxchg[], __sys_cmpxchg_end[];
+extern char __sys_cmpxchg_grab_lock[];
+extern char __start_atomic_asm_code[], __end_atomic_asm_code[];
+#endif
+
+/* Handle the discontiguity between _sdata and _stext. */
+static inline int arch_is_kernel_data(unsigned long addr)
+{
+ return addr >= (unsigned long)_sdata &&
+ addr < (unsigned long)_end;
+}
+
+#endif /* _ASM_TILE_SECTIONS_H */
diff --git a/arch/tile/include/asm/sembuf.h b/arch/tile/include/asm/sembuf.h
new file mode 100644
index 000000000000..7673b83cfef7
--- /dev/null
+++ b/arch/tile/include/asm/sembuf.h
@@ -0,0 +1 @@
+#include <asm-generic/sembuf.h>
diff --git a/arch/tile/include/asm/setup.h b/arch/tile/include/asm/setup.h
new file mode 100644
index 000000000000..823ddd47ff6e
--- /dev/null
+++ b/arch/tile/include/asm/setup.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SETUP_H
+#define _ASM_TILE_SETUP_H
+
+#include <linux/pfn.h>
+#include <linux/init.h>
+
+/*
+ * Reserved space for vmalloc and iomap - defined in asm/page.h
+ */
+#define MAXMEM_PFN PFN_DOWN(MAXMEM)
+
+#define COMMAND_LINE_SIZE 2048
+
+void early_panic(const char *fmt, ...);
+void warn_early_printk(void);
+void __init disable_early_printk(void);
+
+#endif /* _ASM_TILE_SETUP_H */
diff --git a/arch/tile/include/asm/shmbuf.h b/arch/tile/include/asm/shmbuf.h
new file mode 100644
index 000000000000..83c05fc2de38
--- /dev/null
+++ b/arch/tile/include/asm/shmbuf.h
@@ -0,0 +1 @@
+#include <asm-generic/shmbuf.h>
diff --git a/arch/tile/include/asm/shmparam.h b/arch/tile/include/asm/shmparam.h
new file mode 100644
index 000000000000..93f30deb95d0
--- /dev/null
+++ b/arch/tile/include/asm/shmparam.h
@@ -0,0 +1 @@
+#include <asm-generic/shmparam.h>
diff --git a/arch/tile/include/asm/sigcontext.h b/arch/tile/include/asm/sigcontext.h
new file mode 100644
index 000000000000..7cd7672e3ad4
--- /dev/null
+++ b/arch/tile/include/asm/sigcontext.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SIGCONTEXT_H
+#define _ASM_TILE_SIGCONTEXT_H
+
+/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
+#include <asm/ptrace.h>
+
+/* Must track <sys/ucontext.h> */
+
+struct sigcontext {
+ struct pt_regs regs;
+};
+
+#endif /* _ASM_TILE_SIGCONTEXT_H */
diff --git a/arch/tile/include/asm/sigframe.h b/arch/tile/include/asm/sigframe.h
new file mode 100644
index 000000000000..994d3d30205f
--- /dev/null
+++ b/arch/tile/include/asm/sigframe.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SIGFRAME_H
+#define _ASM_TILE_SIGFRAME_H
+
+/* Indicate that syscall return should not examine r0 */
+#define INT_SWINT_1_SIGRETURN (~0)
+
+#ifndef __ASSEMBLY__
+
+#include <arch/abi.h>
+
+struct rt_sigframe {
+ unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
+ struct siginfo info;
+ struct ucontext uc;
+};
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_SIGFRAME_H */
diff --git a/arch/tile/include/asm/siginfo.h b/arch/tile/include/asm/siginfo.h
new file mode 100644
index 000000000000..0c12d1b9ddf2
--- /dev/null
+++ b/arch/tile/include/asm/siginfo.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SIGINFO_H
+#define _ASM_TILE_SIGINFO_H
+
+#define __ARCH_SI_TRAPNO
+
+#include <asm-generic/siginfo.h>
+
+/*
+ * Additional Tile-specific SIGILL si_codes
+ */
+#define ILL_DBLFLT (__SI_FAULT|9) /* double fault */
+#define ILL_HARDWALL (__SI_FAULT|10) /* user networks hardwall violation */
+#undef NSIGILL
+#define NSIGILL 10
+
+#endif /* _ASM_TILE_SIGINFO_H */
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
new file mode 100644
index 000000000000..eb0253f32202
--- /dev/null
+++ b/arch/tile/include/asm/signal.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SIGNAL_H
+#define _ASM_TILE_SIGNAL_H
+
+/* Do not notify a ptracer when this signal is handled. */
+#define SA_NOPTRACE 0x02000000u
+
+/* Used in earlier Tilera releases, so keeping for binary compatibility. */
+#define SA_RESTORER 0x04000000u
+
+#include <asm-generic/signal.h>
+
+#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *);
+int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
+void do_signal(struct pt_regs *regs);
+#endif
+
+#endif /* _ASM_TILE_SIGNAL_H */
diff --git a/arch/tile/include/asm/smp.h b/arch/tile/include/asm/smp.h
new file mode 100644
index 000000000000..532124ae4b12
--- /dev/null
+++ b/arch/tile/include/asm/smp.h
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SMP_H
+#define _ASM_TILE_SMP_H
+
+#ifdef CONFIG_SMP
+
+#include <asm/processor.h>
+#include <linux/cpumask.h>
+#include <linux/irqreturn.h>
+#include <hv/hypervisor.h>
+
+/* Set up this tile to support receiving hypervisor messages */
+void init_messaging(void);
+
+/* Set up this tile to support receiving device interrupts and IPIs. */
+void init_per_tile_IRQs(void);
+
+/* Send a message to processors specified in mask */
+void send_IPI_many(const struct cpumask *mask, int tag);
+
+/* Send a message to all but the sending processor */
+void send_IPI_allbutself(int tag);
+
+/* Send a message to a specific processor */
+void send_IPI_single(int dest, int tag);
+
+/* Process an IPI message */
+void evaluate_message(int tag);
+
+/* Boot a secondary cpu */
+void online_secondary(void);
+
+/* Call a function on a specified set of CPUs (may include this one). */
+extern void on_each_cpu_mask(const struct cpumask *mask,
+ void (*func)(void *), void *info, bool wait);
+
+/* Topology of the supervisor tile grid, and coordinates of boot processor */
+extern HV_Topology smp_topology;
+
+/* Accessors for grid size */
+#define smp_height (smp_topology.height)
+#define smp_width (smp_topology.width)
+
+/* Convenience functions for converting cpu <-> coords. */
+static inline int cpu_x(int cpu)
+{
+ return cpu % smp_width;
+}
+static inline int cpu_y(int cpu)
+{
+ return cpu / smp_width;
+}
+static inline int xy_to_cpu(int x, int y)
+{
+ return y * smp_width + x;
+}
+
+/* Hypervisor message tags sent via the tile send_IPI*() routines. */
+#define MSG_TAG_START_CPU 1
+#define MSG_TAG_STOP_CPU 2
+#define MSG_TAG_CALL_FUNCTION_MANY 3
+#define MSG_TAG_CALL_FUNCTION_SINGLE 4
+
+/* Hook for the generic smp_call_function_many() routine. */
+static inline void arch_send_call_function_ipi_mask(struct cpumask *mask)
+{
+ send_IPI_many(mask, MSG_TAG_CALL_FUNCTION_MANY);
+}
+
+/* Hook for the generic smp_call_function_single() routine. */
+static inline void arch_send_call_function_single_ipi(int cpu)
+{
+ send_IPI_single(cpu, MSG_TAG_CALL_FUNCTION_SINGLE);
+}
+
+/* Print out the boot string describing which cpus were disabled. */
+void print_disabled_cpus(void);
+
+#else /* !CONFIG_SMP */
+
+#define on_each_cpu_mask(mask, func, info, wait) \
+ do { if (cpumask_test_cpu(0, (mask))) func(info); } while (0)
+
+#define smp_master_cpu 0
+#define smp_height 1
+#define smp_width 1
+#define cpu_x(cpu) 0
+#define cpu_y(cpu) 0
+#define xy_to_cpu(x, y) 0
+
+#endif /* !CONFIG_SMP */
+
+
+/* Which cpus may be used as the lotar in a page table entry. */
+extern struct cpumask cpu_lotar_map;
+#define cpu_is_valid_lotar(cpu) cpumask_test_cpu((cpu), &cpu_lotar_map)
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+/* Which processors are used for hash-for-home mapping */
+extern struct cpumask hash_for_home_map;
+#endif
+
+/* Which cpus can have their cache flushed by hv_flush_remote(). */
+extern struct cpumask cpu_cacheable_map;
+#define cpu_cacheable(cpu) cpumask_test_cpu((cpu), &cpu_cacheable_map)
+
+/* Convert an HV_LOTAR value into a cpu. */
+static inline int hv_lotar_to_cpu(HV_LOTAR lotar)
+{
+ return HV_LOTAR_X(lotar) + (HV_LOTAR_Y(lotar) * smp_width);
+}
+
+/*
+ * Extension of <linux/cpumask.h> functionality when you just want
+ * to express a mask or suppression or inclusion region without
+ * being too concerned about exactly which cpus are valid in that region.
+ */
+int bitmap_parselist_crop(const char *bp, unsigned long *maskp, int nmaskbits);
+
+#define cpulist_parse_crop(buf, dst) \
+ __cpulist_parse_crop((buf), (dst), NR_CPUS)
+static inline int __cpulist_parse_crop(const char *buf, struct cpumask *dstp,
+ int nbits)
+{
+ return bitmap_parselist_crop(buf, cpumask_bits(dstp), nbits);
+}
+
+/* Initialize the IPI subsystem. */
+void ipi_init(void);
+
+/* Function for start-cpu message to cause us to jump to. */
+extern unsigned long start_cpu_function_addr;
+
+#endif /* _ASM_TILE_SMP_H */
diff --git a/arch/tile/include/asm/socket.h b/arch/tile/include/asm/socket.h
new file mode 100644
index 000000000000..6b71384b9d8b
--- /dev/null
+++ b/arch/tile/include/asm/socket.h
@@ -0,0 +1 @@
+#include <asm-generic/socket.h>
diff --git a/arch/tile/include/asm/sockios.h b/arch/tile/include/asm/sockios.h
new file mode 100644
index 000000000000..def6d4746ee7
--- /dev/null
+++ b/arch/tile/include/asm/sockios.h
@@ -0,0 +1 @@
+#include <asm-generic/sockios.h>
diff --git a/arch/tile/include/asm/spinlock.h b/arch/tile/include/asm/spinlock.h
new file mode 100644
index 000000000000..1a8bd4740c28
--- /dev/null
+++ b/arch/tile/include/asm/spinlock.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SPINLOCK_H
+#define _ASM_TILE_SPINLOCK_H
+
+#ifdef __tilegx__
+#include <asm/spinlock_64.h>
+#else
+#include <asm/spinlock_32.h>
+#endif
+
+#endif /* _ASM_TILE_SPINLOCK_H */
diff --git a/arch/tile/include/asm/spinlock_32.h b/arch/tile/include/asm/spinlock_32.h
new file mode 100644
index 000000000000..88efdde8dd2b
--- /dev/null
+++ b/arch/tile/include/asm/spinlock_32.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * 32-bit SMP spinlocks.
+ */
+
+#ifndef _ASM_TILE_SPINLOCK_32_H
+#define _ASM_TILE_SPINLOCK_32_H
+
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/system.h>
+#include <linux/compiler.h>
+
+/*
+ * We only use even ticket numbers so the '1' inserted by a tns is
+ * an unambiguous "ticket is busy" flag.
+ */
+#define TICKET_QUANTUM 2
+
+
+/*
+ * SMP ticket spinlocks, allowing only a single CPU anywhere
+ *
+ * (the type definitions are in asm/spinlock_types.h)
+ */
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+ /*
+ * Note that even if a new ticket is in the process of being
+ * acquired, so lock->next_ticket is 1, it's still reasonable
+ * to claim the lock is held, since it will be momentarily
+ * if not already. There's no need to wait for a "valid"
+ * lock->next_ticket to become available.
+ */
+ return lock->next_ticket != lock->current_ticket;
+}
+
+void arch_spin_lock(arch_spinlock_t *lock);
+
+/* We cannot take an interrupt after getting a ticket, so don't enable them. */
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+
+int arch_spin_trylock(arch_spinlock_t *lock);
+
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+ /* For efficiency, overlap fetching the old ticket with the wmb(). */
+ int old_ticket = lock->current_ticket;
+ wmb(); /* guarantee anything modified under the lock is visible */
+ lock->current_ticket = old_ticket + TICKET_QUANTUM;
+}
+
+void arch_spin_unlock_wait(arch_spinlock_t *lock);
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * We use a "tns/store-back" technique on a single word to manage
+ * the lock state, looping around to retry if the tns returns 1.
+ */
+
+/* Internal layout of the word; do not use. */
+#define _WR_NEXT_SHIFT 8
+#define _WR_CURR_SHIFT 16
+#define _WR_WIDTH 8
+#define _RD_COUNT_SHIFT 24
+#define _RD_COUNT_WIDTH 8
+
+/* Internal functions; do not use. */
+void arch_read_lock_slow(arch_rwlock_t *, u32);
+int arch_read_trylock_slow(arch_rwlock_t *);
+void arch_read_unlock_slow(arch_rwlock_t *);
+void arch_write_lock_slow(arch_rwlock_t *, u32);
+void arch_write_unlock_slow(arch_rwlock_t *, u32);
+
+/**
+ * arch_read_can_lock() - would read_trylock() succeed?
+ */
+static inline int arch_read_can_lock(arch_rwlock_t *rwlock)
+{
+ return (rwlock->lock << _RD_COUNT_WIDTH) == 0;
+}
+
+/**
+ * arch_write_can_lock() - would write_trylock() succeed?
+ */
+static inline int arch_write_can_lock(arch_rwlock_t *rwlock)
+{
+ return rwlock->lock == 0;
+}
+
+/**
+ * arch_read_lock() - acquire a read lock.
+ */
+static inline void arch_read_lock(arch_rwlock_t *rwlock)
+{
+ u32 val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val << _RD_COUNT_WIDTH)) {
+ arch_read_lock_slow(rwlock, val);
+ return;
+ }
+ rwlock->lock = val + (1 << _RD_COUNT_SHIFT);
+}
+
+/**
+ * arch_read_lock() - acquire a write lock.
+ */
+static inline void arch_write_lock(arch_rwlock_t *rwlock)
+{
+ u32 val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val != 0)) {
+ arch_write_lock_slow(rwlock, val);
+ return;
+ }
+ rwlock->lock = 1 << _WR_NEXT_SHIFT;
+}
+
+/**
+ * arch_read_trylock() - try to acquire a read lock.
+ */
+static inline int arch_read_trylock(arch_rwlock_t *rwlock)
+{
+ int locked;
+ u32 val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val & 1))
+ return arch_read_trylock_slow(rwlock);
+ locked = (val << _RD_COUNT_WIDTH) == 0;
+ rwlock->lock = val + (locked << _RD_COUNT_SHIFT);
+ return locked;
+}
+
+/**
+ * arch_write_trylock() - try to acquire a write lock.
+ */
+static inline int arch_write_trylock(arch_rwlock_t *rwlock)
+{
+ u32 val = __insn_tns((int *)&rwlock->lock);
+
+ /*
+ * If a tns is in progress, or there's a waiting or active locker,
+ * or active readers, we can't take the lock, so give up.
+ */
+ if (unlikely(val != 0)) {
+ if (!(val & 1))
+ rwlock->lock = val;
+ return 0;
+ }
+
+ /* Set the "next" field to mark it locked. */
+ rwlock->lock = 1 << _WR_NEXT_SHIFT;
+ return 1;
+}
+
+/**
+ * arch_read_unlock() - release a read lock.
+ */
+static inline void arch_read_unlock(arch_rwlock_t *rwlock)
+{
+ u32 val;
+ mb(); /* guarantee anything modified under the lock is visible */
+ val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val & 1)) {
+ arch_read_unlock_slow(rwlock);
+ return;
+ }
+ rwlock->lock = val - (1 << _RD_COUNT_SHIFT);
+}
+
+/**
+ * arch_write_unlock() - release a write lock.
+ */
+static inline void arch_write_unlock(arch_rwlock_t *rwlock)
+{
+ u32 val;
+ mb(); /* guarantee anything modified under the lock is visible */
+ val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val != (1 << _WR_NEXT_SHIFT))) {
+ arch_write_unlock_slow(rwlock, val);
+ return;
+ }
+ rwlock->lock = 0;
+}
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#endif /* _ASM_TILE_SPINLOCK_32_H */
diff --git a/arch/tile/include/asm/spinlock_types.h b/arch/tile/include/asm/spinlock_types.h
new file mode 100644
index 000000000000..a71f59b49c50
--- /dev/null
+++ b/arch/tile/include/asm/spinlock_types.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SPINLOCK_TYPES_H
+#define _ASM_TILE_SPINLOCK_TYPES_H
+
+#ifndef __LINUX_SPINLOCK_TYPES_H
+# error "please don't include this file directly"
+#endif
+
+#ifdef __tilegx__
+
+/* Low 15 bits are "next"; high 15 bits are "current". */
+typedef struct arch_spinlock {
+ unsigned int lock;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { 0 }
+
+/* High bit is "writer owns"; low 31 bits are a count of readers. */
+typedef struct arch_rwlock {
+ unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
+
+#else
+
+typedef struct arch_spinlock {
+ /* Next ticket number to hand out. */
+ int next_ticket;
+ /* The ticket number that currently owns this lock. */
+ int current_ticket;
+} arch_spinlock_t;
+
+#define __ARCH_SPIN_LOCK_UNLOCKED { 0, 0 }
+
+/*
+ * Byte 0 for tns (only the low bit is used), byte 1 for ticket-lock "next",
+ * byte 2 for ticket-lock "current", byte 3 for reader count.
+ */
+typedef struct arch_rwlock {
+ unsigned int lock;
+} arch_rwlock_t;
+
+#define __ARCH_RW_LOCK_UNLOCKED { 0 }
+
+#endif
+#endif /* _ASM_TILE_SPINLOCK_TYPES_H */
diff --git a/arch/tile/include/asm/stack.h b/arch/tile/include/asm/stack.h
new file mode 100644
index 000000000000..f908473c322d
--- /dev/null
+++ b/arch/tile/include/asm/stack.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_STACK_H
+#define _ASM_TILE_STACK_H
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <asm/backtrace.h>
+#include <hv/hypervisor.h>
+
+/* Everything we need to keep track of a backtrace iteration */
+struct KBacktraceIterator {
+ BacktraceIterator it;
+ struct task_struct *task; /* task we are backtracing */
+ HV_PTE *pgtable; /* page table for user space access */
+ int end; /* iteration complete. */
+ int new_context; /* new context is starting */
+ int profile; /* profiling, so stop on async intrpt */
+ int verbose; /* printk extra info (don't want to
+ * do this for profiling) */
+ int is_current; /* backtracing current task */
+};
+
+/* Iteration methods for kernel backtraces */
+
+/*
+ * Initialize a KBacktraceIterator from a task_struct, and optionally from
+ * a set of registers. If the registers are omitted, the process is
+ * assumed to be descheduled, and registers are read from the process's
+ * thread_struct and stack. "verbose" means to printk some additional
+ * information about fault handlers as we pass them on the stack.
+ */
+extern void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
+ struct task_struct *, struct pt_regs *);
+
+/* Initialize iterator based on current stack. */
+extern void KBacktraceIterator_init_current(struct KBacktraceIterator *kbt);
+
+/* Helper method for above. */
+extern void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt,
+ ulong pc, ulong lr, ulong sp, ulong r52);
+
+/* No more frames? */
+extern int KBacktraceIterator_end(struct KBacktraceIterator *kbt);
+
+/* Advance to the next frame. */
+extern void KBacktraceIterator_next(struct KBacktraceIterator *kbt);
+
+/*
+ * Dump stack given complete register info. Use only from the
+ * architecture-specific code; show_stack()
+ * and dump_stack() (in entry.S) are architecture-independent entry points.
+ */
+extern void tile_show_stack(struct KBacktraceIterator *, int headers);
+
+/* Dump stack of current process, with registers to seed the backtrace. */
+extern void dump_stack_regs(struct pt_regs *);
+
+/* Helper method for assembly dump_stack(). */
+extern void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
+
+#endif /* _ASM_TILE_STACK_H */
diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/asm/stat.h
new file mode 100644
index 000000000000..3dc90fa92c70
--- /dev/null
+++ b/arch/tile/include/asm/stat.h
@@ -0,0 +1 @@
+#include <asm-generic/stat.h>
diff --git a/arch/tile/include/asm/statfs.h b/arch/tile/include/asm/statfs.h
new file mode 100644
index 000000000000..0b91fe198c20
--- /dev/null
+++ b/arch/tile/include/asm/statfs.h
@@ -0,0 +1 @@
+#include <asm-generic/statfs.h>
diff --git a/arch/tile/include/asm/string.h b/arch/tile/include/asm/string.h
new file mode 100644
index 000000000000..7535cf1a30e4
--- /dev/null
+++ b/arch/tile/include/asm/string.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_STRING_H
+#define _ASM_TILE_STRING_H
+
+#define __HAVE_ARCH_MEMCHR
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_STRCHR
+#define __HAVE_ARCH_STRLEN
+
+extern __kernel_size_t strlen(const char *);
+extern char *strchr(const char *s, int c);
+extern void *memchr(const void *s, int c, size_t n);
+extern void *memset(void *, int, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#endif /* _ASM_TILE_STRING_H */
diff --git a/arch/tile/include/asm/swab.h b/arch/tile/include/asm/swab.h
new file mode 100644
index 000000000000..25c686a00f1d
--- /dev/null
+++ b/arch/tile/include/asm/swab.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SWAB_H
+#define _ASM_TILE_SWAB_H
+
+/* Tile gcc is always >= 4.3.0, so we use __builtin_bswap. */
+#define __arch_swab32(x) __builtin_bswap32(x)
+#define __arch_swab64(x) __builtin_bswap64(x)
+
+/* Use the variant that is natural for the wordsize. */
+#ifdef CONFIG_64BIT
+#define __arch_swab16(x) (__builtin_bswap64(x) >> 48)
+#else
+#define __arch_swab16(x) (__builtin_bswap32(x) >> 16)
+#endif
+
+#endif /* _ASM_TILE_SWAB_H */
diff --git a/arch/tile/include/asm/syscall.h b/arch/tile/include/asm/syscall.h
new file mode 100644
index 000000000000..d35e0dcb67b1
--- /dev/null
+++ b/arch/tile/include/asm/syscall.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_TILE_SYSCALL_H
+#define _ASM_TILE_SYSCALL_H
+
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <arch/abi.h>
+
+/*
+ * Only the low 32 bits of orig_r0 are meaningful, so we return int.
+ * This importantly ignores the high bits on 64-bit, so comparisons
+ * sign-extend the low 32 bits.
+ */
+static inline int syscall_get_nr(struct task_struct *t, struct pt_regs *regs)
+{
+ return regs->regs[TREG_SYSCALL_NR];
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ regs->regs[0] = regs->orig_r0;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ unsigned long error = regs->regs[0];
+ return IS_ERR_VALUE(error) ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->regs[0];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ regs->regs[0] = (long) error ?: val;
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(args, &regs[i], n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(&regs[i], args, n * sizeof(args[0]));
+}
+
+#endif /* _ASM_TILE_SYSCALL_H */
diff --git a/arch/tile/include/asm/syscalls.h b/arch/tile/include/asm/syscalls.h
new file mode 100644
index 000000000000..af165a74537f
--- /dev/null
+++ b/arch/tile/include/asm/syscalls.h
@@ -0,0 +1,108 @@
+/*
+ * syscalls.h - Linux syscall interfaces (arch-specific)
+ *
+ * Copyright (c) 2008 Jaswinder Singh Rajput
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SYSCALLS_H
+#define _ASM_TILE_SYSCALLS_H
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/signal.h>
+#include <linux/types.h>
+#include <linux/compat.h>
+
+/* The array of function pointers for syscalls. */
+extern void *sys_call_table[];
+#ifdef CONFIG_COMPAT
+extern void *compat_sys_call_table[];
+#endif
+
+/*
+ * Note that by convention, any syscall which requires the current
+ * register set takes an additional "struct pt_regs *" pointer; the
+ * sys_xxx() function just adds the pointer and tail-calls to _sys_xxx().
+ */
+
+/* kernel/sys.c */
+ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count);
+long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len, int advice);
+int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi, int advice);
+long sys_flush_cache(void);
+long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff);
+#ifdef __tilegx__
+long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t pgoff);
+#endif
+
+/* kernel/process.c */
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid);
+long _sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid,
+ struct pt_regs *regs);
+long sys_fork(void);
+long _sys_fork(struct pt_regs *regs);
+long sys_vfork(void);
+long _sys_vfork(struct pt_regs *regs);
+long sys_execve(char __user *filename, char __user * __user *argv,
+ char __user * __user *envp);
+long _sys_execve(char __user *filename, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs);
+
+/* kernel/signal.c */
+long sys_sigaltstack(const stack_t __user *, stack_t __user *);
+long _sys_sigaltstack(const stack_t __user *, stack_t __user *,
+ struct pt_regs *);
+long sys_rt_sigreturn(void);
+long _sys_rt_sigreturn(struct pt_regs *regs);
+
+/* platform-independent functions */
+long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize);
+long sys_rt_sigaction(int sig, const struct sigaction __user *act,
+ struct sigaction __user *oact, size_t sigsetsize);
+
+#ifndef __tilegx__
+/* mm/fault.c */
+int sys_cmpxchg_badaddr(unsigned long address);
+int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
+#endif
+
+#ifdef CONFIG_COMPAT
+long compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
+ compat_uptr_t __user *envp);
+long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
+ compat_uptr_t __user *envp, struct pt_regs *regs);
+long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr);
+long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr,
+ struct pt_regs *regs);
+long compat_sys_rt_sigreturn(void);
+long _compat_sys_rt_sigreturn(struct pt_regs *regs);
+
+/* These four are not defined for 64-bit, but serve as "compat" syscalls. */
+long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg);
+long sys_fstat64(unsigned long fd, struct stat64 __user *statbuf);
+long sys_truncate64(const char __user *path, loff_t length);
+long sys_ftruncate64(unsigned int fd, loff_t length);
+#endif
+
+#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/asm/system.h b/arch/tile/include/asm/system.h
new file mode 100644
index 000000000000..f749be327ce0
--- /dev/null
+++ b/arch/tile/include/asm/system.h
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_SYSTEM_H
+#define _ASM_TILE_SYSTEM_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/types.h>
+#include <linux/irqflags.h>
+
+/* NOTE: we can't include <linux/ptrace.h> due to #include dependencies. */
+#include <asm/ptrace.h>
+
+#include <arch/chip.h>
+#include <arch/sim_def.h>
+#include <arch/spr_def.h>
+
+/*
+ * read_barrier_depends - Flush all pending reads that subsequents reads
+ * depend on.
+ *
+ * No data-dependent reads from memory-like regions are ever reordered
+ * over this barrier. All reads preceding this primitive are guaranteed
+ * to access memory (but not necessarily other CPUs' caches) before any
+ * reads following this primitive that depend on the data return by
+ * any of the preceding reads. This primitive is much lighter weight than
+ * rmb() on most CPUs, and is never heavier weight than is
+ * rmb().
+ *
+ * These ordering constraints are respected by both the local CPU
+ * and the compiler.
+ *
+ * Ordering is not guaranteed by anything other than these primitives,
+ * not even by data dependencies. See the documentation for
+ * memory_barrier() for examples and URLs to more information.
+ *
+ * For example, the following code would force ordering (the initial
+ * value of "a" is zero, "b" is one, and "p" is "&a"):
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * b = 2;
+ * memory_barrier();
+ * p = &b; q = p;
+ * read_barrier_depends();
+ * d = *q;
+ * </programlisting>
+ *
+ * because the read of "*q" depends on the read of "p" and these
+ * two reads are separated by a read_barrier_depends(). However,
+ * the following code, with the same initial values for "a" and "b":
+ *
+ * <programlisting>
+ * CPU 0 CPU 1
+ *
+ * a = 2;
+ * memory_barrier();
+ * b = 3; y = b;
+ * read_barrier_depends();
+ * x = a;
+ * </programlisting>
+ *
+ * does not enforce ordering, since there is no data dependency between
+ * the read of "a" and the read of "b". Therefore, on some CPUs, such
+ * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
+ * in cases like this where there are no data dependencies.
+ */
+
+#define read_barrier_depends() do { } while (0)
+
+#define __sync() __insn_mf()
+
+#if CHIP_HAS_SPLIT_CYCLE()
+#define get_cycles_low() __insn_mfspr(SPR_CYCLE_LOW)
+#else
+#define get_cycles_low() __insn_mfspr(SPR_CYCLE) /* just get all 64 bits */
+#endif
+
+/* Fence to guarantee visibility of stores to incoherent memory. */
+static inline void
+mb_incoherent(void)
+{
+ __insn_mf();
+
+#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
+ {
+ int __mb_incoherent(void);
+#if CHIP_HAS_TILE_WRITE_PENDING()
+ const unsigned long WRITE_TIMEOUT_CYCLES = 400;
+ unsigned long start = get_cycles_low();
+ do {
+ if (__insn_mfspr(SPR_TILE_WRITE_PENDING) == 0)
+ return;
+ } while ((get_cycles_low() - start) < WRITE_TIMEOUT_CYCLES);
+#endif /* CHIP_HAS_TILE_WRITE_PENDING() */
+ (void) __mb_incoherent();
+ }
+#endif /* CHIP_HAS_MF_WAITS_FOR_VICTIMS() */
+}
+
+#define fast_wmb() __sync()
+#define fast_rmb() __sync()
+#define fast_mb() __sync()
+#define fast_iob() mb_incoherent()
+
+#define wmb() fast_wmb()
+#define rmb() fast_rmb()
+#define mb() fast_mb()
+#define iob() fast_iob()
+
+#ifdef CONFIG_SMP
+#define smp_mb() mb()
+#define smp_rmb() rmb()
+#define smp_wmb() wmb()
+#define smp_read_barrier_depends() read_barrier_depends()
+#else
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() do { } while (0)
+#endif
+
+#define set_mb(var, value) \
+ do { var = value; mb(); } while (0)
+
+/*
+ * Pause the DMA engine and static network before task switching.
+ */
+#define prepare_arch_switch(next) _prepare_arch_switch(next)
+void _prepare_arch_switch(struct task_struct *next);
+
+
+/*
+ * switch_to(n) should switch tasks to task nr n, first
+ * checking that n isn't the current task, in which case it does nothing.
+ * The number of callee-saved registers saved on the kernel stack
+ * is defined here for use in copy_thread() and must agree with __switch_to().
+ */
+#endif /* !__ASSEMBLY__ */
+#define CALLEE_SAVED_FIRST_REG 30
+#define CALLEE_SAVED_REGS_COUNT 24 /* r30 to r52, plus an empty to align */
+#ifndef __ASSEMBLY__
+struct task_struct;
+#define switch_to(prev, next, last) ((last) = _switch_to((prev), (next)))
+extern struct task_struct *_switch_to(struct task_struct *prev,
+ struct task_struct *next);
+
+/* Helper function for _switch_to(). */
+extern struct task_struct *__switch_to(struct task_struct *prev,
+ struct task_struct *next,
+ unsigned long new_system_save_1_0);
+
+/* Address that switched-away from tasks are at. */
+extern unsigned long get_switch_to_pc(void);
+
+/*
+ * On SMP systems, when the scheduler does migration-cost autodetection,
+ * it needs a way to flush as much of the CPU's caches as possible:
+ *
+ * TODO: fill this in!
+ */
+static inline void sched_cacheflush(void)
+{
+}
+
+#define arch_align_stack(x) (x)
+
+/*
+ * Is the kernel doing fixups of unaligned accesses? If <0, no kernel
+ * intervention occurs and SIGBUS is delivered with no data address
+ * info. If 0, the kernel single-steps the instruction to discover
+ * the data address to provide with the SIGBUS. If 1, the kernel does
+ * a fixup.
+ */
+extern int unaligned_fixup;
+
+/* Is the kernel printing on each unaligned fixup? */
+extern int unaligned_printk;
+
+/* Number of unaligned fixups performed */
+extern unsigned int unaligned_fixup_count;
+
+/* Init-time routine to do tile-specific per-cpu setup. */
+void setup_cpu(int boot);
+
+/* User-level DMA management functions */
+void grant_dma_mpls(void);
+void restrict_dma_mpls(void);
+
+#ifdef CONFIG_HARDWALL
+/* User-level network management functions */
+void reset_network_state(void);
+void grant_network_mpls(void);
+void restrict_network_mpls(void);
+int hardwall_deactivate(struct task_struct *task);
+
+/* Hook hardwall code into changes in affinity. */
+#define arch_set_cpus_allowed(p, new_mask) do { \
+ if (p->thread.hardwall && !cpumask_equal(&p->cpus_allowed, new_mask)) \
+ hardwall_deactivate(p); \
+} while (0)
+#endif
+
+/* Invoke the simulator "syscall" mechanism (see arch/tile/kernel/entry.S). */
+extern int _sim_syscall(int syscall_num, ...);
+#define sim_syscall(syscall_num, ...) \
+ _sim_syscall(SIM_CONTROL_SYSCALL + \
+ ((syscall_num) << _SIM_CONTROL_OPERATOR_BITS), \
+ ## __VA_ARGS__)
+
+/*
+ * Kernel threads can check to see if they need to migrate their
+ * stack whenever they return from a context switch; for user
+ * threads, we defer until they are returning to user-space.
+ */
+#define finish_arch_switch(prev) do { \
+ if (unlikely((prev)->state == TASK_DEAD)) \
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_EXIT | \
+ ((prev)->pid << _SIM_CONTROL_OPERATOR_BITS)); \
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_SWITCH | \
+ (current->pid << _SIM_CONTROL_OPERATOR_BITS)); \
+ if (current->mm == NULL && !kstack_hash && \
+ current_thread_info()->homecache_cpu != smp_processor_id()) \
+ homecache_migrate_kthread(); \
+} while (0)
+
+/* Support function for forking a new task. */
+void ret_from_fork(void);
+
+/* Called from ret_from_fork() when a new process starts up. */
+struct task_struct *sim_notify_fork(struct task_struct *prev);
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_SYSTEM_H */
diff --git a/arch/tile/include/asm/termbits.h b/arch/tile/include/asm/termbits.h
new file mode 100644
index 000000000000..3935b106de79
--- /dev/null
+++ b/arch/tile/include/asm/termbits.h
@@ -0,0 +1 @@
+#include <asm-generic/termbits.h>
diff --git a/arch/tile/include/asm/termios.h b/arch/tile/include/asm/termios.h
new file mode 100644
index 000000000000..280d78a9d966
--- /dev/null
+++ b/arch/tile/include/asm/termios.h
@@ -0,0 +1 @@
+#include <asm-generic/termios.h>
diff --git a/arch/tile/include/asm/thread_info.h b/arch/tile/include/asm/thread_info.h
new file mode 100644
index 000000000000..3872f2b345d2
--- /dev/null
+++ b/arch/tile/include/asm/thread_info.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2002 David Howells (dhowells@redhat.com)
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_THREAD_INFO_H
+#define _ASM_TILE_THREAD_INFO_H
+
+#include <asm/processor.h>
+#include <asm/page.h>
+#ifndef __ASSEMBLY__
+
+/*
+ * Low level task data that assembly code needs immediate access to.
+ * The structure is placed at the bottom of the supervisor stack.
+ */
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ unsigned long status; /* thread-synchronous flags */
+ __u32 homecache_cpu; /* CPU we are homecached on */
+ __u32 cpu; /* current CPU */
+ int preempt_count; /* 0 => preemptable,
+ <0 => BUG */
+
+ mm_segment_t addr_limit; /* thread address space
+ (KERNEL_DS or USER_DS) */
+ struct restart_block restart_block;
+ struct single_step_state *step_state; /* single step state
+ (if non-zero) */
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure.
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+ .step_state = NULL, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+#endif /* !__ASSEMBLY__ */
+
+#if PAGE_SIZE < 8192
+#define THREAD_SIZE_ORDER (13 - PAGE_SHIFT)
+#else
+#define THREAD_SIZE_ORDER (0)
+#endif
+
+#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
+#define LOG2_THREAD_SIZE (PAGE_SHIFT + THREAD_SIZE_ORDER)
+
+#define STACK_WARN (THREAD_SIZE/8)
+
+#ifndef __ASSEMBLY__
+
+/* How to get the thread information struct from C. */
+register unsigned long stack_pointer __asm__("sp");
+
+#define current_thread_info() \
+ ((struct thread_info *)(stack_pointer & -THREAD_SIZE))
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+extern struct thread_info *alloc_thread_info(struct task_struct *task);
+extern void free_thread_info(struct thread_info *info);
+
+/* Sit on a nap instruction until interrupted. */
+extern void smp_nap(void);
+
+/* Enable interrupts racelessly and nap forever: helper for cpu_idle(). */
+extern void _cpu_idle(void);
+
+/* Switch boot idle thread to a freshly-allocated stack and free old stack. */
+extern void cpu_idle_on_new_stack(struct thread_info *old_ti,
+ unsigned long new_sp,
+ unsigned long new_ss10);
+
+#else /* __ASSEMBLY__ */
+
+/* how to get the thread information struct from ASM */
+#ifdef __tilegx__
+#define GET_THREAD_INFO(reg) move reg, sp; mm reg, zero, LOG2_THREAD_SIZE, 63
+#else
+#define GET_THREAD_INFO(reg) mm reg, sp, zero, LOG2_THREAD_SIZE, 31
+#endif
+
+#endif /* !__ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x10000000
+
+/*
+ * Thread information flags that various assembly files may need to access.
+ * Keep flags accessed frequently in low bits, particular since it makes
+ * it easier to build constants in assembly.
+ */
+#define TIF_SIGPENDING 0 /* signal pending */
+#define TIF_NEED_RESCHED 1 /* rescheduling necessary */
+#define TIF_SINGLESTEP 2 /* restore singlestep on return to
+ user mode */
+#define TIF_ASYNC_TLB 3 /* got an async TLB fault in kernel */
+#define TIF_SYSCALL_TRACE 4 /* syscall trace active */
+#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
+#define TIF_SECCOMP 6 /* secure computing */
+#define TIF_MEMDIE 7 /* OOM killer at work */
+
+#define _TIF_SIGPENDING (1<<TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED)
+#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP)
+#define _TIF_ASYNC_TLB (1<<TIF_ASYNC_TLB)
+#define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE)
+#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
+#define _TIF_SECCOMP (1<<TIF_SECCOMP)
+#define _TIF_MEMDIE (1<<TIF_MEMDIE)
+
+/* Work to do on any return to user space. */
+#define _TIF_ALLWORK_MASK \
+ (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|_TIF_ASYNC_TLB)
+
+/*
+ * Thread-synchronous status.
+ *
+ * This is different from the flags in that nobody else
+ * ever touches our thread-synchronous status, so we don't
+ * have to worry about atomic accesses.
+ */
+#ifdef __tilegx__
+#define TS_COMPAT 0x0001 /* 32-bit compatibility mode */
+#endif
+#define TS_POLLING 0x0004 /* in idle loop but not sleeping */
+#define TS_RESTORE_SIGMASK 0x0008 /* restore signal mask in do_signal */
+
+#define tsk_is_polling(t) (task_thread_info(t)->status & TS_POLLING)
+
+#ifndef __ASSEMBLY__
+#define HAVE_SET_RESTORE_SIGMASK 1
+static inline void set_restore_sigmask(void)
+{
+ struct thread_info *ti = current_thread_info();
+ ti->status |= TS_RESTORE_SIGMASK;
+ set_bit(TIF_SIGPENDING, &ti->flags);
+}
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_THREAD_INFO_H */
diff --git a/arch/tile/include/asm/timex.h b/arch/tile/include/asm/timex.h
new file mode 100644
index 000000000000..3baf5fc4c0a1
--- /dev/null
+++ b/arch/tile/include/asm/timex.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_TIMEX_H
+#define _ASM_TILE_TIMEX_H
+
+/*
+ * This rate should be a multiple of the possible HZ values (100, 250, 1000)
+ * and a fraction of the possible hardware timer frequencies. Our timer
+ * frequency is highly tunable but also quite precise, so for the primary use
+ * of this value (setting ACT_HZ from HZ) we just pick a value that causes
+ * ACT_HZ to be set to HZ. We make the value somewhat large just to be
+ * more robust in case someone tries out a new value of HZ.
+ */
+#define CLOCK_TICK_RATE 1000000
+
+typedef unsigned long long cycles_t;
+
+#if CHIP_HAS_SPLIT_CYCLE()
+cycles_t get_cycles(void);
+#else
+static inline cycles_t get_cycles(void)
+{
+ return __insn_mfspr(SPR_CYCLE);
+}
+#endif
+
+cycles_t get_clock_rate(void);
+
+/* Called at cpu initialization to set some low-level constants. */
+void setup_clock(void);
+
+/* Called at cpu initialization to start the tile-timer clock device. */
+void setup_tile_timer(void);
+
+#endif /* _ASM_TILE_TIMEX_H */
diff --git a/arch/tile/include/asm/tlb.h b/arch/tile/include/asm/tlb.h
new file mode 100644
index 000000000000..4a891a1a8df3
--- /dev/null
+++ b/arch/tile/include/asm/tlb.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_TLB_H
+#define _ASM_TILE_TLB_H
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_TILE_TLB_H */
diff --git a/arch/tile/include/asm/tlbflush.h b/arch/tile/include/asm/tlbflush.h
new file mode 100644
index 000000000000..96199d214fb8
--- /dev/null
+++ b/arch/tile/include/asm/tlbflush.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_TLBFLUSH_H
+#define _ASM_TILE_TLBFLUSH_H
+
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <asm/cacheflush.h>
+#include <asm/page.h>
+#include <hv/hypervisor.h>
+
+/*
+ * Rather than associating each mm with its own ASID, we just use
+ * ASIDs to allow us to lazily flush the TLB when we switch mms.
+ * This way we only have to do an actual TLB flush on mm switch
+ * every time we wrap ASIDs, not every single time we switch.
+ *
+ * FIXME: We might improve performance by keeping ASIDs around
+ * properly, though since the hypervisor direct-maps VAs to TSB
+ * entries, we're likely to have lost at least the executable page
+ * mappings by the time we switch back to the original mm.
+ */
+DECLARE_PER_CPU(int, current_asid);
+
+/* The hypervisor tells us what ASIDs are available to us. */
+extern int min_asid, max_asid;
+
+static inline unsigned long hv_page_size(const struct vm_area_struct *vma)
+{
+ return (vma->vm_flags & VM_HUGETLB) ? HPAGE_SIZE : PAGE_SIZE;
+}
+
+/* Pass as vma pointer for non-executable mapping, if no vma available. */
+#define FLUSH_NONEXEC ((const struct vm_area_struct *)-1UL)
+
+/* Flush a single user page on this cpu. */
+static inline void local_flush_tlb_page(const struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long page_size)
+{
+ int rc = hv_flush_page(addr, page_size);
+ if (rc < 0)
+ panic("hv_flush_page(%#lx,%#lx) failed: %d",
+ addr, page_size, rc);
+ if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
+ __flush_icache();
+}
+
+/* Flush range of user pages on this cpu. */
+static inline void local_flush_tlb_pages(const struct vm_area_struct *vma,
+ unsigned long addr,
+ unsigned long page_size,
+ unsigned long len)
+{
+ int rc = hv_flush_pages(addr, page_size, len);
+ if (rc < 0)
+ panic("hv_flush_pages(%#lx,%#lx,%#lx) failed: %d",
+ addr, page_size, len, rc);
+ if (!vma || (vma != FLUSH_NONEXEC && (vma->vm_flags & VM_EXEC)))
+ __flush_icache();
+}
+
+/* Flush all user pages on this cpu. */
+static inline void local_flush_tlb(void)
+{
+ int rc = hv_flush_all(1); /* preserve global mappings */
+ if (rc < 0)
+ panic("hv_flush_all(1) failed: %d", rc);
+ __flush_icache();
+}
+
+/*
+ * Global pages have to be flushed a bit differently. Not a real
+ * performance problem because this does not happen often.
+ */
+static inline void local_flush_tlb_all(void)
+{
+ int i;
+ for (i = 0; ; ++i) {
+ HV_VirtAddrRange r = hv_inquire_virtual(i);
+ if (r.size == 0)
+ break;
+ local_flush_tlb_pages(NULL, r.start, PAGE_SIZE, r.size);
+ local_flush_tlb_pages(NULL, r.start, HPAGE_SIZE, r.size);
+ }
+}
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb() flushes the current mm struct TLBs
+ * - flush_tlb_all() flushes all processes TLBs
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages
+ * - flush_tlb_others(cpumask, mm, va) flushes TLBs on other cpus
+ *
+ * Here (as in vm_area_struct), "end" means the first byte after
+ * our end address.
+ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void flush_tlb_current_task(void);
+extern void flush_tlb_mm(struct mm_struct *);
+extern void flush_tlb_page(const struct vm_area_struct *, unsigned long);
+extern void flush_tlb_page_mm(const struct vm_area_struct *,
+ struct mm_struct *, unsigned long);
+extern void flush_tlb_range(const struct vm_area_struct *,
+ unsigned long start, unsigned long end);
+
+#define flush_tlb() flush_tlb_current_task()
+
+#endif /* _ASM_TILE_TLBFLUSH_H */
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h
new file mode 100644
index 000000000000..343172d422a9
--- /dev/null
+++ b/arch/tile/include/asm/topology.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_TOPOLOGY_H
+#define _ASM_TILE_TOPOLOGY_H
+
+#ifdef CONFIG_NUMA
+
+#include <linux/cpumask.h>
+
+/* Mappings between logical cpu number and node number. */
+extern struct cpumask node_2_cpu_mask[];
+extern char cpu_2_node[];
+
+/* Returns the number of the node containing CPU 'cpu'. */
+static inline int cpu_to_node(int cpu)
+{
+ return cpu_2_node[cpu];
+}
+
+/*
+ * Returns the number of the node containing Node 'node'.
+ * This architecture is flat, so it is a pretty simple function!
+ */
+#define parent_node(node) (node)
+
+/* Returns a bitmask of CPUs on Node 'node'. */
+static inline const struct cpumask *cpumask_of_node(int node)
+{
+ return &node_2_cpu_mask[node];
+}
+
+/* For now, use numa node -1 for global allocation. */
+#define pcibus_to_node(bus) ((void)(bus), -1)
+
+/* sched_domains SD_NODE_INIT for TILE architecture */
+#define SD_NODE_INIT (struct sched_domain) { \
+ .min_interval = 8, \
+ .max_interval = 32, \
+ .busy_factor = 32, \
+ .imbalance_pct = 125, \
+ .cache_nice_tries = 1, \
+ .busy_idx = 3, \
+ .idle_idx = 1, \
+ .newidle_idx = 2, \
+ .wake_idx = 1, \
+ .flags = SD_LOAD_BALANCE \
+ | SD_BALANCE_NEWIDLE \
+ | SD_BALANCE_EXEC \
+ | SD_BALANCE_FORK \
+ | SD_WAKE_AFFINE \
+ | SD_SERIALIZE, \
+ .last_balance = jiffies, \
+ .balance_interval = 1, \
+}
+
+/* By definition, we create nodes based on online memory. */
+#define node_has_online_mem(nid) 1
+
+#endif /* CONFIG_NUMA */
+
+#include <asm-generic/topology.h>
+
+#ifdef CONFIG_SMP
+#define topology_physical_package_id(cpu) ((void)(cpu), 0)
+#define topology_core_id(cpu) (cpu)
+#define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask)
+#define topology_thread_cpumask(cpu) cpumask_of(cpu)
+
+/* indicates that pointers to the topology struct cpumask maps are valid */
+#define arch_provides_topology_pointers yes
+#endif
+
+#endif /* _ASM_TILE_TOPOLOGY_H */
diff --git a/arch/tile/include/asm/traps.h b/arch/tile/include/asm/traps.h
new file mode 100644
index 000000000000..432a9c15c8a2
--- /dev/null
+++ b/arch/tile/include/asm/traps.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_TRAPS_H
+#define _ASM_TILE_TRAPS_H
+
+/* mm/fault.c */
+void do_page_fault(struct pt_regs *, int fault_num,
+ unsigned long address, unsigned long write);
+void do_async_page_fault(struct pt_regs *);
+
+#ifndef __tilegx__
+/*
+ * We return this structure in registers to avoid having to write
+ * additional save/restore code in the intvec.S caller.
+ */
+struct intvec_state {
+ void *handler;
+ unsigned long vecnum;
+ unsigned long fault_num;
+ unsigned long info;
+ unsigned long retval;
+};
+struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
+ unsigned long address,
+ unsigned long info);
+#endif
+
+/* kernel/traps.c */
+void do_trap(struct pt_regs *, int fault_num, unsigned long reason);
+void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52);
+
+/* kernel/time.c */
+void do_timer_interrupt(struct pt_regs *, int fault_num);
+
+/* kernel/messaging.c */
+void hv_message_intr(struct pt_regs *, int intnum);
+
+/* kernel/irq.c */
+void tile_dev_intr(struct pt_regs *, int intnum);
+
+#ifdef CONFIG_HARDWALL
+/* kernel/hardwall.c */
+void do_hardwall_trap(struct pt_regs *, int fault_num);
+#endif
+
+/* kernel/ptrace.c */
+void do_breakpoint(struct pt_regs *, int fault_num);
+
+
+#endif /* _ASM_TILE_SYSCALLS_H */
diff --git a/arch/tile/include/asm/types.h b/arch/tile/include/asm/types.h
new file mode 100644
index 000000000000..b9e79bc580dd
--- /dev/null
+++ b/arch/tile/include/asm/types.h
@@ -0,0 +1 @@
+#include <asm-generic/types.h>
diff --git a/arch/tile/include/asm/uaccess.h b/arch/tile/include/asm/uaccess.h
new file mode 100644
index 000000000000..ed17a80ec0ed
--- /dev/null
+++ b/arch/tile/include/asm/uaccess.h
@@ -0,0 +1,580 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_UACCESS_H
+#define _ASM_TILE_UACCESS_H
+
+/*
+ * User space memory access functions
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <asm-generic/uaccess-unaligned.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+
+#define VERIFY_READ 0
+#define VERIFY_WRITE 1
+
+/*
+ * The fs value determines whether argument validity checking should be
+ * performed or not. If get_fs() == USER_DS, checking is performed, with
+ * get_fs() == KERNEL_DS, checking is bypassed.
+ *
+ * For historical reasons, these macros are grossly misnamed.
+ */
+#define MAKE_MM_SEG(a) ((mm_segment_t) { (a) })
+
+#define KERNEL_DS MAKE_MM_SEG(-1UL)
+#define USER_DS MAKE_MM_SEG(PAGE_OFFSET)
+
+#define get_ds() (KERNEL_DS)
+#define get_fs() (current_thread_info()->addr_limit)
+#define set_fs(x) (current_thread_info()->addr_limit = (x))
+
+#define segment_eq(a, b) ((a).seg == (b).seg)
+
+#ifndef __tilegx__
+/*
+ * We could allow mapping all 16 MB at 0xfc000000, but we set up a
+ * special hack in arch_setup_additional_pages() to auto-create a mapping
+ * for the first 16 KB, and it would seem strange to have different
+ * user-accessible semantics for memory at 0xfc000000 and above 0xfc004000.
+ */
+static inline int is_arch_mappable_range(unsigned long addr,
+ unsigned long size)
+{
+ return (addr >= MEM_USER_INTRPT &&
+ addr < (MEM_USER_INTRPT + INTRPT_SIZE) &&
+ size <= (MEM_USER_INTRPT + INTRPT_SIZE) - addr);
+}
+#define is_arch_mappable_range is_arch_mappable_range
+#else
+#define is_arch_mappable_range(addr, size) 0
+#endif
+
+/*
+ * Test whether a block of memory is a valid user space address.
+ * Returns 0 if the range is valid, nonzero otherwise.
+ */
+int __range_ok(unsigned long addr, unsigned long size);
+
+/**
+ * access_ok: - Checks if a user space pointer is valid
+ * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE. Note that
+ * %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
+ * to write to a block, it is always safe to read from it.
+ * @addr: User space pointer to start of block to check
+ * @size: Size of block to check
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Checks if a pointer to a block of memory in user space is valid.
+ *
+ * Returns true (nonzero) if the memory block may be valid, false (zero)
+ * if it is definitely invalid.
+ *
+ * Note that, depending on architecture, this function probably just
+ * checks that the pointer is in the user space range - after calling
+ * this function, memory access functions may still return -EFAULT.
+ */
+#define access_ok(type, addr, size) ({ \
+ __chk_user_ptr(addr); \
+ likely(__range_ok((unsigned long)(addr), (size)) == 0); \
+})
+
+/*
+ * The exception table consists of pairs of addresses: the first is the
+ * address of an instruction that is allowed to fault, and the second is
+ * the address at which the program should continue. No registers are
+ * modified, so it is entirely up to the continuation code to figure out
+ * what to do.
+ *
+ * All the routines below use bits of fixup code that are out of line
+ * with the main instruction path. This means when everything is well,
+ * we don't even have to jump over them. Further, they do not intrude
+ * on our cache or tlb entries.
+ */
+
+struct exception_table_entry {
+ unsigned long insn, fixup;
+};
+
+extern int fixup_exception(struct pt_regs *regs);
+
+/*
+ * We return the __get_user_N function results in a structure,
+ * thus in r0 and r1. If "err" is zero, "val" is the result
+ * of the read; otherwise, "err" is -EFAULT.
+ *
+ * We rarely need 8-byte values on a 32-bit architecture, but
+ * we size the structure to accommodate. In practice, for the
+ * the smaller reads, we can zero the high word for free, and
+ * the caller will ignore it by virtue of casting anyway.
+ */
+struct __get_user {
+ unsigned long long val;
+ int err;
+};
+
+/*
+ * FIXME: we should express these as inline extended assembler, since
+ * they're fundamentally just a variable dereference and some
+ * supporting exception_table gunk. Note that (a la i386) we can
+ * extend the copy_to_user and copy_from_user routines to call into
+ * such extended assembler routines, though we will have to use a
+ * different return code in that case (1, 2, or 4, rather than -EFAULT).
+ */
+extern struct __get_user __get_user_1(const void __user *);
+extern struct __get_user __get_user_2(const void __user *);
+extern struct __get_user __get_user_4(const void __user *);
+extern struct __get_user __get_user_8(const void __user *);
+extern int __put_user_1(long, void __user *);
+extern int __put_user_2(long, void __user *);
+extern int __put_user_4(long, void __user *);
+extern int __put_user_8(long long, void __user *);
+
+/* Unimplemented routines to cause linker failures */
+extern struct __get_user __get_user_bad(void);
+extern int __put_user_bad(void);
+
+/*
+ * Careful: we have to cast the result to the type of the pointer
+ * for sign reasons.
+ */
+/**
+ * __get_user: - Get a simple variable from user space, with less checking.
+ * @x: Variable to store result.
+ * @ptr: Source address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple variable from user space to kernel
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and the result of
+ * dereferencing @ptr must be assignable to @x without a cast.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ * On error, the variable @x is set to zero.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ */
+#define __get_user(x, ptr) \
+({ struct __get_user __ret; \
+ __typeof__(*(ptr)) const __user *__gu_addr = (ptr); \
+ __chk_user_ptr(__gu_addr); \
+ switch (sizeof(*(__gu_addr))) { \
+ case 1: \
+ __ret = __get_user_1(__gu_addr); \
+ break; \
+ case 2: \
+ __ret = __get_user_2(__gu_addr); \
+ break; \
+ case 4: \
+ __ret = __get_user_4(__gu_addr); \
+ break; \
+ case 8: \
+ __ret = __get_user_8(__gu_addr); \
+ break; \
+ default: \
+ __ret = __get_user_bad(); \
+ break; \
+ } \
+ (x) = (__typeof__(*__gu_addr)) (__typeof__(*__gu_addr - *__gu_addr)) \
+ __ret.val; \
+ __ret.err; \
+})
+
+/**
+ * __put_user: - Write a simple value into user space, with less checking.
+ * @x: Value to copy to user space.
+ * @ptr: Destination address, in user space.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * This macro copies a single simple value from kernel space to user
+ * space. It supports simple types like char and int, but not larger
+ * data types like structures or arrays.
+ *
+ * @ptr must have pointer-to-simple-variable type, and @x must be assignable
+ * to the result of dereferencing @ptr.
+ *
+ * Caller must check the pointer with access_ok() before calling this
+ * function.
+ *
+ * Returns zero on success, or -EFAULT on error.
+ *
+ * Implementation note: The "case 8" logic of casting to the type of
+ * the result of subtracting the value from itself is basically a way
+ * of keeping all integer types the same, but casting any pointers to
+ * ptrdiff_t, i.e. also an integer type. This way there are no
+ * questionable casts seen by the compiler on an ILP32 platform.
+ */
+#define __put_user(x, ptr) \
+({ \
+ int __pu_err = 0; \
+ __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
+ typeof(*__pu_addr) __pu_val = (x); \
+ __chk_user_ptr(__pu_addr); \
+ switch (sizeof(__pu_val)) { \
+ case 1: \
+ __pu_err = __put_user_1((long)__pu_val, __pu_addr); \
+ break; \
+ case 2: \
+ __pu_err = __put_user_2((long)__pu_val, __pu_addr); \
+ break; \
+ case 4: \
+ __pu_err = __put_user_4((long)__pu_val, __pu_addr); \
+ break; \
+ case 8: \
+ __pu_err = \
+ __put_user_8((__typeof__(__pu_val - __pu_val))__pu_val,\
+ __pu_addr); \
+ break; \
+ default: \
+ __pu_err = __put_user_bad(); \
+ break; \
+ } \
+ __pu_err; \
+})
+
+/*
+ * The versions of get_user and put_user without initial underscores
+ * check the address of their arguments to make sure they are not
+ * in kernel space.
+ */
+#define put_user(x, ptr) \
+({ \
+ __typeof__(*(ptr)) __user *__Pu_addr = (ptr); \
+ access_ok(VERIFY_WRITE, (__Pu_addr), sizeof(*(__Pu_addr))) ? \
+ __put_user((x), (__Pu_addr)) : \
+ -EFAULT; \
+})
+
+#define get_user(x, ptr) \
+({ \
+ __typeof__(*(ptr)) const __user *__Gu_addr = (ptr); \
+ access_ok(VERIFY_READ, (__Gu_addr), sizeof(*(__Gu_addr))) ? \
+ __get_user((x), (__Gu_addr)) : \
+ ((x) = 0, -EFAULT); \
+})
+
+/**
+ * __copy_to_user() - copy data into user space, with less checking.
+ * @to: Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from kernel space to user space. Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * An alternate version - __copy_to_user_inatomic() - is designed
+ * to be called from atomic context, typically bracketed by calls
+ * to pagefault_disable() and pagefault_enable().
+ */
+extern unsigned long __must_check __copy_to_user_inatomic(
+ void __user *to, const void *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ might_fault();
+ return __copy_to_user_inatomic(to, from, n);
+}
+
+static inline unsigned long __must_check
+copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n))
+ n = __copy_to_user(to, from, n);
+ return n;
+}
+
+/**
+ * __copy_from_user() - copy data from user space, with less checking.
+ * @to: Destination address, in kernel space.
+ * @from: Source address, in user space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from user space to kernel space. Caller must check
+ * the specified block with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ *
+ * If some data could not be copied, this function will pad the copied
+ * data to the requested size using zero bytes.
+ *
+ * An alternate version - __copy_from_user_inatomic() - is designed
+ * to be called from atomic context, typically bracketed by calls
+ * to pagefault_disable() and pagefault_enable(). This version
+ * does *NOT* pad with zeros.
+ */
+extern unsigned long __must_check __copy_from_user_inatomic(
+ void *to, const void __user *from, unsigned long n);
+extern unsigned long __must_check __copy_from_user_zeroing(
+ void *to, const void __user *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ might_fault();
+ return __copy_from_user_zeroing(to, from, n);
+}
+
+static inline unsigned long __must_check
+_copy_from_user(void *to, const void __user *from, unsigned long n)
+{
+ if (access_ok(VERIFY_READ, from, n))
+ n = __copy_from_user(to, from, n);
+ else
+ memset(to, 0, n);
+ return n;
+}
+
+#ifdef CONFIG_DEBUG_COPY_FROM_USER
+extern void copy_from_user_overflow(void)
+ __compiletime_warning("copy_from_user() size is not provably correct");
+
+static inline unsigned long __must_check copy_from_user(void *to,
+ const void __user *from,
+ unsigned long n)
+{
+ int sz = __compiletime_object_size(to);
+
+ if (likely(sz == -1 || sz >= n))
+ n = _copy_from_user(to, from, n);
+ else
+ copy_from_user_overflow();
+
+ return n;
+}
+#else
+#define copy_from_user _copy_from_user
+#endif
+
+#ifdef __tilegx__
+/**
+ * __copy_in_user() - copy data within user space, with less checking.
+ * @to: Destination address, in user space.
+ * @from: Source address, in kernel space.
+ * @n: Number of bytes to copy.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Copy data from user space to user space. Caller must check
+ * the specified blocks with access_ok() before calling this function.
+ *
+ * Returns number of bytes that could not be copied.
+ * On success, this will be zero.
+ */
+extern unsigned long __copy_in_user_asm(
+ void __user *to, const void __user *from, unsigned long n);
+
+static inline unsigned long __must_check
+__copy_in_user(void __user *to, const void __user *from, unsigned long n)
+{
+ might_sleep();
+ return __copy_in_user_asm(to, from, n);
+}
+
+static inline unsigned long __must_check
+copy_in_user(void __user *to, const void __user *from, unsigned long n)
+{
+ if (access_ok(VERIFY_WRITE, to, n) && access_ok(VERIFY_READ, from, n))
+ n = __copy_in_user(to, from, n);
+ return n;
+}
+#endif
+
+
+/**
+ * strlen_user: - Get the size of a string in user space.
+ * @str: The string to measure.
+ *
+ * Context: User context only. This function may sleep.
+ *
+ * Get the size of a NUL-terminated string in user space.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ * On exception, returns 0.
+ *
+ * If there is a limit on the length of a valid string, you may wish to
+ * consider using strnlen_user() instead.
+ */
+extern long strnlen_user_asm(const char __user *str, long n);
+static inline long __must_check strnlen_user(const char __user *str, long n)
+{
+ might_fault();
+ return strnlen_user_asm(str, n);
+}
+#define strlen_user(str) strnlen_user(str, LONG_MAX)
+
+/**
+ * strncpy_from_user: - Copy a NUL terminated string from userspace, with less checking.
+ * @dst: Destination address, in kernel space. This buffer must be at
+ * least @count bytes long.
+ * @src: Source address, in user space.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from userspace to kernel space.
+ * Caller must check the specified block with access_ok() before calling
+ * this function.
+ *
+ * On success, returns the length of the string (not including the trailing
+ * NUL).
+ *
+ * If access to userspace fails, returns -EFAULT (some data may have been
+ * copied).
+ *
+ * If @count is smaller than the length of the string, copies @count bytes
+ * and returns @count.
+ */
+extern long strncpy_from_user_asm(char *dst, const char __user *src, long);
+static inline long __must_check __strncpy_from_user(
+ char *dst, const char __user *src, long count)
+{
+ might_fault();
+ return strncpy_from_user_asm(dst, src, count);
+}
+static inline long __must_check strncpy_from_user(
+ char *dst, const char __user *src, long count)
+{
+ if (access_ok(VERIFY_READ, src, 1))
+ return __strncpy_from_user(dst, src, count);
+ return -EFAULT;
+}
+
+/**
+ * clear_user: - Zero a block of memory in user space.
+ * @mem: Destination address, in user space.
+ * @len: Number of bytes to zero.
+ *
+ * Zero a block of memory in user space.
+ *
+ * Returns number of bytes that could not be cleared.
+ * On success, this will be zero.
+ */
+extern unsigned long clear_user_asm(void __user *mem, unsigned long len);
+static inline unsigned long __must_check __clear_user(
+ void __user *mem, unsigned long len)
+{
+ might_fault();
+ return clear_user_asm(mem, len);
+}
+static inline unsigned long __must_check clear_user(
+ void __user *mem, unsigned long len)
+{
+ if (access_ok(VERIFY_WRITE, mem, len))
+ return __clear_user(mem, len);
+ return len;
+}
+
+/**
+ * flush_user: - Flush a block of memory in user space from cache.
+ * @mem: Destination address, in user space.
+ * @len: Number of bytes to flush.
+ *
+ * Returns number of bytes that could not be flushed.
+ * On success, this will be zero.
+ */
+extern unsigned long flush_user_asm(void __user *mem, unsigned long len);
+static inline unsigned long __must_check __flush_user(
+ void __user *mem, unsigned long len)
+{
+ int retval;
+
+ might_fault();
+ retval = flush_user_asm(mem, len);
+ mb_incoherent();
+ return retval;
+}
+
+static inline unsigned long __must_check flush_user(
+ void __user *mem, unsigned long len)
+{
+ if (access_ok(VERIFY_WRITE, mem, len))
+ return __flush_user(mem, len);
+ return len;
+}
+
+/**
+ * inv_user: - Invalidate a block of memory in user space from cache.
+ * @mem: Destination address, in user space.
+ * @len: Number of bytes to invalidate.
+ *
+ * Returns number of bytes that could not be invalidated.
+ * On success, this will be zero.
+ *
+ * Note that on Tile64, the "inv" operation is in fact a
+ * "flush and invalidate", so cache write-backs will occur prior
+ * to the cache being marked invalid.
+ */
+extern unsigned long inv_user_asm(void __user *mem, unsigned long len);
+static inline unsigned long __must_check __inv_user(
+ void __user *mem, unsigned long len)
+{
+ int retval;
+
+ might_fault();
+ retval = inv_user_asm(mem, len);
+ mb_incoherent();
+ return retval;
+}
+static inline unsigned long __must_check inv_user(
+ void __user *mem, unsigned long len)
+{
+ if (access_ok(VERIFY_WRITE, mem, len))
+ return __inv_user(mem, len);
+ return len;
+}
+
+/**
+ * finv_user: - Flush-inval a block of memory in user space from cache.
+ * @mem: Destination address, in user space.
+ * @len: Number of bytes to invalidate.
+ *
+ * Returns number of bytes that could not be flush-invalidated.
+ * On success, this will be zero.
+ */
+extern unsigned long finv_user_asm(void __user *mem, unsigned long len);
+static inline unsigned long __must_check __finv_user(
+ void __user *mem, unsigned long len)
+{
+ int retval;
+
+ might_fault();
+ retval = finv_user_asm(mem, len);
+ mb_incoherent();
+ return retval;
+}
+static inline unsigned long __must_check finv_user(
+ void __user *mem, unsigned long len)
+{
+ if (access_ok(VERIFY_WRITE, mem, len))
+ return __finv_user(mem, len);
+ return len;
+}
+
+#endif /* _ASM_TILE_UACCESS_H */
diff --git a/arch/tile/include/asm/ucontext.h b/arch/tile/include/asm/ucontext.h
new file mode 100644
index 000000000000..9bc07b9f30fb
--- /dev/null
+++ b/arch/tile/include/asm/ucontext.h
@@ -0,0 +1 @@
+#include <asm-generic/ucontext.h>
diff --git a/arch/tile/include/asm/unaligned.h b/arch/tile/include/asm/unaligned.h
new file mode 100644
index 000000000000..137e2de5b102
--- /dev/null
+++ b/arch/tile/include/asm/unaligned.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef _ASM_TILE_UNALIGNED_H
+#define _ASM_TILE_UNALIGNED_H
+
+#include <linux/unaligned/le_struct.h>
+#include <linux/unaligned/be_byteshift.h>
+#include <linux/unaligned/generic.h>
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+
+#endif /* _ASM_TILE_UNALIGNED_H */
diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h
new file mode 100644
index 000000000000..f2e3ff485333
--- /dev/null
+++ b/arch/tile/include/asm/unistd.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
+#define _ASM_TILE_UNISTD_H
+
+#ifndef __LP64__
+/* Use the flavor of this syscall that matches the 32-bit API better. */
+#define __ARCH_WANT_SYNC_FILE_RANGE2
+#endif
+
+/* Use the standard ABI for syscalls. */
+#include <asm-generic/unistd.h>
+
+/* Additional Tilera-specific syscalls. */
+#define __NR_flush_cache (__NR_arch_specific_syscall + 1)
+__SYSCALL(__NR_flush_cache, sys_flush_cache)
+
+#ifndef __tilegx__
+/* "Fast" syscalls provide atomic support for 32-bit chips. */
+#define __NR_FAST_cmpxchg -1
+#define __NR_FAST_atomic_update -2
+#define __NR_FAST_cmpxchg64 -3
+#define __NR_cmpxchg_badaddr (__NR_arch_specific_syscall + 0)
+__SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr)
+#endif
+
+#ifdef __KERNEL__
+/* In compat mode, we use sys_llseek() for compat_sys_llseek(). */
+#ifdef CONFIG_COMPAT
+#define __ARCH_WANT_SYS_LLSEEK
+#endif
+#endif
+
+#endif /* _ASM_TILE_UNISTD_H */
diff --git a/arch/tile/include/asm/user.h b/arch/tile/include/asm/user.h
new file mode 100644
index 000000000000..cbc8b4d5a5ce
--- /dev/null
+++ b/arch/tile/include/asm/user.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#ifndef _ASM_TILE_USER_H
+#define _ASM_TILE_USER_H
+
+/* This header is for a.out file formats, which TILE does not support. */
+
+#endif /* _ASM_TILE_USER_H */
diff --git a/arch/tile/include/asm/xor.h b/arch/tile/include/asm/xor.h
new file mode 100644
index 000000000000..c82eb12a5b18
--- /dev/null
+++ b/arch/tile/include/asm/xor.h
@@ -0,0 +1 @@
+#include <asm-generic/xor.h>
diff --git a/arch/tile/include/hv/drv_pcie_rc_intf.h b/arch/tile/include/hv/drv_pcie_rc_intf.h
new file mode 100644
index 000000000000..9bd2243bece0
--- /dev/null
+++ b/arch/tile/include/hv/drv_pcie_rc_intf.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/**
+ * @file drv_pcie_rc_intf.h
+ * Interface definitions for the PCIE Root Complex.
+ */
+
+#ifndef _SYS_HV_DRV_PCIE_RC_INTF_H
+#define _SYS_HV_DRV_PCIE_RC_INTF_H
+
+/** File offset for reading the interrupt base number used for PCIE legacy
+ interrupts and PLX Gen 1 requirement flag */
+#define PCIE_RC_CONFIG_MASK_OFF 0
+
+
+/**
+ * Structure used for obtaining PCIe config information, read from the PCIE
+ * subsystem /ctl file at initialization
+ */
+typedef struct pcie_rc_config
+{
+ int intr; /**< interrupt number used for downcall */
+ int plx_gen1; /**< flag for PLX Gen 1 configuration */
+} pcie_rc_config_t;
+
+#endif /* _SYS_HV_DRV_PCIE_RC_INTF_H */
diff --git a/arch/tile/include/hv/hypervisor.h b/arch/tile/include/hv/hypervisor.h
new file mode 100644
index 000000000000..59b46dc53994
--- /dev/null
+++ b/arch/tile/include/hv/hypervisor.h
@@ -0,0 +1,2375 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/**
+ * @file hypervisor.h
+ * The hypervisor's public API.
+ */
+
+#ifndef _TILE_HV_H
+#define _TILE_HV_H
+
+#include <arch/chip.h>
+
+#include <hv/pagesize.h>
+
+/* Linux builds want unsigned long constants, but assembler wants numbers */
+#ifdef __ASSEMBLER__
+/** One, for assembler */
+#define __HV_SIZE_ONE 1
+#elif !defined(__tile__) && CHIP_VA_WIDTH() > 32
+/** One, for 64-bit on host */
+#define __HV_SIZE_ONE 1ULL
+#else
+/** One, for Linux */
+#define __HV_SIZE_ONE 1UL
+#endif
+
+/** The log2 of the span of a level-1 page table, in bytes.
+ */
+#define HV_LOG2_L1_SPAN 32
+
+/** The span of a level-1 page table, in bytes.
+ */
+#define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
+
+/** The size of small pages, in bytes. This value should be verified
+ * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
+ */
+#define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
+
+/** The size of large pages, in bytes. This value should be verified
+ * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
+ */
+#define HV_PAGE_SIZE_LARGE (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_LARGE)
+
+/** The log2 of the granularity at which page tables must be aligned;
+ * in other words, the CPA for a page table must have this many zero
+ * bits at the bottom of the address.
+ */
+#define HV_LOG2_PAGE_TABLE_ALIGN 11
+
+/** The granularity at which page tables must be aligned.
+ */
+#define HV_PAGE_TABLE_ALIGN (__HV_SIZE_ONE << HV_LOG2_PAGE_TABLE_ALIGN)
+
+/** Normal start of hypervisor glue in client physical memory. */
+#define HV_GLUE_START_CPA 0x10000
+
+/** This much space is reserved at HV_GLUE_START_CPA
+ * for the hypervisor glue. The client program must start at
+ * some address higher than this, and in particular the address of
+ * its text section should be equal to zero modulo HV_PAGE_SIZE_LARGE
+ * so that relative offsets to the HV glue are correct.
+ */
+#define HV_GLUE_RESERVED_SIZE 0x10000
+
+/** Each entry in the hv dispatch array takes this many bytes. */
+#define HV_DISPATCH_ENTRY_SIZE 32
+
+/** Version of the hypervisor interface defined by this file */
+#define _HV_VERSION 11
+
+/* Index into hypervisor interface dispatch code blocks.
+ *
+ * Hypervisor calls are invoked from user space by calling code
+ * at an address HV_BASE_ADDRESS + (index) * HV_DISPATCH_ENTRY_SIZE,
+ * where index is one of these enum values.
+ *
+ * Normally a supervisor is expected to produce a set of symbols
+ * starting at HV_BASE_ADDRESS that obey this convention, but a user
+ * program could call directly through function pointers if desired.
+ *
+ * These numbers are part of the binary API and will not be changed
+ * without updating HV_VERSION, which should be a rare event.
+ */
+
+/** reserved. */
+#define _HV_DISPATCH_RESERVED 0
+
+/** hv_init */
+#define HV_DISPATCH_INIT 1
+
+/** hv_install_context */
+#define HV_DISPATCH_INSTALL_CONTEXT 2
+
+/** hv_sysconf */
+#define HV_DISPATCH_SYSCONF 3
+
+/** hv_get_rtc */
+#define HV_DISPATCH_GET_RTC 4
+
+/** hv_set_rtc */
+#define HV_DISPATCH_SET_RTC 5
+
+/** hv_flush_asid */
+#define HV_DISPATCH_FLUSH_ASID 6
+
+/** hv_flush_page */
+#define HV_DISPATCH_FLUSH_PAGE 7
+
+/** hv_flush_pages */
+#define HV_DISPATCH_FLUSH_PAGES 8
+
+/** hv_restart */
+#define HV_DISPATCH_RESTART 9
+
+/** hv_halt */
+#define HV_DISPATCH_HALT 10
+
+/** hv_power_off */
+#define HV_DISPATCH_POWER_OFF 11
+
+/** hv_inquire_physical */
+#define HV_DISPATCH_INQUIRE_PHYSICAL 12
+
+/** hv_inquire_memory_controller */
+#define HV_DISPATCH_INQUIRE_MEMORY_CONTROLLER 13
+
+/** hv_inquire_virtual */
+#define HV_DISPATCH_INQUIRE_VIRTUAL 14
+
+/** hv_inquire_asid */
+#define HV_DISPATCH_INQUIRE_ASID 15
+
+/** hv_nanosleep */
+#define HV_DISPATCH_NANOSLEEP 16
+
+/** hv_console_read_if_ready */
+#define HV_DISPATCH_CONSOLE_READ_IF_READY 17
+
+/** hv_console_write */
+#define HV_DISPATCH_CONSOLE_WRITE 18
+
+/** hv_downcall_dispatch */
+#define HV_DISPATCH_DOWNCALL_DISPATCH 19
+
+/** hv_inquire_topology */
+#define HV_DISPATCH_INQUIRE_TOPOLOGY 20
+
+/** hv_fs_findfile */
+#define HV_DISPATCH_FS_FINDFILE 21
+
+/** hv_fs_fstat */
+#define HV_DISPATCH_FS_FSTAT 22
+
+/** hv_fs_pread */
+#define HV_DISPATCH_FS_PREAD 23
+
+/** hv_physaddr_read64 */
+#define HV_DISPATCH_PHYSADDR_READ64 24
+
+/** hv_physaddr_write64 */
+#define HV_DISPATCH_PHYSADDR_WRITE64 25
+
+/** hv_get_command_line */
+#define HV_DISPATCH_GET_COMMAND_LINE 26
+
+/** hv_set_caching */
+#define HV_DISPATCH_SET_CACHING 27
+
+/** hv_bzero_page */
+#define HV_DISPATCH_BZERO_PAGE 28
+
+/** hv_register_message_state */
+#define HV_DISPATCH_REGISTER_MESSAGE_STATE 29
+
+/** hv_send_message */
+#define HV_DISPATCH_SEND_MESSAGE 30
+
+/** hv_receive_message */
+#define HV_DISPATCH_RECEIVE_MESSAGE 31
+
+/** hv_inquire_context */
+#define HV_DISPATCH_INQUIRE_CONTEXT 32
+
+/** hv_start_all_tiles */
+#define HV_DISPATCH_START_ALL_TILES 33
+
+/** hv_dev_open */
+#define HV_DISPATCH_DEV_OPEN 34
+
+/** hv_dev_close */
+#define HV_DISPATCH_DEV_CLOSE 35
+
+/** hv_dev_pread */
+#define HV_DISPATCH_DEV_PREAD 36
+
+/** hv_dev_pwrite */
+#define HV_DISPATCH_DEV_PWRITE 37
+
+/** hv_dev_poll */
+#define HV_DISPATCH_DEV_POLL 38
+
+/** hv_dev_poll_cancel */
+#define HV_DISPATCH_DEV_POLL_CANCEL 39
+
+/** hv_dev_preada */
+#define HV_DISPATCH_DEV_PREADA 40
+
+/** hv_dev_pwritea */
+#define HV_DISPATCH_DEV_PWRITEA 41
+
+/** hv_flush_remote */
+#define HV_DISPATCH_FLUSH_REMOTE 42
+
+/** hv_console_putc */
+#define HV_DISPATCH_CONSOLE_PUTC 43
+
+/** hv_inquire_tiles */
+#define HV_DISPATCH_INQUIRE_TILES 44
+
+/** hv_confstr */
+#define HV_DISPATCH_CONFSTR 45
+
+/** hv_reexec */
+#define HV_DISPATCH_REEXEC 46
+
+/** hv_set_command_line */
+#define HV_DISPATCH_SET_COMMAND_LINE 47
+
+#if !CHIP_HAS_IPI()
+
+/** hv_clear_intr */
+#define HV_DISPATCH_CLEAR_INTR 48
+
+/** hv_enable_intr */
+#define HV_DISPATCH_ENABLE_INTR 49
+
+/** hv_disable_intr */
+#define HV_DISPATCH_DISABLE_INTR 50
+
+/** hv_raise_intr */
+#define HV_DISPATCH_RAISE_INTR 51
+
+/** hv_trigger_ipi */
+#define HV_DISPATCH_TRIGGER_IPI 52
+
+#endif /* !CHIP_HAS_IPI() */
+
+/** hv_store_mapping */
+#define HV_DISPATCH_STORE_MAPPING 53
+
+/** hv_inquire_realpa */
+#define HV_DISPATCH_INQUIRE_REALPA 54
+
+/** hv_flush_all */
+#define HV_DISPATCH_FLUSH_ALL 55
+
+#if CHIP_HAS_IPI()
+/** hv_get_ipi_pte */
+#define HV_DISPATCH_GET_IPI_PTE 56
+#endif
+
+/** One more than the largest dispatch value */
+#define _HV_DISPATCH_END 57
+
+
+#ifndef __ASSEMBLER__
+
+#ifdef __KERNEL__
+#include <asm/types.h>
+typedef u32 __hv32; /**< 32-bit value */
+typedef u64 __hv64; /**< 64-bit value */
+#else
+#include <stdint.h>
+typedef uint32_t __hv32; /**< 32-bit value */
+typedef uint64_t __hv64; /**< 64-bit value */
+#endif
+
+
+/** Hypervisor physical address. */
+typedef __hv64 HV_PhysAddr;
+
+#if CHIP_VA_WIDTH() > 32
+/** Hypervisor virtual address. */
+typedef __hv64 HV_VirtAddr;
+#else
+/** Hypervisor virtual address. */
+typedef __hv32 HV_VirtAddr;
+#endif /* CHIP_VA_WIDTH() > 32 */
+
+/** Hypervisor ASID. */
+typedef unsigned int HV_ASID;
+
+/** Hypervisor tile location for a memory access
+ * ("location overridden target").
+ */
+typedef unsigned int HV_LOTAR;
+
+/** Hypervisor size of a page. */
+typedef unsigned long HV_PageSize;
+
+/** A page table entry.
+ */
+typedef struct
+{
+ __hv64 val; /**< Value of PTE */
+} HV_PTE;
+
+/** Hypervisor error code. */
+typedef int HV_Errno;
+
+#endif /* !__ASSEMBLER__ */
+
+#define HV_OK 0 /**< No error */
+#define HV_EINVAL -801 /**< Invalid argument */
+#define HV_ENODEV -802 /**< No such device */
+#define HV_ENOENT -803 /**< No such file or directory */
+#define HV_EBADF -804 /**< Bad file number */
+#define HV_EFAULT -805 /**< Bad address */
+#define HV_ERECIP -806 /**< Bad recipients */
+#define HV_E2BIG -807 /**< Message too big */
+#define HV_ENOTSUP -808 /**< Service not supported */
+#define HV_EBUSY -809 /**< Device busy */
+#define HV_ENOSYS -810 /**< Invalid syscall */
+#define HV_EPERM -811 /**< No permission */
+#define HV_ENOTREADY -812 /**< Device not ready */
+#define HV_EIO -813 /**< I/O error */
+#define HV_ENOMEM -814 /**< Out of memory */
+
+#define HV_ERR_MAX -801 /**< Largest HV error code */
+#define HV_ERR_MIN -814 /**< Smallest HV error code */
+
+#ifndef __ASSEMBLER__
+
+/** Pass HV_VERSION to hv_init to request this version of the interface. */
+typedef enum { HV_VERSION = _HV_VERSION } HV_VersionNumber;
+
+/** Initializes the hypervisor.
+ *
+ * @param interface_version_number The version of the hypervisor interface
+ * that this program expects, typically HV_VERSION.
+ * @param chip_num Architecture number of the chip the client was built for.
+ * @param chip_rev_num Revision number of the chip the client was built for.
+ */
+void hv_init(HV_VersionNumber interface_version_number,
+ int chip_num, int chip_rev_num);
+
+
+/** Queries we can make for hv_sysconf().
+ *
+ * These numbers are part of the binary API and guaranteed not to change.
+ */
+typedef enum {
+ /** An invalid value; do not use. */
+ _HV_SYSCONF_RESERVED = 0,
+
+ /** The length of the glue section containing the hv_ procs, in bytes. */
+ HV_SYSCONF_GLUE_SIZE = 1,
+
+ /** The size of small pages, in bytes. */
+ HV_SYSCONF_PAGE_SIZE_SMALL = 2,
+
+ /** The size of large pages, in bytes. */
+ HV_SYSCONF_PAGE_SIZE_LARGE = 3,
+
+ /** Processor clock speed, in hertz. */
+ HV_SYSCONF_CPU_SPEED = 4,
+
+ /** Processor temperature, in degrees Kelvin. The value
+ * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
+ * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
+ * that the temperature has hit an upper limit and is no longer being
+ * accurately tracked.
+ */
+ HV_SYSCONF_CPU_TEMP = 5,
+
+ /** Board temperature, in degrees Kelvin. The value
+ * HV_SYSCONF_TEMP_KTOC may be subtracted from this to get degrees
+ * Celsius. If that Celsius value is HV_SYSCONF_OVERTEMP, this indicates
+ * that the temperature has hit an upper limit and is no longer being
+ * accurately tracked.
+ */
+ HV_SYSCONF_BOARD_TEMP = 6
+
+} HV_SysconfQuery;
+
+/** Offset to subtract from returned Kelvin temperature to get degrees
+ Celsius. */
+#define HV_SYSCONF_TEMP_KTOC 273
+
+/** Pseudo-temperature value indicating that the temperature has
+ * pegged at its upper limit and is no longer accurate; note that this is
+ * the value after subtracting HV_SYSCONF_TEMP_KTOC. */
+#define HV_SYSCONF_OVERTEMP 999
+
+/** Query a configuration value from the hypervisor.
+ * @param query Which value is requested (HV_SYSCONF_xxx).
+ * @return The requested value, or -1 the requested value is illegal or
+ * unavailable.
+ */
+long hv_sysconf(HV_SysconfQuery query);
+
+
+/** Queries we can make for hv_confstr().
+ *
+ * These numbers are part of the binary API and guaranteed not to change.
+ */
+typedef enum {
+ /** An invalid value; do not use. */
+ _HV_CONFSTR_RESERVED = 0,
+
+ /** Board part number. */
+ HV_CONFSTR_BOARD_PART_NUM = 1,
+
+ /** Board serial number. */
+ HV_CONFSTR_BOARD_SERIAL_NUM = 2,
+
+ /** Chip serial number. */
+ HV_CONFSTR_CHIP_SERIAL_NUM = 3,
+
+ /** Board revision level. */
+ HV_CONFSTR_BOARD_REV = 4,
+
+ /** Hypervisor software version. */
+ HV_CONFSTR_HV_SW_VER = 5,
+
+ /** The name for this chip model. */
+ HV_CONFSTR_CHIP_MODEL = 6,
+
+ /** Human-readable board description. */
+ HV_CONFSTR_BOARD_DESC = 7,
+
+ /** Human-readable description of the hypervisor configuration. */
+ HV_CONFSTR_HV_CONFIG = 8,
+
+ /** Human-readable version string for the boot image (for instance,
+ * who built it and when, what configuration file was used). */
+ HV_CONFSTR_HV_CONFIG_VER = 9,
+
+ /** Mezzanine part number. */
+ HV_CONFSTR_MEZZ_PART_NUM = 10,
+
+ /** Mezzanine serial number. */
+ HV_CONFSTR_MEZZ_SERIAL_NUM = 11,
+
+ /** Mezzanine revision level. */
+ HV_CONFSTR_MEZZ_REV = 12,
+
+ /** Human-readable mezzanine description. */
+ HV_CONFSTR_MEZZ_DESC = 13,
+
+ /** Control path for the onboard network switch. */
+ HV_CONFSTR_SWITCH_CONTROL = 14,
+
+ /** Chip revision level. */
+ HV_CONFSTR_CHIP_REV = 15
+
+} HV_ConfstrQuery;
+
+/** Query a configuration string from the hypervisor.
+ *
+ * @param query Identifier for the specific string to be retrieved
+ * (HV_CONFSTR_xxx).
+ * @param buf Buffer in which to place the string.
+ * @param len Length of the buffer.
+ * @return If query is valid, then the length of the corresponding string,
+ * including the trailing null; if this is greater than len, the string
+ * was truncated. If query is invalid, HV_EINVAL. If the specified
+ * buffer is not writable by the client, HV_EFAULT.
+ */
+int hv_confstr(HV_ConfstrQuery query, HV_VirtAddr buf, int len);
+
+/** Tile coordinate */
+typedef struct
+{
+ /** X coordinate, relative to supervisor's top-left coordinate */
+ int x;
+
+ /** Y coordinate, relative to supervisor's top-left coordinate */
+ int y;
+} HV_Coord;
+
+
+#if CHIP_HAS_IPI()
+
+/** Get the PTE for sending an IPI to a particular tile.
+ *
+ * @param tile Tile which will receive the IPI.
+ * @param pl Indicates which IPI registers: 0 = IPI_0, 1 = IPI_1.
+ * @param pte Filled with resulting PTE.
+ * @result Zero if no error, non-zero for invalid parameters.
+ */
+int hv_get_ipi_pte(HV_Coord tile, int pl, HV_PTE* pte);
+
+#else /* !CHIP_HAS_IPI() */
+
+/** A set of interrupts. */
+typedef __hv32 HV_IntrMask;
+
+/** The low interrupt numbers are reserved for use by the client in
+ * delivering IPIs. Any interrupt numbers higher than this value are
+ * reserved for use by HV device drivers. */
+#define HV_MAX_IPI_INTERRUPT 7
+
+/** Enable a set of device interrupts.
+ *
+ * @param enab_mask Bitmap of interrupts to enable.
+ */
+void hv_enable_intr(HV_IntrMask enab_mask);
+
+/** Disable a set of device interrupts.
+ *
+ * @param disab_mask Bitmap of interrupts to disable.
+ */
+void hv_disable_intr(HV_IntrMask disab_mask);
+
+/** Clear a set of device interrupts.
+ *
+ * @param clear_mask Bitmap of interrupts to clear.
+ */
+void hv_clear_intr(HV_IntrMask clear_mask);
+
+/** Assert a set of device interrupts.
+ *
+ * @param assert_mask Bitmap of interrupts to clear.
+ */
+void hv_assert_intr(HV_IntrMask assert_mask);
+
+/** Trigger a one-shot interrupt on some tile
+ *
+ * @param tile Which tile to interrupt.
+ * @param interrupt Interrupt number to trigger; must be between 0 and
+ * HV_MAX_IPI_INTERRUPT.
+ * @return HV_OK on success, or a hypervisor error code.
+ */
+HV_Errno hv_trigger_ipi(HV_Coord tile, int interrupt);
+
+#endif /* !CHIP_HAS_IPI() */
+
+/** Store memory mapping in debug memory so that external debugger can read it.
+ * A maximum of 16 entries can be stored.
+ *
+ * @param va VA of memory that is mapped.
+ * @param len Length of mapped memory.
+ * @param pa PA of memory that is mapped.
+ * @return 0 on success, -1 if the maximum number of mappings is exceeded.
+ */
+int hv_store_mapping(HV_VirtAddr va, unsigned int len, HV_PhysAddr pa);
+
+/** Given a client PA and a length, return its real (HV) PA.
+ *
+ * @param cpa Client physical address.
+ * @param len Length of mapped memory.
+ * @return physical address, or -1 if cpa or len is not valid.
+ */
+HV_PhysAddr hv_inquire_realpa(HV_PhysAddr cpa, unsigned int len);
+
+/** RTC return flag for no RTC chip present.
+ */
+#define HV_RTC_NO_CHIP 0x1
+
+/** RTC return flag for low-voltage condition, indicating that battery had
+ * died and time read is unreliable.
+ */
+#define HV_RTC_LOW_VOLTAGE 0x2
+
+/** Date/Time of day */
+typedef struct {
+#if CHIP_WORD_SIZE() > 32
+ __hv64 tm_sec; /**< Seconds, 0-59 */
+ __hv64 tm_min; /**< Minutes, 0-59 */
+ __hv64 tm_hour; /**< Hours, 0-23 */
+ __hv64 tm_mday; /**< Day of month, 0-30 */
+ __hv64 tm_mon; /**< Month, 0-11 */
+ __hv64 tm_year; /**< Years since 1900, 0-199 */
+ __hv64 flags; /**< Return flags, 0 if no error */
+#else
+ __hv32 tm_sec; /**< Seconds, 0-59 */
+ __hv32 tm_min; /**< Minutes, 0-59 */
+ __hv32 tm_hour; /**< Hours, 0-23 */
+ __hv32 tm_mday; /**< Day of month, 0-30 */
+ __hv32 tm_mon; /**< Month, 0-11 */
+ __hv32 tm_year; /**< Years since 1900, 0-199 */
+ __hv32 flags; /**< Return flags, 0 if no error */
+#endif
+} HV_RTCTime;
+
+/** Read the current time-of-day clock.
+ * @return HV_RTCTime of current time (GMT).
+ */
+HV_RTCTime hv_get_rtc(void);
+
+
+/** Set the current time-of-day clock.
+ * @param time time to reset time-of-day to (GMT).
+ */
+void hv_set_rtc(HV_RTCTime time);
+
+/** Installs a context, comprising a page table and other attributes.
+ *
+ * Once this service completes, page_table will be used to translate
+ * subsequent virtual address references to physical memory.
+ *
+ * Installing a context does not cause an implicit TLB flush. Before
+ * reusing an ASID value for a different address space, the client is
+ * expected to flush old references from the TLB with hv_flush_asid().
+ * (Alternately, hv_flush_all() may be used to flush many ASIDs at once.)
+ * After invalidating a page table entry, changing its attributes, or
+ * changing its target CPA, the client is expected to flush old references
+ * from the TLB with hv_flush_page() or hv_flush_pages(). Making a
+ * previously invalid page valid does not require a flush.
+ *
+ * Specifying an invalid ASID, or an invalid CPA (client physical address)
+ * (either as page_table_pointer, or within the referenced table),
+ * or another page table data item documented as above as illegal may
+ * lead to client termination; since the validation of the table is
+ * done as needed, this may happen before the service returns, or at
+ * some later time, or never, depending upon the client's pattern of
+ * memory references. Page table entries which supply translations for
+ * invalid virtual addresses may result in client termination, or may
+ * be silently ignored. "Invalid" in this context means a value which
+ * was not provided to the client via the appropriate hv_inquire_* routine.
+ *
+ * To support changing the instruction VAs at the same time as
+ * installing the new page table, this call explicitly supports
+ * setting the "lr" register to a different address and then jumping
+ * directly to the hv_install_context() routine. In this case, the
+ * new page table does not need to contain any mapping for the
+ * hv_install_context address itself.
+ *
+ * @param page_table Root of the page table.
+ * @param access PTE providing info on how to read the page table. This
+ * value must be consistent between multiple tiles sharing a page table,
+ * and must also be consistent with any virtual mappings the client
+ * may be using to access the page table.
+ * @param asid HV_ASID the page table is to be used for.
+ * @param flags Context flags, denoting attributes or privileges of the
+ * current context (HV_CTX_xxx).
+ * @return Zero on success, or a hypervisor error code on failure.
+ */
+int hv_install_context(HV_PhysAddr page_table, HV_PTE access, HV_ASID asid,
+ __hv32 flags);
+
+#endif /* !__ASSEMBLER__ */
+
+#define HV_CTX_DIRECTIO 0x1 /**< Direct I/O requests are accepted from
+ PL0. */
+
+#ifndef __ASSEMBLER__
+
+/** Value returned from hv_inquire_context(). */
+typedef struct
+{
+ /** Physical address of page table */
+ HV_PhysAddr page_table;
+
+ /** PTE which defines access method for top of page table */
+ HV_PTE access;
+
+ /** ASID associated with this page table */
+ HV_ASID asid;
+
+ /** Context flags */
+ __hv32 flags;
+} HV_Context;
+
+/** Retrieve information about the currently installed context.
+ * @return The data passed to the last successful hv_install_context call.
+ */
+HV_Context hv_inquire_context(void);
+
+
+/** Flushes all translations associated with the named address space
+ * identifier from the TLB and any other hypervisor data structures.
+ * Translations installed with the "global" bit are not flushed.
+ *
+ * Specifying an invalid ASID may lead to client termination. "Invalid"
+ * in this context means a value which was not provided to the client
+ * via <tt>hv_inquire_asid()</tt>.
+ *
+ * @param asid HV_ASID whose entries are to be flushed.
+ * @return Zero on success, or a hypervisor error code on failure.
+*/
+int hv_flush_asid(HV_ASID asid);
+
+
+/** Flushes all translations associated with the named virtual address
+ * and page size from the TLB and other hypervisor data structures. Only
+ * pages visible to the current ASID are affected; note that this includes
+ * global pages in addition to pages specific to the current ASID.
+ *
+ * The supplied VA need not be aligned; it may be anywhere in the
+ * subject page.
+ *
+ * Specifying an invalid virtual address may lead to client termination,
+ * or may silently succeed. "Invalid" in this context means a value
+ * which was not provided to the client via hv_inquire_virtual.
+ *
+ * @param address Address of the page to flush.
+ * @param page_size Size of pages to assume.
+ * @return Zero on success, or a hypervisor error code on failure.
+ */
+int hv_flush_page(HV_VirtAddr address, HV_PageSize page_size);
+
+
+/** Flushes all translations associated with the named virtual address range
+ * and page size from the TLB and other hypervisor data structures. Only
+ * pages visible to the current ASID are affected; note that this includes
+ * global pages in addition to pages specific to the current ASID.
+ *
+ * The supplied VA need not be aligned; it may be anywhere in the
+ * subject page.
+ *
+ * Specifying an invalid virtual address may lead to client termination,
+ * or may silently succeed. "Invalid" in this context means a value
+ * which was not provided to the client via hv_inquire_virtual.
+ *
+ * @param start Address to flush.
+ * @param page_size Size of pages to assume.
+ * @param size The number of bytes to flush. Any page in the range
+ * [start, start + size) will be flushed from the TLB.
+ * @return Zero on success, or a hypervisor error code on failure.
+ */
+int hv_flush_pages(HV_VirtAddr start, HV_PageSize page_size,
+ unsigned long size);
+
+
+/** Flushes all non-global translations (if preserve_global is true),
+ * or absolutely all translations (if preserve_global is false).
+ *
+ * @param preserve_global Non-zero if we want to preserve "global" mappings.
+ * @return Zero on success, or a hypervisor error code on failure.
+*/
+int hv_flush_all(int preserve_global);
+
+
+/** Restart machine with optional restart command and optional args.
+ * @param cmd Const pointer to command to restart with, or NULL
+ * @param args Const pointer to argument string to restart with, or NULL
+ */
+void hv_restart(HV_VirtAddr cmd, HV_VirtAddr args);
+
+
+/** Halt machine. */
+void hv_halt(void);
+
+
+/** Power off machine. */
+void hv_power_off(void);
+
+
+/** Re-enter virtual-is-physical memory translation mode and restart
+ * execution at a given address.
+ * @param entry Client physical address at which to begin execution.
+ * @return A hypervisor error code on failure; if the operation is
+ * successful the call does not return.
+ */
+int hv_reexec(HV_PhysAddr entry);
+
+
+/** Chip topology */
+typedef struct
+{
+ /** Relative coordinates of the querying tile */
+ HV_Coord coord;
+
+ /** Width of the querying supervisor's tile rectangle. */
+ int width;
+
+ /** Height of the querying supervisor's tile rectangle. */
+ int height;
+
+} HV_Topology;
+
+/** Returns information about the tile coordinate system.
+ *
+ * Each supervisor is given a rectangle of tiles it potentially controls.
+ * These tiles are labeled using a relative coordinate system with (0,0) as
+ * the upper left tile regardless of their physical location on the chip.
+ *
+ * This call returns both the size of that rectangle and the position
+ * within that rectangle of the querying tile.
+ *
+ * Not all tiles within that rectangle may be available to the supervisor;
+ * to get the precise set of available tiles, you must also call
+ * hv_inquire_tiles(HV_INQ_TILES_AVAIL, ...).
+ **/
+HV_Topology hv_inquire_topology(void);
+
+/** Sets of tiles we can retrieve with hv_inquire_tiles().
+ *
+ * These numbers are part of the binary API and guaranteed not to change.
+ */
+typedef enum {
+ /** An invalid value; do not use. */
+ _HV_INQ_TILES_RESERVED = 0,
+
+ /** All available tiles within the supervisor's tile rectangle. */
+ HV_INQ_TILES_AVAIL = 1,
+
+ /** The set of tiles used for hash-for-home caching. */
+ HV_INQ_TILES_HFH_CACHE = 2,
+
+ /** The set of tiles that can be legally used as a LOTAR for a PTE. */
+ HV_INQ_TILES_LOTAR = 3
+} HV_InqTileSet;
+
+/** Returns specific information about various sets of tiles within the
+ * supervisor's tile rectangle.
+ *
+ * @param set Which set of tiles to retrieve.
+ * @param cpumask Pointer to a returned bitmask (in row-major order,
+ * supervisor-relative) of tiles. The low bit of the first word
+ * corresponds to the tile at the upper left-hand corner of the
+ * supervisor's rectangle. In order for the supervisor to know the
+ * buffer length to supply, it should first call hv_inquire_topology.
+ * @param length Number of bytes available for the returned bitmask.
+ **/
+HV_Errno hv_inquire_tiles(HV_InqTileSet set, HV_VirtAddr cpumask, int length);
+
+
+/** An identifier for a memory controller. Multiple memory controllers
+ * may be connected to one chip, and this uniquely identifies each one.
+ */
+typedef int HV_MemoryController;
+
+/** A range of physical memory. */
+typedef struct
+{
+ HV_PhysAddr start; /**< Starting address. */
+ __hv64 size; /**< Size in bytes. */
+ HV_MemoryController controller; /**< Which memory controller owns this. */
+} HV_PhysAddrRange;
+
+/** Returns information about a range of physical memory.
+ *
+ * hv_inquire_physical() returns one of the ranges of client
+ * physical addresses which are available to this client.
+ *
+ * The first range is retrieved by specifying an idx of 0, and
+ * successive ranges are returned with subsequent idx values. Ranges
+ * are ordered by increasing start address (i.e., as idx increases,
+ * so does start), do not overlap, and do not touch (i.e., the
+ * available memory is described with the fewest possible ranges).
+ *
+ * If an out-of-range idx value is specified, the returned size will be zero.
+ * A client can count the number of ranges by increasing idx until the
+ * returned size is zero. There will always be at least one valid range.
+ *
+ * Some clients might not be prepared to deal with more than one
+ * physical address range; they still ought to call this routine and
+ * issue a warning message if they're given more than one range, on the
+ * theory that whoever configured the hypervisor to provide that memory
+ * should know that it's being wasted.
+ */
+HV_PhysAddrRange hv_inquire_physical(int idx);
+
+
+/** Memory controller information. */
+typedef struct
+{
+ HV_Coord coord; /**< Relative tile coordinates of the port used by a
+ specified tile to communicate with this controller. */
+ __hv64 speed; /**< Speed of this controller in bytes per second. */
+} HV_MemoryControllerInfo;
+
+/** Returns information about a particular memory controller.
+ *
+ * hv_inquire_memory_controller(coord,idx) returns information about a
+ * particular controller. Two pieces of information are returned:
+ * - The relative coordinates of the port on the controller that the specified
+ * tile would use to contact it. The relative coordinates may lie
+ * outside the supervisor's rectangle, i.e. the controller may not
+ * be attached to a node managed by the querying node's supervisor.
+ * In particular note that x or y may be negative.
+ * - The speed of the memory controller. (This is a not-to-exceed value
+ * based on the raw hardware data rate, and may not be achievable in
+ * practice; it is provided to give clients information on the relative
+ * performance of the available controllers.)
+ *
+ * Clients should avoid calling this interface with invalid values.
+ * A client who does may be terminated.
+ * @param coord Tile for which to calculate the relative port position.
+ * @param controller Index of the controller; identical to value returned
+ * from other routines like hv_inquire_physical.
+ * @return Information about the controller.
+ */
+HV_MemoryControllerInfo hv_inquire_memory_controller(HV_Coord coord,
+ int controller);
+
+
+/** A range of virtual memory. */
+typedef struct
+{
+ HV_VirtAddr start; /**< Starting address. */
+ __hv64 size; /**< Size in bytes. */
+} HV_VirtAddrRange;
+
+/** Returns information about a range of virtual memory.
+ *
+ * hv_inquire_virtual() returns one of the ranges of client
+ * virtual addresses which are available to this client.
+ *
+ * The first range is retrieved by specifying an idx of 0, and
+ * successive ranges are returned with subsequent idx values. Ranges
+ * are ordered by increasing start address (i.e., as idx increases,
+ * so does start), do not overlap, and do not touch (i.e., the
+ * available memory is described with the fewest possible ranges).
+ *
+ * If an out-of-range idx value is specified, the returned size will be zero.
+ * A client can count the number of ranges by increasing idx until the
+ * returned size is zero. There will always be at least one valid range.
+ *
+ * Some clients may well have various virtual addresses hardwired
+ * into themselves; for instance, their instruction stream may
+ * have been compiled expecting to live at a particular address.
+ * Such clients should use this interface to verify they've been
+ * given the virtual address space they expect, and issue a (potentially
+ * fatal) warning message otherwise.
+ *
+ * Note that the returned size is a __hv64, not a __hv32, so it is
+ * possible to express a single range spanning the entire 32-bit
+ * address space.
+ */
+HV_VirtAddrRange hv_inquire_virtual(int idx);
+
+
+/** A range of ASID values. */
+typedef struct
+{
+ HV_ASID start; /**< First ASID in the range. */
+ unsigned int size; /**< Number of ASIDs. Zero for an invalid range. */
+} HV_ASIDRange;
+
+/** Returns information about a range of ASIDs.
+ *
+ * hv_inquire_asid() returns one of the ranges of address
+ * space identifiers which are available to this client.
+ *
+ * The first range is retrieved by specifying an idx of 0, and
+ * successive ranges are returned with subsequent idx values. Ranges
+ * are ordered by increasing start value (i.e., as idx increases,
+ * so does start), do not overlap, and do not touch (i.e., the
+ * available ASIDs are described with the fewest possible ranges).
+ *
+ * If an out-of-range idx value is specified, the returned size will be zero.
+ * A client can count the number of ranges by increasing idx until the
+ * returned size is zero. There will always be at least one valid range.
+ */
+HV_ASIDRange hv_inquire_asid(int idx);
+
+
+/** Waits for at least the specified number of nanoseconds then returns.
+ *
+ * @param nanosecs The number of nanoseconds to sleep.
+ */
+void hv_nanosleep(int nanosecs);
+
+
+/** Reads a character from the console without blocking.
+ *
+ * @return A value from 0-255 indicates the value successfully read.
+ * A negative value means no value was ready.
+ */
+int hv_console_read_if_ready(void);
+
+
+/** Writes a character to the console, blocking if the console is busy.
+ *
+ * This call cannot fail. If the console is broken for some reason,
+ * output will simply vanish.
+ * @param byte Character to write.
+ */
+void hv_console_putc(int byte);
+
+
+/** Writes a string to the console, blocking if the console is busy.
+ * @param bytes Pointer to characters to write.
+ * @param len Number of characters to write.
+ * @return Number of characters written, or HV_EFAULT if the buffer is invalid.
+ */
+int hv_console_write(HV_VirtAddr bytes, int len);
+
+
+/** Dispatch the next interrupt from the client downcall mechanism.
+ *
+ * The hypervisor uses downcalls to notify the client of asynchronous
+ * events. Some of these events are hypervisor-created (like incoming
+ * messages). Some are regular interrupts which initially occur in
+ * the hypervisor, and are normally handled directly by the client;
+ * when these occur in a client's interrupt critical section, they must
+ * be delivered through the downcall mechanism.
+ *
+ * A downcall is initially delivered to the client as an INTCTRL_1
+ * interrupt. Upon entry to the INTCTRL_1 vector, the client must
+ * immediately invoke the hv_downcall_dispatch service. This service
+ * will not return; instead it will cause one of the client's actual
+ * downcall-handling interrupt vectors to be entered. The EX_CONTEXT
+ * registers in the client will be set so that when the client irets,
+ * it will return to the code which was interrupted by the INTCTRL_1
+ * interrupt.
+ *
+ * Under some circumstances, the firing of INTCTRL_1 can race with
+ * the lowering of a device interrupt. In such a case, the
+ * hv_downcall_dispatch service may issue an iret instruction instead
+ * of entering one of the client's actual downcall-handling interrupt
+ * vectors. This will return execution to the location that was
+ * interrupted by INTCTRL_1.
+ *
+ * Any saving of registers should be done by the actual handling
+ * vectors; no registers should be changed by the INTCTRL_1 handler.
+ * In particular, the client should not use a jal instruction to invoke
+ * the hv_downcall_dispatch service, as that would overwrite the client's
+ * lr register. Note that the hv_downcall_dispatch service may overwrite
+ * one or more of the client's system save registers.
+ *
+ * The client must not modify the INTCTRL_1_STATUS SPR. The hypervisor
+ * will set this register to cause a downcall to happen, and will clear
+ * it when no further downcalls are pending.
+ *
+ * When a downcall vector is entered, the INTCTRL_1 interrupt will be
+ * masked. When the client is done processing a downcall, and is ready
+ * to accept another, it must unmask this interrupt; if more downcalls
+ * are pending, this will cause the INTCTRL_1 vector to be reentered.
+ * Currently the following interrupt vectors can be entered through a
+ * downcall:
+ *
+ * INT_MESSAGE_RCV_DWNCL (hypervisor message available)
+ * INT_DMATLB_MISS_DWNCL (DMA TLB miss)
+ * INT_SNITLB_MISS_DWNCL (SNI TLB miss)
+ * INT_DMATLB_ACCESS_DWNCL (DMA TLB access violation)
+ */
+void hv_downcall_dispatch(void);
+
+#endif /* !__ASSEMBLER__ */
+
+/** We use actual interrupt vectors which never occur (they're only there
+ * to allow setting MPLs for related SPRs) for our downcall vectors.
+ */
+/** Message receive downcall interrupt vector */
+#define INT_MESSAGE_RCV_DWNCL INT_BOOT_ACCESS
+/** DMA TLB miss downcall interrupt vector */
+#define INT_DMATLB_MISS_DWNCL INT_DMA_ASID
+/** Static nework processor instruction TLB miss interrupt vector */
+#define INT_SNITLB_MISS_DWNCL INT_SNI_ASID
+/** DMA TLB access violation downcall interrupt vector */
+#define INT_DMATLB_ACCESS_DWNCL INT_DMA_CPL
+/** Device interrupt downcall interrupt vector */
+#define INT_DEV_INTR_DWNCL INT_WORLD_ACCESS
+
+#ifndef __ASSEMBLER__
+
+/** Requests the inode for a specific full pathname.
+ *
+ * Performs a lookup in the hypervisor filesystem for a given filename.
+ * Multiple calls with the same filename will always return the same inode.
+ * If there is no such filename, HV_ENOENT is returned.
+ * A bad filename pointer may result in HV_EFAULT instead.
+ *
+ * @param filename Constant pointer to name of requested file
+ * @return Inode of requested file
+ */
+int hv_fs_findfile(HV_VirtAddr filename);
+
+
+/** Data returned from an fstat request.
+ * Note that this structure should be no more than 40 bytes in size so
+ * that it can always be returned completely in registers.
+ */
+typedef struct
+{
+ int size; /**< Size of file (or HV_Errno on error) */
+ unsigned int flags; /**< Flags (see HV_FS_FSTAT_FLAGS) */
+} HV_FS_StatInfo;
+
+/** Bitmask flags for fstat request */
+typedef enum
+{
+ HV_FS_ISDIR = 0x0001 /**< Is the entry a directory? */
+} HV_FS_FSTAT_FLAGS;
+
+/** Get stat information on a given file inode.
+ *
+ * Return information on the file with the given inode.
+ *
+ * IF the HV_FS_ISDIR bit is set, the "file" is a directory. Reading
+ * it will return NUL-separated filenames (no directory part) relative
+ * to the path to the inode of the directory "file". These can be
+ * appended to the path to the directory "file" after a forward slash
+ * to create additional filenames. Note that it is not required
+ * that all valid paths be decomposable into valid parent directories;
+ * a filesystem may validly have just a few files, none of which have
+ * HV_FS_ISDIR set. However, if clients may wish to enumerate the
+ * files in the filesystem, it is recommended to include all the
+ * appropriate parent directory "files" to give a consistent view.
+ *
+ * An invalid file inode will cause an HV_EBADF error to be returned.
+ *
+ * @param inode The inode number of the query
+ * @return An HV_FS_StatInfo structure
+ */
+HV_FS_StatInfo hv_fs_fstat(int inode);
+
+
+/** Read data from a specific hypervisor file.
+ * On error, may return HV_EBADF for a bad inode or HV_EFAULT for a bad buf.
+ * Reads near the end of the file will return fewer bytes than requested.
+ * Reads at or beyond the end of a file will return zero.
+ *
+ * @param inode the hypervisor file to read
+ * @param buf the buffer to read data into
+ * @param length the number of bytes of data to read
+ * @param offset the offset into the file to read the data from
+ * @return number of bytes successfully read, or an HV_Errno code
+ */
+int hv_fs_pread(int inode, HV_VirtAddr buf, int length, int offset);
+
+
+/** Read a 64-bit word from the specified physical address.
+ * The address must be 8-byte aligned.
+ * Specifying an invalid physical address will lead to client termination.
+ * @param addr The physical address to read
+ * @param access The PTE describing how to read the memory
+ * @return The 64-bit value read from the given address
+ */
+unsigned long long hv_physaddr_read64(HV_PhysAddr addr, HV_PTE access);
+
+
+/** Write a 64-bit word to the specified physical address.
+ * The address must be 8-byte aligned.
+ * Specifying an invalid physical address will lead to client termination.
+ * @param addr The physical address to write
+ * @param access The PTE that says how to write the memory
+ * @param val The 64-bit value to write to the given address
+ */
+void hv_physaddr_write64(HV_PhysAddr addr, HV_PTE access,
+ unsigned long long val);
+
+
+/** Get the value of the command-line for the supervisor, if any.
+ * This will not include the filename of the booted supervisor, but may
+ * include configured-in boot arguments or the hv_restart() arguments.
+ * If the buffer is not long enough the hypervisor will NUL the first
+ * character of the buffer but not write any other data.
+ * @param buf The virtual address to write the command-line string to.
+ * @param length The length of buf, in characters.
+ * @return The actual length of the command line, including the trailing NUL
+ * (may be larger than "length").
+ */
+int hv_get_command_line(HV_VirtAddr buf, int length);
+
+
+/** Set a new value for the command-line for the supervisor, which will
+ * be returned from subsequent invocations of hv_get_command_line() on
+ * this tile.
+ * @param buf The virtual address to read the command-line string from.
+ * @param length The length of buf, in characters; must be no more than
+ * HV_COMMAND_LINE_LEN.
+ * @return Zero if successful, or a hypervisor error code.
+ */
+HV_Errno hv_set_command_line(HV_VirtAddr buf, int length);
+
+/** Maximum size of a command line passed to hv_set_command_line(); note
+ * that a line returned from hv_get_command_line() could be larger than
+ * this.*/
+#define HV_COMMAND_LINE_LEN 256
+
+/** Tell the hypervisor how to cache non-priority pages
+ * (its own as well as pages explicitly represented in page tables).
+ * Normally these will be represented as red/black pages, but
+ * when the supervisor starts to allocate "priority" pages in the PTE
+ * the hypervisor will need to start marking those pages as (e.g.) "red"
+ * and non-priority pages as either "black" (if they cache-alias
+ * with the existing priority pages) or "red/black" (if they don't).
+ * The bitmask provides information on which parts of the cache
+ * have been used for pinned pages so far on this tile; if (1 << N)
+ * appears in the bitmask, that indicates that a page has been marked
+ * "priority" whose PFN equals N, mod 8.
+ * @param bitmask A bitmap of priority page set values
+ */
+void hv_set_caching(unsigned int bitmask);
+
+
+/** Zero out a specified number of pages.
+ * The va and size must both be multiples of 4096.
+ * Caches are bypassed and memory is directly set to zero.
+ * This API is implemented only in the magic hypervisor and is intended
+ * to provide a performance boost to the minimal supervisor by
+ * giving it a fast way to zero memory pages when allocating them.
+ * @param va Virtual address where the page has been mapped
+ * @param size Number of bytes (must be a page size multiple)
+ */
+void hv_bzero_page(HV_VirtAddr va, unsigned int size);
+
+
+/** State object for the hypervisor messaging subsystem. */
+typedef struct
+{
+#if CHIP_VA_WIDTH() > 32
+ __hv64 opaque[2]; /**< No user-serviceable parts inside */
+#else
+ __hv32 opaque[2]; /**< No user-serviceable parts inside */
+#endif
+}
+HV_MsgState;
+
+/** Register to receive incoming messages.
+ *
+ * This routine configures the current tile so that it can receive
+ * incoming messages. It must be called before the client can receive
+ * messages with the hv_receive_message routine, and must be called on
+ * each tile which will receive messages.
+ *
+ * msgstate is the virtual address of a state object of type HV_MsgState.
+ * Once the state is registered, the client must not read or write the
+ * state object; doing so will cause undefined results.
+ *
+ * If this routine is called with msgstate set to 0, the client's message
+ * state will be freed and it will no longer be able to receive messages.
+ * Note that this may cause the loss of any as-yet-undelivered messages
+ * for the client.
+ *
+ * If another client attempts to send a message to a client which has
+ * not yet called hv_register_message_state, or which has freed its
+ * message state, the message will not be delivered, as if the client
+ * had insufficient buffering.
+ *
+ * This routine returns HV_OK if the registration was successful, and
+ * HV_EINVAL if the supplied state object is unsuitable. Note that some
+ * errors may not be detected during this routine, but might be detected
+ * during a subsequent message delivery.
+ * @param msgstate State object.
+ **/
+HV_Errno hv_register_message_state(HV_MsgState* msgstate);
+
+/** Possible message recipient states. */
+typedef enum
+{
+ HV_TO_BE_SENT, /**< Not sent (not attempted, or recipient not ready) */
+ HV_SENT, /**< Successfully sent */
+ HV_BAD_RECIP /**< Bad recipient coordinates (permanent error) */
+} HV_Recip_State;
+
+/** Message recipient. */
+typedef struct
+{
+ /** X coordinate, relative to supervisor's top-left coordinate */
+ unsigned int x:11;
+
+ /** Y coordinate, relative to supervisor's top-left coordinate */
+ unsigned int y:11;
+
+ /** Status of this recipient */
+ HV_Recip_State state:10;
+} HV_Recipient;
+
+/** Send a message to a set of recipients.
+ *
+ * This routine sends a message to a set of recipients.
+ *
+ * recips is an array of HV_Recipient structures. Each specifies a tile,
+ * and a message state; initially, it is expected that the state will
+ * be set to HV_TO_BE_SENT. nrecip specifies the number of recipients
+ * in the recips array.
+ *
+ * For each recipient whose state is HV_TO_BE_SENT, the hypervisor attempts
+ * to send that tile the specified message. In order to successfully
+ * receive the message, the receiver must be a valid tile to which the
+ * sender has access, must not be the sending tile itself, and must have
+ * sufficient free buffer space. (The hypervisor guarantees that each
+ * tile which has called hv_register_message_state() will be able to
+ * buffer one message from every other tile which can legally send to it;
+ * more space may be provided but is not guaranteed.) If an invalid tile
+ * is specified, the recipient's state is set to HV_BAD_RECIP; this is a
+ * permanent delivery error. If the message is successfully delivered
+ * to the recipient's buffer, the recipient's state is set to HV_SENT.
+ * Otherwise, the recipient's state is unchanged. Message delivery is
+ * synchronous; all attempts to send messages are completed before this
+ * routine returns.
+ *
+ * If no permanent delivery errors were encountered, the routine returns
+ * the number of messages successfully sent: that is, the number of
+ * recipients whose states changed from HV_TO_BE_SENT to HV_SENT during
+ * this operation. If any permanent delivery errors were encountered,
+ * the routine returns HV_ERECIP. In the event of permanent delivery
+ * errors, it may be the case that delivery was not attempted to all
+ * recipients; if any messages were succesfully delivered, however,
+ * recipients' state values will be updated appropriately.
+ *
+ * It is explicitly legal to specify a recipient structure whose state
+ * is not HV_TO_BE_SENT; such a recipient is ignored. One suggested way
+ * of using hv_send_message to send a message to multiple tiles is to set
+ * up a list of recipients, and then call the routine repeatedly with the
+ * same list, each time accumulating the number of messages successfully
+ * sent, until all messages are sent, a permanent error is encountered,
+ * or the desired number of attempts have been made. When used in this
+ * way, the routine will deliver each message no more than once to each
+ * recipient.
+ *
+ * Note that a message being successfully delivered to the recipient's
+ * buffer space does not guarantee that it is received by the recipient,
+ * either immediately or at any time in the future; the recipient might
+ * never call hv_receive_message, or could register a different state
+ * buffer, losing the message.
+ *
+ * Specifiying the same recipient more than once in the recipient list
+ * is an error, which will not result in an error return but which may
+ * or may not result in more than one message being delivered to the
+ * recipient tile.
+ *
+ * buf and buflen specify the message to be sent. buf is a virtual address
+ * which must be currently mapped in the client's page table; if not, the
+ * routine returns HV_EFAULT. buflen must be greater than zero and less
+ * than or equal to HV_MAX_MESSAGE_SIZE, and nrecip must be less than the
+ * number of tiles to which the sender has access; if not, the routine
+ * returns HV_EINVAL.
+ * @param recips List of recipients.
+ * @param nrecip Number of recipients.
+ * @param buf Address of message data.
+ * @param buflen Length of message data.
+ **/
+int hv_send_message(HV_Recipient *recips, int nrecip,
+ HV_VirtAddr buf, int buflen);
+
+/** Maximum hypervisor message size, in bytes */
+#define HV_MAX_MESSAGE_SIZE 28
+
+
+/** Return value from hv_receive_message() */
+typedef struct
+{
+ int msglen; /**< Message length in bytes, or an error code */
+ __hv32 source; /**< Code identifying message sender (HV_MSG_xxx) */
+} HV_RcvMsgInfo;
+
+#define HV_MSG_TILE 0x0 /**< Message source is another tile */
+#define HV_MSG_INTR 0x1 /**< Message source is a driver interrupt */
+
+/** Receive a message.
+ *
+ * This routine retrieves a message from the client's incoming message
+ * buffer.
+ *
+ * Multiple messages sent from a particular sending tile to a particular
+ * receiving tile are received in the order that they were sent; however,
+ * no ordering is guaranteed between messages sent by different tiles.
+ *
+ * Whenever the a client's message buffer is empty, the first message
+ * subsequently received will cause the client's MESSAGE_RCV_DWNCL
+ * interrupt vector to be invoked through the interrupt downcall mechanism
+ * (see the description of the hv_downcall_dispatch() routine for details
+ * on downcalls).
+ *
+ * Another message-available downcall will not occur until a call to
+ * this routine is made when the message buffer is empty, and a message
+ * subsequently arrives. Note that such a downcall could occur while
+ * this routine is executing. If the calling code does not wish this
+ * to happen, it is recommended that this routine be called with the
+ * INTCTRL_1 interrupt masked, or inside an interrupt critical section.
+ *
+ * msgstate is the value previously passed to hv_register_message_state().
+ * buf is the virtual address of the buffer into which the message will
+ * be written; buflen is the length of the buffer.
+ *
+ * This routine returns an HV_RcvMsgInfo structure. The msglen member
+ * of that structure is the length of the message received, zero if no
+ * message is available, or HV_E2BIG if the message is too large for the
+ * specified buffer. If the message is too large, it is not consumed,
+ * and may be retrieved by a subsequent call to this routine specifying
+ * a sufficiently large buffer. A buffer which is HV_MAX_MESSAGE_SIZE
+ * bytes long is guaranteed to be able to receive any possible message.
+ *
+ * The source member of the HV_RcvMsgInfo structure describes the sender
+ * of the message. For messages sent by another client tile via an
+ * hv_send_message() call, this value is HV_MSG_TILE; for messages sent
+ * as a result of a device interrupt, this value is HV_MSG_INTR.
+ */
+
+HV_RcvMsgInfo hv_receive_message(HV_MsgState msgstate, HV_VirtAddr buf,
+ int buflen);
+
+
+/** Start remaining tiles owned by this supervisor. Initially, only one tile
+ * executes the client program; after it calls this service, the other tiles
+ * are started. This allows the initial tile to do one-time configuration
+ * of shared data structures without having to lock them against simultaneous
+ * access.
+ */
+void hv_start_all_tiles(void);
+
+
+/** Open a hypervisor device.
+ *
+ * This service initializes an I/O device and its hypervisor driver software,
+ * and makes it available for use. The open operation is per-device per-chip;
+ * once it has been performed, the device handle returned may be used in other
+ * device services calls made by any tile.
+ *
+ * @param name Name of the device. A base device name is just a text string
+ * (say, "pcie"). If there is more than one instance of a device, the
+ * base name is followed by a slash and a device number (say, "pcie/0").
+ * Some devices may support further structure beneath those components;
+ * most notably, devices which require control operations do so by
+ * supporting reads and/or writes to a control device whose name
+ * includes a trailing "/ctl" (say, "pcie/0/ctl").
+ * @param flags Flags (HV_DEV_xxx).
+ * @return A positive integer device handle, or a negative error code.
+ */
+int hv_dev_open(HV_VirtAddr name, __hv32 flags);
+
+
+/** Close a hypervisor device.
+ *
+ * This service uninitializes an I/O device and its hypervisor driver
+ * software, and makes it unavailable for use. The close operation is
+ * per-device per-chip; once it has been performed, the device is no longer
+ * available. Normally there is no need to ever call the close service.
+ *
+ * @param devhdl Device handle of the device to be closed.
+ * @return Zero if the close is successful, otherwise, a negative error code.
+ */
+int hv_dev_close(int devhdl);
+
+
+/** Read data from a hypervisor device synchronously.
+ *
+ * This service transfers data from a hypervisor device to a memory buffer.
+ * When the service returns, the data has been written from the memory buffer,
+ * and the buffer will not be further modified by the driver.
+ *
+ * No ordering is guaranteed between requests issued from different tiles.
+ *
+ * Devices may choose to support both the synchronous and asynchronous read
+ * operations, only one of them, or neither of them.
+ *
+ * @param devhdl Device handle of the device to be read from.
+ * @param flags Flags (HV_DEV_xxx).
+ * @param va Virtual address of the target data buffer. This buffer must
+ * be mapped in the currently installed page table; if not, HV_EFAULT
+ * may be returned.
+ * @param len Number of bytes to be transferred.
+ * @param offset Driver-dependent offset. For a random-access device, this is
+ * often a byte offset from the beginning of the device; in other cases,
+ * like on a control device, it may have a different meaning.
+ * @return A non-negative value if the read was at least partially successful;
+ * otherwise, a negative error code. The precise interpretation of
+ * the return value is driver-dependent, but many drivers will return
+ * the number of bytes successfully transferred.
+ */
+int hv_dev_pread(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
+ __hv64 offset);
+
+#define HV_DEV_NB_EMPTY 0x1 /**< Don't block when no bytes of data can
+ be transferred. */
+#define HV_DEV_NB_PARTIAL 0x2 /**< Don't block when some bytes, but not all
+ of the requested bytes, can be
+ transferred. */
+#define HV_DEV_NOCACHE 0x4 /**< The caller warrants that none of the
+ cache lines which might contain data
+ from the requested buffer are valid.
+ Useful with asynchronous operations
+ only. */
+
+#define HV_DEV_ALLFLAGS (HV_DEV_NB_EMPTY | HV_DEV_NB_PARTIAL | \
+ HV_DEV_NOCACHE) /**< All HV_DEV_xxx flags */
+
+/** Write data to a hypervisor device synchronously.
+ *
+ * This service transfers data from a memory buffer to a hypervisor device.
+ * When the service returns, the data has been read from the memory buffer,
+ * and the buffer may be overwritten by the client; the data may not
+ * necessarily have been conveyed to the actual hardware I/O interface.
+ *
+ * No ordering is guaranteed between requests issued from different tiles.
+ *
+ * Devices may choose to support both the synchronous and asynchronous write
+ * operations, only one of them, or neither of them.
+ *
+ * @param devhdl Device handle of the device to be written to.
+ * @param flags Flags (HV_DEV_xxx).
+ * @param va Virtual address of the source data buffer. This buffer must
+ * be mapped in the currently installed page table; if not, HV_EFAULT
+ * may be returned.
+ * @param len Number of bytes to be transferred.
+ * @param offset Driver-dependent offset. For a random-access device, this is
+ * often a byte offset from the beginning of the device; in other cases,
+ * like on a control device, it may have a different meaning.
+ * @return A non-negative value if the write was at least partially successful;
+ * otherwise, a negative error code. The precise interpretation of
+ * the return value is driver-dependent, but many drivers will return
+ * the number of bytes successfully transferred.
+ */
+int hv_dev_pwrite(int devhdl, __hv32 flags, HV_VirtAddr va, __hv32 len,
+ __hv64 offset);
+
+
+/** Interrupt arguments, used in the asynchronous I/O interfaces. */
+#if CHIP_VA_WIDTH() > 32
+typedef __hv64 HV_IntArg;
+#else
+typedef __hv32 HV_IntArg;
+#endif
+
+/** Interrupt messages are delivered via the mechanism as normal messages,
+ * but have a message source of HV_DEV_INTR. The message is formatted
+ * as an HV_IntrMsg structure.
+ */
+
+typedef struct
+{
+ HV_IntArg intarg; /**< Interrupt argument, passed to the poll/preada/pwritea
+ services */
+ HV_IntArg intdata; /**< Interrupt-specific interrupt data */
+} HV_IntrMsg;
+
+/** Request an interrupt message when a device condition is satisfied.
+ *
+ * This service requests that an interrupt message be delivered to the
+ * requesting tile when a device becomes readable or writable, or when any
+ * data queued to the device via previous write operations from this tile
+ * has been actually sent out on the hardware I/O interface. Devices may
+ * choose to support any, all, or none of the available conditions.
+ *
+ * If multiple conditions are specified, only one message will be
+ * delivered. If the event mask delivered to that interrupt handler
+ * indicates that some of the conditions have not yet occurred, the
+ * client must issue another poll() call if it wishes to wait for those
+ * conditions.
+ *
+ * Only one poll may be outstanding per device handle per tile. If more than
+ * one tile is polling on the same device and condition, they will all be
+ * notified when it happens. Because of this, clients may not assume that
+ * the condition signaled is necessarily still true when they request a
+ * subsequent service; for instance, the readable data which caused the
+ * poll call to interrupt may have been read by another tile in the interim.
+ *
+ * The notification interrupt message could come directly, or via the
+ * downcall (intctrl1) method, depending on what the tile is doing
+ * when the condition is satisfied. Note that it is possible for the
+ * requested interrupt to be delivered after this service is called but
+ * before it returns.
+ *
+ * @param devhdl Device handle of the device to be polled.
+ * @param events Flags denoting the events which will cause the interrupt to
+ * be delivered (HV_DEVPOLL_xxx).
+ * @param intarg Value which will be delivered as the intarg member of the
+ * eventual interrupt message; the intdata member will be set to a
+ * mask of HV_DEVPOLL_xxx values indicating which conditions have been
+ * satisifed.
+ * @return Zero if the interrupt was successfully scheduled; otherwise, a
+ * negative error code.
+ */
+int hv_dev_poll(int devhdl, __hv32 events, HV_IntArg intarg);
+
+#define HV_DEVPOLL_READ 0x1 /**< Test device for readability */
+#define HV_DEVPOLL_WRITE 0x2 /**< Test device for writability */
+#define HV_DEVPOLL_FLUSH 0x4 /**< Test device for output drained */
+
+
+/** Cancel a request for an interrupt when a device event occurs.
+ *
+ * This service requests that no interrupt be delivered when the events
+ * noted in the last-issued poll() call happen. Once this service returns,
+ * the interrupt has been canceled; however, it is possible for the interrupt
+ * to be delivered after this service is called but before it returns.
+ *
+ * @param devhdl Device handle of the device on which to cancel polling.
+ * @return Zero if the poll was successfully canceled; otherwise, a negative
+ * error code.
+ */
+int hv_dev_poll_cancel(int devhdl);
+
+
+/** Scatter-gather list for preada/pwritea calls. */
+typedef struct
+#if CHIP_VA_WIDTH() <= 32
+__attribute__ ((packed, aligned(4)))
+#endif
+{
+ HV_PhysAddr pa; /**< Client physical address of the buffer segment. */
+ HV_PTE pte; /**< Page table entry describing the caching and location
+ override characteristics of the buffer segment. Some
+ drivers ignore this element and will require that
+ the NOCACHE flag be set on their requests. */
+ __hv32 len; /**< Length of the buffer segment. */
+} HV_SGL;
+
+#define HV_SGL_MAXLEN 16 /**< Maximum number of entries in a scatter-gather
+ list */
+
+/** Read data from a hypervisor device asynchronously.
+ *
+ * This service transfers data from a hypervisor device to a memory buffer.
+ * When the service returns, the read has been scheduled. When the read
+ * completes, an interrupt message will be delivered, and the buffer will
+ * not be further modified by the driver.
+ *
+ * The number of possible outstanding asynchronous requests is defined by
+ * each driver, but it is recommended that it be at least two requests
+ * per tile per device.
+ *
+ * No ordering is guaranteed between synchronous and asynchronous requests,
+ * even those issued on the same tile.
+ *
+ * The completion interrupt message could come directly, or via the downcall
+ * (intctrl1) method, depending on what the tile is doing when the read
+ * completes. Interrupts do not coalesce; one is delivered for each
+ * asynchronous I/O request. Note that it is possible for the requested
+ * interrupt to be delivered after this service is called but before it
+ * returns.
+ *
+ * Devices may choose to support both the synchronous and asynchronous read
+ * operations, only one of them, or neither of them.
+ *
+ * @param devhdl Device handle of the device to be read from.
+ * @param flags Flags (HV_DEV_xxx).
+ * @param sgl_len Number of elements in the scatter-gather list.
+ * @param sgl Scatter-gather list describing the memory to which data will be
+ * written.
+ * @param offset Driver-dependent offset. For a random-access device, this is
+ * often a byte offset from the beginning of the device; in other cases,
+ * like on a control device, it may have a different meaning.
+ * @param intarg Value which will be delivered as the intarg member of the
+ * eventual interrupt message; the intdata member will be set to the
+ * normal return value from the read request.
+ * @return Zero if the read was successfully scheduled; otherwise, a negative
+ * error code. Note that some drivers may choose to pre-validate
+ * their arguments, and may thus detect certain device error
+ * conditions at this time rather than when the completion notification
+ * occurs, but this is not required.
+ */
+int hv_dev_preada(int devhdl, __hv32 flags, __hv32 sgl_len,
+ HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
+
+
+/** Write data to a hypervisor device asynchronously.
+ *
+ * This service transfers data from a memory buffer to a hypervisor
+ * device. When the service returns, the write has been scheduled.
+ * When the write completes, an interrupt message will be delivered,
+ * and the buffer may be overwritten by the client; the data may not
+ * necessarily have been conveyed to the actual hardware I/O interface.
+ *
+ * The number of possible outstanding asynchronous requests is defined by
+ * each driver, but it is recommended that it be at least two requests
+ * per tile per device.
+ *
+ * No ordering is guaranteed between synchronous and asynchronous requests,
+ * even those issued on the same tile.
+ *
+ * The completion interrupt message could come directly, or via the downcall
+ * (intctrl1) method, depending on what the tile is doing when the read
+ * completes. Interrupts do not coalesce; one is delivered for each
+ * asynchronous I/O request. Note that it is possible for the requested
+ * interrupt to be delivered after this service is called but before it
+ * returns.
+ *
+ * Devices may choose to support both the synchronous and asynchronous write
+ * operations, only one of them, or neither of them.
+ *
+ * @param devhdl Device handle of the device to be read from.
+ * @param flags Flags (HV_DEV_xxx).
+ * @param sgl_len Number of elements in the scatter-gather list.
+ * @param sgl Scatter-gather list describing the memory from which data will be
+ * read.
+ * @param offset Driver-dependent offset. For a random-access device, this is
+ * often a byte offset from the beginning of the device; in other cases,
+ * like on a control device, it may have a different meaning.
+ * @param intarg Value which will be delivered as the intarg member of the
+ * eventual interrupt message; the intdata member will be set to the
+ * normal return value from the write request.
+ * @return Zero if the write was successfully scheduled; otherwise, a negative
+ * error code. Note that some drivers may choose to pre-validate
+ * their arguments, and may thus detect certain device error
+ * conditions at this time rather than when the completion notification
+ * occurs, but this is not required.
+ */
+int hv_dev_pwritea(int devhdl, __hv32 flags, __hv32 sgl_len,
+ HV_SGL sgl[/* sgl_len */], __hv64 offset, HV_IntArg intarg);
+
+
+/** Define a pair of tile and ASID to identify a user process context. */
+typedef struct
+{
+ /** X coordinate, relative to supervisor's top-left coordinate */
+ unsigned int x:11;
+
+ /** Y coordinate, relative to supervisor's top-left coordinate */
+ unsigned int y:11;
+
+ /** ASID of the process on this x,y tile */
+ HV_ASID asid:10;
+} HV_Remote_ASID;
+
+/** Flush cache and/or TLB state on remote tiles.
+ *
+ * @param cache_pa Client physical address to flush from cache (ignored if
+ * the length encoded in cache_control is zero, or if
+ * HV_FLUSH_EVICT_L2 is set, or if cache_cpumask is NULL).
+ * @param cache_control This argument allows you to specify a length of
+ * physical address space to flush (maximum HV_FLUSH_MAX_CACHE_LEN).
+ * You can "or" in HV_FLUSH_EVICT_L2 to flush the whole L2 cache.
+ * You can "or" in HV_FLUSH_EVICT_LI1 to flush the whole LII cache.
+ * HV_FLUSH_ALL flushes all caches.
+ * @param cache_cpumask Bitmask (in row-major order, supervisor-relative) of
+ * tile indices to perform cache flush on. The low bit of the first
+ * word corresponds to the tile at the upper left-hand corner of the
+ * supervisor's rectangle. If passed as a NULL pointer, equivalent
+ * to an empty bitmask. On chips which support hash-for-home caching,
+ * if passed as -1, equivalent to a mask containing tiles which could
+ * be doing hash-for-home caching.
+ * @param tlb_va Virtual address to flush from TLB (ignored if
+ * tlb_length is zero or tlb_cpumask is NULL).
+ * @param tlb_length Number of bytes of data to flush from the TLB.
+ * @param tlb_pgsize Page size to use for TLB flushes.
+ * tlb_va and tlb_length need not be aligned to this size.
+ * @param tlb_cpumask Bitmask for tlb flush, like cache_cpumask.
+ * If passed as a NULL pointer, equivalent to an empty bitmask.
+ * @param asids Pointer to an HV_Remote_ASID array of tile/ASID pairs to flush.
+ * @param asidcount Number of HV_Remote_ASID entries in asids[].
+ * @return Zero for success, or else HV_EINVAL or HV_EFAULT for errors that
+ * are detected while parsing the arguments.
+ */
+int hv_flush_remote(HV_PhysAddr cache_pa, unsigned long cache_control,
+ unsigned long* cache_cpumask,
+ HV_VirtAddr tlb_va, unsigned long tlb_length,
+ unsigned long tlb_pgsize, unsigned long* tlb_cpumask,
+ HV_Remote_ASID* asids, int asidcount);
+
+/** Include in cache_control to ensure a flush of the entire L2. */
+#define HV_FLUSH_EVICT_L2 (1UL << 31)
+
+/** Include in cache_control to ensure a flush of the entire L1I. */
+#define HV_FLUSH_EVICT_L1I (1UL << 30)
+
+/** Maximum legal size to use for the "length" component of cache_control. */
+#define HV_FLUSH_MAX_CACHE_LEN ((1UL << 30) - 1)
+
+/** Use for cache_control to ensure a flush of all caches. */
+#define HV_FLUSH_ALL -1UL
+
+#else /* __ASSEMBLER__ */
+
+/** Include in cache_control to ensure a flush of the entire L2. */
+#define HV_FLUSH_EVICT_L2 (1 << 31)
+
+/** Include in cache_control to ensure a flush of the entire L1I. */
+#define HV_FLUSH_EVICT_L1I (1 << 30)
+
+/** Maximum legal size to use for the "length" component of cache_control. */
+#define HV_FLUSH_MAX_CACHE_LEN ((1 << 30) - 1)
+
+/** Use for cache_control to ensure a flush of all caches. */
+#define HV_FLUSH_ALL -1
+
+#endif /* __ASSEMBLER__ */
+
+#ifndef __ASSEMBLER__
+
+/** Return a 64-bit value corresponding to the PTE if needed */
+#define hv_pte_val(pte) ((pte).val)
+
+/** Cast a 64-bit value to an HV_PTE */
+#define hv_pte(val) ((HV_PTE) { val })
+
+#endif /* !__ASSEMBLER__ */
+
+
+/** Bits in the size of an HV_PTE */
+#define HV_LOG2_PTE_SIZE 3
+
+/** Size of an HV_PTE */
+#define HV_PTE_SIZE (1 << HV_LOG2_PTE_SIZE)
+
+
+/* Bits in HV_PTE's low word. */
+#define HV_PTE_INDEX_PRESENT 0 /**< PTE is valid */
+#define HV_PTE_INDEX_MIGRATING 1 /**< Page is migrating */
+#define HV_PTE_INDEX_CLIENT0 2 /**< Page client state 0 */
+#define HV_PTE_INDEX_CLIENT1 3 /**< Page client state 1 */
+#define HV_PTE_INDEX_NC 4 /**< L1$/L2$ incoherent with L3$ */
+#define HV_PTE_INDEX_NO_ALLOC_L1 5 /**< Page is uncached in local L1$ */
+#define HV_PTE_INDEX_NO_ALLOC_L2 6 /**< Page is uncached in local L2$ */
+#define HV_PTE_INDEX_CACHED_PRIORITY 7 /**< Page is priority cached */
+#define HV_PTE_INDEX_PAGE 8 /**< PTE describes a page */
+#define HV_PTE_INDEX_GLOBAL 9 /**< Page is global */
+#define HV_PTE_INDEX_USER 10 /**< Page is user-accessible */
+#define HV_PTE_INDEX_ACCESSED 11 /**< Page has been accessed */
+#define HV_PTE_INDEX_DIRTY 12 /**< Page has been written */
+ /* Bits 13-15 are reserved for
+ future use. */
+#define HV_PTE_INDEX_MODE 16 /**< Page mode; see HV_PTE_MODE_xxx */
+#define HV_PTE_MODE_BITS 3 /**< Number of bits in mode */
+ /* Bit 19 is reserved for
+ future use. */
+#define HV_PTE_INDEX_LOTAR 20 /**< Page's LOTAR; must be high bits
+ of word */
+#define HV_PTE_LOTAR_BITS 12 /**< Number of bits in a LOTAR */
+
+/* Bits in HV_PTE's high word. */
+#define HV_PTE_INDEX_READABLE 32 /**< Page is readable */
+#define HV_PTE_INDEX_WRITABLE 33 /**< Page is writable */
+#define HV_PTE_INDEX_EXECUTABLE 34 /**< Page is executable */
+#define HV_PTE_INDEX_PTFN 35 /**< Page's PTFN; must be high bits
+ of word */
+#define HV_PTE_PTFN_BITS 29 /**< Number of bits in a PTFN */
+
+/** Position of the PFN field within the PTE (subset of the PTFN). */
+#define HV_PTE_INDEX_PFN (HV_PTE_INDEX_PTFN + (HV_LOG2_PAGE_SIZE_SMALL - \
+ HV_LOG2_PAGE_TABLE_ALIGN))
+
+/** Length of the PFN field within the PTE (subset of the PTFN). */
+#define HV_PTE_INDEX_PFN_BITS (HV_PTE_INDEX_PTFN_BITS - \
+ (HV_LOG2_PAGE_SIZE_SMALL - \
+ HV_LOG2_PAGE_TABLE_ALIGN))
+
+/*
+ * Legal values for the PTE's mode field
+ */
+/** Data is not resident in any caches; loads and stores access memory
+ * directly.
+ */
+#define HV_PTE_MODE_UNCACHED 1
+
+/** Data is resident in the tile's local L1 and/or L2 caches; if a load
+ * or store misses there, it goes to memory.
+ *
+ * The copy in the local L1$/L2$ is not invalidated when the copy in
+ * memory is changed.
+ */
+#define HV_PTE_MODE_CACHE_NO_L3 2
+
+/** Data is resident in the tile's local L1 and/or L2 caches. If a load
+ * or store misses there, it goes to an L3 cache in a designated tile;
+ * if it misses there, it goes to memory.
+ *
+ * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
+ * when the copy in the remote L3$ is changed. Otherwise, such
+ * invalidation will not occur.
+ *
+ * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
+ * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
+ * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
+ */
+#define HV_PTE_MODE_CACHE_TILE_L3 3
+
+/** Data is resident in the tile's local L1 and/or L2 caches. If a load
+ * or store misses there, it goes to an L3 cache in one of a set of
+ * designated tiles; if it misses there, it goes to memory. Which tile
+ * is chosen from the set depends upon a hash function applied to the
+ * physical address. This mode is not supported on chips for which
+ * CHIP_HAS_CBOX_HOME_MAP() is 0.
+ *
+ * If the NC bit is not set, the copy in the local L1$/L2$ is invalidated
+ * when the copy in the remote L3$ is changed. Otherwise, such
+ * invalidation will not occur.
+ *
+ * Chips for which CHIP_HAS_COHERENT_LOCAL_CACHE() is 0 do not support
+ * invalidation from an L3$ to another tile's L1$/L2$. If the NC bit is
+ * clear on such a chip, no copy is kept in the local L1$/L2$ in this mode.
+ */
+#define HV_PTE_MODE_CACHE_HASH_L3 4
+
+/** Data is not resident in memory; accesses are instead made to an I/O
+ * device, whose tile coordinates are given by the PTE's LOTAR field.
+ * This mode is only supported on chips for which CHIP_HAS_MMIO() is 1.
+ * The EXECUTABLE bit may not be set in an MMIO PTE.
+ */
+#define HV_PTE_MODE_MMIO 5
+
+
+/* C wants 1ULL so it is typed as __hv64, but the assembler needs just numbers.
+ * The assembler can't handle shifts greater than 31, but treats them
+ * as shifts mod 32, so assembler code must be aware of which word
+ * the bit belongs in when using these macros.
+ */
+#ifdef __ASSEMBLER__
+#define __HV_PTE_ONE 1 /**< One, for assembler */
+#else
+#define __HV_PTE_ONE 1ULL /**< One, for C */
+#endif
+
+/** Is this PTE present?
+ *
+ * If this bit is set, this PTE represents a valid translation or level-2
+ * page table pointer. Otherwise, the page table does not contain a
+ * translation for the subject virtual pages.
+ *
+ * If this bit is not set, the other bits in the PTE are not
+ * interpreted by the hypervisor, and may contain any value.
+ */
+#define HV_PTE_PRESENT (__HV_PTE_ONE << HV_PTE_INDEX_PRESENT)
+
+/** Does this PTE map a page?
+ *
+ * If this bit is set in the level-1 page table, the entry should be
+ * interpreted as a level-2 page table entry mapping a large page.
+ *
+ * This bit should not be modified by the client while PRESENT is set, as
+ * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
+ *
+ * In a level-2 page table, this bit is ignored and must be zero.
+ */
+#define HV_PTE_PAGE (__HV_PTE_ONE << HV_PTE_INDEX_PAGE)
+
+/** Is this a global (non-ASID) mapping?
+ *
+ * If this bit is set, the translations established by this PTE will
+ * not be flushed from the TLB by the hv_flush_asid() service; they
+ * will be flushed by the hv_flush_page() or hv_flush_pages() services.
+ *
+ * Setting this bit for translations which are identical in all page
+ * tables (for instance, code and data belonging to a client OS) can
+ * be very beneficial, as it will reduce the number of TLB misses.
+ * Note that, while it is not an error which will be detected by the
+ * hypervisor, it is an extremely bad idea to set this bit for
+ * translations which are _not_ identical in all page tables.
+ *
+ * This bit should not be modified by the client while PRESENT is set, as
+ * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_GLOBAL (__HV_PTE_ONE << HV_PTE_INDEX_GLOBAL)
+
+/** Is this mapping accessible to users?
+ *
+ * If this bit is set, code running at any PL will be permitted to
+ * access the virtual addresses mapped by this PTE. Otherwise, only
+ * code running at PL 1 or above will be allowed to do so.
+ *
+ * This bit should not be modified by the client while PRESENT is set, as
+ * doing so may race with the hypervisor's update of ACCESSED and DIRTY bits.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_USER (__HV_PTE_ONE << HV_PTE_INDEX_USER)
+
+/** Has this mapping been accessed?
+ *
+ * This bit is set by the hypervisor when the memory described by the
+ * translation is accessed for the first time. It is never cleared by
+ * the hypervisor, but may be cleared by the client. After the bit
+ * has been cleared, subsequent references are not guaranteed to set
+ * it again until the translation has been flushed from the TLB.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_ACCESSED (__HV_PTE_ONE << HV_PTE_INDEX_ACCESSED)
+
+/** Is this mapping dirty?
+ *
+ * This bit is set by the hypervisor when the memory described by the
+ * translation is written for the first time. It is never cleared by
+ * the hypervisor, but may be cleared by the client. After the bit
+ * has been cleared, subsequent references are not guaranteed to set
+ * it again until the translation has been flushed from the TLB.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_DIRTY (__HV_PTE_ONE << HV_PTE_INDEX_DIRTY)
+
+/** Migrating bit in PTE.
+ *
+ * This bit is guaranteed not to be inspected or modified by the
+ * hypervisor. The name is indicative of the suggested use by the client
+ * to tag pages whose L3 cache is being migrated from one cpu to another.
+ */
+#define HV_PTE_MIGRATING (__HV_PTE_ONE << HV_PTE_INDEX_MIGRATING)
+
+/** Client-private bit in PTE.
+ *
+ * This bit is guaranteed not to be inspected or modified by the
+ * hypervisor.
+ */
+#define HV_PTE_CLIENT0 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT0)
+
+/** Client-private bit in PTE.
+ *
+ * This bit is guaranteed not to be inspected or modified by the
+ * hypervisor.
+ */
+#define HV_PTE_CLIENT1 (__HV_PTE_ONE << HV_PTE_INDEX_CLIENT1)
+
+/** Non-coherent (NC) bit in PTE.
+ *
+ * If this bit is set, the mapping that is set up will be non-coherent
+ * (also known as non-inclusive). This means that changes to the L3
+ * cache will not cause a local copy to be invalidated. It is generally
+ * recommended only for read-only mappings.
+ *
+ * In level-1 PTEs, if the Page bit is clear, this bit determines how the
+ * level-2 page table is accessed.
+ */
+#define HV_PTE_NC (__HV_PTE_ONE << HV_PTE_INDEX_NC)
+
+/** Is this page prevented from filling the L1$?
+ *
+ * If this bit is set, the page described by the PTE will not be cached
+ * the local cpu's L1 cache.
+ *
+ * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
+ * it is illegal to use this attribute, and may cause client termination.
+ *
+ * In level-1 PTEs, if the Page bit is clear, this bit
+ * determines how the level-2 page table is accessed.
+ */
+#define HV_PTE_NO_ALLOC_L1 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L1)
+
+/** Is this page prevented from filling the L2$?
+ *
+ * If this bit is set, the page described by the PTE will not be cached
+ * the local cpu's L2 cache.
+ *
+ * If CHIP_HAS_NC_AND_NOALLOC_BITS() is not true in <chip.h> for this chip,
+ * it is illegal to use this attribute, and may cause client termination.
+ *
+ * In level-1 PTEs, if the Page bit is clear, this bit determines how the
+ * level-2 page table is accessed.
+ */
+#define HV_PTE_NO_ALLOC_L2 (__HV_PTE_ONE << HV_PTE_INDEX_NO_ALLOC_L2)
+
+/** Is this a priority page?
+ *
+ * If this bit is set, the page described by the PTE will be given
+ * priority in the cache. Normally this translates into allowing the
+ * page to use only the "red" half of the cache. The client may wish to
+ * then use the hv_set_caching service to specify that other pages which
+ * alias this page will use only the "black" half of the cache.
+ *
+ * If the Cached Priority bit is clear, the hypervisor uses the
+ * current hv_set_caching() value to choose how to cache the page.
+ *
+ * It is illegal to set the Cached Priority bit if the Non-Cached bit
+ * is set and the Cached Remotely bit is clear, i.e. if requests to
+ * the page map directly to memory.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_CACHED_PRIORITY (__HV_PTE_ONE << \
+ HV_PTE_INDEX_CACHED_PRIORITY)
+
+/** Is this a readable mapping?
+ *
+ * If this bit is set, code will be permitted to read from (e.g.,
+ * issue load instructions against) the virtual addresses mapped by
+ * this PTE.
+ *
+ * It is illegal for this bit to be clear if the Writable bit is set.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_READABLE (__HV_PTE_ONE << HV_PTE_INDEX_READABLE)
+
+/** Is this a writable mapping?
+ *
+ * If this bit is set, code will be permitted to write to (e.g., issue
+ * store instructions against) the virtual addresses mapped by this
+ * PTE.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_WRITABLE (__HV_PTE_ONE << HV_PTE_INDEX_WRITABLE)
+
+/** Is this an executable mapping?
+ *
+ * If this bit is set, code will be permitted to execute from
+ * (e.g., jump to) the virtual addresses mapped by this PTE.
+ *
+ * This bit applies to any processor on the tile, if there are more
+ * than one.
+ *
+ * This bit is ignored in level-1 PTEs unless the Page bit is set.
+ */
+#define HV_PTE_EXECUTABLE (__HV_PTE_ONE << HV_PTE_INDEX_EXECUTABLE)
+
+/** The width of a LOTAR's x or y bitfield. */
+#define HV_LOTAR_WIDTH 11
+
+/** Converts an x,y pair to a LOTAR value. */
+#define HV_XY_TO_LOTAR(x, y) ((HV_LOTAR)(((x) << HV_LOTAR_WIDTH) | (y)))
+
+/** Extracts the X component of a lotar. */
+#define HV_LOTAR_X(lotar) ((lotar) >> HV_LOTAR_WIDTH)
+
+/** Extracts the Y component of a lotar. */
+#define HV_LOTAR_Y(lotar) ((lotar) & ((1 << HV_LOTAR_WIDTH) - 1))
+
+#ifndef __ASSEMBLER__
+
+/** Define accessor functions for a PTE bit. */
+#define _HV_BIT(name, bit) \
+static __inline int \
+hv_pte_get_##name(HV_PTE pte) \
+{ \
+ return (pte.val >> HV_PTE_INDEX_##bit) & 1; \
+} \
+ \
+static __inline HV_PTE \
+hv_pte_set_##name(HV_PTE pte) \
+{ \
+ pte.val |= 1ULL << HV_PTE_INDEX_##bit; \
+ return pte; \
+} \
+ \
+static __inline HV_PTE \
+hv_pte_clear_##name(HV_PTE pte) \
+{ \
+ pte.val &= ~(1ULL << HV_PTE_INDEX_##bit); \
+ return pte; \
+}
+
+/* Generate accessors to get, set, and clear various PTE flags.
+ */
+_HV_BIT(present, PRESENT)
+_HV_BIT(page, PAGE)
+_HV_BIT(client0, CLIENT0)
+_HV_BIT(client1, CLIENT1)
+_HV_BIT(migrating, MIGRATING)
+_HV_BIT(nc, NC)
+_HV_BIT(readable, READABLE)
+_HV_BIT(writable, WRITABLE)
+_HV_BIT(executable, EXECUTABLE)
+_HV_BIT(accessed, ACCESSED)
+_HV_BIT(dirty, DIRTY)
+_HV_BIT(no_alloc_l1, NO_ALLOC_L1)
+_HV_BIT(no_alloc_l2, NO_ALLOC_L2)
+_HV_BIT(cached_priority, CACHED_PRIORITY)
+_HV_BIT(global, GLOBAL)
+_HV_BIT(user, USER)
+
+#undef _HV_BIT
+
+/** Get the page mode from the PTE.
+ *
+ * This field generally determines whether and how accesses to the page
+ * are cached; the HV_PTE_MODE_xxx symbols define the legal values for the
+ * page mode. The NC, NO_ALLOC_L1, and NO_ALLOC_L2 bits modify this
+ * general policy.
+ */
+static __inline unsigned int
+hv_pte_get_mode(const HV_PTE pte)
+{
+ return (((__hv32) pte.val) >> HV_PTE_INDEX_MODE) &
+ ((1 << HV_PTE_MODE_BITS) - 1);
+}
+
+/** Set the page mode into a PTE. See hv_pte_get_mode. */
+static __inline HV_PTE
+hv_pte_set_mode(HV_PTE pte, unsigned int val)
+{
+ pte.val &= ~(((1ULL << HV_PTE_MODE_BITS) - 1) << HV_PTE_INDEX_MODE);
+ pte.val |= val << HV_PTE_INDEX_MODE;
+ return pte;
+}
+
+/** Get the page frame number from the PTE.
+ *
+ * This field contains the upper bits of the CPA (client physical
+ * address) of the target page; the complete CPA is this field with
+ * HV_LOG2_PAGE_SIZE_SMALL zero bits appended to it.
+ *
+ * For PTEs in a level-1 page table where the Page bit is set, the
+ * CPA must be aligned modulo the large page size.
+ */
+static __inline unsigned int
+hv_pte_get_pfn(const HV_PTE pte)
+{
+ return pte.val >> HV_PTE_INDEX_PFN;
+}
+
+
+/** Set the page frame number into a PTE. See hv_pte_get_pfn. */
+static __inline HV_PTE
+hv_pte_set_pfn(HV_PTE pte, unsigned int val)
+{
+ /*
+ * Note that the use of "PTFN" in the next line is intentional; we
+ * don't want any garbage lower bits left in that field.
+ */
+ pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS) - 1) << HV_PTE_INDEX_PTFN);
+ pte.val |= (__hv64) val << HV_PTE_INDEX_PFN;
+ return pte;
+}
+
+/** Get the page table frame number from the PTE.
+ *
+ * This field contains the upper bits of the CPA (client physical
+ * address) of the target page table; the complete CPA is this field with
+ * with HV_PAGE_TABLE_ALIGN zero bits appended to it.
+ *
+ * For PTEs in a level-1 page table when the Page bit is not set, the
+ * CPA must be aligned modulo the sticter of HV_PAGE_TABLE_ALIGN and
+ * the level-2 page table size.
+ */
+static __inline unsigned long
+hv_pte_get_ptfn(const HV_PTE pte)
+{
+ return pte.val >> HV_PTE_INDEX_PTFN;
+}
+
+
+/** Set the page table frame number into a PTE. See hv_pte_get_ptfn. */
+static __inline HV_PTE
+hv_pte_set_ptfn(HV_PTE pte, unsigned long val)
+{
+ pte.val &= ~(((1ULL << HV_PTE_PTFN_BITS)-1) << HV_PTE_INDEX_PTFN);
+ pte.val |= (__hv64) val << HV_PTE_INDEX_PTFN;
+ return pte;
+}
+
+
+/** Get the remote tile caching this page.
+ *
+ * Specifies the remote tile which is providing the L3 cache for this page.
+ *
+ * This field is ignored unless the page mode is HV_PTE_MODE_CACHE_TILE_L3.
+ *
+ * In level-1 PTEs, if the Page bit is clear, this field determines how the
+ * level-2 page table is accessed.
+ */
+static __inline unsigned int
+hv_pte_get_lotar(const HV_PTE pte)
+{
+ unsigned int lotar = ((__hv32) pte.val) >> HV_PTE_INDEX_LOTAR;
+
+ return HV_XY_TO_LOTAR( (lotar >> (HV_PTE_LOTAR_BITS / 2)),
+ (lotar & ((1 << (HV_PTE_LOTAR_BITS / 2)) - 1)) );
+}
+
+
+/** Set the remote tile caching a page into a PTE. See hv_pte_get_lotar. */
+static __inline HV_PTE
+hv_pte_set_lotar(HV_PTE pte, unsigned int val)
+{
+ unsigned int x = HV_LOTAR_X(val);
+ unsigned int y = HV_LOTAR_Y(val);
+
+ pte.val &= ~(((1ULL << HV_PTE_LOTAR_BITS)-1) << HV_PTE_INDEX_LOTAR);
+ pte.val |= (x << (HV_PTE_INDEX_LOTAR + HV_PTE_LOTAR_BITS / 2)) |
+ (y << HV_PTE_INDEX_LOTAR);
+ return pte;
+}
+
+#endif /* !__ASSEMBLER__ */
+
+/** Converts a client physical address to a pfn. */
+#define HV_CPA_TO_PFN(p) ((p) >> HV_LOG2_PAGE_SIZE_SMALL)
+
+/** Converts a pfn to a client physical address. */
+#define HV_PFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_SIZE_SMALL)
+
+/** Converts a client physical address to a ptfn. */
+#define HV_CPA_TO_PTFN(p) ((p) >> HV_LOG2_PAGE_TABLE_ALIGN)
+
+/** Converts a ptfn to a client physical address. */
+#define HV_PTFN_TO_CPA(p) (((HV_PhysAddr)(p)) << HV_LOG2_PAGE_TABLE_ALIGN)
+
+/** Converts a ptfn to a pfn. */
+#define HV_PTFN_TO_PFN(p) \
+ ((p) >> (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
+
+/** Converts a pfn to a ptfn. */
+#define HV_PFN_TO_PTFN(p) \
+ ((p) << (HV_LOG2_PAGE_SIZE_SMALL - HV_LOG2_PAGE_TABLE_ALIGN))
+
+#if CHIP_VA_WIDTH() > 32
+
+/** Log number of HV_PTE entries in L0 page table */
+#define HV_LOG2_L0_ENTRIES (CHIP_VA_WIDTH() - HV_LOG2_L1_SPAN)
+
+/** Number of HV_PTE entries in L0 page table */
+#define HV_L0_ENTRIES (1 << HV_LOG2_L0_ENTRIES)
+
+/** Log size of L0 page table in bytes */
+#define HV_LOG2_L0_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L0_ENTRIES)
+
+/** Size of L0 page table in bytes */
+#define HV_L0_SIZE (1 << HV_LOG2_L0_SIZE)
+
+#ifdef __ASSEMBLER__
+
+/** Index in L0 for a specific VA */
+#define HV_L0_INDEX(va) \
+ (((va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
+
+#else
+
+/** Index in L1 for a specific VA */
+#define HV_L0_INDEX(va) \
+ (((HV_VirtAddr)(va) >> HV_LOG2_L1_SPAN) & (HV_L0_ENTRIES - 1))
+
+#endif
+
+#endif /* CHIP_VA_WIDTH() > 32 */
+
+/** Log number of HV_PTE entries in L1 page table */
+#define HV_LOG2_L1_ENTRIES (HV_LOG2_L1_SPAN - HV_LOG2_PAGE_SIZE_LARGE)
+
+/** Number of HV_PTE entries in L1 page table */
+#define HV_L1_ENTRIES (1 << HV_LOG2_L1_ENTRIES)
+
+/** Log size of L1 page table in bytes */
+#define HV_LOG2_L1_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L1_ENTRIES)
+
+/** Size of L1 page table in bytes */
+#define HV_L1_SIZE (1 << HV_LOG2_L1_SIZE)
+
+/** Log number of HV_PTE entries in level-2 page table */
+#define HV_LOG2_L2_ENTRIES (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL)
+
+/** Number of HV_PTE entries in level-2 page table */
+#define HV_L2_ENTRIES (1 << HV_LOG2_L2_ENTRIES)
+
+/** Log size of level-2 page table in bytes */
+#define HV_LOG2_L2_SIZE (HV_LOG2_PTE_SIZE + HV_LOG2_L2_ENTRIES)
+
+/** Size of level-2 page table in bytes */
+#define HV_L2_SIZE (1 << HV_LOG2_L2_SIZE)
+
+#ifdef __ASSEMBLER__
+
+#if CHIP_VA_WIDTH() > 32
+
+/** Index in L1 for a specific VA */
+#define HV_L1_INDEX(va) \
+ (((va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
+
+#else /* CHIP_VA_WIDTH() > 32 */
+
+/** Index in L1 for a specific VA */
+#define HV_L1_INDEX(va) \
+ (((va) >> HV_LOG2_PAGE_SIZE_LARGE))
+
+#endif /* CHIP_VA_WIDTH() > 32 */
+
+/** Index in level-2 page table for a specific VA */
+#define HV_L2_INDEX(va) \
+ (((va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
+
+#else /* __ASSEMBLER __ */
+
+#if CHIP_VA_WIDTH() > 32
+
+/** Index in L1 for a specific VA */
+#define HV_L1_INDEX(va) \
+ (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE) & (HV_L1_ENTRIES - 1))
+
+#else /* CHIP_VA_WIDTH() > 32 */
+
+/** Index in L1 for a specific VA */
+#define HV_L1_INDEX(va) \
+ (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_LARGE))
+
+#endif /* CHIP_VA_WIDTH() > 32 */
+
+/** Index in level-2 page table for a specific VA */
+#define HV_L2_INDEX(va) \
+ (((HV_VirtAddr)(va) >> HV_LOG2_PAGE_SIZE_SMALL) & (HV_L2_ENTRIES - 1))
+
+#endif /* __ASSEMBLER __ */
+
+#endif /* _TILE_HV_H */
diff --git a/arch/tile/include/hv/pagesize.h b/arch/tile/include/hv/pagesize.h
new file mode 100644
index 000000000000..58bed114fedd
--- /dev/null
+++ b/arch/tile/include/hv/pagesize.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/**
+ * @file pagesize.h
+ */
+
+#ifndef _HV_PAGESIZE_H
+#define _HV_PAGESIZE_H
+
+/** The log2 of the size of small pages, in bytes. This value should
+ * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
+ */
+#define HV_LOG2_PAGE_SIZE_SMALL 16
+
+/** The log2 of the size of large pages, in bytes. This value should be
+ * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
+ */
+#define HV_LOG2_PAGE_SIZE_LARGE 24
+
+#endif /* _HV_PAGESIZE_H */
diff --git a/arch/tile/include/hv/syscall_public.h b/arch/tile/include/hv/syscall_public.h
new file mode 100644
index 000000000000..9cc0837e69fd
--- /dev/null
+++ b/arch/tile/include/hv/syscall_public.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/**
+ * @file syscall.h
+ * Indices for the hypervisor system calls that are intended to be called
+ * directly, rather than only through hypervisor-generated "glue" code.
+ */
+
+#ifndef _SYS_HV_INCLUDE_SYSCALL_PUBLIC_H
+#define _SYS_HV_INCLUDE_SYSCALL_PUBLIC_H
+
+/** Fast syscall flag bit location. When this bit is set, the hypervisor
+ * handles the syscall specially.
+ */
+#define HV_SYS_FAST_SHIFT 14
+
+/** Fast syscall flag bit mask. */
+#define HV_SYS_FAST_MASK (1 << HV_SYS_FAST_SHIFT)
+
+/** Bit location for flagging fast syscalls that can be called from PL0. */
+#define HV_SYS_FAST_PLO_SHIFT 13
+
+/** Fast syscall allowing PL0 bit mask. */
+#define HV_SYS_FAST_PL0_MASK (1 << HV_SYS_FAST_PLO_SHIFT)
+
+/** Perform an MF that waits for all victims to reach DRAM. */
+#define HV_SYS_fence_incoherent (51 | HV_SYS_FAST_MASK \
+ | HV_SYS_FAST_PL0_MASK)
+
+#endif /* !_SYS_HV_INCLUDE_SYSCALL_PUBLIC_H */
diff --git a/arch/tile/kernel/Makefile b/arch/tile/kernel/Makefile
new file mode 100644
index 000000000000..112b1e248f05
--- /dev/null
+++ b/arch/tile/kernel/Makefile
@@ -0,0 +1,17 @@
+#
+# Makefile for the Linux/TILE kernel.
+#
+
+extra-y := vmlinux.lds head_$(BITS).o
+obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \
+ pci-dma.o proc.o process.o ptrace.o reboot.o \
+ setup.o signal.o single_step.o stack.o sys.o time.o traps.o \
+ intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
+
+obj-$(CONFIG_HARDWALL) += hardwall.o
+obj-$(CONFIG_TILEGX) += futex_64.o
+obj-$(CONFIG_COMPAT) += compat.o compat_signal.o
+obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
diff --git a/arch/tile/kernel/asm-offsets.c b/arch/tile/kernel/asm-offsets.c
new file mode 100644
index 000000000000..01ddf19cc36d
--- /dev/null
+++ b/arch/tile/kernel/asm-offsets.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Generates definitions from c-type structures used by assembly sources.
+ */
+
+#include <linux/kbuild.h>
+#include <linux/thread_info.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/ptrace.h>
+#include <hv/hypervisor.h>
+
+/* Check for compatible compiler early in the build. */
+#ifdef CONFIG_TILEGX
+# ifndef __tilegx__
+# error Can only build TILE-Gx configurations with tilegx compiler
+# endif
+# ifndef __LP64__
+# error Must not specify -m32 when building the TILE-Gx kernel
+# endif
+#else
+# ifdef __tilegx__
+# error Can not build TILEPro/TILE64 configurations with tilegx compiler
+# endif
+#endif
+
+void foo(void)
+{
+ DEFINE(SINGLESTEP_STATE_BUFFER_OFFSET, \
+ offsetof(struct single_step_state, buffer));
+ DEFINE(SINGLESTEP_STATE_FLAGS_OFFSET, \
+ offsetof(struct single_step_state, flags));
+ DEFINE(SINGLESTEP_STATE_ORIG_PC_OFFSET, \
+ offsetof(struct single_step_state, orig_pc));
+ DEFINE(SINGLESTEP_STATE_NEXT_PC_OFFSET, \
+ offsetof(struct single_step_state, next_pc));
+ DEFINE(SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET, \
+ offsetof(struct single_step_state, branch_next_pc));
+ DEFINE(SINGLESTEP_STATE_UPDATE_VALUE_OFFSET, \
+ offsetof(struct single_step_state, update_value));
+
+ DEFINE(THREAD_INFO_TASK_OFFSET, \
+ offsetof(struct thread_info, task));
+ DEFINE(THREAD_INFO_FLAGS_OFFSET, \
+ offsetof(struct thread_info, flags));
+ DEFINE(THREAD_INFO_STATUS_OFFSET, \
+ offsetof(struct thread_info, status));
+ DEFINE(THREAD_INFO_HOMECACHE_CPU_OFFSET, \
+ offsetof(struct thread_info, homecache_cpu));
+ DEFINE(THREAD_INFO_STEP_STATE_OFFSET, \
+ offsetof(struct thread_info, step_state));
+
+ DEFINE(TASK_STRUCT_THREAD_KSP_OFFSET,
+ offsetof(struct task_struct, thread.ksp));
+ DEFINE(TASK_STRUCT_THREAD_PC_OFFSET,
+ offsetof(struct task_struct, thread.pc));
+
+ DEFINE(HV_TOPOLOGY_WIDTH_OFFSET, \
+ offsetof(HV_Topology, width));
+ DEFINE(HV_TOPOLOGY_HEIGHT_OFFSET, \
+ offsetof(HV_Topology, height));
+
+ DEFINE(IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET, \
+ offsetof(irq_cpustat_t, irq_syscall_count));
+}
diff --git a/arch/tile/kernel/backtrace.c b/arch/tile/kernel/backtrace.c
new file mode 100644
index 000000000000..77265f3b58d6
--- /dev/null
+++ b/arch/tile/kernel/backtrace.c
@@ -0,0 +1,621 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include <asm/backtrace.h>
+
+#include <arch/chip.h>
+
+#if TILE_CHIP < 10
+
+
+#include <asm/opcode-tile.h>
+
+
+#define TREG_SP 54
+#define TREG_LR 55
+
+
+/** A decoded bundle used for backtracer analysis. */
+struct BacktraceBundle {
+ tile_bundle_bits bits;
+ int num_insns;
+ struct tile_decoded_instruction
+ insns[TILE_MAX_INSTRUCTIONS_PER_BUNDLE];
+};
+
+
+/* This implementation only makes sense for native tools. */
+/** Default function to read memory. */
+static bool bt_read_memory(void *result, VirtualAddress addr,
+ size_t size, void *extra)
+{
+ /* FIXME: this should do some horrible signal stuff to catch
+ * SEGV cleanly and fail.
+ *
+ * Or else the caller should do the setjmp for efficiency.
+ */
+
+ memcpy(result, (const void *)addr, size);
+ return true;
+}
+
+
+/** Locates an instruction inside the given bundle that
+ * has the specified mnemonic, and whose first 'num_operands_to_match'
+ * operands exactly match those in 'operand_values'.
+ */
+static const struct tile_decoded_instruction *find_matching_insn(
+ const struct BacktraceBundle *bundle,
+ tile_mnemonic mnemonic,
+ const int *operand_values,
+ int num_operands_to_match)
+{
+ int i, j;
+ bool match;
+
+ for (i = 0; i < bundle->num_insns; i++) {
+ const struct tile_decoded_instruction *insn =
+ &bundle->insns[i];
+
+ if (insn->opcode->mnemonic != mnemonic)
+ continue;
+
+ match = true;
+ for (j = 0; j < num_operands_to_match; j++) {
+ if (operand_values[j] != insn->operand_values[j]) {
+ match = false;
+ break;
+ }
+ }
+
+ if (match)
+ return insn;
+ }
+
+ return NULL;
+}
+
+/** Does this bundle contain an 'iret' instruction? */
+static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
+{
+ return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
+}
+
+/** Does this bundle contain an 'addi sp, sp, OFFSET' or
+ * 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET?
+ */
+static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
+{
+ static const int vals[2] = { TREG_SP, TREG_SP };
+
+ const struct tile_decoded_instruction *insn =
+ find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2);
+ if (insn == NULL)
+ insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2);
+ if (insn == NULL)
+ return false;
+
+ *adjust = insn->operand_values[2];
+ return true;
+}
+
+/** Does this bundle contain any 'info OP' or 'infol OP'
+ * instruction, and if so, what are their OP? Note that OP is interpreted
+ * as an unsigned value by this code since that's what the caller wants.
+ * Returns the number of info ops found.
+ */
+static int bt_get_info_ops(const struct BacktraceBundle *bundle,
+ int operands[MAX_INFO_OPS_PER_BUNDLE])
+{
+ int num_ops = 0;
+ int i;
+
+ for (i = 0; i < bundle->num_insns; i++) {
+ const struct tile_decoded_instruction *insn =
+ &bundle->insns[i];
+
+ if (insn->opcode->mnemonic == TILE_OPC_INFO ||
+ insn->opcode->mnemonic == TILE_OPC_INFOL) {
+ operands[num_ops++] = insn->operand_values[0];
+ }
+ }
+
+ return num_ops;
+}
+
+/** Does this bundle contain a jrp instruction, and if so, to which
+ * register is it jumping?
+ */
+static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
+{
+ const struct tile_decoded_instruction *insn =
+ find_matching_insn(bundle, TILE_OPC_JRP, NULL, 0);
+ if (insn == NULL)
+ return false;
+
+ *target_reg = insn->operand_values[0];
+ return true;
+}
+
+/** Does this bundle modify the specified register in any way? */
+static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
+{
+ int i, j;
+ for (i = 0; i < bundle->num_insns; i++) {
+ const struct tile_decoded_instruction *insn =
+ &bundle->insns[i];
+
+ if (insn->opcode->implicitly_written_register == reg)
+ return true;
+
+ for (j = 0; j < insn->opcode->num_operands; j++)
+ if (insn->operands[j]->is_dest_reg &&
+ insn->operand_values[j] == reg)
+ return true;
+ }
+
+ return false;
+}
+
+/** Does this bundle modify sp? */
+static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
+{
+ return bt_modifies_reg(bundle, TREG_SP);
+}
+
+/** Does this bundle modify lr? */
+static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
+{
+ return bt_modifies_reg(bundle, TREG_LR);
+}
+
+/** Does this bundle contain the instruction 'move fp, sp'? */
+static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
+{
+ static const int vals[2] = { 52, TREG_SP };
+ return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
+}
+
+/** Does this bundle contain the instruction 'sw sp, lr'? */
+static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
+{
+ static const int vals[2] = { TREG_SP, TREG_LR };
+ return find_matching_insn(bundle, TILE_OPC_SW, vals, 2) != NULL;
+}
+
+/** Locates the caller's PC and SP for a program starting at the
+ * given address.
+ */
+static void find_caller_pc_and_caller_sp(CallerLocation *location,
+ const VirtualAddress start_pc,
+ BacktraceMemoryReader read_memory_func,
+ void *read_memory_func_extra)
+{
+ /* Have we explicitly decided what the sp is,
+ * rather than just the default?
+ */
+ bool sp_determined = false;
+
+ /* Has any bundle seen so far modified lr? */
+ bool lr_modified = false;
+
+ /* Have we seen a move from sp to fp? */
+ bool sp_moved_to_r52 = false;
+
+ /* Have we seen a terminating bundle? */
+ bool seen_terminating_bundle = false;
+
+ /* Cut down on round-trip reading overhead by reading several
+ * bundles at a time.
+ */
+ tile_bundle_bits prefetched_bundles[32];
+ int num_bundles_prefetched = 0;
+ int next_bundle = 0;
+ VirtualAddress pc;
+
+ /* Default to assuming that the caller's sp is the current sp.
+ * This is necessary to handle the case where we start backtracing
+ * right at the end of the epilog.
+ */
+ location->sp_location = SP_LOC_OFFSET;
+ location->sp_offset = 0;
+
+ /* Default to having no idea where the caller PC is. */
+ location->pc_location = PC_LOC_UNKNOWN;
+
+ /* Don't even try if the PC is not aligned. */
+ if (start_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0)
+ return;
+
+ for (pc = start_pc;; pc += sizeof(tile_bundle_bits)) {
+
+ struct BacktraceBundle bundle;
+ int num_info_ops, info_operands[MAX_INFO_OPS_PER_BUNDLE];
+ int one_ago, jrp_reg;
+ bool has_jrp;
+
+ if (next_bundle >= num_bundles_prefetched) {
+ /* Prefetch some bytes, but don't cross a page
+ * boundary since that might cause a read failure we
+ * don't care about if we only need the first few
+ * bytes. Note: we don't care what the actual page
+ * size is; using the minimum possible page size will
+ * prevent any problems.
+ */
+ unsigned int bytes_to_prefetch = 4096 - (pc & 4095);
+ if (bytes_to_prefetch > sizeof prefetched_bundles)
+ bytes_to_prefetch = sizeof prefetched_bundles;
+
+ if (!read_memory_func(prefetched_bundles, pc,
+ bytes_to_prefetch,
+ read_memory_func_extra)) {
+ if (pc == start_pc) {
+ /* The program probably called a bad
+ * address, such as a NULL pointer.
+ * So treat this as if we are at the
+ * start of the function prolog so the
+ * backtrace will show how we got here.
+ */
+ location->pc_location = PC_LOC_IN_LR;
+ return;
+ }
+
+ /* Unreadable address. Give up. */
+ break;
+ }
+
+ next_bundle = 0;
+ num_bundles_prefetched =
+ bytes_to_prefetch / sizeof(tile_bundle_bits);
+ }
+
+ /* Decode the next bundle. */
+ bundle.bits = prefetched_bundles[next_bundle++];
+ bundle.num_insns =
+ parse_insn_tile(bundle.bits, pc, bundle.insns);
+ num_info_ops = bt_get_info_ops(&bundle, info_operands);
+
+ /* First look at any one_ago info ops if they are interesting,
+ * since they should shadow any non-one-ago info ops.
+ */
+ for (one_ago = (pc != start_pc) ? 1 : 0;
+ one_ago >= 0; one_ago--) {
+ int i;
+ for (i = 0; i < num_info_ops; i++) {
+ int info_operand = info_operands[i];
+ if (info_operand < CALLER_UNKNOWN_BASE) {
+ /* Weird; reserved value, ignore it. */
+ continue;
+ }
+
+ /* Skip info ops which are not in the
+ * "one_ago" mode we want right now.
+ */
+ if (((info_operand & ONE_BUNDLE_AGO_FLAG) != 0)
+ != (one_ago != 0))
+ continue;
+
+ /* Clear the flag to make later checking
+ * easier. */
+ info_operand &= ~ONE_BUNDLE_AGO_FLAG;
+
+ /* Default to looking at PC_IN_LR_FLAG. */
+ if (info_operand & PC_IN_LR_FLAG)
+ location->pc_location =
+ PC_LOC_IN_LR;
+ else
+ location->pc_location =
+ PC_LOC_ON_STACK;
+
+ switch (info_operand) {
+ case CALLER_UNKNOWN_BASE:
+ location->pc_location = PC_LOC_UNKNOWN;
+ location->sp_location = SP_LOC_UNKNOWN;
+ return;
+
+ case CALLER_SP_IN_R52_BASE:
+ case CALLER_SP_IN_R52_BASE | PC_IN_LR_FLAG:
+ location->sp_location = SP_LOC_IN_R52;
+ return;
+
+ default:
+ {
+ const unsigned int val = info_operand
+ - CALLER_SP_OFFSET_BASE;
+ const unsigned int sp_offset =
+ (val >> NUM_INFO_OP_FLAGS) * 8;
+ if (sp_offset < 32768) {
+ /* This is a properly encoded
+ * SP offset. */
+ location->sp_location =
+ SP_LOC_OFFSET;
+ location->sp_offset =
+ sp_offset;
+ return;
+ } else {
+ /* This looked like an SP
+ * offset, but it's outside
+ * the legal range, so this
+ * must be an unrecognized
+ * info operand. Ignore it.
+ */
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (seen_terminating_bundle) {
+ /* We saw a terminating bundle during the previous
+ * iteration, so we were only looking for an info op.
+ */
+ break;
+ }
+
+ if (bundle.bits == 0) {
+ /* Wacky terminating bundle. Stop looping, and hope
+ * we've already seen enough to find the caller.
+ */
+ break;
+ }
+
+ /*
+ * Try to determine caller's SP.
+ */
+
+ if (!sp_determined) {
+ int adjust;
+ if (bt_has_addi_sp(&bundle, &adjust)) {
+ location->sp_location = SP_LOC_OFFSET;
+
+ if (adjust <= 0) {
+ /* We are in prolog about to adjust
+ * SP. */
+ location->sp_offset = 0;
+ } else {
+ /* We are in epilog restoring SP. */
+ location->sp_offset = adjust;
+ }
+
+ sp_determined = true;
+ } else {
+ if (bt_has_move_r52_sp(&bundle)) {
+ /* Maybe in prolog, creating an
+ * alloca-style frame. But maybe in
+ * the middle of a fixed-size frame
+ * clobbering r52 with SP.
+ */
+ sp_moved_to_r52 = true;
+ }
+
+ if (bt_modifies_sp(&bundle)) {
+ if (sp_moved_to_r52) {
+ /* We saw SP get saved into
+ * r52 earlier (or now), which
+ * must have been in the
+ * prolog, so we now know that
+ * SP is still holding the
+ * caller's sp value.
+ */
+ location->sp_location =
+ SP_LOC_OFFSET;
+ location->sp_offset = 0;
+ } else {
+ /* Someone must have saved
+ * aside the caller's SP value
+ * into r52, so r52 holds the
+ * current value.
+ */
+ location->sp_location =
+ SP_LOC_IN_R52;
+ }
+ sp_determined = true;
+ }
+ }
+ }
+
+ if (bt_has_iret(&bundle)) {
+ /* This is a terminating bundle. */
+ seen_terminating_bundle = true;
+ continue;
+ }
+
+ /*
+ * Try to determine caller's PC.
+ */
+
+ jrp_reg = -1;
+ has_jrp = bt_has_jrp(&bundle, &jrp_reg);
+ if (has_jrp)
+ seen_terminating_bundle = true;
+
+ if (location->pc_location == PC_LOC_UNKNOWN) {
+ if (has_jrp) {
+ if (jrp_reg == TREG_LR && !lr_modified) {
+ /* Looks like a leaf function, or else
+ * lr is already restored. */
+ location->pc_location =
+ PC_LOC_IN_LR;
+ } else {
+ location->pc_location =
+ PC_LOC_ON_STACK;
+ }
+ } else if (bt_has_sw_sp_lr(&bundle)) {
+ /* In prolog, spilling initial lr to stack. */
+ location->pc_location = PC_LOC_IN_LR;
+ } else if (bt_modifies_lr(&bundle)) {
+ lr_modified = true;
+ }
+ }
+ }
+}
+
+void backtrace_init(BacktraceIterator *state,
+ BacktraceMemoryReader read_memory_func,
+ void *read_memory_func_extra,
+ VirtualAddress pc, VirtualAddress lr,
+ VirtualAddress sp, VirtualAddress r52)
+{
+ CallerLocation location;
+ VirtualAddress fp, initial_frame_caller_pc;
+
+ if (read_memory_func == NULL) {
+ read_memory_func = bt_read_memory;
+ }
+
+ /* Find out where we are in the initial frame. */
+ find_caller_pc_and_caller_sp(&location, pc,
+ read_memory_func, read_memory_func_extra);
+
+ switch (location.sp_location) {
+ case SP_LOC_UNKNOWN:
+ /* Give up. */
+ fp = -1;
+ break;
+
+ case SP_LOC_IN_R52:
+ fp = r52;
+ break;
+
+ case SP_LOC_OFFSET:
+ fp = sp + location.sp_offset;
+ break;
+
+ default:
+ /* Give up. */
+ fp = -1;
+ break;
+ }
+
+ /* The frame pointer should theoretically be aligned mod 8. If
+ * it's not even aligned mod 4 then something terrible happened
+ * and we should mark it as invalid.
+ */
+ if (fp % 4 != 0)
+ fp = -1;
+
+ /* -1 means "don't know initial_frame_caller_pc". */
+ initial_frame_caller_pc = -1;
+
+ switch (location.pc_location) {
+ case PC_LOC_UNKNOWN:
+ /* Give up. */
+ fp = -1;
+ break;
+
+ case PC_LOC_IN_LR:
+ if (lr == 0 || lr % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) {
+ /* Give up. */
+ fp = -1;
+ } else {
+ initial_frame_caller_pc = lr;
+ }
+ break;
+
+ case PC_LOC_ON_STACK:
+ /* Leave initial_frame_caller_pc as -1,
+ * meaning check the stack.
+ */
+ break;
+
+ default:
+ /* Give up. */
+ fp = -1;
+ break;
+ }
+
+ state->pc = pc;
+ state->sp = sp;
+ state->fp = fp;
+ state->initial_frame_caller_pc = initial_frame_caller_pc;
+ state->read_memory_func = read_memory_func;
+ state->read_memory_func_extra = read_memory_func_extra;
+}
+
+bool backtrace_next(BacktraceIterator *state)
+{
+ VirtualAddress next_fp, next_pc, next_frame[2];
+
+ if (state->fp == -1) {
+ /* No parent frame. */
+ return false;
+ }
+
+ /* Try to read the frame linkage data chaining to the next function. */
+ if (!state->read_memory_func(&next_frame, state->fp, sizeof next_frame,
+ state->read_memory_func_extra)) {
+ return false;
+ }
+
+ next_fp = next_frame[1];
+ if (next_fp % 4 != 0) {
+ /* Caller's frame pointer is suspect, so give up.
+ * Technically it should be aligned mod 8, but we will
+ * be forgiving here.
+ */
+ return false;
+ }
+
+ if (state->initial_frame_caller_pc != -1) {
+ /* We must be in the initial stack frame and already know the
+ * caller PC.
+ */
+ next_pc = state->initial_frame_caller_pc;
+
+ /* Force reading stack next time, in case we were in the
+ * initial frame. We don't do this above just to paranoidly
+ * avoid changing the struct at all when we return false.
+ */
+ state->initial_frame_caller_pc = -1;
+ } else {
+ /* Get the caller PC from the frame linkage area. */
+ next_pc = next_frame[0];
+ if (next_pc == 0 ||
+ next_pc % TILE_BUNDLE_ALIGNMENT_IN_BYTES != 0) {
+ /* The PC is suspect, so give up. */
+ return false;
+ }
+ }
+
+ /* Update state to become the caller's stack frame. */
+ state->pc = next_pc;
+ state->sp = state->fp;
+ state->fp = next_fp;
+
+ return true;
+}
+
+#else /* TILE_CHIP < 10 */
+
+void backtrace_init(BacktraceIterator *state,
+ BacktraceMemoryReader read_memory_func,
+ void *read_memory_func_extra,
+ VirtualAddress pc, VirtualAddress lr,
+ VirtualAddress sp, VirtualAddress r52)
+{
+ state->pc = pc;
+ state->sp = sp;
+ state->fp = -1;
+ state->initial_frame_caller_pc = -1;
+ state->read_memory_func = read_memory_func;
+ state->read_memory_func_extra = read_memory_func_extra;
+}
+
+bool backtrace_next(BacktraceIterator *state) { return false; }
+
+#endif /* TILE_CHIP < 10 */
diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c
new file mode 100644
index 000000000000..b1e06d041555
--- /dev/null
+++ b/arch/tile/kernel/compat.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+/* Adjust unistd.h to provide 32-bit numbers and functions. */
+#define __SYSCALL_COMPAT
+
+#include <linux/compat.h>
+#include <linux/msg.h>
+#include <linux/syscalls.h>
+#include <linux/kdev_t.h>
+#include <linux/fs.h>
+#include <linux/fcntl.h>
+#include <linux/smp_lock.h>
+#include <linux/uaccess.h>
+#include <linux/signal.h>
+#include <asm/syscalls.h>
+
+/*
+ * Syscalls that take 64-bit numbers traditionally take them in 32-bit
+ * "high" and "low" value parts on 32-bit architectures.
+ * In principle, one could imagine passing some register arguments as
+ * fully 64-bit on TILE-Gx in 32-bit mode, but it seems easier to
+ * adapt the usual convention.
+ */
+
+long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high)
+{
+ return sys_truncate(filename, ((loff_t)high << 32) | low);
+}
+
+long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high)
+{
+ return sys_ftruncate(fd, ((loff_t)high << 32) | low);
+}
+
+long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
+ u32 dummy, u32 low, u32 high)
+{
+ return sys_pread64(fd, ubuf, count, ((loff_t)high << 32) | low);
+}
+
+long compat_sys_pwrite64(unsigned int fd, char __user *ubuf, size_t count,
+ u32 dummy, u32 low, u32 high)
+{
+ return sys_pwrite64(fd, ubuf, count, ((loff_t)high << 32) | low);
+}
+
+long compat_sys_lookup_dcookie(u32 low, u32 high, char __user *buf, size_t len)
+{
+ return sys_lookup_dcookie(((loff_t)high << 32) | low, buf, len);
+}
+
+long compat_sys_sync_file_range2(int fd, unsigned int flags,
+ u32 offset_lo, u32 offset_hi,
+ u32 nbytes_lo, u32 nbytes_hi)
+{
+ return sys_sync_file_range(fd, ((loff_t)offset_hi << 32) | offset_lo,
+ ((loff_t)nbytes_hi << 32) | nbytes_lo,
+ flags);
+}
+
+long compat_sys_fallocate(int fd, int mode,
+ u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi)
+{
+ return sys_fallocate(fd, mode, ((loff_t)offset_hi << 32) | offset_lo,
+ ((loff_t)len_hi << 32) | len_lo);
+}
+
+
+
+long compat_sys_sched_rr_get_interval(compat_pid_t pid,
+ struct compat_timespec __user *interval)
+{
+ struct timespec t;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ ret = sys_sched_rr_get_interval(pid,
+ (struct timespec __force __user *)&t);
+ set_fs(old_fs);
+ if (put_compat_timespec(&t, interval))
+ return -EFAULT;
+ return ret;
+}
+
+/*
+ * The usual compat_sys_msgsnd() and _msgrcv() seem to be assuming
+ * some different calling convention than our normal 32-bit tile code.
+ */
+
+/* Already defined in ipc/compat.c, but we need it here. */
+struct compat_msgbuf {
+ compat_long_t mtype;
+ char mtext[1];
+};
+
+long tile_compat_sys_msgsnd(int msqid,
+ struct compat_msgbuf __user *msgp,
+ size_t msgsz, int msgflg)
+{
+ compat_long_t mtype;
+
+ if (get_user(mtype, &msgp->mtype))
+ return -EFAULT;
+ return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
+}
+
+long tile_compat_sys_msgrcv(int msqid,
+ struct compat_msgbuf __user *msgp,
+ size_t msgsz, long msgtyp, int msgflg)
+{
+ long err, mtype;
+
+ err = do_msgrcv(msqid, &mtype, msgp->mtext, msgsz, msgtyp, msgflg);
+ if (err < 0)
+ goto out;
+
+ if (put_user(mtype, &msgp->mtype))
+ err = -EFAULT;
+ out:
+ return err;
+}
+
+/* Provide the compat syscall number to call mapping. */
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (compat_##call),
+
+/* The generic versions of these don't work for Tile. */
+#define compat_sys_msgrcv tile_compat_sys_msgrcv
+#define compat_sys_msgsnd tile_compat_sys_msgsnd
+
+/* See comments in sys.c */
+#define compat_sys_fadvise64 sys32_fadvise64
+#define compat_sys_fadvise64_64 sys32_fadvise64_64
+#define compat_sys_readahead sys32_readahead
+#define compat_sys_sync_file_range compat_sys_sync_file_range2
+
+/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */
+#define compat_sys_stat64 sys_newstat
+#define compat_sys_lstat64 sys_newlstat
+#define compat_sys_fstat64 sys_newfstat
+#define compat_sys_fstatat64 sys_newfstatat
+
+/* Pass full 64-bit values through ptrace. */
+#define compat_sys_ptrace tile_compat_sys_ptrace
+
+/*
+ * Note that we can't include <linux/unistd.h> here since the header
+ * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
+ */
+void *compat_sys_call_table[__NR_syscalls] = {
+ [0 ... __NR_syscalls-1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c
new file mode 100644
index 000000000000..d5efb215dd5f
--- /dev/null
+++ b/arch/tile/kernel/compat_signal.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/suspend.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <asm/processor.h>
+#include <asm/ucontext.h>
+#include <asm/sigframe.h>
+#include <asm/syscalls.h>
+#include <arch/interrupts.h>
+
+struct compat_sigaction {
+ compat_uptr_t sa_handler;
+ compat_ulong_t sa_flags;
+ compat_uptr_t sa_restorer;
+ sigset_t sa_mask __packed;
+};
+
+struct compat_sigaltstack {
+ compat_uptr_t ss_sp;
+ int ss_flags;
+ compat_size_t ss_size;
+};
+
+struct compat_ucontext {
+ compat_ulong_t uc_flags;
+ compat_uptr_t uc_link;
+ struct compat_sigaltstack uc_stack;
+ struct sigcontext uc_mcontext;
+ sigset_t uc_sigmask; /* mask last for extensibility */
+};
+
+struct compat_siginfo {
+ int si_signo;
+ int si_errno;
+ int si_code;
+
+ union {
+ int _pad[SI_PAD_SIZE];
+
+ /* kill() */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ } _kill;
+
+ /* POSIX.1b timers */
+ struct {
+ compat_timer_t _tid; /* timer id */
+ int _overrun; /* overrun count */
+ compat_sigval_t _sigval; /* same as below */
+ int _sys_private; /* not to be passed to user */
+ int _overrun_incr; /* amount to add to overrun */
+ } _timer;
+
+ /* POSIX.1b signals */
+ struct {
+ unsigned int _pid; /* sender's pid */
+ unsigned int _uid; /* sender's uid */
+ compat_sigval_t _sigval;
+ } _rt;
+
+ /* SIGCHLD */
+ struct {
+ unsigned int _pid; /* which child */
+ unsigned int _uid; /* sender's uid */
+ int _status; /* exit code */
+ compat_clock_t _utime;
+ compat_clock_t _stime;
+ } _sigchld;
+
+ /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+ struct {
+ unsigned int _addr; /* faulting insn/memory ref. */
+#ifdef __ARCH_SI_TRAPNO
+ int _trapno; /* TRAP # which caused the signal */
+#endif
+ } _sigfault;
+
+ /* SIGPOLL */
+ struct {
+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */
+ int _fd;
+ } _sigpoll;
+ } _sifields;
+};
+
+struct compat_rt_sigframe {
+ unsigned char save_area[C_ABI_SAVE_AREA_SIZE]; /* caller save area */
+ struct compat_siginfo info;
+ struct compat_ucontext uc;
+};
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
+ struct compat_sigaction __user *oact,
+ size_t sigsetsize)
+{
+ struct k_sigaction new_sa, old_sa;
+ int ret = -EINVAL;
+
+ /* XXX: Don't preclude handling different sized sigset_t's. */
+ if (sigsetsize != sizeof(sigset_t))
+ goto out;
+
+ if (act) {
+ compat_uptr_t handler, restorer;
+
+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(handler, &act->sa_handler) ||
+ __get_user(new_sa.sa.sa_flags, &act->sa_flags) ||
+ __get_user(restorer, &act->sa_restorer) ||
+ __copy_from_user(&new_sa.sa.sa_mask, &act->sa_mask,
+ sizeof(sigset_t)))
+ return -EFAULT;
+ new_sa.sa.sa_handler = compat_ptr(handler);
+ new_sa.sa.sa_restorer = compat_ptr(restorer);
+ }
+
+ ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
+
+ if (!ret && oact) {
+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(ptr_to_compat(old_sa.sa.sa_handler),
+ &oact->sa_handler) ||
+ __put_user(ptr_to_compat(old_sa.sa.sa_restorer),
+ &oact->sa_restorer) ||
+ __put_user(old_sa.sa.sa_flags, &oact->sa_flags) ||
+ __copy_to_user(&oact->sa_mask, &old_sa.sa.sa_mask,
+ sizeof(sigset_t)))
+ return -EFAULT;
+ }
+out:
+ return ret;
+}
+
+long compat_sys_rt_sigqueueinfo(int pid, int sig,
+ struct compat_siginfo __user *uinfo)
+{
+ siginfo_t info;
+ int ret;
+ mm_segment_t old_fs = get_fs();
+
+ if (copy_siginfo_from_user32(&info, uinfo))
+ return -EFAULT;
+ set_fs(KERNEL_DS);
+ ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *)&info);
+ set_fs(old_fs);
+ return ret;
+}
+
+int copy_siginfo_to_user32(struct compat_siginfo __user *to, siginfo_t *from)
+{
+ int err;
+
+ if (!access_ok(VERIFY_WRITE, to, sizeof(struct compat_siginfo)))
+ return -EFAULT;
+
+ /* If you change siginfo_t structure, please make sure that
+ this code is fixed accordingly.
+ It should never copy any pad contained in the structure
+ to avoid security leaks, but must copy the generic
+ 3 ints plus the relevant union member. */
+ err = __put_user(from->si_signo, &to->si_signo);
+ err |= __put_user(from->si_errno, &to->si_errno);
+ err |= __put_user((short)from->si_code, &to->si_code);
+
+ if (from->si_code < 0) {
+ err |= __put_user(from->si_pid, &to->si_pid);
+ err |= __put_user(from->si_uid, &to->si_uid);
+ err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
+ } else {
+ /*
+ * First 32bits of unions are always present:
+ * si_pid === si_band === si_tid === si_addr(LS half)
+ */
+ err |= __put_user(from->_sifields._pad[0],
+ &to->_sifields._pad[0]);
+ switch (from->si_code >> 16) {
+ case __SI_FAULT >> 16:
+ break;
+ case __SI_CHLD >> 16:
+ err |= __put_user(from->si_utime, &to->si_utime);
+ err |= __put_user(from->si_stime, &to->si_stime);
+ err |= __put_user(from->si_status, &to->si_status);
+ /* FALL THROUGH */
+ default:
+ case __SI_KILL >> 16:
+ err |= __put_user(from->si_uid, &to->si_uid);
+ break;
+ case __SI_POLL >> 16:
+ err |= __put_user(from->si_fd, &to->si_fd);
+ break;
+ case __SI_TIMER >> 16:
+ err |= __put_user(from->si_overrun, &to->si_overrun);
+ err |= __put_user(ptr_to_compat(from->si_ptr),
+ &to->si_ptr);
+ break;
+ /* This is not generated by the kernel as of now. */
+ case __SI_RT >> 16:
+ case __SI_MESGQ >> 16:
+ err |= __put_user(from->si_uid, &to->si_uid);
+ err |= __put_user(from->si_int, &to->si_int);
+ break;
+ }
+ }
+ return err;
+}
+
+int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
+{
+ int err;
+ u32 ptr32;
+
+ if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo)))
+ return -EFAULT;
+
+ err = __get_user(to->si_signo, &from->si_signo);
+ err |= __get_user(to->si_errno, &from->si_errno);
+ err |= __get_user(to->si_code, &from->si_code);
+
+ err |= __get_user(to->si_pid, &from->si_pid);
+ err |= __get_user(to->si_uid, &from->si_uid);
+ err |= __get_user(ptr32, &from->si_ptr);
+ to->si_ptr = compat_ptr(ptr32);
+
+ return err;
+}
+
+long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
+ struct compat_sigaltstack __user *uoss_ptr,
+ struct pt_regs *regs)
+{
+ stack_t uss, uoss;
+ int ret;
+ mm_segment_t seg;
+
+ if (uss_ptr) {
+ u32 ptr;
+
+ memset(&uss, 0, sizeof(stack_t));
+ if (!access_ok(VERIFY_READ, uss_ptr, sizeof(*uss_ptr)) ||
+ __get_user(ptr, &uss_ptr->ss_sp) ||
+ __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
+ __get_user(uss.ss_size, &uss_ptr->ss_size))
+ return -EFAULT;
+ uss.ss_sp = compat_ptr(ptr);
+ }
+ seg = get_fs();
+ set_fs(KERNEL_DS);
+ ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
+ (stack_t __user __force *)&uoss,
+ (unsigned long)compat_ptr(regs->sp));
+ set_fs(seg);
+ if (ret >= 0 && uoss_ptr) {
+ if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
+ __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
+ __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
+ __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+ ret = -EFAULT;
+ }
+ return ret;
+}
+
+long _compat_sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct compat_rt_sigframe __user *frame =
+ (struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
+ sigset_t set;
+ long r0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ goto badframe;
+
+ if (_compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
+ goto badframe;
+
+ return r0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void __user *compat_get_sigframe(struct k_sigaction *ka,
+ struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long sp;
+
+ /* Default to using normal stack */
+ sp = (unsigned long)compat_ptr(regs->sp);
+
+ /*
+ * If we are on the alternate signal stack and would overflow
+ * it, don't. Return an always-bogus address instead so we
+ * will die with SIGSEGV.
+ */
+ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
+ return (void __user __force *)-1UL;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (sas_ss_flags(sp) == 0)
+ sp = current->sas_ss_sp + current->sas_ss_size;
+ }
+
+ sp -= frame_size;
+ /*
+ * Align the stack pointer according to the TILE ABI,
+ * i.e. so that on function entry (sp & 15) == 0.
+ */
+ sp &= -16UL;
+ return (void __user *) sp;
+}
+
+int compat_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ unsigned long restorer;
+ struct compat_rt_sigframe __user *frame;
+ int err = 0;
+ int usig;
+
+ frame = compat_get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ /* Always write at least the signal number for the stack backtracer. */
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ /* At sigreturn time, restore the callee-save registers too. */
+ err |= copy_siginfo_to_user32(&frame->info, info);
+ regs->flags |= PT_FLAGS_RESTORE_REGS;
+ } else {
+ err |= __put_user(info->si_signo, &frame->info.si_signo);
+ }
+
+ /* Create the ucontext. */
+ err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __put_user(ptr_to_compat((void *)(current->sas_ss_sp)),
+ &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->sp),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ if (err)
+ goto give_sigsegv;
+
+ restorer = VDSO_BASE;
+ if (ka->sa.sa_flags & SA_RESTORER)
+ restorer = ptr_to_compat_reg(ka->sa.sa_restorer);
+
+ /*
+ * Set up registers for signal handler.
+ * Registers that we don't modify keep the value they had from
+ * user-space at the time we took the signal.
+ */
+ regs->pc = ptr_to_compat_reg(ka->sa.sa_handler);
+ regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
+ regs->sp = ptr_to_compat_reg(frame);
+ regs->lr = restorer;
+ regs->regs[0] = (unsigned long) usig;
+
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ /* Need extra arguments, so mark to restore caller-saves. */
+ regs->regs[1] = ptr_to_compat_reg(&frame->info);
+ regs->regs[2] = ptr_to_compat_reg(&frame->uc);
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+ }
+
+ /*
+ * Notify any tracer that was single-stepping it.
+ * The tracer may want to single-step inside the
+ * handler too.
+ */
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(sig, current);
+ return -EFAULT;
+}
diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c
new file mode 100644
index 000000000000..2c54fd43a8a0
--- /dev/null
+++ b/arch/tile/kernel/early_printk.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/setup.h>
+#include <hv/hypervisor.h>
+
+static void early_hv_write(struct console *con, const char *s, unsigned n)
+{
+ hv_console_write((HV_VirtAddr) s, n);
+}
+
+static struct console early_hv_console = {
+ .name = "earlyhv",
+ .write = early_hv_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+/* Direct interface for emergencies */
+static struct console *early_console = &early_hv_console;
+static int early_console_initialized;
+static int early_console_complete;
+
+static void early_vprintk(const char *fmt, va_list ap)
+{
+ char buf[512];
+ int n = vscnprintf(buf, sizeof(buf), fmt, ap);
+ early_console->write(early_console, buf, n);
+}
+
+void early_printk(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ early_vprintk(fmt, ap);
+ va_end(ap);
+}
+
+void early_panic(const char *fmt, ...)
+{
+ va_list ap;
+ raw_local_irq_disable_all();
+ va_start(ap, fmt);
+ early_printk("Kernel panic - not syncing: ");
+ early_vprintk(fmt, ap);
+ early_console->write(early_console, "\n", 1);
+ va_end(ap);
+ dump_stack();
+ hv_halt();
+}
+
+static int __initdata keep_early;
+
+static int __init setup_early_printk(char *str)
+{
+ if (early_console_initialized)
+ return 1;
+
+ if (str != NULL && strncmp(str, "keep", 4) == 0)
+ keep_early = 1;
+
+ early_console = &early_hv_console;
+ early_console_initialized = 1;
+ register_console(early_console);
+
+ return 0;
+}
+
+void __init disable_early_printk(void)
+{
+ early_console_complete = 1;
+ if (!early_console_initialized || !early_console)
+ return;
+ if (!keep_early) {
+ early_printk("disabling early console\n");
+ unregister_console(early_console);
+ early_console_initialized = 0;
+ } else {
+ early_printk("keeping early console\n");
+ }
+}
+
+void warn_early_printk(void)
+{
+ if (early_console_complete || early_console_initialized)
+ return;
+ early_printk("\
+Machine shutting down before console output is fully initialized.\n\
+You may wish to reboot and add the option 'earlyprintk' to your\n\
+boot command line to see any diagnostic early console output.\n\
+");
+}
+
+early_param("earlyprintk", setup_early_printk);
diff --git a/arch/tile/kernel/entry.S b/arch/tile/kernel/entry.S
new file mode 100644
index 000000000000..3d01383b1b0e
--- /dev/null
+++ b/arch/tile/kernel/entry.S
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/unistd.h>
+#include <asm/irqflags.h>
+#include <arch/abi.h>
+
+#ifdef __tilegx__
+#define bnzt bnezt
+#endif
+
+STD_ENTRY(current_text_addr)
+ { move r0, lr; jrp lr }
+ STD_ENDPROC(current_text_addr)
+
+STD_ENTRY(_sim_syscall)
+ /*
+ * Wait for r0-r9 to be ready (and lr on the off chance we
+ * want the syscall to locate its caller), then make a magic
+ * simulator syscall.
+ *
+ * We carefully stall until the registers are readable in case they
+ * are the target of a slow load, etc. so that tile-sim will
+ * definitely be able to read all of them inside the magic syscall.
+ *
+ * Technically this is wrong for r3-r9 and lr, since an interrupt
+ * could come in and restore the registers with a slow load right
+ * before executing the mtspr. We may need to modify tile-sim to
+ * explicitly stall for this case, but we do not yet have
+ * a way to implement such a stall.
+ */
+ { and zero, lr, r9 ; and zero, r8, r7 }
+ { and zero, r6, r5 ; and zero, r4, r3 }
+ { and zero, r2, r1 ; mtspr SIM_CONTROL, r0 }
+ { jrp lr }
+ STD_ENDPROC(_sim_syscall)
+
+/*
+ * Implement execve(). The i386 code has a note that forking from kernel
+ * space results in no copy on write until the execve, so we should be
+ * careful not to write to the stack here.
+ */
+STD_ENTRY(kernel_execve)
+ moveli TREG_SYSCALL_NR_NAME, __NR_execve
+ swint1
+ jrp lr
+ STD_ENDPROC(kernel_execve)
+
+/* Delay a fixed number of cycles. */
+STD_ENTRY(__delay)
+ { addi r0, r0, -1; bnzt r0, . }
+ jrp lr
+ STD_ENDPROC(__delay)
+
+/*
+ * We don't run this function directly, but instead copy it to a page
+ * we map into every user process. See vdso_setup().
+ *
+ * Note that libc has a copy of this function that it uses to compare
+ * against the PC when a stack backtrace ends, so if this code is
+ * changed, the libc implementation(s) should also be updated.
+ */
+ .pushsection .data
+ENTRY(__rt_sigreturn)
+ moveli TREG_SYSCALL_NR_NAME,__NR_rt_sigreturn
+ swint1
+ ENDPROC(__rt_sigreturn)
+ ENTRY(__rt_sigreturn_end)
+ .popsection
+
+STD_ENTRY(dump_stack)
+ { move r2, lr; lnk r1 }
+ { move r4, r52; addli r1, r1, dump_stack - . }
+ { move r3, sp; j _dump_stack }
+ jrp lr /* keep backtracer happy */
+ STD_ENDPROC(dump_stack)
+
+STD_ENTRY(KBacktraceIterator_init_current)
+ { move r2, lr; lnk r1 }
+ { move r4, r52; addli r1, r1, KBacktraceIterator_init_current - . }
+ { move r3, sp; j _KBacktraceIterator_init_current }
+ jrp lr /* keep backtracer happy */
+ STD_ENDPROC(KBacktraceIterator_init_current)
+
+/*
+ * Reset our stack to r1/r2 (sp and ksp0+cpu respectively), then
+ * free the old stack (passed in r0) and re-invoke cpu_idle().
+ * We update sp and ksp0 simultaneously to avoid backtracer warnings.
+ */
+STD_ENTRY(cpu_idle_on_new_stack)
+ {
+ move sp, r1
+ mtspr SYSTEM_SAVE_1_0, r2
+ }
+ jal free_thread_info
+ j cpu_idle
+ STD_ENDPROC(cpu_idle_on_new_stack)
+
+/* Loop forever on a nap during SMP boot. */
+STD_ENTRY(smp_nap)
+ nap
+ j smp_nap /* we are not architecturally guaranteed not to exit nap */
+ jrp lr /* clue in the backtracer */
+ STD_ENDPROC(smp_nap)
+
+/*
+ * Enable interrupts racelessly and then nap until interrupted.
+ * This function's _cpu_idle_nap address is special; see intvec.S.
+ * When interrupted at _cpu_idle_nap, we bump the PC forward 8, and
+ * as a result return to the function that called _cpu_idle().
+ */
+STD_ENTRY(_cpu_idle)
+ {
+ lnk r0
+ movei r1, 1
+ }
+ {
+ addli r0, r0, _cpu_idle_nap - .
+ mtspr INTERRUPT_CRITICAL_SECTION, r1
+ }
+ IRQ_ENABLE(r2, r3) /* unmask, but still with ICS set */
+ mtspr EX_CONTEXT_1_1, r1 /* PL1, ICS clear */
+ mtspr EX_CONTEXT_1_0, r0
+ iret
+ .global _cpu_idle_nap
+_cpu_idle_nap:
+ nap
+ jrp lr
+ STD_ENDPROC(_cpu_idle)
diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c
new file mode 100644
index 000000000000..7bf0627b733d
--- /dev/null
+++ b/arch/tile/kernel/hardwall.c
@@ -0,0 +1,794 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/rwsem.h>
+#include <linux/kprobes.h>
+#include <linux/sched.h>
+#include <linux/hardirq.h>
+#include <linux/uaccess.h>
+#include <linux/smp.h>
+#include <linux/cdev.h>
+#include <linux/compat.h>
+#include <asm/hardwall.h>
+#include <asm/traps.h>
+#include <asm/siginfo.h>
+#include <asm/irq_regs.h>
+
+#include <arch/interrupts.h>
+#include <arch/spr_def.h>
+
+
+/*
+ * This data structure tracks the rectangle data, etc., associated
+ * one-to-one with a "struct file *" from opening HARDWALL_FILE.
+ * Note that the file's private data points back to this structure.
+ */
+struct hardwall_info {
+ struct list_head list; /* "rectangles" list */
+ struct list_head task_head; /* head of tasks in this hardwall */
+ int ulhc_x; /* upper left hand corner x coord */
+ int ulhc_y; /* upper left hand corner y coord */
+ int width; /* rectangle width */
+ int height; /* rectangle height */
+ int teardown_in_progress; /* are we tearing this one down? */
+};
+
+/* Currently allocated hardwall rectangles */
+static LIST_HEAD(rectangles);
+
+/*
+ * Guard changes to the hardwall data structures.
+ * This could be finer grained (e.g. one lock for the list of hardwall
+ * rectangles, then separate embedded locks for each one's list of tasks),
+ * but there are subtle correctness issues when trying to start with
+ * a task's "hardwall" pointer and lock the correct rectangle's embedded
+ * lock in the presence of a simultaneous deactivation, so it seems
+ * easier to have a single lock, given that none of these data
+ * structures are touched very frequently during normal operation.
+ */
+static DEFINE_SPINLOCK(hardwall_lock);
+
+/* Allow disabling UDN access. */
+static int udn_disabled;
+static int __init noudn(char *str)
+{
+ pr_info("User-space UDN access is disabled\n");
+ udn_disabled = 1;
+ return 0;
+}
+early_param("noudn", noudn);
+
+
+/*
+ * Low-level primitives
+ */
+
+/* Set a CPU bit if the CPU is online. */
+#define cpu_online_set(cpu, dst) do { \
+ if (cpu_online(cpu)) \
+ cpumask_set_cpu(cpu, dst); \
+} while (0)
+
+
+/* Does the given rectangle contain the given x,y coordinate? */
+static int contains(struct hardwall_info *r, int x, int y)
+{
+ return (x >= r->ulhc_x && x < r->ulhc_x + r->width) &&
+ (y >= r->ulhc_y && y < r->ulhc_y + r->height);
+}
+
+/* Compute the rectangle parameters and validate the cpumask. */
+static int setup_rectangle(struct hardwall_info *r, struct cpumask *mask)
+{
+ int x, y, cpu, ulhc, lrhc;
+
+ /* The first cpu is the ULHC, the last the LRHC. */
+ ulhc = find_first_bit(cpumask_bits(mask), nr_cpumask_bits);
+ lrhc = find_last_bit(cpumask_bits(mask), nr_cpumask_bits);
+
+ /* Compute the rectangle attributes from the cpus. */
+ r->ulhc_x = cpu_x(ulhc);
+ r->ulhc_y = cpu_y(ulhc);
+ r->width = cpu_x(lrhc) - r->ulhc_x + 1;
+ r->height = cpu_y(lrhc) - r->ulhc_y + 1;
+
+ /* Width and height must be positive */
+ if (r->width <= 0 || r->height <= 0)
+ return -EINVAL;
+
+ /* Confirm that the cpumask is exactly the rectangle. */
+ for (y = 0, cpu = 0; y < smp_height; ++y)
+ for (x = 0; x < smp_width; ++x, ++cpu)
+ if (cpumask_test_cpu(cpu, mask) != contains(r, x, y))
+ return -EINVAL;
+
+ /*
+ * Note that offline cpus can't be drained when this UDN
+ * rectangle eventually closes. We used to detect this
+ * situation and print a warning, but it annoyed users and
+ * they ignored it anyway, so now we just return without a
+ * warning.
+ */
+ return 0;
+}
+
+/* Do the two given rectangles overlap on any cpu? */
+static int overlaps(struct hardwall_info *a, struct hardwall_info *b)
+{
+ return a->ulhc_x + a->width > b->ulhc_x && /* A not to the left */
+ b->ulhc_x + b->width > a->ulhc_x && /* B not to the left */
+ a->ulhc_y + a->height > b->ulhc_y && /* A not above */
+ b->ulhc_y + b->height > a->ulhc_y; /* B not above */
+}
+
+
+/*
+ * Hardware management of hardwall setup, teardown, trapping,
+ * and enabling/disabling PL0 access to the networks.
+ */
+
+/* Bit field values to mask together for writes to SPR_XDN_DIRECTION_PROTECT */
+enum direction_protect {
+ N_PROTECT = (1 << 0),
+ E_PROTECT = (1 << 1),
+ S_PROTECT = (1 << 2),
+ W_PROTECT = (1 << 3)
+};
+
+static void enable_firewall_interrupts(void)
+{
+ raw_local_irq_unmask_now(INT_UDN_FIREWALL);
+}
+
+static void disable_firewall_interrupts(void)
+{
+ raw_local_irq_mask_now(INT_UDN_FIREWALL);
+}
+
+/* Set up hardwall on this cpu based on the passed hardwall_info. */
+static void hardwall_setup_ipi_func(void *info)
+{
+ struct hardwall_info *r = info;
+ int cpu = smp_processor_id();
+ int x = cpu % smp_width;
+ int y = cpu / smp_width;
+ int bits = 0;
+ if (x == r->ulhc_x)
+ bits |= W_PROTECT;
+ if (x == r->ulhc_x + r->width - 1)
+ bits |= E_PROTECT;
+ if (y == r->ulhc_y)
+ bits |= N_PROTECT;
+ if (y == r->ulhc_y + r->height - 1)
+ bits |= S_PROTECT;
+ BUG_ON(bits == 0);
+ __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, bits);
+ enable_firewall_interrupts();
+
+}
+
+/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */
+static void hardwall_setup(struct hardwall_info *r)
+{
+ int x, y, cpu, delta;
+ struct cpumask rect_cpus;
+
+ cpumask_clear(&rect_cpus);
+
+ /* First include the top and bottom edges */
+ cpu = r->ulhc_y * smp_width + r->ulhc_x;
+ delta = (r->height - 1) * smp_width;
+ for (x = 0; x < r->width; ++x, ++cpu) {
+ cpu_online_set(cpu, &rect_cpus);
+ cpu_online_set(cpu + delta, &rect_cpus);
+ }
+
+ /* Then the left and right edges */
+ cpu -= r->width;
+ delta = r->width - 1;
+ for (y = 0; y < r->height; ++y, cpu += smp_width) {
+ cpu_online_set(cpu, &rect_cpus);
+ cpu_online_set(cpu + delta, &rect_cpus);
+ }
+
+ /* Then tell all the cpus to set up their protection SPR */
+ on_each_cpu_mask(&rect_cpus, hardwall_setup_ipi_func, r, 1);
+}
+
+void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
+{
+ struct hardwall_info *rect;
+ struct task_struct *p;
+ struct siginfo info;
+ int x, y;
+ int cpu = smp_processor_id();
+ int found_processes;
+ unsigned long flags;
+
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ irq_enter();
+
+ /* This tile trapped a network access; find the rectangle. */
+ x = cpu % smp_width;
+ y = cpu / smp_width;
+ spin_lock_irqsave(&hardwall_lock, flags);
+ list_for_each_entry(rect, &rectangles, list) {
+ if (contains(rect, x, y))
+ break;
+ }
+
+ /*
+ * It shouldn't be possible not to find this cpu on the
+ * rectangle list, since only cpus in rectangles get hardwalled.
+ * The hardwall is only removed after the UDN is drained.
+ */
+ BUG_ON(&rect->list == &rectangles);
+
+ /*
+ * If we already started teardown on this hardwall, don't worry;
+ * the abort signal has been sent and we are just waiting for things
+ * to quiesce.
+ */
+ if (rect->teardown_in_progress) {
+ pr_notice("cpu %d: detected hardwall violation %#lx"
+ " while teardown already in progress\n",
+ cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
+ goto done;
+ }
+
+ /*
+ * Kill off any process that is activated in this rectangle.
+ * We bypass security to deliver the signal, since it must be
+ * one of the activated processes that generated the UDN
+ * message that caused this trap, and all the activated
+ * processes shared a single open file so are pretty tightly
+ * bound together from a security point of view to begin with.
+ */
+ rect->teardown_in_progress = 1;
+ wmb(); /* Ensure visibility of rectangle before notifying processes. */
+ pr_notice("cpu %d: detected hardwall violation %#lx...\n",
+ cpu, (long) __insn_mfspr(SPR_UDN_DIRECTION_PROTECT));
+ info.si_signo = SIGILL;
+ info.si_errno = 0;
+ info.si_code = ILL_HARDWALL;
+ found_processes = 0;
+ list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
+ BUG_ON(p->thread.hardwall != rect);
+ if (p->sighand) {
+ found_processes = 1;
+ pr_notice("hardwall: killing %d\n", p->pid);
+ spin_lock(&p->sighand->siglock);
+ __group_send_sig_info(info.si_signo, &info, p);
+ spin_unlock(&p->sighand->siglock);
+ }
+ }
+ if (!found_processes)
+ pr_notice("hardwall: no associated processes!\n");
+
+ done:
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+
+ /*
+ * We have to disable firewall interrupts now, or else when we
+ * return from this handler, we will simply re-interrupt back to
+ * it. However, we can't clear the protection bits, since we
+ * haven't yet drained the network, and that would allow packets
+ * to cross out of the hardwall region.
+ */
+ disable_firewall_interrupts();
+
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+
+/* Allow access from user space to the UDN. */
+void grant_network_mpls(void)
+{
+ __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_0, 1);
+ __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_0, 1);
+ __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_0, 1);
+ __insn_mtspr(SPR_MPL_UDN_TIMER_SET_0, 1);
+#if !CHIP_HAS_REV1_XDN()
+ __insn_mtspr(SPR_MPL_UDN_REFILL_SET_0, 1);
+ __insn_mtspr(SPR_MPL_UDN_CA_SET_0, 1);
+#endif
+}
+
+/* Deny access from user space to the UDN. */
+void restrict_network_mpls(void)
+{
+ __insn_mtspr(SPR_MPL_UDN_ACCESS_SET_1, 1);
+ __insn_mtspr(SPR_MPL_UDN_AVAIL_SET_1, 1);
+ __insn_mtspr(SPR_MPL_UDN_COMPLETE_SET_1, 1);
+ __insn_mtspr(SPR_MPL_UDN_TIMER_SET_1, 1);
+#if !CHIP_HAS_REV1_XDN()
+ __insn_mtspr(SPR_MPL_UDN_REFILL_SET_1, 1);
+ __insn_mtspr(SPR_MPL_UDN_CA_SET_1, 1);
+#endif
+}
+
+
+/*
+ * Code to create, activate, deactivate, and destroy hardwall rectangles.
+ */
+
+/* Create a hardwall for the given rectangle */
+static struct hardwall_info *hardwall_create(
+ size_t size, const unsigned char __user *bits)
+{
+ struct hardwall_info *iter, *rect;
+ struct cpumask mask;
+ unsigned long flags;
+ int rc;
+
+ /* Reject crazy sizes out of hand, a la sys_mbind(). */
+ if (size > PAGE_SIZE)
+ return ERR_PTR(-EINVAL);
+
+ /* Copy whatever fits into a cpumask. */
+ if (copy_from_user(&mask, bits, min(sizeof(struct cpumask), size)))
+ return ERR_PTR(-EFAULT);
+
+ /*
+ * If the size was short, clear the rest of the mask;
+ * otherwise validate that the rest of the user mask was zero
+ * (we don't try hard to be efficient when validating huge masks).
+ */
+ if (size < sizeof(struct cpumask)) {
+ memset((char *)&mask + size, 0, sizeof(struct cpumask) - size);
+ } else if (size > sizeof(struct cpumask)) {
+ size_t i;
+ for (i = sizeof(struct cpumask); i < size; ++i) {
+ char c;
+ if (get_user(c, &bits[i]))
+ return ERR_PTR(-EFAULT);
+ if (c)
+ return ERR_PTR(-EINVAL);
+ }
+ }
+
+ /* Allocate a new rectangle optimistically. */
+ rect = kmalloc(sizeof(struct hardwall_info),
+ GFP_KERNEL | __GFP_ZERO);
+ INIT_LIST_HEAD(&rect->task_head);
+
+ /* Compute the rectangle size and validate that it's plausible. */
+ rc = setup_rectangle(rect, &mask);
+ if (rc != 0) {
+ kfree(rect);
+ return ERR_PTR(rc);
+ }
+
+ /* Confirm it doesn't overlap and add it to the list. */
+ spin_lock_irqsave(&hardwall_lock, flags);
+ list_for_each_entry(iter, &rectangles, list) {
+ if (overlaps(iter, rect)) {
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+ kfree(rect);
+ return ERR_PTR(-EBUSY);
+ }
+ }
+ list_add_tail(&rect->list, &rectangles);
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+
+ /* Set up appropriate hardwalling on all affected cpus. */
+ hardwall_setup(rect);
+
+ return rect;
+}
+
+/* Activate a given hardwall on this cpu for this process. */
+static int hardwall_activate(struct hardwall_info *rect)
+{
+ int cpu, x, y;
+ unsigned long flags;
+ struct task_struct *p = current;
+ struct thread_struct *ts = &p->thread;
+
+ /* Require a rectangle. */
+ if (rect == NULL)
+ return -ENODATA;
+
+ /* Not allowed to activate a rectangle that is being torn down. */
+ if (rect->teardown_in_progress)
+ return -EINVAL;
+
+ /*
+ * Get our affinity; if we're not bound to this tile uniquely,
+ * we can't access the network registers.
+ */
+ if (cpumask_weight(&p->cpus_allowed) != 1)
+ return -EPERM;
+
+ /* Make sure we are bound to a cpu in this rectangle. */
+ cpu = smp_processor_id();
+ BUG_ON(cpumask_first(&p->cpus_allowed) != cpu);
+ x = cpu_x(cpu);
+ y = cpu_y(cpu);
+ if (!contains(rect, x, y))
+ return -EINVAL;
+
+ /* If we are already bound to this hardwall, it's a no-op. */
+ if (ts->hardwall) {
+ BUG_ON(ts->hardwall != rect);
+ return 0;
+ }
+
+ /* Success! This process gets to use the user networks on this cpu. */
+ ts->hardwall = rect;
+ spin_lock_irqsave(&hardwall_lock, flags);
+ list_add(&ts->hardwall_list, &rect->task_head);
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+ grant_network_mpls();
+ printk(KERN_DEBUG "Pid %d (%s) activated for hardwall: cpu %d\n",
+ p->pid, p->comm, cpu);
+ return 0;
+}
+
+/*
+ * Deactivate a task's hardwall. Must hold hardwall_lock.
+ * This method may be called from free_task(), so we don't want to
+ * rely on too many fields of struct task_struct still being valid.
+ * We assume the cpus_allowed, pid, and comm fields are still valid.
+ */
+static void _hardwall_deactivate(struct task_struct *task)
+{
+ struct thread_struct *ts = &task->thread;
+
+ if (cpumask_weight(&task->cpus_allowed) != 1) {
+ pr_err("pid %d (%s) releasing networks with"
+ " an affinity mask containing %d cpus!\n",
+ task->pid, task->comm,
+ cpumask_weight(&task->cpus_allowed));
+ BUG();
+ }
+
+ BUG_ON(ts->hardwall == NULL);
+ ts->hardwall = NULL;
+ list_del(&ts->hardwall_list);
+ if (task == current)
+ restrict_network_mpls();
+}
+
+/* Deactivate a task's hardwall. */
+int hardwall_deactivate(struct task_struct *task)
+{
+ unsigned long flags;
+ int activated;
+
+ spin_lock_irqsave(&hardwall_lock, flags);
+ activated = (task->thread.hardwall != NULL);
+ if (activated)
+ _hardwall_deactivate(task);
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+
+ if (!activated)
+ return -EINVAL;
+
+ printk(KERN_DEBUG "Pid %d (%s) deactivated for hardwall: cpu %d\n",
+ task->pid, task->comm, smp_processor_id());
+ return 0;
+}
+
+/* Stop a UDN switch before draining the network. */
+static void stop_udn_switch(void *ignored)
+{
+#if !CHIP_HAS_REV1_XDN()
+ /* Freeze the switch and the demux. */
+ __insn_mtspr(SPR_UDN_SP_FREEZE,
+ SPR_UDN_SP_FREEZE__SP_FRZ_MASK |
+ SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK |
+ SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK);
+#endif
+}
+
+/* Drain all the state from a stopped switch. */
+static void drain_udn_switch(void *ignored)
+{
+#if !CHIP_HAS_REV1_XDN()
+ int i;
+ int from_tile_words, ca_count;
+
+ /* Empty out the 5 switch point fifos. */
+ for (i = 0; i < 5; i++) {
+ int words, j;
+ __insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
+ words = __insn_mfspr(SPR_UDN_SP_STATE) & 0xF;
+ for (j = 0; j < words; j++)
+ (void) __insn_mfspr(SPR_UDN_SP_FIFO_DATA);
+ BUG_ON((__insn_mfspr(SPR_UDN_SP_STATE) & 0xF) != 0);
+ }
+
+ /* Dump out the 3 word fifo at top. */
+ from_tile_words = (__insn_mfspr(SPR_UDN_DEMUX_STATUS) >> 10) & 0x3;
+ for (i = 0; i < from_tile_words; i++)
+ (void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO);
+
+ /* Empty out demuxes. */
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
+ (void) __tile_udn0_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
+ (void) __tile_udn1_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
+ (void) __tile_udn2_receive();
+ while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
+ (void) __tile_udn3_receive();
+ BUG_ON((__insn_mfspr(SPR_UDN_DATA_AVAIL) & 0xF) != 0);
+
+ /* Empty out catch all. */
+ ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT);
+ for (i = 0; i < ca_count; i++)
+ (void) __insn_mfspr(SPR_UDN_CA_DATA);
+ BUG_ON(__insn_mfspr(SPR_UDN_DEMUX_CA_COUNT) != 0);
+
+ /* Clear demux logic. */
+ __insn_mtspr(SPR_UDN_DEMUX_CTL, 1);
+
+ /*
+ * Write switch state; experimentation indicates that 0xc3000
+ * is an idle switch point.
+ */
+ for (i = 0; i < 5; i++) {
+ __insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
+ __insn_mtspr(SPR_UDN_SP_STATE, 0xc3000);
+ }
+#endif
+}
+
+/* Reset random UDN state registers at boot up and during hardwall teardown. */
+void reset_network_state(void)
+{
+#if !CHIP_HAS_REV1_XDN()
+ /* Reset UDN coordinates to their standard value */
+ unsigned int cpu = smp_processor_id();
+ unsigned int x = cpu % smp_width;
+ unsigned int y = cpu / smp_width;
+#endif
+
+ if (udn_disabled)
+ return;
+
+#if !CHIP_HAS_REV1_XDN()
+ __insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
+
+ /* Set demux tags to predefined values and enable them. */
+ __insn_mtspr(SPR_UDN_TAG_VALID, 0xf);
+ __insn_mtspr(SPR_UDN_TAG_0, (1 << 0));
+ __insn_mtspr(SPR_UDN_TAG_1, (1 << 1));
+ __insn_mtspr(SPR_UDN_TAG_2, (1 << 2));
+ __insn_mtspr(SPR_UDN_TAG_3, (1 << 3));
+#endif
+
+ /* Clear out other random registers so we have a clean slate. */
+ __insn_mtspr(SPR_UDN_AVAIL_EN, 0);
+ __insn_mtspr(SPR_UDN_DEADLOCK_TIMEOUT, 0);
+#if !CHIP_HAS_REV1_XDN()
+ __insn_mtspr(SPR_UDN_REFILL_EN, 0);
+ __insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0);
+ __insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0);
+#endif
+
+ /* Start the switch and demux. */
+#if !CHIP_HAS_REV1_XDN()
+ __insn_mtspr(SPR_UDN_SP_FREEZE, 0);
+#endif
+}
+
+/* Restart a UDN switch after draining. */
+static void restart_udn_switch(void *ignored)
+{
+ reset_network_state();
+
+ /* Disable firewall interrupts. */
+ __insn_mtspr(SPR_UDN_DIRECTION_PROTECT, 0);
+ disable_firewall_interrupts();
+}
+
+/* Build a struct cpumask containing all valid tiles in bounding rectangle. */
+static void fill_mask(struct hardwall_info *r, struct cpumask *result)
+{
+ int x, y, cpu;
+
+ cpumask_clear(result);
+
+ cpu = r->ulhc_y * smp_width + r->ulhc_x;
+ for (y = 0; y < r->height; ++y, cpu += smp_width - r->width) {
+ for (x = 0; x < r->width; ++x, ++cpu)
+ cpu_online_set(cpu, result);
+ }
+}
+
+/* Last reference to a hardwall is gone, so clear the network. */
+static void hardwall_destroy(struct hardwall_info *rect)
+{
+ struct task_struct *task;
+ unsigned long flags;
+ struct cpumask mask;
+
+ /* Make sure this file actually represents a rectangle. */
+ if (rect == NULL)
+ return;
+
+ /*
+ * Deactivate any remaining tasks. It's possible to race with
+ * some other thread that is exiting and hasn't yet called
+ * deactivate (when freeing its thread_info), so we carefully
+ * deactivate any remaining tasks before freeing the
+ * hardwall_info object itself.
+ */
+ spin_lock_irqsave(&hardwall_lock, flags);
+ list_for_each_entry(task, &rect->task_head, thread.hardwall_list)
+ _hardwall_deactivate(task);
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+
+ /* Drain the UDN. */
+ printk(KERN_DEBUG "Clearing hardwall rectangle %dx%d %d,%d\n",
+ rect->width, rect->height, rect->ulhc_x, rect->ulhc_y);
+ fill_mask(rect, &mask);
+ on_each_cpu_mask(&mask, stop_udn_switch, NULL, 1);
+ on_each_cpu_mask(&mask, drain_udn_switch, NULL, 1);
+
+ /* Restart switch and disable firewall. */
+ on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
+
+ /* Now free the rectangle from the list. */
+ spin_lock_irqsave(&hardwall_lock, flags);
+ BUG_ON(!list_empty(&rect->task_head));
+ list_del(&rect->list);
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+ kfree(rect);
+}
+
+
+/*
+ * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c.
+ */
+int proc_tile_hardwall_show(struct seq_file *sf, void *v)
+{
+ struct hardwall_info *r;
+
+ if (udn_disabled) {
+ seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height);
+ return 0;
+ }
+
+ spin_lock_irq(&hardwall_lock);
+ list_for_each_entry(r, &rectangles, list) {
+ struct task_struct *p;
+ seq_printf(sf, "%dx%d %d,%d pids:",
+ r->width, r->height, r->ulhc_x, r->ulhc_y);
+ list_for_each_entry(p, &r->task_head, thread.hardwall_list) {
+ unsigned int cpu = cpumask_first(&p->cpus_allowed);
+ unsigned int x = cpu % smp_width;
+ unsigned int y = cpu / smp_width;
+ seq_printf(sf, " %d@%d,%d", p->pid, x, y);
+ }
+ seq_printf(sf, "\n");
+ }
+ spin_unlock_irq(&hardwall_lock);
+ return 0;
+}
+
+
+/*
+ * Character device support via ioctl/close.
+ */
+
+static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
+{
+ struct hardwall_info *rect = file->private_data;
+
+ if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE)
+ return -EINVAL;
+
+ switch (_IOC_NR(a)) {
+ case _HARDWALL_CREATE:
+ if (udn_disabled)
+ return -ENOSYS;
+ if (rect != NULL)
+ return -EALREADY;
+ rect = hardwall_create(_IOC_SIZE(a),
+ (const unsigned char __user *)b);
+ if (IS_ERR(rect))
+ return PTR_ERR(rect);
+ file->private_data = rect;
+ return 0;
+
+ case _HARDWALL_ACTIVATE:
+ return hardwall_activate(rect);
+
+ case _HARDWALL_DEACTIVATE:
+ if (current->thread.hardwall != rect)
+ return -EINVAL;
+ return hardwall_deactivate(current);
+
+ default:
+ return -EINVAL;
+ }
+}
+
+#ifdef CONFIG_COMPAT
+static long hardwall_compat_ioctl(struct file *file,
+ unsigned int a, unsigned long b)
+{
+ /* Sign-extend the argument so it can be used as a pointer. */
+ return hardwall_ioctl(file, a, (unsigned long)compat_ptr(b));
+}
+#endif
+
+/* The user process closed the file; revoke access to user networks. */
+static int hardwall_flush(struct file *file, fl_owner_t owner)
+{
+ struct hardwall_info *rect = file->private_data;
+ struct task_struct *task, *tmp;
+ unsigned long flags;
+
+ if (rect) {
+ /*
+ * NOTE: if multiple threads are activated on this hardwall
+ * file, the other threads will continue having access to the
+ * UDN until they are context-switched out and back in again.
+ *
+ * NOTE: A NULL files pointer means the task is being torn
+ * down, so in that case we also deactivate it.
+ */
+ spin_lock_irqsave(&hardwall_lock, flags);
+ list_for_each_entry_safe(task, tmp, &rect->task_head,
+ thread.hardwall_list) {
+ if (task->files == owner || task->files == NULL)
+ _hardwall_deactivate(task);
+ }
+ spin_unlock_irqrestore(&hardwall_lock, flags);
+ }
+
+ return 0;
+}
+
+/* This hardwall is gone, so destroy it. */
+static int hardwall_release(struct inode *inode, struct file *file)
+{
+ hardwall_destroy(file->private_data);
+ return 0;
+}
+
+static const struct file_operations dev_hardwall_fops = {
+ .unlocked_ioctl = hardwall_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = hardwall_compat_ioctl,
+#endif
+ .flush = hardwall_flush,
+ .release = hardwall_release,
+};
+
+static struct cdev hardwall_dev;
+
+static int __init dev_hardwall_init(void)
+{
+ int rc;
+ dev_t dev;
+
+ rc = alloc_chrdev_region(&dev, 0, 1, "hardwall");
+ if (rc < 0)
+ return rc;
+ cdev_init(&hardwall_dev, &dev_hardwall_fops);
+ rc = cdev_add(&hardwall_dev, dev, 1);
+ if (rc < 0)
+ return rc;
+
+ return 0;
+}
+late_initcall(dev_hardwall_init);
diff --git a/arch/tile/kernel/head_32.S b/arch/tile/kernel/head_32.S
new file mode 100644
index 000000000000..2b4f6c091701
--- /dev/null
+++ b/arch/tile/kernel/head_32.S
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * TILE startup code.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/thread_info.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
+
+/*
+ * This module contains the entry code for kernel images. It performs the
+ * minimal setup needed to call the generic C routines.
+ */
+
+ __HEAD
+ENTRY(_start)
+ /* Notify the hypervisor of what version of the API we want */
+ {
+ movei r1, TILE_CHIP
+ movei r2, TILE_CHIP_REV
+ }
+ {
+ moveli r0, _HV_VERSION
+ jal hv_init
+ }
+ /* Get a reasonable default ASID in r0 */
+ {
+ move r0, zero
+ jal hv_inquire_asid
+ }
+ /* Install the default page table */
+ {
+ moveli r6, lo16(swapper_pgprot - PAGE_OFFSET)
+ move r4, r0 /* use starting ASID of range for this page table */
+ }
+ {
+ moveli r0, lo16(swapper_pg_dir - PAGE_OFFSET)
+ auli r6, r6, ha16(swapper_pgprot - PAGE_OFFSET)
+ }
+ {
+ lw r2, r6
+ addi r6, r6, 4
+ }
+ {
+ lw r3, r6
+ auli r0, r0, ha16(swapper_pg_dir - PAGE_OFFSET)
+ }
+ {
+ inv r6
+ move r1, zero /* high 32 bits of CPA is zero */
+ }
+ {
+ moveli lr, lo16(1f)
+ move r5, zero
+ }
+ {
+ auli lr, lr, ha16(1f)
+ j hv_install_context
+ }
+1:
+
+ /* Get our processor number and save it away in SAVE_1_0. */
+ jal hv_inquire_topology
+ mulll_uu r4, r1, r2 /* r1 == y, r2 == width */
+ add r4, r4, r0 /* r0 == x, so r4 == cpu == y*width + x */
+
+#ifdef CONFIG_SMP
+ /*
+ * Load up our per-cpu offset. When the first (master) tile
+ * boots, this value is still zero, so we will load boot_pc
+ * with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
+ * The master tile initializes the per-cpu offset array, so that
+ * when subsequent (secondary) tiles boot, they will instead load
+ * from their per-cpu versions of boot_sp and boot_pc.
+ */
+ moveli r5, lo16(__per_cpu_offset)
+ auli r5, r5, ha16(__per_cpu_offset)
+ s2a r5, r4, r5
+ lw r5, r5
+ bnz r5, 1f
+
+ /*
+ * Save the width and height to the smp_topology variable
+ * for later use.
+ */
+ moveli r0, lo16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
+ auli r0, r0, ha16(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
+ {
+ sw r0, r2
+ addi r0, r0, (HV_TOPOLOGY_HEIGHT_OFFSET - HV_TOPOLOGY_WIDTH_OFFSET)
+ }
+ sw r0, r3
+1:
+#else
+ move r5, zero
+#endif
+
+ /* Load and go with the correct pc and sp. */
+ {
+ addli r1, r5, lo16(boot_sp)
+ addli r0, r5, lo16(boot_pc)
+ }
+ {
+ auli r1, r1, ha16(boot_sp)
+ auli r0, r0, ha16(boot_pc)
+ }
+ lw r0, r0
+ lw sp, r1
+ or r4, sp, r4
+ mtspr SYSTEM_SAVE_1_0, r4 /* save ksp0 + cpu */
+ addi sp, sp, -STACK_TOP_DELTA
+ {
+ move lr, zero /* stop backtraces in the called function */
+ jr r0
+ }
+ ENDPROC(_start)
+
+.section ".bss.page_aligned","w"
+ .align PAGE_SIZE
+ENTRY(empty_zero_page)
+ .fill PAGE_SIZE,1,0
+ END(empty_zero_page)
+
+ .macro PTE va, cpa, bits1, no_org=0
+ .ifeq \no_org
+ .org swapper_pg_dir + HV_L1_INDEX(\va) * HV_PTE_SIZE
+ .endif
+ .word HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED | \
+ (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
+ .word (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
+ .endm
+
+.section ".data.page_aligned","wa"
+ .align PAGE_SIZE
+ENTRY(swapper_pg_dir)
+ /*
+ * All data pages from PAGE_OFFSET to MEM_USER_INTRPT are mapped as
+ * VA = PA + PAGE_OFFSET. We remap things with more precise access
+ * permissions and more respect for size of RAM later.
+ */
+ .set addr, 0
+ .rept (MEM_USER_INTRPT - PAGE_OFFSET) >> PGDIR_SHIFT
+ PTE addr + PAGE_OFFSET, addr, HV_PTE_READABLE | HV_PTE_WRITABLE
+ .set addr, addr + PGDIR_SIZE
+ .endr
+
+ /* The true text VAs are mapped as VA = PA + MEM_SV_INTRPT */
+ PTE MEM_SV_INTRPT, 0, HV_PTE_READABLE | HV_PTE_EXECUTABLE
+ .org swapper_pg_dir + HV_L1_SIZE
+ END(swapper_pg_dir)
+
+ /*
+ * Isolate swapper_pgprot to its own cache line, since each cpu
+ * starting up will read it using VA-is-PA and local homing.
+ * This would otherwise likely conflict with other data on the cache
+ * line, once we have set its permanent home in the page tables.
+ */
+ __INITDATA
+ .align CHIP_L2_LINE_SIZE()
+ENTRY(swapper_pgprot)
+ PTE 0, 0, HV_PTE_READABLE | HV_PTE_WRITABLE, 1
+ .align CHIP_L2_LINE_SIZE()
+ END(swapper_pgprot)
diff --git a/arch/tile/kernel/hvglue.lds b/arch/tile/kernel/hvglue.lds
new file mode 100644
index 000000000000..2b7cd0a659a9
--- /dev/null
+++ b/arch/tile/kernel/hvglue.lds
@@ -0,0 +1,58 @@
+/* Hypervisor call vector addresses; see <hv/hypervisor.h> */
+hv_init = TEXT_OFFSET + 0x10020;
+hv_install_context = TEXT_OFFSET + 0x10040;
+hv_sysconf = TEXT_OFFSET + 0x10060;
+hv_get_rtc = TEXT_OFFSET + 0x10080;
+hv_set_rtc = TEXT_OFFSET + 0x100a0;
+hv_flush_asid = TEXT_OFFSET + 0x100c0;
+hv_flush_page = TEXT_OFFSET + 0x100e0;
+hv_flush_pages = TEXT_OFFSET + 0x10100;
+hv_restart = TEXT_OFFSET + 0x10120;
+hv_halt = TEXT_OFFSET + 0x10140;
+hv_power_off = TEXT_OFFSET + 0x10160;
+hv_inquire_physical = TEXT_OFFSET + 0x10180;
+hv_inquire_memory_controller = TEXT_OFFSET + 0x101a0;
+hv_inquire_virtual = TEXT_OFFSET + 0x101c0;
+hv_inquire_asid = TEXT_OFFSET + 0x101e0;
+hv_nanosleep = TEXT_OFFSET + 0x10200;
+hv_console_read_if_ready = TEXT_OFFSET + 0x10220;
+hv_console_write = TEXT_OFFSET + 0x10240;
+hv_downcall_dispatch = TEXT_OFFSET + 0x10260;
+hv_inquire_topology = TEXT_OFFSET + 0x10280;
+hv_fs_findfile = TEXT_OFFSET + 0x102a0;
+hv_fs_fstat = TEXT_OFFSET + 0x102c0;
+hv_fs_pread = TEXT_OFFSET + 0x102e0;
+hv_physaddr_read64 = TEXT_OFFSET + 0x10300;
+hv_physaddr_write64 = TEXT_OFFSET + 0x10320;
+hv_get_command_line = TEXT_OFFSET + 0x10340;
+hv_set_caching = TEXT_OFFSET + 0x10360;
+hv_bzero_page = TEXT_OFFSET + 0x10380;
+hv_register_message_state = TEXT_OFFSET + 0x103a0;
+hv_send_message = TEXT_OFFSET + 0x103c0;
+hv_receive_message = TEXT_OFFSET + 0x103e0;
+hv_inquire_context = TEXT_OFFSET + 0x10400;
+hv_start_all_tiles = TEXT_OFFSET + 0x10420;
+hv_dev_open = TEXT_OFFSET + 0x10440;
+hv_dev_close = TEXT_OFFSET + 0x10460;
+hv_dev_pread = TEXT_OFFSET + 0x10480;
+hv_dev_pwrite = TEXT_OFFSET + 0x104a0;
+hv_dev_poll = TEXT_OFFSET + 0x104c0;
+hv_dev_poll_cancel = TEXT_OFFSET + 0x104e0;
+hv_dev_preada = TEXT_OFFSET + 0x10500;
+hv_dev_pwritea = TEXT_OFFSET + 0x10520;
+hv_flush_remote = TEXT_OFFSET + 0x10540;
+hv_console_putc = TEXT_OFFSET + 0x10560;
+hv_inquire_tiles = TEXT_OFFSET + 0x10580;
+hv_confstr = TEXT_OFFSET + 0x105a0;
+hv_reexec = TEXT_OFFSET + 0x105c0;
+hv_set_command_line = TEXT_OFFSET + 0x105e0;
+hv_clear_intr = TEXT_OFFSET + 0x10600;
+hv_enable_intr = TEXT_OFFSET + 0x10620;
+hv_disable_intr = TEXT_OFFSET + 0x10640;
+hv_raise_intr = TEXT_OFFSET + 0x10660;
+hv_trigger_ipi = TEXT_OFFSET + 0x10680;
+hv_store_mapping = TEXT_OFFSET + 0x106a0;
+hv_inquire_realpa = TEXT_OFFSET + 0x106c0;
+hv_flush_all = TEXT_OFFSET + 0x106e0;
+hv_get_ipi_pte = TEXT_OFFSET + 0x10700;
+hv_glue_internals = TEXT_OFFSET + 0x10720;
diff --git a/arch/tile/kernel/init_task.c b/arch/tile/kernel/init_task.c
new file mode 100644
index 000000000000..928b31870669
--- /dev/null
+++ b/arch/tile/kernel/init_task.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+#include <linux/module.h>
+#include <linux/start_kernel.h>
+#include <linux/uaccess.h>
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is THREAD_SIZE aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union __init_task_data = {
+ INIT_THREAD_INFO(init_task)
+};
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
+
+/*
+ * per-CPU stack and boot info.
+ */
+DEFINE_PER_CPU(unsigned long, boot_sp) =
+ (unsigned long)init_stack + THREAD_SIZE;
+
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(unsigned long, boot_pc) = (unsigned long)start_kernel;
+#else
+/*
+ * The variable must be __initdata since it references __init code.
+ * With CONFIG_SMP it is per-cpu data, which is exempt from validation.
+ */
+unsigned long __initdata boot_pc = (unsigned long)start_kernel;
+#endif
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S
new file mode 100644
index 000000000000..3404c75f8e64
--- /dev/null
+++ b/arch/tile/kernel/intvec_32.S
@@ -0,0 +1,2008 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Linux interrupt vectors.
+ */
+
+#include <linux/linkage.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/unistd.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/irqflags.h>
+#include <asm/atomic.h>
+#include <asm/asm-offsets.h>
+#include <hv/hypervisor.h>
+#include <arch/abi.h>
+#include <arch/interrupts.h>
+#include <arch/spr_def.h>
+
+#ifdef CONFIG_PREEMPT
+# error "No support for kernel preemption currently"
+#endif
+
+#if INT_INTCTRL_1 < 32 || INT_INTCTRL_1 >= 48
+# error INT_INTCTRL_1 coded to set high interrupt mask
+#endif
+
+#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
+
+#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
+
+#if !CHIP_HAS_WH64()
+ /* By making this an empty macro, we can use wh64 in the code. */
+ .macro wh64 reg
+ .endm
+#endif
+
+ .macro push_reg reg, ptr=sp, delta=-4
+ {
+ sw \ptr, \reg
+ addli \ptr, \ptr, \delta
+ }
+ .endm
+
+ .macro pop_reg reg, ptr=sp, delta=4
+ {
+ lw \reg, \ptr
+ addli \ptr, \ptr, \delta
+ }
+ .endm
+
+ .macro pop_reg_zero reg, zreg, ptr=sp, delta=4
+ {
+ move \zreg, zero
+ lw \reg, \ptr
+ addi \ptr, \ptr, \delta
+ }
+ .endm
+
+ .macro push_extra_callee_saves reg
+ PTREGS_PTR(\reg, PTREGS_OFFSET_REG(51))
+ push_reg r51, \reg
+ push_reg r50, \reg
+ push_reg r49, \reg
+ push_reg r48, \reg
+ push_reg r47, \reg
+ push_reg r46, \reg
+ push_reg r45, \reg
+ push_reg r44, \reg
+ push_reg r43, \reg
+ push_reg r42, \reg
+ push_reg r41, \reg
+ push_reg r40, \reg
+ push_reg r39, \reg
+ push_reg r38, \reg
+ push_reg r37, \reg
+ push_reg r36, \reg
+ push_reg r35, \reg
+ push_reg r34, \reg, PTREGS_OFFSET_BASE - PTREGS_OFFSET_REG(34)
+ .endm
+
+ .macro panic str
+ .pushsection .rodata, "a"
+1:
+ .asciz "\str"
+ .popsection
+ {
+ moveli r0, lo16(1b)
+ }
+ {
+ auli r0, r0, ha16(1b)
+ jal panic
+ }
+ .endm
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+ .pushsection .text.intvec_feedback,"ax"
+intvec_feedback:
+ .popsection
+#endif
+
+ /*
+ * Default interrupt handler.
+ *
+ * vecnum is where we'll put this code.
+ * c_routine is the C routine we'll call.
+ *
+ * The C routine is passed two arguments:
+ * - A pointer to the pt_regs state.
+ * - The interrupt vector number.
+ *
+ * The "processing" argument specifies the code for processing
+ * the interrupt. Defaults to "handle_interrupt".
+ */
+ .macro int_hand vecnum, vecname, c_routine, processing=handle_interrupt
+ .org (\vecnum << 8)
+intvec_\vecname:
+ .ifc \vecnum, INT_SWINT_1
+ blz TREG_SYSCALL_NR_NAME, sys_cmpxchg
+ .endif
+
+ /* Temporarily save a register so we have somewhere to work. */
+
+ mtspr SYSTEM_SAVE_1_1, r0
+ mfspr r0, EX_CONTEXT_1_1
+
+ /* The cmpxchg code clears sp to force us to reset it here on fault. */
+ {
+ bz sp, 2f
+ andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
+ }
+
+ .ifc \vecnum, INT_DOUBLE_FAULT
+ /*
+ * For double-faults from user-space, fall through to the normal
+ * register save and stack setup path. Otherwise, it's the
+ * hypervisor giving us one last chance to dump diagnostics, and we
+ * branch to the kernel_double_fault routine to do so.
+ */
+ bz r0, 1f
+ j _kernel_double_fault
+1:
+ .else
+ /*
+ * If we're coming from user-space, then set sp to the top of
+ * the kernel stack. Otherwise, assume sp is already valid.
+ */
+ {
+ bnz r0, 0f
+ move r0, sp
+ }
+ .endif
+
+ .ifc \c_routine, do_page_fault
+ /*
+ * The page_fault handler may be downcalled directly by the
+ * hypervisor even when Linux is running and has ICS set.
+ *
+ * In this case the contents of EX_CONTEXT_1_1 reflect the
+ * previous fault and can't be relied on to choose whether or
+ * not to reinitialize the stack pointer. So we add a test
+ * to see whether SYSTEM_SAVE_1_2 has the high bit set,
+ * and if so we don't reinitialize sp, since we must be coming
+ * from Linux. (In fact the precise case is !(val & ~1),
+ * but any Linux PC has to have the high bit set.)
+ *
+ * Note that the hypervisor *always* sets SYSTEM_SAVE_1_2 for
+ * any path that turns into a downcall to one of our TLB handlers.
+ */
+ mfspr r0, SYSTEM_SAVE_1_2
+ {
+ blz r0, 0f /* high bit in S_S_1_2 is for a PC to use */
+ move r0, sp
+ }
+ .endif
+
+2:
+ /*
+ * SYSTEM_SAVE_1_0 holds the cpu number in the low bits, and
+ * the current stack top in the higher bits. So we recover
+ * our stack top by just masking off the low bits, then
+ * point sp at the top aligned address on the actual stack page.
+ */
+ mfspr r0, SYSTEM_SAVE_1_0
+ mm r0, r0, zero, LOG2_THREAD_SIZE, 31
+
+0:
+ /*
+ * Align the stack mod 64 so we can properly predict what
+ * cache lines we need to write-hint to reduce memory fetch
+ * latency as we enter the kernel. The layout of memory is
+ * as follows, with cache line 0 at the lowest VA, and cache
+ * line 4 just below the r0 value this "andi" computes.
+ * Note that we never write to cache line 4, and we skip
+ * cache line 1 for syscalls.
+ *
+ * cache line 4: ptregs padding (two words)
+ * cache line 3: r46...lr, pc, ex1, faultnum, orig_r0, flags, pad
+ * cache line 2: r30...r45
+ * cache line 1: r14...r29
+ * cache line 0: 2 x frame, r0..r13
+ */
+ andi r0, r0, -64
+
+ /*
+ * Push the first four registers on the stack, so that we can set
+ * them to vector-unique values before we jump to the common code.
+ *
+ * Registers are pushed on the stack as a struct pt_regs,
+ * with the sp initially just above the struct, and when we're
+ * done, sp points to the base of the struct, minus
+ * C_ABI_SAVE_AREA_SIZE, so we can directly jal to C code.
+ *
+ * This routine saves just the first four registers, plus the
+ * stack context so we can do proper backtracing right away,
+ * and defers to handle_interrupt to save the rest.
+ * The backtracer needs pc, ex1, lr, sp, r52, and faultnum.
+ */
+ addli r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP)
+ wh64 r0 /* cache line 3 */
+ {
+ sw r0, lr
+ addli r0, r0, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
+ }
+ {
+ sw r0, sp
+ addli sp, r0, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_SP
+ }
+ {
+ sw sp, r52
+ addli sp, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(52)
+ }
+ wh64 sp /* cache line 0 */
+ {
+ sw sp, r1
+ addli sp, sp, PTREGS_OFFSET_REG(2) - PTREGS_OFFSET_REG(1)
+ }
+ {
+ sw sp, r2
+ addli sp, sp, PTREGS_OFFSET_REG(3) - PTREGS_OFFSET_REG(2)
+ }
+ {
+ sw sp, r3
+ addli sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3)
+ }
+ mfspr r0, EX_CONTEXT_1_0
+ .ifc \processing,handle_syscall
+ /*
+ * Bump the saved PC by one bundle so that when we return, we won't
+ * execute the same swint instruction again. We need to do this while
+ * we're in the critical section.
+ */
+ addi r0, r0, 8
+ .endif
+ {
+ sw sp, r0
+ addli sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
+ }
+ mfspr r0, EX_CONTEXT_1_1
+ {
+ sw sp, r0
+ addi sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
+ /*
+ * Use r0 for syscalls so it's a temporary; use r1 for interrupts
+ * so that it gets passed through unchanged to the handler routine.
+ * Note that the .if conditional confusingly spans bundles.
+ */
+ .ifc \processing,handle_syscall
+ movei r0, \vecnum
+ }
+ {
+ sw sp, r0
+ .else
+ movei r1, \vecnum
+ }
+ {
+ sw sp, r1
+ .endif
+ addli sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM
+ }
+ mfspr r0, SYSTEM_SAVE_1_1 /* Original r0 */
+ {
+ sw sp, r0
+ addi sp, sp, -PTREGS_OFFSET_REG(0) - 4
+ }
+ {
+ sw sp, zero /* write zero into "Next SP" frame pointer */
+ addi sp, sp, -4 /* leave SP pointing at bottom of frame */
+ }
+ .ifc \processing,handle_syscall
+ j handle_syscall
+ .else
+ /*
+ * Capture per-interrupt SPR context to registers.
+ * We overload the meaning of r3 on this path such that if its bit 31
+ * is set, we have to mask all interrupts including NMIs before
+ * clearing the interrupt critical section bit.
+ * See discussion below at "finish_interrupt_save".
+ */
+ .ifc \c_routine, do_page_fault
+ mfspr r2, SYSTEM_SAVE_1_3 /* address of page fault */
+ mfspr r3, SYSTEM_SAVE_1_2 /* info about page fault */
+ .else
+ .ifc \vecnum, INT_DOUBLE_FAULT
+ {
+ mfspr r2, SYSTEM_SAVE_1_2 /* double fault info from HV */
+ movei r3, 0
+ }
+ .else
+ .ifc \c_routine, do_trap
+ {
+ mfspr r2, GPV_REASON
+ movei r3, 0
+ }
+ .else
+ .ifc \c_routine, op_handle_perf_interrupt
+ {
+ mfspr r2, PERF_COUNT_STS
+ movei r3, -1 /* not used, but set for consistency */
+ }
+ .else
+#if CHIP_HAS_AUX_PERF_COUNTERS()
+ .ifc \c_routine, op_handle_aux_perf_interrupt
+ {
+ mfspr r2, AUX_PERF_COUNT_STS
+ movei r3, -1 /* not used, but set for consistency */
+ }
+ .else
+#endif
+ movei r3, 0
+#if CHIP_HAS_AUX_PERF_COUNTERS()
+ .endif
+#endif
+ .endif
+ .endif
+ .endif
+ .endif
+ /* Put function pointer in r0 */
+ moveli r0, lo16(\c_routine)
+ {
+ auli r0, r0, ha16(\c_routine)
+ j \processing
+ }
+ .endif
+ ENDPROC(intvec_\vecname)
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+ .pushsection .text.intvec_feedback,"ax"
+ .org (\vecnum << 5)
+ FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8)
+ jrp lr
+ .popsection
+#endif
+
+ .endm
+
+
+ /*
+ * Save the rest of the registers that we didn't save in the actual
+ * vector itself. We can't use r0-r10 inclusive here.
+ */
+ .macro finish_interrupt_save, function
+
+ /* If it's a syscall, save a proper orig_r0, otherwise just zero. */
+ PTREGS_PTR(r52, PTREGS_OFFSET_ORIG_R0)
+ {
+ .ifc \function,handle_syscall
+ sw r52, r0
+ .else
+ sw r52, zero
+ .endif
+ PTREGS_PTR(r52, PTREGS_OFFSET_TP)
+ }
+
+ /*
+ * For ordinary syscalls, we save neither caller- nor callee-
+ * save registers, since the syscall invoker doesn't expect the
+ * caller-saves to be saved, and the called kernel functions will
+ * take care of saving the callee-saves for us.
+ *
+ * For interrupts we save just the caller-save registers. Saving
+ * them is required (since the "caller" can't save them). Again,
+ * the called kernel functions will restore the callee-save
+ * registers for us appropriately.
+ *
+ * On return, we normally restore nothing special for syscalls,
+ * and just the caller-save registers for interrupts.
+ *
+ * However, there are some important caveats to all this:
+ *
+ * - We always save a few callee-save registers to give us
+ * some scratchpad registers to carry across function calls.
+ *
+ * - fork/vfork/etc require us to save all the callee-save
+ * registers, which we do in PTREGS_SYSCALL_ALL_REGS, below.
+ *
+ * - We always save r0..r5 and r10 for syscalls, since we need
+ * to reload them a bit later for the actual kernel call, and
+ * since we might need them for -ERESTARTNOINTR, etc.
+ *
+ * - Before invoking a signal handler, we save the unsaved
+ * callee-save registers so they are visible to the
+ * signal handler or any ptracer.
+ *
+ * - If the unsaved callee-save registers are modified, we set
+ * a bit in pt_regs so we know to reload them from pt_regs
+ * and not just rely on the kernel function unwinding.
+ * (Done for ptrace register writes and SA_SIGINFO handler.)
+ */
+ {
+ sw r52, tp
+ PTREGS_PTR(r52, PTREGS_OFFSET_REG(33))
+ }
+ wh64 r52 /* cache line 2 */
+ push_reg r33, r52
+ push_reg r32, r52
+ push_reg r31, r52
+ .ifc \function,handle_syscall
+ push_reg r30, r52, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(30)
+ push_reg TREG_SYSCALL_NR_NAME, r52, \
+ PTREGS_OFFSET_REG(5) - PTREGS_OFFSET_SYSCALL
+ .else
+
+ push_reg r30, r52, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(30)
+ wh64 r52 /* cache line 1 */
+ push_reg r29, r52
+ push_reg r28, r52
+ push_reg r27, r52
+ push_reg r26, r52
+ push_reg r25, r52
+ push_reg r24, r52
+ push_reg r23, r52
+ push_reg r22, r52
+ push_reg r21, r52
+ push_reg r20, r52
+ push_reg r19, r52
+ push_reg r18, r52
+ push_reg r17, r52
+ push_reg r16, r52
+ push_reg r15, r52
+ push_reg r14, r52
+ push_reg r13, r52
+ push_reg r12, r52
+ push_reg r11, r52
+ push_reg r10, r52
+ push_reg r9, r52
+ push_reg r8, r52
+ push_reg r7, r52
+ push_reg r6, r52
+
+ .endif
+
+ push_reg r5, r52
+ sw r52, r4
+
+ /* Load tp with our per-cpu offset. */
+#ifdef CONFIG_SMP
+ {
+ mfspr r20, SYSTEM_SAVE_1_0
+ moveli r21, lo16(__per_cpu_offset)
+ }
+ {
+ auli r21, r21, ha16(__per_cpu_offset)
+ mm r20, r20, zero, 0, LOG2_THREAD_SIZE-1
+ }
+ s2a r20, r20, r21
+ lw tp, r20
+#else
+ move tp, zero
+#endif
+
+ /*
+ * If we will be returning to the kernel, we will need to
+ * reset the interrupt masks to the state they had before.
+ * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled.
+ * We load flags in r32 here so we can jump to .Lrestore_regs
+ * directly after do_page_fault_ics() if necessary.
+ */
+ mfspr r32, EX_CONTEXT_1_1
+ {
+ andi r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
+ PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
+ }
+ bzt r32, 1f /* zero if from user space */
+ IRQS_DISABLED(r32) /* zero if irqs enabled */
+#if PT_FLAGS_DISABLE_IRQ != 1
+# error Value of IRQS_DISABLED used to set PT_FLAGS_DISABLE_IRQ; fix
+#endif
+1:
+ .ifnc \function,handle_syscall
+ /* Record the fact that we saved the caller-save registers above. */
+ ori r32, r32, PT_FLAGS_CALLER_SAVES
+ .endif
+ sw r21, r32
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+ /*
+ * Notify the feedback routines that we were in the
+ * appropriate fixed interrupt vector area. Note that we
+ * still have ICS set at this point, so we can't invoke any
+ * atomic operations or we will panic. The feedback
+ * routines internally preserve r0..r10 and r30 up.
+ */
+ .ifnc \function,handle_syscall
+ shli r20, r1, 5
+ .else
+ moveli r20, INT_SWINT_1 << 5
+ .endif
+ addli r20, r20, lo16(intvec_feedback)
+ auli r20, r20, ha16(intvec_feedback)
+ jalr r20
+
+ /* And now notify the feedback routines that we are here. */
+ FEEDBACK_ENTER(\function)
+#endif
+
+ /*
+ * we've captured enough state to the stack (including in
+ * particular our EX_CONTEXT state) that we can now release
+ * the interrupt critical section and replace it with our
+ * standard "interrupts disabled" mask value. This allows
+ * synchronous interrupts (and profile interrupts) to punch
+ * through from this point onwards.
+ *
+ * If bit 31 of r3 is set during a non-NMI interrupt, we know we
+ * are on the path where the hypervisor has punched through our
+ * ICS with a page fault, so we call out to do_page_fault_ics()
+ * to figure out what to do with it. If the fault was in
+ * an atomic op, we unlock the atomic lock, adjust the
+ * saved register state a little, and return "zero" in r4,
+ * falling through into the normal page-fault interrupt code.
+ * If the fault was in a kernel-space atomic operation, then
+ * do_page_fault_ics() resolves it itself, returns "one" in r4,
+ * and as a result goes directly to restoring registers and iret,
+ * without trying to adjust the interrupt masks at all.
+ * The do_page_fault_ics() API involves passing and returning
+ * a five-word struct (in registers) to avoid writing the
+ * save and restore code here.
+ */
+ .ifc \function,handle_nmi
+ IRQ_DISABLE_ALL(r20)
+ .else
+ .ifnc \function,handle_syscall
+ bgezt r3, 1f
+ {
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ jal do_page_fault_ics
+ }
+ FEEDBACK_REENTER(\function)
+ bzt r4, 1f
+ j .Lrestore_regs
+1:
+ .endif
+ IRQ_DISABLE(r20, r21)
+ .endif
+ mtspr INTERRUPT_CRITICAL_SECTION, zero
+
+#if CHIP_HAS_WH64()
+ /*
+ * Prepare the first 256 stack bytes to be rapidly accessible
+ * without having to fetch the background data. We don't really
+ * know how far to write-hint, but kernel stacks generally
+ * aren't that big, and write-hinting here does take some time.
+ */
+ addi r52, sp, -64
+ {
+ wh64 r52
+ addi r52, r52, -64
+ }
+ {
+ wh64 r52
+ addi r52, r52, -64
+ }
+ {
+ wh64 r52
+ addi r52, r52, -64
+ }
+ wh64 r52
+#endif
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+ .ifnc \function,handle_nmi
+ /*
+ * We finally have enough state set up to notify the irq
+ * tracing code that irqs were disabled on entry to the handler.
+ * The TRACE_IRQS_OFF call clobbers registers r0-r29.
+ * For syscalls, we already have the register state saved away
+ * on the stack, so we don't bother to do any register saves here,
+ * and later we pop the registers back off the kernel stack.
+ * For interrupt handlers, save r0-r3 in callee-saved registers.
+ */
+ .ifnc \function,handle_syscall
+ { move r30, r0; move r31, r1 }
+ { move r32, r2; move r33, r3 }
+ .endif
+ TRACE_IRQS_OFF
+ .ifnc \function,handle_syscall
+ { move r0, r30; move r1, r31 }
+ { move r2, r32; move r3, r33 }
+ .endif
+ .endif
+#endif
+
+ .endm
+
+ .macro check_single_stepping, kind, not_single_stepping
+ /*
+ * Check for single stepping in user-level priv
+ * kind can be "normal", "ill", or "syscall"
+ * At end, if fall-thru
+ * r29: thread_info->step_state
+ * r28: &pt_regs->pc
+ * r27: pt_regs->pc
+ * r26: thread_info->step_state->buffer
+ */
+
+ /* Check for single stepping */
+ GET_THREAD_INFO(r29)
+ {
+ /* Get pointer to field holding step state */
+ addi r29, r29, THREAD_INFO_STEP_STATE_OFFSET
+
+ /* Get pointer to EX1 in register state */
+ PTREGS_PTR(r27, PTREGS_OFFSET_EX1)
+ }
+ {
+ /* Get pointer to field holding PC */
+ PTREGS_PTR(r28, PTREGS_OFFSET_PC)
+
+ /* Load the pointer to the step state */
+ lw r29, r29
+ }
+ /* Load EX1 */
+ lw r27, r27
+ {
+ /* Points to flags */
+ addi r23, r29, SINGLESTEP_STATE_FLAGS_OFFSET
+
+ /* No single stepping if there is no step state structure */
+ bzt r29, \not_single_stepping
+ }
+ {
+ /* mask off ICS and any other high bits */
+ andi r27, r27, SPR_EX_CONTEXT_1_1__PL_MASK
+
+ /* Load pointer to single step instruction buffer */
+ lw r26, r29
+ }
+ /* Check priv state */
+ bnz r27, \not_single_stepping
+
+ /* Get flags */
+ lw r22, r23
+ {
+ /* Branch if single-step mode not enabled */
+ bbnst r22, \not_single_stepping
+
+ /* Clear enabled flag */
+ andi r22, r22, ~SINGLESTEP_STATE_MASK_IS_ENABLED
+ }
+ .ifc \kind,normal
+ {
+ /* Load PC */
+ lw r27, r28
+
+ /* Point to the entry containing the original PC */
+ addi r24, r29, SINGLESTEP_STATE_ORIG_PC_OFFSET
+ }
+ {
+ /* Disable single stepping flag */
+ sw r23, r22
+ }
+ {
+ /* Get the original pc */
+ lw r24, r24
+
+ /* See if the PC is at the start of the single step buffer */
+ seq r25, r26, r27
+ }
+ /*
+ * NOTE: it is really expected that the PC be in the single step buffer
+ * at this point
+ */
+ bzt r25, \not_single_stepping
+
+ /* Restore the original PC */
+ sw r28, r24
+ .else
+ .ifc \kind,syscall
+ {
+ /* Load PC */
+ lw r27, r28
+
+ /* Point to the entry containing the next PC */
+ addi r24, r29, SINGLESTEP_STATE_NEXT_PC_OFFSET
+ }
+ {
+ /* Increment the stopped PC by the bundle size */
+ addi r26, r26, 8
+
+ /* Disable single stepping flag */
+ sw r23, r22
+ }
+ {
+ /* Get the next pc */
+ lw r24, r24
+
+ /*
+ * See if the PC is one bundle past the start of the
+ * single step buffer
+ */
+ seq r25, r26, r27
+ }
+ {
+ /*
+ * NOTE: it is really expected that the PC be in the
+ * single step buffer at this point
+ */
+ bzt r25, \not_single_stepping
+ }
+ /* Set to the next PC */
+ sw r28, r24
+ .else
+ {
+ /* Point to 3rd bundle in buffer */
+ addi r25, r26, 16
+
+ /* Load PC */
+ lw r27, r28
+ }
+ {
+ /* Disable single stepping flag */
+ sw r23, r22
+
+ /* See if the PC is in the single step buffer */
+ slte_u r24, r26, r27
+ }
+ {
+ slte_u r25, r27, r25
+
+ /*
+ * NOTE: it is really expected that the PC be in the
+ * single step buffer at this point
+ */
+ bzt r24, \not_single_stepping
+ }
+ bzt r25, \not_single_stepping
+ .endif
+ .endif
+ .endm
+
+ /*
+ * Redispatch a downcall.
+ */
+ .macro dc_dispatch vecnum, vecname
+ .org (\vecnum << 8)
+intvec_\vecname:
+ j hv_downcall_dispatch
+ ENDPROC(intvec_\vecname)
+ .endm
+
+ /*
+ * Common code for most interrupts. The C function we're eventually
+ * going to is in r0, and the faultnum is in r1; the original
+ * values for those registers are on the stack.
+ */
+ .pushsection .text.handle_interrupt,"ax"
+handle_interrupt:
+ finish_interrupt_save handle_interrupt
+
+ /*
+ * Check for if we are single stepping in user level. If so, then
+ * we need to restore the PC.
+ */
+
+ check_single_stepping normal, .Ldispatch_interrupt
+.Ldispatch_interrupt:
+
+ /* Jump to the C routine; it should enable irqs as soon as possible. */
+ {
+ jalr r0
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ }
+ FEEDBACK_REENTER(handle_interrupt)
+ {
+ movei r30, 0 /* not an NMI */
+ j interrupt_return
+ }
+ STD_ENDPROC(handle_interrupt)
+
+/*
+ * This routine takes a boolean in r30 indicating if this is an NMI.
+ * If so, we also expect a boolean in r31 indicating whether to
+ * re-enable the oprofile interrupts.
+ */
+STD_ENTRY(interrupt_return)
+ /* If we're resuming to kernel space, don't check thread flags. */
+ {
+ bnz r30, .Lrestore_all /* NMIs don't special-case user-space */
+ PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
+ }
+ lw r29, r29
+ andi r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
+ {
+ bzt r29, .Lresume_userspace
+ PTREGS_PTR(r29, PTREGS_OFFSET_PC)
+ }
+
+ /* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
+ {
+ lw r28, r29
+ moveli r27, lo16(_cpu_idle_nap)
+ }
+ {
+ auli r27, r27, ha16(_cpu_idle_nap)
+ }
+ {
+ seq r27, r27, r28
+ }
+ {
+ bbns r27, .Lrestore_all
+ addi r28, r28, 8
+ }
+ sw r29, r28
+ j .Lrestore_all
+
+.Lresume_userspace:
+ FEEDBACK_REENTER(interrupt_return)
+
+ /*
+ * Disable interrupts so as to make sure we don't
+ * miss an interrupt that sets any of the thread flags (like
+ * need_resched or sigpending) between sampling and the iret.
+ * Routines like schedule() or do_signal() may re-enable
+ * interrupts before returning.
+ */
+ IRQ_DISABLE(r20, r21)
+ TRACE_IRQS_OFF /* Note: clobbers registers r0-r29 */
+
+ /* Get base of stack in r32; note r30/31 are used as arguments here. */
+ GET_THREAD_INFO(r32)
+
+
+ /* Check to see if there is any work to do before returning to user. */
+ {
+ addi r29, r32, THREAD_INFO_FLAGS_OFFSET
+ moveli r28, lo16(_TIF_ALLWORK_MASK)
+ }
+ {
+ lw r29, r29
+ auli r28, r28, ha16(_TIF_ALLWORK_MASK)
+ }
+ and r28, r29, r28
+ bnz r28, .Lwork_pending
+
+ /*
+ * In the NMI case we
+ * omit the call to single_process_check_nohz, which normally checks
+ * to see if we should start or stop the scheduler tick, because
+ * we can't call arbitrary Linux code from an NMI context.
+ * We always call the homecache TLB deferral code to re-trigger
+ * the deferral mechanism.
+ *
+ * The other chunk of responsibility this code has is to reset the
+ * interrupt masks appropriately to reset irqs and NMIs. We have
+ * to call TRACE_IRQS_OFF and TRACE_IRQS_ON to support all the
+ * lockdep-type stuff, but we can't set ICS until afterwards, since
+ * ICS can only be used in very tight chunks of code to avoid
+ * tripping over various assertions that it is off.
+ *
+ * (There is what looks like a window of vulnerability here since
+ * we might take a profile interrupt between the two SPR writes
+ * that set the mask, but since we write the low SPR word first,
+ * and our interrupt entry code checks the low SPR word, any
+ * profile interrupt will actually disable interrupts in both SPRs
+ * before returning, which is OK.)
+ */
+.Lrestore_all:
+ PTREGS_PTR(r0, PTREGS_OFFSET_EX1)
+ {
+ lw r0, r0
+ PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS)
+ }
+ {
+ andi r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK
+ lw r32, r32
+ }
+ bnz r0, 1f
+ j 2f
+#if PT_FLAGS_DISABLE_IRQ != 1
+# error Assuming PT_FLAGS_DISABLE_IRQ == 1 so we can use bbnst below
+#endif
+1: bbnst r32, 2f
+ IRQ_DISABLE(r20,r21)
+ TRACE_IRQS_OFF
+ movei r0, 1
+ mtspr INTERRUPT_CRITICAL_SECTION, r0
+ bzt r30, .Lrestore_regs
+ j 3f
+2: TRACE_IRQS_ON
+ movei r0, 1
+ mtspr INTERRUPT_CRITICAL_SECTION, r0
+ IRQ_ENABLE(r20, r21)
+ bzt r30, .Lrestore_regs
+3:
+
+
+ /*
+ * We now commit to returning from this interrupt, since we will be
+ * doing things like setting EX_CONTEXT SPRs and unwinding the stack
+ * frame. No calls should be made to any other code after this point.
+ * This code should only be entered with ICS set.
+ * r32 must still be set to ptregs.flags.
+ * We launch loads to each cache line separately first, so we can
+ * get some parallelism out of the memory subsystem.
+ * We start zeroing caller-saved registers throughout, since
+ * that will save some cycles if this turns out to be a syscall.
+ */
+.Lrestore_regs:
+ FEEDBACK_REENTER(interrupt_return) /* called from elsewhere */
+
+ /*
+ * Rotate so we have one high bit and one low bit to test.
+ * - low bit says whether to restore all the callee-saved registers,
+ * or just r30-r33, and r52 up.
+ * - high bit (i.e. sign bit) says whether to restore all the
+ * caller-saved registers, or just r0.
+ */
+#if PT_FLAGS_CALLER_SAVES != 2 || PT_FLAGS_RESTORE_REGS != 4
+# error Rotate trick does not work :-)
+#endif
+ {
+ rli r20, r32, 30
+ PTREGS_PTR(sp, PTREGS_OFFSET_REG(0))
+ }
+
+ /*
+ * Load cache lines 0, 2, and 3 in that order, then use
+ * the last loaded value, which makes it likely that the other
+ * cache lines have also loaded, at which point we should be
+ * able to safely read all the remaining words on those cache
+ * lines without waiting for the memory subsystem.
+ */
+ pop_reg_zero r0, r1, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0)
+ pop_reg_zero r30, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(30)
+ pop_reg_zero r21, r3, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
+ pop_reg_zero lr, r4, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_EX1
+ {
+ mtspr EX_CONTEXT_1_0, r21
+ move r5, zero
+ }
+ {
+ mtspr EX_CONTEXT_1_1, lr
+ andi lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
+ }
+
+ /* Restore callee-saveds that we actually use. */
+ pop_reg_zero r52, r6, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_REG(52)
+ pop_reg_zero r31, r7
+ pop_reg_zero r32, r8
+ pop_reg_zero r33, r9, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(33)
+
+ /*
+ * If we modified other callee-saveds, restore them now.
+ * This is rare, but could be via ptrace or signal handler.
+ */
+ {
+ move r10, zero
+ bbs r20, .Lrestore_callees
+ }
+.Lcontinue_restore_regs:
+
+ /* Check if we're returning from a syscall. */
+ {
+ move r11, zero
+ blzt r20, 1f /* no, so go restore callee-save registers */
+ }
+
+ /*
+ * Check if we're returning to userspace.
+ * Note that if we're not, we don't worry about zeroing everything.
+ */
+ {
+ addli sp, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(29)
+ bnz lr, .Lkernel_return
+ }
+
+ /*
+ * On return from syscall, we've restored r0 from pt_regs, but we
+ * clear the remainder of the caller-saved registers. We could
+ * restore the syscall arguments, but there's not much point,
+ * and it ensures user programs aren't trying to use the
+ * caller-saves if we clear them, as well as avoiding leaking
+ * kernel pointers into userspace.
+ */
+ pop_reg_zero lr, r12, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
+ pop_reg_zero tp, r13, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
+ {
+ lw sp, sp
+ move r14, zero
+ move r15, zero
+ }
+ { move r16, zero; move r17, zero }
+ { move r18, zero; move r19, zero }
+ { move r20, zero; move r21, zero }
+ { move r22, zero; move r23, zero }
+ { move r24, zero; move r25, zero }
+ { move r26, zero; move r27, zero }
+ { move r28, zero; move r29, zero }
+ iret
+
+ /*
+ * Not a syscall, so restore caller-saved registers.
+ * First kick off a load for cache line 1, which we're touching
+ * for the first time here.
+ */
+ .align 64
+1: pop_reg r29, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(29)
+ pop_reg r1
+ pop_reg r2
+ pop_reg r3
+ pop_reg r4
+ pop_reg r5
+ pop_reg r6
+ pop_reg r7
+ pop_reg r8
+ pop_reg r9
+ pop_reg r10
+ pop_reg r11
+ pop_reg r12
+ pop_reg r13
+ pop_reg r14
+ pop_reg r15
+ pop_reg r16
+ pop_reg r17
+ pop_reg r18
+ pop_reg r19
+ pop_reg r20
+ pop_reg r21
+ pop_reg r22
+ pop_reg r23
+ pop_reg r24
+ pop_reg r25
+ pop_reg r26
+ pop_reg r27
+ pop_reg r28, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(28)
+ /* r29 already restored above */
+ bnz lr, .Lkernel_return
+ pop_reg lr, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
+ pop_reg tp, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
+ lw sp, sp
+ iret
+
+ /*
+ * We can't restore tp when in kernel mode, since a thread might
+ * have migrated from another cpu and brought a stale tp value.
+ */
+.Lkernel_return:
+ pop_reg lr, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
+ lw sp, sp
+ iret
+
+ /* Restore callee-saved registers from r34 to r51. */
+.Lrestore_callees:
+ addli sp, sp, PTREGS_OFFSET_REG(34) - PTREGS_OFFSET_REG(29)
+ pop_reg r34
+ pop_reg r35
+ pop_reg r36
+ pop_reg r37
+ pop_reg r38
+ pop_reg r39
+ pop_reg r40
+ pop_reg r41
+ pop_reg r42
+ pop_reg r43
+ pop_reg r44
+ pop_reg r45
+ pop_reg r46
+ pop_reg r47
+ pop_reg r48
+ pop_reg r49
+ pop_reg r50
+ pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
+ j .Lcontinue_restore_regs
+
+.Lwork_pending:
+ /* Mask the reschedule flag */
+ andi r28, r29, _TIF_NEED_RESCHED
+
+ {
+ /*
+ * If the NEED_RESCHED flag is called, we call schedule(), which
+ * may drop this context right here and go do something else.
+ * On return, jump back to .Lresume_userspace and recheck.
+ */
+ bz r28, .Lasync_tlb
+
+ /* Mask the async-tlb flag */
+ andi r28, r29, _TIF_ASYNC_TLB
+ }
+
+ jal schedule
+ FEEDBACK_REENTER(interrupt_return)
+
+ /* Reload the flags and check again */
+ j .Lresume_userspace
+
+.Lasync_tlb:
+ {
+ bz r28, .Lneed_sigpending
+
+ /* Mask the sigpending flag */
+ andi r28, r29, _TIF_SIGPENDING
+ }
+
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ jal do_async_page_fault
+ FEEDBACK_REENTER(interrupt_return)
+
+ /*
+ * Go restart the "resume userspace" process. We may have
+ * fired a signal, and we need to disable interrupts again.
+ */
+ j .Lresume_userspace
+
+.Lneed_sigpending:
+ /*
+ * At this point we are either doing signal handling or single-step,
+ * so either way make sure we have all the registers saved.
+ */
+ push_extra_callee_saves r0
+
+ {
+ /* If no signal pending, skip to singlestep check */
+ bz r28, .Lneed_singlestep
+
+ /* Mask the singlestep flag */
+ andi r28, r29, _TIF_SINGLESTEP
+ }
+
+ jal do_signal
+ FEEDBACK_REENTER(interrupt_return)
+
+ /* Reload the flags and check again */
+ j .Lresume_userspace
+
+.Lneed_singlestep:
+ {
+ /* Get a pointer to the EX1 field */
+ PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
+
+ /* If we get here, our bit must be set. */
+ bz r28, .Lwork_confusion
+ }
+ /* If we are in priv mode, don't single step */
+ lw r28, r29
+ andi r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK /* mask off ICS */
+ bnz r28, .Lrestore_all
+
+ /* Allow interrupts within the single step code */
+ TRACE_IRQS_ON /* Note: clobbers registers r0-r29 */
+ IRQ_ENABLE(r20, r21)
+
+ /* try to single-step the current instruction */
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ jal single_step_once
+ FEEDBACK_REENTER(interrupt_return)
+
+ /* Re-disable interrupts. TRACE_IRQS_OFF in .Lrestore_all. */
+ IRQ_DISABLE(r20,r21)
+
+ j .Lrestore_all
+
+.Lwork_confusion:
+ move r0, r28
+ panic "thread_info allwork flags unhandled on userspace resume: %#x"
+
+ STD_ENDPROC(interrupt_return)
+
+ /*
+ * This interrupt variant clears the INT_INTCTRL_1 interrupt mask bit
+ * before returning, so we can properly get more downcalls.
+ */
+ .pushsection .text.handle_interrupt_downcall,"ax"
+handle_interrupt_downcall:
+ finish_interrupt_save handle_interrupt_downcall
+ check_single_stepping normal, .Ldispatch_downcall
+.Ldispatch_downcall:
+
+ /* Clear INTCTRL_1 from the set of interrupts we ever enable. */
+ GET_INTERRUPTS_ENABLED_MASK_PTR(r30)
+ {
+ addi r30, r30, 4
+ movei r31, INT_MASK(INT_INTCTRL_1)
+ }
+ {
+ lw r20, r30
+ nor r21, r31, zero
+ }
+ and r20, r20, r21
+ sw r30, r20
+
+ {
+ jalr r0
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ }
+ FEEDBACK_REENTER(handle_interrupt_downcall)
+
+ /* Allow INTCTRL_1 to be enabled next time we enable interrupts. */
+ lw r20, r30
+ or r20, r20, r31
+ sw r30, r20
+
+ {
+ movei r30, 0 /* not an NMI */
+ j interrupt_return
+ }
+ STD_ENDPROC(handle_interrupt_downcall)
+
+ /*
+ * Some interrupts don't check for single stepping
+ */
+ .pushsection .text.handle_interrupt_no_single_step,"ax"
+handle_interrupt_no_single_step:
+ finish_interrupt_save handle_interrupt_no_single_step
+ {
+ jalr r0
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ }
+ FEEDBACK_REENTER(handle_interrupt_no_single_step)
+ {
+ movei r30, 0 /* not an NMI */
+ j interrupt_return
+ }
+ STD_ENDPROC(handle_interrupt_no_single_step)
+
+ /*
+ * "NMI" interrupts mask ALL interrupts before calling the
+ * handler, and don't check thread flags, etc., on the way
+ * back out. In general, the only things we do here for NMIs
+ * are the register save/restore, fixing the PC if we were
+ * doing single step, and the dataplane kernel-TLB management.
+ * We don't (for example) deal with start/stop of the sched tick.
+ */
+ .pushsection .text.handle_nmi,"ax"
+handle_nmi:
+ finish_interrupt_save handle_nmi
+ check_single_stepping normal, .Ldispatch_nmi
+.Ldispatch_nmi:
+ {
+ jalr r0
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ }
+ FEEDBACK_REENTER(handle_nmi)
+ j interrupt_return
+ STD_ENDPROC(handle_nmi)
+
+ /*
+ * Parallel code for syscalls to handle_interrupt.
+ */
+ .pushsection .text.handle_syscall,"ax"
+handle_syscall:
+ finish_interrupt_save handle_syscall
+
+ /*
+ * Check for if we are single stepping in user level. If so, then
+ * we need to restore the PC.
+ */
+ check_single_stepping syscall, .Ldispatch_syscall
+.Ldispatch_syscall:
+
+ /* Enable irqs. */
+ TRACE_IRQS_ON
+ IRQ_ENABLE(r20, r21)
+
+ /* Bump the counter for syscalls made on this tile. */
+ moveli r20, lo16(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
+ auli r20, r20, ha16(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
+ add r20, r20, tp
+ lw r21, r20
+ addi r21, r21, 1
+ sw r20, r21
+
+ /* Trace syscalls, if requested. */
+ GET_THREAD_INFO(r31)
+ addi r31, r31, THREAD_INFO_FLAGS_OFFSET
+ lw r30, r31
+ andi r30, r30, _TIF_SYSCALL_TRACE
+ bzt r30, .Lrestore_syscall_regs
+ jal do_syscall_trace
+ FEEDBACK_REENTER(handle_syscall)
+
+ /*
+ * We always reload our registers from the stack at this
+ * point. They might be valid, if we didn't build with
+ * TRACE_IRQFLAGS, and this isn't a dataplane tile, and we're not
+ * doing syscall tracing, but there are enough cases now that it
+ * seems simplest just to do the reload unconditionally.
+ */
+.Lrestore_syscall_regs:
+ PTREGS_PTR(r11, PTREGS_OFFSET_REG(0))
+ pop_reg r0, r11
+ pop_reg r1, r11
+ pop_reg r2, r11
+ pop_reg r3, r11
+ pop_reg r4, r11
+ pop_reg r5, r11, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(5)
+ pop_reg TREG_SYSCALL_NR_NAME, r11
+
+ /* Ensure that the syscall number is within the legal range. */
+ moveli r21, __NR_syscalls
+ {
+ slt_u r21, TREG_SYSCALL_NR_NAME, r21
+ moveli r20, lo16(sys_call_table)
+ }
+ {
+ bbns r21, .Linvalid_syscall
+ auli r20, r20, ha16(sys_call_table)
+ }
+ s2a r20, TREG_SYSCALL_NR_NAME, r20
+ lw r20, r20
+
+ /* Jump to syscall handler. */
+ jalr r20; .Lhandle_syscall_link:
+ FEEDBACK_REENTER(handle_syscall)
+
+ /*
+ * Write our r0 onto the stack so it gets restored instead
+ * of whatever the user had there before.
+ */
+ PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
+ sw r29, r0
+
+ /* Do syscall trace again, if requested. */
+ lw r30, r31
+ andi r30, r30, _TIF_SYSCALL_TRACE
+ bzt r30, 1f
+ jal do_syscall_trace
+ FEEDBACK_REENTER(handle_syscall)
+1: j .Lresume_userspace /* jump into middle of interrupt_return */
+
+.Linvalid_syscall:
+ /* Report an invalid syscall back to the user program */
+ {
+ PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
+ movei r28, -ENOSYS
+ }
+ sw r29, r28
+ j .Lresume_userspace /* jump into middle of interrupt_return */
+ STD_ENDPROC(handle_syscall)
+
+ /* Return the address for oprofile to suppress in backtraces. */
+STD_ENTRY_SECTION(handle_syscall_link_address, .text.handle_syscall)
+ lnk r0
+ {
+ addli r0, r0, .Lhandle_syscall_link - .
+ jrp lr
+ }
+ STD_ENDPROC(handle_syscall_link_address)
+
+STD_ENTRY(ret_from_fork)
+ jal sim_notify_fork
+ jal schedule_tail
+ FEEDBACK_REENTER(ret_from_fork)
+ j .Lresume_userspace /* jump into middle of interrupt_return */
+ STD_ENDPROC(ret_from_fork)
+
+ /*
+ * Code for ill interrupt.
+ */
+ .pushsection .text.handle_ill,"ax"
+handle_ill:
+ finish_interrupt_save handle_ill
+
+ /*
+ * Check for if we are single stepping in user level. If so, then
+ * we need to restore the PC.
+ */
+ check_single_stepping ill, .Ldispatch_normal_ill
+
+ {
+ /* See if the PC is the 1st bundle in the buffer */
+ seq r25, r27, r26
+
+ /* Point to the 2nd bundle in the buffer */
+ addi r26, r26, 8
+ }
+ {
+ /* Point to the original pc */
+ addi r24, r29, SINGLESTEP_STATE_ORIG_PC_OFFSET
+
+ /* Branch if the PC is the 1st bundle in the buffer */
+ bnz r25, 3f
+ }
+ {
+ /* See if the PC is the 2nd bundle of the buffer */
+ seq r25, r27, r26
+
+ /* Set PC to next instruction */
+ addi r24, r29, SINGLESTEP_STATE_NEXT_PC_OFFSET
+ }
+ {
+ /* Point to flags */
+ addi r25, r29, SINGLESTEP_STATE_FLAGS_OFFSET
+
+ /* Branch if PC is in the second bundle */
+ bz r25, 2f
+ }
+ /* Load flags */
+ lw r25, r25
+ {
+ /*
+ * Get the offset for the register to restore
+ * Note: the lower bound is 2, so we have implicit scaling by 4.
+ * No multiplication of the register number by the size of a register
+ * is needed.
+ */
+ mm r27, r25, zero, SINGLESTEP_STATE_TARGET_LB, \
+ SINGLESTEP_STATE_TARGET_UB
+
+ /* Mask Rewrite_LR */
+ andi r25, r25, SINGLESTEP_STATE_MASK_UPDATE
+ }
+ {
+ addi r29, r29, SINGLESTEP_STATE_UPDATE_VALUE_OFFSET
+
+ /* Don't rewrite temp register */
+ bz r25, 3f
+ }
+ {
+ /* Get the temp value */
+ lw r29, r29
+
+ /* Point to where the register is stored */
+ add r27, r27, sp
+ }
+
+ /* Add in the C ABI save area size to the register offset */
+ addi r27, r27, C_ABI_SAVE_AREA_SIZE
+
+ /* Restore the user's register with the temp value */
+ sw r27, r29
+ j 3f
+
+2:
+ /* Must be in the third bundle */
+ addi r24, r29, SINGLESTEP_STATE_BRANCH_NEXT_PC_OFFSET
+
+3:
+ /* set PC and continue */
+ lw r26, r24
+ sw r28, r26
+
+ /* Clear TIF_SINGLESTEP */
+ GET_THREAD_INFO(r0)
+
+ addi r1, r0, THREAD_INFO_FLAGS_OFFSET
+ {
+ lw r2, r1
+ addi r0, r0, THREAD_INFO_TASK_OFFSET /* currently a no-op */
+ }
+ andi r2, r2, ~_TIF_SINGLESTEP
+ sw r1, r2
+
+ /* Issue a sigtrap */
+ {
+ lw r0, r0 /* indirect thru thread_info to get task_info*/
+ addi r1, sp, C_ABI_SAVE_AREA_SIZE /* put ptregs pointer into r1 */
+ move r2, zero /* load error code into r2 */
+ }
+
+ jal send_sigtrap /* issue a SIGTRAP */
+ FEEDBACK_REENTER(handle_ill)
+ j .Lresume_userspace /* jump into middle of interrupt_return */
+
+.Ldispatch_normal_ill:
+ {
+ jalr r0
+ PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+ }
+ FEEDBACK_REENTER(handle_ill)
+ {
+ movei r30, 0 /* not an NMI */
+ j interrupt_return
+ }
+ STD_ENDPROC(handle_ill)
+
+ .pushsection .rodata, "a"
+ .align 8
+bpt_code:
+ bpt
+ ENDPROC(bpt_code)
+ .popsection
+
+/* Various stub interrupt handlers and syscall handlers */
+
+STD_ENTRY_LOCAL(_kernel_double_fault)
+ mfspr r1, EX_CONTEXT_1_0
+ move r2, lr
+ move r3, sp
+ move r4, r52
+ addi sp, sp, -C_ABI_SAVE_AREA_SIZE
+ j kernel_double_fault
+ STD_ENDPROC(_kernel_double_fault)
+
+STD_ENTRY_LOCAL(bad_intr)
+ mfspr r2, EX_CONTEXT_1_0
+ panic "Unhandled interrupt %#x: PC %#lx"
+ STD_ENDPROC(bad_intr)
+
+/* Put address of pt_regs in reg and jump. */
+#define PTREGS_SYSCALL(x, reg) \
+ STD_ENTRY(x); \
+ { \
+ PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
+ j _##x \
+ }; \
+ STD_ENDPROC(x)
+
+PTREGS_SYSCALL(sys_execve, r3)
+PTREGS_SYSCALL(sys_sigaltstack, r2)
+PTREGS_SYSCALL(sys_rt_sigreturn, r0)
+
+/* Save additional callee-saves to pt_regs, put address in reg and jump. */
+#define PTREGS_SYSCALL_ALL_REGS(x, reg) \
+ STD_ENTRY(x); \
+ push_extra_callee_saves reg; \
+ j _##x; \
+ STD_ENDPROC(x)
+
+PTREGS_SYSCALL_ALL_REGS(sys_fork, r0)
+PTREGS_SYSCALL_ALL_REGS(sys_vfork, r0)
+PTREGS_SYSCALL_ALL_REGS(sys_clone, r4)
+PTREGS_SYSCALL_ALL_REGS(sys_cmpxchg_badaddr, r1)
+
+/*
+ * This entrypoint is taken for the cmpxchg and atomic_update fast
+ * swints. We may wish to generalize it to other fast swints at some
+ * point, but for now there are just two very similar ones, which
+ * makes it faster.
+ *
+ * The fast swint code is designed to have a small footprint. It does
+ * not save or restore any GPRs, counting on the caller-save registers
+ * to be available to it on entry. It does not modify any callee-save
+ * registers (including "lr"). It does not check what PL it is being
+ * called at, so you'd better not call it other than at PL0.
+ *
+ * It does not use the stack, but since it might be re-interrupted by
+ * a page fault which would assume the stack was valid, it does
+ * save/restore the stack pointer and zero it out to make sure it gets reset.
+ * Since we always keep interrupts disabled, the hypervisor won't
+ * clobber our EX_CONTEXT_1_x registers, so we don't save/restore them
+ * (other than to advance the PC on return).
+ *
+ * We have to manually validate the user vs kernel address range
+ * (since at PL1 we can read/write both), and for performance reasons
+ * we don't allow cmpxchg on the fc000000 memory region, since we only
+ * validate that the user address is below PAGE_OFFSET.
+ *
+ * We place it in the __HEAD section to ensure it is relatively
+ * near to the intvec_SWINT_1 code (reachable by a conditional branch).
+ *
+ * Must match register usage in do_page_fault().
+ */
+ __HEAD
+ .align 64
+ /* Align much later jump on the start of a cache line. */
+#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ nop; nop
+#endif
+ENTRY(sys_cmpxchg)
+
+ /*
+ * Save "sp" and set it zero for any possible page fault.
+ *
+ * HACK: We want to both zero sp and check r0's alignment,
+ * so we do both at once. If "sp" becomes nonzero we
+ * know r0 is unaligned and branch to the error handler that
+ * restores sp, so this is OK.
+ *
+ * ICS is disabled right now so having a garbage but nonzero
+ * sp is OK, since we won't execute any faulting instructions
+ * when it is nonzero.
+ */
+ {
+ move r27, sp
+ andi sp, r0, 3
+ }
+
+ /*
+ * Get the lock address in ATOMIC_LOCK_REG, and also validate that the
+ * address is less than PAGE_OFFSET, since that won't trap at PL1.
+ * We only use bits less than PAGE_SHIFT to avoid having to worry
+ * about aliasing among multiple mappings of the same physical page,
+ * and we ignore the low 3 bits so we have one lock that covers
+ * both a cmpxchg64() and a cmpxchg() on either its low or high word.
+ * NOTE: this code must match __atomic_hashed_lock() in lib/atomic.c.
+ */
+
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ {
+ /* Check for unaligned input. */
+ bnz sp, .Lcmpxchg_badaddr
+ mm r25, r0, zero, 3, PAGE_SHIFT-1
+ }
+ {
+ crc32_32 r25, zero, r25
+ moveli r21, lo16(atomic_lock_ptr)
+ }
+ {
+ auli r21, r21, ha16(atomic_lock_ptr)
+ auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */
+ }
+ {
+ shri r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
+ slt_u r23, r0, r23
+
+ /*
+ * Ensure that the TLB is loaded before we take out the lock.
+ * On TILEPro, this will start fetching the value all the way
+ * into our L1 as well (and if it gets modified before we
+ * grab the lock, it will be invalidated from our cache
+ * before we reload it). On tile64, we'll start fetching it
+ * into our L1 if we're the home, and if we're not, we'll
+ * still at least start fetching it into the home's L2.
+ */
+ lw r26, r0
+ }
+ {
+ s2a r21, r20, r21
+ bbns r23, .Lcmpxchg_badaddr
+ }
+ {
+ lw r21, r21
+ seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64
+ andi r25, r25, ATOMIC_HASH_L2_SIZE - 1
+ }
+ {
+ /* Branch away at this point if we're doing a 64-bit cmpxchg. */
+ bbs r23, .Lcmpxchg64
+ andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
+ }
+
+ {
+ /*
+ * We very carefully align the code that actually runs with
+ * the lock held (nine bundles) so that we know it is all in
+ * the icache when we start. This instruction (the jump) is
+ * at the start of the first cache line, address zero mod 64;
+ * we jump to somewhere in the second cache line to issue the
+ * tns, then jump back to finish up.
+ */
+ s2a ATOMIC_LOCK_REG_NAME, r25, r21
+ j .Lcmpxchg32_tns
+ }
+
+#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+ {
+ /* Check for unaligned input. */
+ bnz sp, .Lcmpxchg_badaddr
+ auli r23, zero, hi16(PAGE_OFFSET) /* hugepage-aligned */
+ }
+ {
+ /*
+ * Slide bits into position for 'mm'. We want to ignore
+ * the low 3 bits of r0, and consider only the next
+ * ATOMIC_HASH_SHIFT bits.
+ * Because of C pointer arithmetic, we want to compute this:
+ *
+ * ((char*)atomic_locks +
+ * (((r0 >> 3) & (1 << (ATOMIC_HASH_SIZE - 1))) << 2))
+ *
+ * Instead of two shifts we just ">> 1", and use 'mm'
+ * to ignore the low and high bits we don't want.
+ */
+ shri r25, r0, 1
+
+ slt_u r23, r0, r23
+
+ /*
+ * Ensure that the TLB is loaded before we take out the lock.
+ * On tilepro, this will start fetching the value all the way
+ * into our L1 as well (and if it gets modified before we
+ * grab the lock, it will be invalidated from our cache
+ * before we reload it). On tile64, we'll start fetching it
+ * into our L1 if we're the home, and if we're not, we'll
+ * still at least start fetching it into the home's L2.
+ */
+ lw r26, r0
+ }
+ {
+ /* atomic_locks is page aligned so this suffices to get its addr. */
+ auli r21, zero, hi16(atomic_locks)
+
+ bbns r23, .Lcmpxchg_badaddr
+ }
+ {
+ /*
+ * Insert the hash bits into the page-aligned pointer.
+ * ATOMIC_HASH_SHIFT is so big that we don't actually hash
+ * the unmasked address bits, as that may cause unnecessary
+ * collisions.
+ */
+ mm ATOMIC_LOCK_REG_NAME, r25, r21, 2, (ATOMIC_HASH_SHIFT + 2) - 1
+
+ seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_cmpxchg64
+ }
+ {
+ /* Branch away at this point if we're doing a 64-bit cmpxchg. */
+ bbs r23, .Lcmpxchg64
+ andi r23, r0, 7 /* Precompute alignment for cmpxchg64. */
+ }
+ {
+ /*
+ * We very carefully align the code that actually runs with
+ * the lock held (nine bundles) so that we know it is all in
+ * the icache when we start. This instruction (the jump) is
+ * at the start of the first cache line, address zero mod 64;
+ * we jump to somewhere in the second cache line to issue the
+ * tns, then jump back to finish up.
+ */
+ j .Lcmpxchg32_tns
+ }
+
+#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+ ENTRY(__sys_cmpxchg_grab_lock)
+
+ /*
+ * Perform the actual cmpxchg or atomic_update.
+ * Note that __futex_mark_unlocked() in uClibc relies on
+ * atomic_update() to always perform an "mf", so don't make
+ * it optional or conditional without modifying that code.
+ */
+.Ldo_cmpxchg32:
+ {
+ lw r21, r0
+ seqi r23, TREG_SYSCALL_NR_NAME, __NR_FAST_atomic_update
+ move r24, r2
+ }
+ {
+ seq r22, r21, r1 /* See if cmpxchg matches. */
+ and r25, r21, r1 /* If atomic_update, compute (*mem & mask) */
+ }
+ {
+ or r22, r22, r23 /* Skip compare branch for atomic_update. */
+ add r25, r25, r2 /* Compute (*mem & mask) + addend. */
+ }
+ {
+ mvnz r24, r23, r25 /* Use atomic_update value if appropriate. */
+ bbns r22, .Lcmpxchg32_mismatch
+ }
+ sw r0, r24
+
+ /* Do slow mtspr here so the following "mf" waits less. */
+ {
+ move sp, r27
+ mtspr EX_CONTEXT_1_0, r28
+ }
+ mf
+
+ /* The following instruction is the start of the second cache line. */
+ {
+ move r0, r21
+ sw ATOMIC_LOCK_REG_NAME, zero
+ }
+ iret
+
+ /* Duplicated code here in the case where we don't overlap "mf" */
+.Lcmpxchg32_mismatch:
+ {
+ move r0, r21
+ sw ATOMIC_LOCK_REG_NAME, zero
+ }
+ {
+ move sp, r27
+ mtspr EX_CONTEXT_1_0, r28
+ }
+ iret
+
+ /*
+ * The locking code is the same for 32-bit cmpxchg/atomic_update,
+ * and for 64-bit cmpxchg. We provide it as a macro and put
+ * it into both versions. We can't share the code literally
+ * since it depends on having the right branch-back address.
+ * Note that the first few instructions should share the cache
+ * line with the second half of the actual locked code.
+ */
+ .macro cmpxchg_lock, bitwidth
+
+ /* Lock; if we succeed, jump back up to the read-modify-write. */
+#ifdef CONFIG_SMP
+ tns r21, ATOMIC_LOCK_REG_NAME
+#else
+ /*
+ * Non-SMP preserves all the lock infrastructure, to keep the
+ * code simpler for the interesting (SMP) case. However, we do
+ * one small optimization here and in atomic_asm.S, which is
+ * to fake out acquiring the actual lock in the atomic_lock table.
+ */
+ movei r21, 0
+#endif
+
+ /* Issue the slow SPR here while the tns result is in flight. */
+ mfspr r28, EX_CONTEXT_1_0
+
+ {
+ addi r28, r28, 8 /* return to the instruction after the swint1 */
+ bzt r21, .Ldo_cmpxchg\bitwidth
+ }
+ /*
+ * The preceding instruction is the last thing that must be
+ * on the second cache line.
+ */
+
+#ifdef CONFIG_SMP
+ /*
+ * We failed to acquire the tns lock on our first try. Now use
+ * bounded exponential backoff to retry, like __atomic_spinlock().
+ */
+ {
+ moveli r23, 2048 /* maximum backoff time in cycles */
+ moveli r25, 32 /* starting backoff time in cycles */
+ }
+1: mfspr r26, CYCLE_LOW /* get start point for this backoff */
+2: mfspr r22, CYCLE_LOW /* test to see if we've backed off enough */
+ sub r22, r22, r26
+ slt r22, r22, r25
+ bbst r22, 2b
+ {
+ shli r25, r25, 1 /* double the backoff; retry the tns */
+ tns r21, ATOMIC_LOCK_REG_NAME
+ }
+ slt r26, r23, r25 /* is the proposed backoff too big? */
+ {
+ mvnz r25, r26, r23
+ bzt r21, .Ldo_cmpxchg\bitwidth
+ }
+ j 1b
+#endif /* CONFIG_SMP */
+ .endm
+
+.Lcmpxchg32_tns:
+ cmpxchg_lock 32
+
+ /*
+ * This code is invoked from sys_cmpxchg after most of the
+ * preconditions have been checked. We still need to check
+ * that r0 is 8-byte aligned, since if it's not we won't
+ * actually be atomic. However, ATOMIC_LOCK_REG has the atomic
+ * lock pointer and r27/r28 have the saved SP/PC.
+ * r23 is holding "r0 & 7" so we can test for alignment.
+ * The compare value is in r2/r3; the new value is in r4/r5.
+ * On return, we must put the old value in r0/r1.
+ */
+ .align 64
+.Lcmpxchg64:
+ {
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ s2a ATOMIC_LOCK_REG_NAME, r25, r21
+#endif
+ bzt r23, .Lcmpxchg64_tns
+ }
+ j .Lcmpxchg_badaddr
+
+.Ldo_cmpxchg64:
+ {
+ lw r21, r0
+ addi r25, r0, 4
+ }
+ {
+ lw r1, r25
+ }
+ seq r26, r21, r2
+ {
+ bz r26, .Lcmpxchg64_mismatch
+ seq r26, r1, r3
+ }
+ {
+ bz r26, .Lcmpxchg64_mismatch
+ }
+ sw r0, r4
+ sw r25, r5
+
+ /*
+ * The 32-bit path provides optimized "match" and "mismatch"
+ * iret paths, but we don't have enough bundles in this cache line
+ * to do that, so we just make even the "mismatch" path do an "mf".
+ */
+.Lcmpxchg64_mismatch:
+ {
+ move sp, r27
+ mtspr EX_CONTEXT_1_0, r28
+ }
+ mf
+ {
+ move r0, r21
+ sw ATOMIC_LOCK_REG_NAME, zero
+ }
+ iret
+
+.Lcmpxchg64_tns:
+ cmpxchg_lock 64
+
+
+ /*
+ * Reset sp and revector to sys_cmpxchg_badaddr(), which will
+ * just raise the appropriate signal and exit. Doing it this
+ * way means we don't have to duplicate the code in intvec.S's
+ * int_hand macro that locates the top of the stack.
+ */
+.Lcmpxchg_badaddr:
+ {
+ moveli TREG_SYSCALL_NR_NAME, __NR_cmpxchg_badaddr
+ move sp, r27
+ }
+ j intvec_SWINT_1
+ ENDPROC(sys_cmpxchg)
+ ENTRY(__sys_cmpxchg_end)
+
+
+/* The single-step support may need to read all the registers. */
+int_unalign:
+ push_extra_callee_saves r0
+ j do_trap
+
+/* Include .intrpt1 array of interrupt vectors */
+ .section ".intrpt1", "ax"
+
+#define op_handle_perf_interrupt bad_intr
+#define op_handle_aux_perf_interrupt bad_intr
+
+#ifndef CONFIG_HARDWALL
+#define do_hardwall_trap bad_intr
+#endif
+
+ int_hand INT_ITLB_MISS, ITLB_MISS, \
+ do_page_fault, handle_interrupt_no_single_step
+ int_hand INT_MEM_ERROR, MEM_ERROR, bad_intr
+ int_hand INT_ILL, ILL, do_trap, handle_ill
+ int_hand INT_GPV, GPV, do_trap
+ int_hand INT_SN_ACCESS, SN_ACCESS, do_trap
+ int_hand INT_IDN_ACCESS, IDN_ACCESS, do_trap
+ int_hand INT_UDN_ACCESS, UDN_ACCESS, do_trap
+ int_hand INT_IDN_REFILL, IDN_REFILL, bad_intr
+ int_hand INT_UDN_REFILL, UDN_REFILL, bad_intr
+ int_hand INT_IDN_COMPLETE, IDN_COMPLETE, bad_intr
+ int_hand INT_UDN_COMPLETE, UDN_COMPLETE, bad_intr
+ int_hand INT_SWINT_3, SWINT_3, do_trap
+ int_hand INT_SWINT_2, SWINT_2, do_trap
+ int_hand INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall
+ int_hand INT_SWINT_0, SWINT_0, do_trap
+ int_hand INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
+ int_hand INT_DTLB_MISS, DTLB_MISS, do_page_fault
+ int_hand INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
+ int_hand INT_DMATLB_MISS, DMATLB_MISS, do_page_fault
+ int_hand INT_DMATLB_ACCESS, DMATLB_ACCESS, do_page_fault
+ int_hand INT_SNITLB_MISS, SNITLB_MISS, do_page_fault
+ int_hand INT_SN_NOTIFY, SN_NOTIFY, bad_intr
+ int_hand INT_SN_FIREWALL, SN_FIREWALL, do_hardwall_trap
+ int_hand INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr
+ int_hand INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
+ int_hand INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
+ int_hand INT_IDN_TIMER, IDN_TIMER, bad_intr
+ int_hand INT_UDN_TIMER, UDN_TIMER, bad_intr
+ int_hand INT_DMA_NOTIFY, DMA_NOTIFY, bad_intr
+ int_hand INT_IDN_CA, IDN_CA, bad_intr
+ int_hand INT_UDN_CA, UDN_CA, bad_intr
+ int_hand INT_IDN_AVAIL, IDN_AVAIL, bad_intr
+ int_hand INT_UDN_AVAIL, UDN_AVAIL, bad_intr
+ int_hand INT_PERF_COUNT, PERF_COUNT, \
+ op_handle_perf_interrupt, handle_nmi
+ int_hand INT_INTCTRL_3, INTCTRL_3, bad_intr
+ int_hand INT_INTCTRL_2, INTCTRL_2, bad_intr
+ dc_dispatch INT_INTCTRL_1, INTCTRL_1
+ int_hand INT_INTCTRL_0, INTCTRL_0, bad_intr
+ int_hand INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
+ hv_message_intr, handle_interrupt_downcall
+ int_hand INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, \
+ tile_dev_intr, handle_interrupt_downcall
+ int_hand INT_I_ASID, I_ASID, bad_intr
+ int_hand INT_D_ASID, D_ASID, bad_intr
+ int_hand INT_DMATLB_MISS_DWNCL, DMATLB_MISS_DWNCL, \
+ do_page_fault, handle_interrupt_downcall
+ int_hand INT_SNITLB_MISS_DWNCL, SNITLB_MISS_DWNCL, \
+ do_page_fault, handle_interrupt_downcall
+ int_hand INT_DMATLB_ACCESS_DWNCL, DMATLB_ACCESS_DWNCL, \
+ do_page_fault, handle_interrupt_downcall
+ int_hand INT_SN_CPL, SN_CPL, bad_intr
+ int_hand INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
+#if CHIP_HAS_AUX_PERF_COUNTERS()
+ int_hand INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
+ op_handle_aux_perf_interrupt, handle_nmi
+#endif
+
+ /* Synthetic interrupt delivered only by the simulator */
+ int_hand INT_BREAKPOINT, BREAKPOINT, do_breakpoint
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
new file mode 100644
index 000000000000..596c60086930
--- /dev/null
+++ b/arch/tile/kernel/irq.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel_stat.h>
+#include <linux/uaccess.h>
+#include <hv/drv_pcie_rc_intf.h>
+#include <arch/spr_def.h>
+#include <asm/traps.h>
+
+/* Bit-flag stored in irq_desc->chip_data to indicate HW-cleared irqs. */
+#define IS_HW_CLEARED 1
+
+/*
+ * The set of interrupts we enable for raw_local_irq_enable().
+ * This is initialized to have just a single interrupt that the kernel
+ * doesn't actually use as a sentinel. During kernel init,
+ * interrupts are added as the kernel gets prepared to support them.
+ * NOTE: we could probably initialize them all statically up front.
+ */
+DEFINE_PER_CPU(unsigned long long, interrupts_enabled_mask) =
+ INITIAL_INTERRUPTS_ENABLED;
+EXPORT_PER_CPU_SYMBOL(interrupts_enabled_mask);
+
+/* Define per-tile device interrupt statistics state. */
+DEFINE_PER_CPU(irq_cpustat_t, irq_stat) ____cacheline_internodealigned_in_smp;
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
+/*
+ * Define per-tile irq disable mask; the hardware/HV only has a single
+ * mask that we use to implement both masking and disabling.
+ */
+static DEFINE_PER_CPU(unsigned long, irq_disable_mask)
+ ____cacheline_internodealigned_in_smp;
+
+/*
+ * Per-tile IRQ nesting depth. Used to make sure we enable newly
+ * enabled IRQs before exiting the outermost interrupt.
+ */
+static DEFINE_PER_CPU(int, irq_depth);
+
+/* State for allocating IRQs on Gx. */
+#if CHIP_HAS_IPI()
+static unsigned long available_irqs = ~(1UL << IRQ_RESCHEDULE);
+static DEFINE_SPINLOCK(available_irqs_lock);
+#endif
+
+#if CHIP_HAS_IPI()
+/* Use SPRs to manipulate device interrupts. */
+#define mask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_SET_1, irq_mask)
+#define unmask_irqs(irq_mask) __insn_mtspr(SPR_IPI_MASK_RESET_1, irq_mask)
+#define clear_irqs(irq_mask) __insn_mtspr(SPR_IPI_EVENT_RESET_1, irq_mask)
+#else
+/* Use HV to manipulate device interrupts. */
+#define mask_irqs(irq_mask) hv_disable_intr(irq_mask)
+#define unmask_irqs(irq_mask) hv_enable_intr(irq_mask)
+#define clear_irqs(irq_mask) hv_clear_intr(irq_mask)
+#endif
+
+/*
+ * The interrupt handling path, implemented in terms of HV interrupt
+ * emulation on TILE64 and TILEPro, and IPI hardware on TILE-Gx.
+ */
+void tile_dev_intr(struct pt_regs *regs, int intnum)
+{
+ int depth = __get_cpu_var(irq_depth)++;
+ unsigned long original_irqs;
+ unsigned long remaining_irqs;
+ struct pt_regs *old_regs;
+
+#if CHIP_HAS_IPI()
+ /*
+ * Pending interrupts are listed in an SPR. We might be
+ * nested, so be sure to only handle irqs that weren't already
+ * masked by a previous interrupt. Then, mask out the ones
+ * we're going to handle.
+ */
+ unsigned long masked = __insn_mfspr(SPR_IPI_MASK_1);
+ original_irqs = __insn_mfspr(SPR_IPI_EVENT_1) & ~masked;
+ __insn_mtspr(SPR_IPI_MASK_SET_1, original_irqs);
+#else
+ /*
+ * Hypervisor performs the equivalent of the Gx code above and
+ * then puts the pending interrupt mask into a system save reg
+ * for us to find.
+ */
+ original_irqs = __insn_mfspr(SPR_SYSTEM_SAVE_1_3);
+#endif
+ remaining_irqs = original_irqs;
+
+ /* Track time spent here in an interrupt context. */
+ old_regs = set_irq_regs(regs);
+ irq_enter();
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ /* Debugging check for stack overflow: less than 1/8th stack free? */
+ {
+ long sp = stack_pointer - (long) current_thread_info();
+ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+ pr_emerg("tile_dev_intr: "
+ "stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
+ }
+ }
+#endif
+ while (remaining_irqs) {
+ unsigned long irq = __ffs(remaining_irqs);
+ remaining_irqs &= ~(1UL << irq);
+
+ /* Count device irqs; Linux IPIs are counted elsewhere. */
+ if (irq != IRQ_RESCHEDULE)
+ __get_cpu_var(irq_stat).irq_dev_intr_count++;
+
+ generic_handle_irq(irq);
+ }
+
+ /*
+ * If we weren't nested, turn on all enabled interrupts,
+ * including any that were reenabled during interrupt
+ * handling.
+ */
+ if (depth == 0)
+ unmask_irqs(~__get_cpu_var(irq_disable_mask));
+
+ __get_cpu_var(irq_depth)--;
+
+ /*
+ * Track time spent against the current process again and
+ * process any softirqs if they are waiting.
+ */
+ irq_exit();
+ set_irq_regs(old_regs);
+}
+
+
+/*
+ * Remove an irq from the disabled mask. If we're in an interrupt
+ * context, defer enabling the HW interrupt until we leave.
+ */
+void enable_percpu_irq(unsigned int irq)
+{
+ get_cpu_var(irq_disable_mask) &= ~(1UL << irq);
+ if (__get_cpu_var(irq_depth) == 0)
+ unmask_irqs(1UL << irq);
+ put_cpu_var(irq_disable_mask);
+}
+EXPORT_SYMBOL(enable_percpu_irq);
+
+/*
+ * Add an irq to the disabled mask. We disable the HW interrupt
+ * immediately so that there's no possibility of it firing. If we're
+ * in an interrupt context, the return path is careful to avoid
+ * unmasking a newly disabled interrupt.
+ */
+void disable_percpu_irq(unsigned int irq)
+{
+ get_cpu_var(irq_disable_mask) |= (1UL << irq);
+ mask_irqs(1UL << irq);
+ put_cpu_var(irq_disable_mask);
+}
+EXPORT_SYMBOL(disable_percpu_irq);
+
+/* Mask an interrupt. */
+static void tile_irq_chip_mask(unsigned int irq)
+{
+ mask_irqs(1UL << irq);
+}
+
+/* Unmask an interrupt. */
+static void tile_irq_chip_unmask(unsigned int irq)
+{
+ unmask_irqs(1UL << irq);
+}
+
+/*
+ * Clear an interrupt before processing it so that any new assertions
+ * will trigger another irq.
+ */
+static void tile_irq_chip_ack(unsigned int irq)
+{
+ if ((unsigned long)get_irq_chip_data(irq) != IS_HW_CLEARED)
+ clear_irqs(1UL << irq);
+}
+
+/*
+ * For per-cpu interrupts, we need to avoid unmasking any interrupts
+ * that we disabled via disable_percpu_irq().
+ */
+static void tile_irq_chip_eoi(unsigned int irq)
+{
+ if (!(__get_cpu_var(irq_disable_mask) & (1UL << irq)))
+ unmask_irqs(1UL << irq);
+}
+
+static struct irq_chip tile_irq_chip = {
+ .typename = "tile_irq_chip",
+ .ack = tile_irq_chip_ack,
+ .eoi = tile_irq_chip_eoi,
+ .mask = tile_irq_chip_mask,
+ .unmask = tile_irq_chip_unmask,
+};
+
+void __init init_IRQ(void)
+{
+ ipi_init();
+}
+
+void __cpuinit setup_irq_regs(void)
+{
+ /* Enable interrupt delivery. */
+ unmask_irqs(~0UL);
+#if CHIP_HAS_IPI()
+ raw_local_irq_unmask(INT_IPI_1);
+#endif
+}
+
+void tile_irq_activate(unsigned int irq, int tile_irq_type)
+{
+ /*
+ * We use handle_level_irq() by default because the pending
+ * interrupt vector (whether modeled by the HV on TILE64 and
+ * TILEPro or implemented in hardware on TILE-Gx) has
+ * level-style semantics for each bit. An interrupt fires
+ * whenever a bit is high, not just at edges.
+ */
+ irq_flow_handler_t handle = handle_level_irq;
+ if (tile_irq_type == TILE_IRQ_PERCPU)
+ handle = handle_percpu_irq;
+ set_irq_chip_and_handler(irq, &tile_irq_chip, handle);
+
+ /*
+ * Flag interrupts that are hardware-cleared so that ack()
+ * won't clear them.
+ */
+ if (tile_irq_type == TILE_IRQ_HW_CLEAR)
+ set_irq_chip_data(irq, (void *)IS_HW_CLEARED);
+}
+EXPORT_SYMBOL(tile_irq_activate);
+
+
+void ack_bad_irq(unsigned int irq)
+{
+ pr_err("unexpected IRQ trap at vector %02x\n", irq);
+}
+
+/*
+ * Generic, controller-independent functions:
+ */
+
+int show_interrupts(struct seq_file *p, void *v)
+{
+ int i = *(loff_t *) v, j;
+ struct irqaction *action;
+ unsigned long flags;
+
+ if (i == 0) {
+ seq_printf(p, " ");
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ seq_printf(p, "CPU%-8d", j);
+ seq_putc(p, '\n');
+ }
+
+ if (i < NR_IRQS) {
+ raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
+ action = irq_desc[i].action;
+ if (!action)
+ goto skip;
+ seq_printf(p, "%3d: ", i);
+#ifndef CONFIG_SMP
+ seq_printf(p, "%10u ", kstat_irqs(i));
+#else
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
+#endif
+ seq_printf(p, " %14s", irq_desc[i].chip->typename);
+ seq_printf(p, " %s", action->name);
+
+ for (action = action->next; action; action = action->next)
+ seq_printf(p, ", %s", action->name);
+
+ seq_putc(p, '\n');
+skip:
+ raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ }
+ return 0;
+}
+
+#if CHIP_HAS_IPI()
+int create_irq(void)
+{
+ unsigned long flags;
+ int result;
+
+ spin_lock_irqsave(&available_irqs_lock, flags);
+ if (available_irqs == 0)
+ result = -ENOMEM;
+ else {
+ result = __ffs(available_irqs);
+ available_irqs &= ~(1UL << result);
+ dynamic_irq_init(result);
+ }
+ spin_unlock_irqrestore(&available_irqs_lock, flags);
+
+ return result;
+}
+EXPORT_SYMBOL(create_irq);
+
+void destroy_irq(unsigned int irq)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&available_irqs_lock, flags);
+ available_irqs |= (1UL << irq);
+ dynamic_irq_cleanup(irq);
+ spin_unlock_irqrestore(&available_irqs_lock, flags);
+}
+EXPORT_SYMBOL(destroy_irq);
+#endif
diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c
new file mode 100644
index 000000000000..ba7a265d6179
--- /dev/null
+++ b/arch/tile/kernel/machine_kexec.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * based on machine_kexec.c from other architectures in linux-2.6.18
+ */
+
+#include <linux/mm.h>
+#include <linux/kexec.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/errno.h>
+#include <linux/vmalloc.h>
+#include <linux/cpumask.h>
+#include <linux/kernel.h>
+#include <linux/elf.h>
+#include <linux/highmem.h>
+#include <linux/mmu_context.h>
+#include <linux/io.h>
+#include <linux/timex.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/cacheflush.h>
+#include <asm/checksum.h>
+#include <hv/hypervisor.h>
+
+
+/*
+ * This stuff is not in elf.h and is not in any other kernel include.
+ * This stuff is needed below in the little boot notes parser to
+ * extract the command line so we can pass it to the hypervisor.
+ */
+struct Elf32_Bhdr {
+ Elf32_Word b_signature;
+ Elf32_Word b_size;
+ Elf32_Half b_checksum;
+ Elf32_Half b_records;
+};
+#define ELF_BOOT_MAGIC 0x0E1FB007
+#define EBN_COMMAND_LINE 0x00000004
+#define roundupsz(X) (((X) + 3) & ~3)
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
+
+
+void machine_shutdown(void)
+{
+ /*
+ * Normally we would stop all the other processors here, but
+ * the check in machine_kexec_prepare below ensures we'll only
+ * get this far if we've been booted with "nosmp" on the
+ * command line or without CONFIG_SMP so there's nothing to do
+ * here (for now).
+ */
+}
+
+void machine_crash_shutdown(struct pt_regs *regs)
+{
+ /*
+ * Cannot happen. This type of kexec is disabled on this
+ * architecture (and enforced in machine_kexec_prepare below).
+ */
+}
+
+
+int machine_kexec_prepare(struct kimage *image)
+{
+ if (num_online_cpus() > 1) {
+ pr_warning("%s: detected attempt to kexec "
+ "with num_online_cpus() > 1\n",
+ __func__);
+ return -ENOSYS;
+ }
+ if (image->type != KEXEC_TYPE_DEFAULT) {
+ pr_warning("%s: detected attempt to kexec "
+ "with unsupported type: %d\n",
+ __func__,
+ image->type);
+ return -ENOSYS;
+ }
+ return 0;
+}
+
+void machine_kexec_cleanup(struct kimage *image)
+{
+ /*
+ * We did nothing in machine_kexec_prepare,
+ * so we have nothing to do here.
+ */
+}
+
+/*
+ * If we can find elf boot notes on this page, return the command
+ * line. Otherwise, silently return null. Somewhat kludgy, but no
+ * good way to do this without significantly rearchitecting the
+ * architecture-independent kexec code.
+ */
+
+static unsigned char *kexec_bn2cl(void *pg)
+{
+ struct Elf32_Bhdr *bhdrp;
+ Elf32_Nhdr *nhdrp;
+ unsigned char *desc;
+ unsigned char *command_line;
+ __sum16 csum;
+
+ bhdrp = (struct Elf32_Bhdr *) pg;
+
+ /*
+ * This routine is invoked for every source page, so make
+ * sure to quietly ignore every impossible page.
+ */
+ if (bhdrp->b_signature != ELF_BOOT_MAGIC ||
+ bhdrp->b_size > PAGE_SIZE)
+ return 0;
+
+ /*
+ * If we get a checksum mismatch, warn with the checksum
+ * so we can diagnose better.
+ */
+ csum = ip_compute_csum(pg, bhdrp->b_size);
+ if (csum != 0) {
+ pr_warning("%s: bad checksum %#x (size %d)\n",
+ __func__, csum, bhdrp->b_size);
+ return 0;
+ }
+
+ nhdrp = (Elf32_Nhdr *) (bhdrp + 1);
+
+ while (nhdrp->n_type != EBN_COMMAND_LINE) {
+
+ desc = (unsigned char *) (nhdrp + 1);
+ desc += roundupsz(nhdrp->n_descsz);
+
+ nhdrp = (Elf32_Nhdr *) desc;
+
+ /* still in bounds? */
+ if ((unsigned char *) (nhdrp + 1) >
+ ((unsigned char *) pg) + bhdrp->b_size) {
+
+ pr_info("%s: out of bounds\n", __func__);
+ return 0;
+ }
+ }
+
+ command_line = (unsigned char *) (nhdrp + 1);
+ desc = command_line;
+
+ while (*desc != '\0') {
+ desc++;
+ if (((unsigned long)desc & PAGE_MASK) != (unsigned long)pg) {
+ pr_info("%s: ran off end of page\n",
+ __func__);
+ return 0;
+ }
+ }
+
+ return command_line;
+}
+
+static void kexec_find_and_set_command_line(struct kimage *image)
+{
+ kimage_entry_t *ptr, entry;
+
+ unsigned char *command_line = 0;
+ unsigned char *r;
+ HV_Errno hverr;
+
+ for (ptr = &image->head;
+ (entry = *ptr) && !(entry & IND_DONE);
+ ptr = (entry & IND_INDIRECTION) ?
+ phys_to_virt((entry & PAGE_MASK)) : ptr + 1) {
+
+ if ((entry & IND_SOURCE)) {
+ void *va =
+ kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0);
+ r = kexec_bn2cl(va);
+ if (r) {
+ command_line = r;
+ break;
+ }
+ kunmap_atomic(va, KM_USER0);
+ }
+ }
+
+ if (command_line != 0) {
+ pr_info("setting new command line to \"%s\"\n",
+ command_line);
+
+ hverr = hv_set_command_line(
+ (HV_VirtAddr) command_line, strlen(command_line));
+ kunmap_atomic(command_line, KM_USER0);
+ } else {
+ pr_info("%s: no command line found; making empty\n",
+ __func__);
+ hverr = hv_set_command_line((HV_VirtAddr) command_line, 0);
+ }
+ if (hverr)
+ pr_warning("%s: hv_set_command_line returned error: %d\n",
+ __func__, hverr);
+}
+
+/*
+ * The kexec code range-checks all its PAs, so to avoid having it run
+ * amok and allocate memory and then sequester it from every other
+ * controller, we force it to come from controller zero. We also
+ * disable the oom-killer since if we do end up running out of memory,
+ * that almost certainly won't help.
+ */
+struct page *kimage_alloc_pages_arch(gfp_t gfp_mask, unsigned int order)
+{
+ gfp_mask |= __GFP_THISNODE | __GFP_NORETRY;
+ return alloc_pages_node(0, gfp_mask, order);
+}
+
+static void setup_quasi_va_is_pa(void)
+{
+ HV_PTE *pgtable;
+ HV_PTE pte;
+ int i;
+
+ /*
+ * Flush our TLB to prevent conflicts between the previous contents
+ * and the new stuff we're about to add.
+ */
+ local_flush_tlb_all();
+
+ /* setup VA is PA, at least up to PAGE_OFFSET */
+
+ pgtable = (HV_PTE *)current->mm->pgd;
+ pte = hv_pte(_PAGE_KERNEL | _PAGE_HUGE_PAGE);
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
+
+ for (i = 0; i < pgd_index(PAGE_OFFSET); i++)
+ pgtable[i] = pfn_pte(i << (HPAGE_SHIFT - PAGE_SHIFT), pte);
+}
+
+
+NORET_TYPE void machine_kexec(struct kimage *image)
+{
+ void *reboot_code_buffer;
+ NORET_TYPE void (*rnk)(unsigned long, void *, unsigned long)
+ ATTRIB_NORET;
+
+ /* Mask all interrupts before starting to reboot. */
+ interrupt_mask_set_mask(~0ULL);
+
+ kexec_find_and_set_command_line(image);
+
+ /*
+ * Adjust the home caching of the control page to be cached on
+ * this cpu, and copy the assembly helper into the control
+ * code page, which we map in the vmalloc area.
+ */
+ homecache_change_page_home(image->control_code_page, 0,
+ smp_processor_id());
+ reboot_code_buffer = vmap(&image->control_code_page, 1, 0,
+ __pgprot(_PAGE_KERNEL | _PAGE_EXECUTABLE));
+ memcpy(reboot_code_buffer, relocate_new_kernel,
+ relocate_new_kernel_size);
+ __flush_icache_range(
+ (unsigned long) reboot_code_buffer,
+ (unsigned long) reboot_code_buffer + relocate_new_kernel_size);
+
+ setup_quasi_va_is_pa();
+
+ /* now call it */
+ rnk = reboot_code_buffer;
+ (*rnk)(image->head, reboot_code_buffer, image->start);
+}
diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c
new file mode 100644
index 000000000000..6d23ed271d10
--- /dev/null
+++ b/arch/tile/kernel/messaging.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <linux/hardirq.h>
+#include <linux/ptrace.h>
+#include <asm/hv_driver.h>
+#include <asm/irq_regs.h>
+#include <asm/traps.h>
+#include <hv/hypervisor.h>
+#include <arch/interrupts.h>
+
+/* All messages are stored here */
+static DEFINE_PER_CPU(HV_MsgState, msg_state);
+
+void __cpuinit init_messaging(void)
+{
+ /* Allocate storage for messages in kernel space */
+ HV_MsgState *state = &__get_cpu_var(msg_state);
+ int rc = hv_register_message_state(state);
+ if (rc != HV_OK)
+ panic("hv_register_message_state: error %d", rc);
+
+ /* Make sure downcall interrupts will be enabled. */
+ raw_local_irq_unmask(INT_INTCTRL_1);
+}
+
+void hv_message_intr(struct pt_regs *regs, int intnum)
+{
+ /*
+ * We enter with interrupts disabled and leave them disabled,
+ * to match expectations of called functions (e.g.
+ * do_ccupdate_local() in mm/slab.c). This is also consistent
+ * with normal call entry for device interrupts.
+ */
+
+ int message[HV_MAX_MESSAGE_SIZE/sizeof(int)];
+ HV_RcvMsgInfo rmi;
+ int nmsgs = 0;
+
+ /* Track time spent here in an interrupt context */
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ irq_enter();
+
+#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ /* Debugging check for stack overflow: less than 1/8th stack free? */
+ {
+ long sp = stack_pointer - (long) current_thread_info();
+ if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
+ pr_emerg("hv_message_intr: "
+ "stack overflow: %ld\n",
+ sp - sizeof(struct thread_info));
+ dump_stack();
+ }
+ }
+#endif
+
+ while (1) {
+ rmi = hv_receive_message(__get_cpu_var(msg_state),
+ (HV_VirtAddr) message,
+ sizeof(message));
+ if (rmi.msglen == 0)
+ break;
+
+ if (rmi.msglen < 0)
+ panic("hv_receive_message failed: %d", rmi.msglen);
+
+ ++nmsgs;
+
+ if (rmi.source == HV_MSG_TILE) {
+ int tag;
+
+ /* we just send tags for now */
+ BUG_ON(rmi.msglen != sizeof(int));
+
+ tag = message[0];
+#ifdef CONFIG_SMP
+ evaluate_message(message[0]);
+#else
+ panic("Received IPI message %d in UP mode", tag);
+#endif
+ } else if (rmi.source == HV_MSG_INTR) {
+ HV_IntrMsg *him = (HV_IntrMsg *)message;
+ struct hv_driver_cb *cb =
+ (struct hv_driver_cb *)him->intarg;
+ cb->callback(cb, him->intdata);
+ __get_cpu_var(irq_stat).irq_hv_msg_count++;
+ }
+ }
+
+ /*
+ * We shouldn't have gotten a message downcall with no
+ * messages available.
+ */
+ if (nmsgs == 0)
+ panic("Message downcall invoked with no messages!");
+
+ /*
+ * Track time spent against the current process again and
+ * process any softirqs if they are waiting.
+ */
+ irq_exit();
+ set_irq_regs(old_regs);
+}
diff --git a/arch/tile/kernel/module.c b/arch/tile/kernel/module.c
new file mode 100644
index 000000000000..e2ab82b7c7e7
--- /dev/null
+++ b/arch/tile/kernel/module.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Based on i386 version, copyright (C) 2001 Rusty Russell.
+ */
+
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <asm/opcode-tile.h>
+#include <asm/pgtable.h>
+
+#ifdef __tilegx__
+# define Elf_Rela Elf64_Rela
+# define ELF_R_SYM ELF64_R_SYM
+# define ELF_R_TYPE ELF64_R_TYPE
+#else
+# define Elf_Rela Elf32_Rela
+# define ELF_R_SYM ELF32_R_SYM
+# define ELF_R_TYPE ELF32_R_TYPE
+#endif
+
+#ifdef MODULE_DEBUG
+#define DEBUGP printk
+#else
+#define DEBUGP(fmt...)
+#endif
+
+/*
+ * Allocate some address space in the range MEM_MODULE_START to
+ * MEM_MODULE_END and populate it with memory.
+ */
+void *module_alloc(unsigned long size)
+{
+ struct page **pages;
+ pgprot_t prot_rwx = __pgprot(_PAGE_KERNEL | _PAGE_KERNEL_EXEC);
+ struct vm_struct *area;
+ int i = 0;
+ int npages;
+
+ if (size == 0)
+ return NULL;
+ npages = (size + PAGE_SIZE - 1) / PAGE_SIZE;
+ pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL);
+ if (pages == NULL)
+ return NULL;
+ for (; i < npages; ++i) {
+ pages[i] = alloc_page(GFP_KERNEL | __GFP_HIGHMEM);
+ if (!pages[i])
+ goto error;
+ }
+
+ area = __get_vm_area(size, VM_ALLOC, MEM_MODULE_START, MEM_MODULE_END);
+ if (!area)
+ goto error;
+
+ if (map_vm_area(area, prot_rwx, &pages)) {
+ vunmap(area->addr);
+ goto error;
+ }
+
+ return area->addr;
+
+error:
+ while (--i >= 0)
+ __free_page(pages[i]);
+ kfree(pages);
+ return NULL;
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+ /*
+ * FIXME: If module_region == mod->init_region, trim exception
+ * table entries.
+ */
+}
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+ Elf_Shdr *sechdrs,
+ char *secstrings,
+ struct module *mod)
+{
+ return 0;
+}
+
+int apply_relocate(Elf_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ pr_err("module %s: .rel relocation unsupported\n", me->name);
+ return -ENOEXEC;
+}
+
+#ifdef __tilegx__
+/*
+ * Validate that the high 16 bits of "value" is just the sign-extension of
+ * the low 48 bits.
+ */
+static int validate_hw2_last(long value, struct module *me)
+{
+ if (((value << 16) >> 16) != value) {
+ pr_warning("module %s: Out of range HW2_LAST value %#lx\n",
+ me->name, value);
+ return 0;
+ }
+ return 1;
+}
+
+/*
+ * Validate that "value" isn't too big to hold in a JumpOff relocation.
+ */
+static int validate_jumpoff(long value)
+{
+ /* Determine size of jump offset. */
+ int shift = __builtin_clzl(get_JumpOff_X1(create_JumpOff_X1(-1)));
+
+ /* Check to see if it fits into the relocation slot. */
+ long f = get_JumpOff_X1(create_JumpOff_X1(value));
+ f = (f << shift) >> shift;
+
+ return f == value;
+}
+#endif
+
+int apply_relocate_add(Elf_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ unsigned int i;
+ Elf_Rela *rel = (void *)sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u64 *location;
+ unsigned long value;
+
+ DEBUGP("Applying relocate section %u to %u\n", relsec,
+ sechdrs[relsec].sh_info);
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset;
+ /*
+ * This is the symbol it is referring to.
+ * Note that all undefined symbols have been resolved.
+ */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF_R_SYM(rel[i].r_info);
+ value = sym->st_value + rel[i].r_addend;
+
+ switch (ELF_R_TYPE(rel[i].r_info)) {
+
+#define MUNGE(func) (*location = ((*location & ~func(-1)) | func(value)))
+
+#ifndef __tilegx__
+ case R_TILE_32:
+ *(uint32_t *)location = value;
+ break;
+ case R_TILE_IMM16_X0_HA:
+ value = (value + 0x8000) >> 16;
+ /*FALLTHROUGH*/
+ case R_TILE_IMM16_X0_LO:
+ MUNGE(create_Imm16_X0);
+ break;
+ case R_TILE_IMM16_X1_HA:
+ value = (value + 0x8000) >> 16;
+ /*FALLTHROUGH*/
+ case R_TILE_IMM16_X1_LO:
+ MUNGE(create_Imm16_X1);
+ break;
+ case R_TILE_JOFFLONG_X1:
+ value -= (unsigned long) location; /* pc-relative */
+ value = (long) value >> 3; /* count by instrs */
+ MUNGE(create_JOffLong_X1);
+ break;
+#else
+ case R_TILEGX_64:
+ *location = value;
+ break;
+ case R_TILEGX_IMM16_X0_HW2_LAST:
+ if (!validate_hw2_last(value, me))
+ return -ENOEXEC;
+ value >>= 16;
+ /*FALLTHROUGH*/
+ case R_TILEGX_IMM16_X0_HW1:
+ value >>= 16;
+ /*FALLTHROUGH*/
+ case R_TILEGX_IMM16_X0_HW0:
+ MUNGE(create_Imm16_X0);
+ break;
+ case R_TILEGX_IMM16_X1_HW2_LAST:
+ if (!validate_hw2_last(value, me))
+ return -ENOEXEC;
+ value >>= 16;
+ /*FALLTHROUGH*/
+ case R_TILEGX_IMM16_X1_HW1:
+ value >>= 16;
+ /*FALLTHROUGH*/
+ case R_TILEGX_IMM16_X1_HW0:
+ MUNGE(create_Imm16_X1);
+ break;
+ case R_TILEGX_JUMPOFF_X1:
+ value -= (unsigned long) location; /* pc-relative */
+ value = (long) value >> 3; /* count by instrs */
+ if (!validate_jumpoff(value)) {
+ pr_warning("module %s: Out of range jump to"
+ " %#llx at %#llx (%p)\n", me->name,
+ sym->st_value + rel[i].r_addend,
+ rel[i].r_offset, location);
+ return -ENOEXEC;
+ }
+ MUNGE(create_JumpOff_X1);
+ break;
+#endif
+
+#undef MUNGE
+
+ default:
+ pr_err("module %s: Unknown relocation: %d\n",
+ me->name, (int) ELF_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ struct module *me)
+{
+ /* FIXME: perhaps remove the "writable" bit from the TLB? */
+ return 0;
+}
+
+void module_arch_cleanup(struct module *mod)
+{
+}
diff --git a/arch/tile/kernel/pci-dma.c b/arch/tile/kernel/pci-dma.c
new file mode 100644
index 000000000000..5ad5e13b0fa6
--- /dev/null
+++ b/arch/tile/kernel/pci-dma.c
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/vmalloc.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
+
+/* Generic DMA mapping functions: */
+
+/*
+ * Allocate what Linux calls "coherent" memory, which for us just
+ * means uncached.
+ */
+void *dma_alloc_coherent(struct device *dev,
+ size_t size,
+ dma_addr_t *dma_handle,
+ gfp_t gfp)
+{
+ u64 dma_mask = dev->coherent_dma_mask ?: DMA_BIT_MASK(32);
+ int node = dev_to_node(dev);
+ int order = get_order(size);
+ struct page *pg;
+ dma_addr_t addr;
+
+ gfp |= __GFP_ZERO;
+
+ /*
+ * By forcing NUMA node 0 for 32-bit masks we ensure that the
+ * high 32 bits of the resulting PA will be zero. If the mask
+ * size is, e.g., 24, we may still not be able to guarantee a
+ * suitable memory address, in which case we will return NULL.
+ * But such devices are uncommon.
+ */
+ if (dma_mask <= DMA_BIT_MASK(32))
+ node = 0;
+
+ pg = homecache_alloc_pages_node(node, gfp, order, PAGE_HOME_UNCACHED);
+ if (pg == NULL)
+ return NULL;
+
+ addr = page_to_phys(pg);
+ if (addr + size > dma_mask) {
+ homecache_free_pages(addr, order);
+ return NULL;
+ }
+
+ *dma_handle = addr;
+ return page_address(pg);
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+/*
+ * Free memory that was allocated with dma_alloc_coherent.
+ */
+void dma_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ homecache_free_pages((unsigned long)vaddr, get_order(size));
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+/*
+ * The map routines "map" the specified address range for DMA
+ * accesses. The memory belongs to the device after this call is
+ * issued, until it is unmapped with dma_unmap_single.
+ *
+ * We don't need to do any mapping, we just flush the address range
+ * out of the cache and return a DMA address.
+ *
+ * The unmap routines do whatever is necessary before the processor
+ * accesses the memory again, and must be called before the driver
+ * touches the memory. We can get away with a cache invalidate if we
+ * can count on nothing having been touched.
+ */
+
+
+/*
+ * dma_map_single can be passed any memory address, and there appear
+ * to be no alignment constraints.
+ *
+ * There is a chance that the start of the buffer will share a cache
+ * line with some other data that has been touched in the meantime.
+ */
+dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ struct page *page;
+ dma_addr_t dma_addr;
+ int thispage;
+
+ BUG_ON(!valid_dma_direction(direction));
+ WARN_ON(size == 0);
+
+ dma_addr = __pa(ptr);
+
+ /* We might have been handed a buffer that wraps a page boundary */
+ while ((int)size > 0) {
+ /* The amount to flush that's on this page */
+ thispage = PAGE_SIZE - ((unsigned long)ptr & (PAGE_SIZE - 1));
+ thispage = min((int)thispage, (int)size);
+ /* Is this valid for any page we could be handed? */
+ page = pfn_to_page(kaddr_to_pfn(ptr));
+ homecache_flush_cache(page, 0);
+ ptr += thispage;
+ size -= thispage;
+ }
+
+ return dma_addr;
+}
+EXPORT_SYMBOL(dma_map_single);
+
+void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_unmap_single);
+
+int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
+ enum dma_data_direction direction)
+{
+ struct scatterlist *sg;
+ int i;
+
+ BUG_ON(!valid_dma_direction(direction));
+
+ WARN_ON(nents == 0 || sglist->length == 0);
+
+ for_each_sg(sglist, sg, nents, i) {
+ struct page *page;
+ sg->dma_address = sg_phys(sg);
+ page = pfn_to_page(sg->dma_address >> PAGE_SHIFT);
+ homecache_flush_cache(page, 0);
+ }
+
+ return nents;
+}
+EXPORT_SYMBOL(dma_map_sg);
+
+void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_unmap_sg);
+
+dma_addr_t dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+
+ homecache_flush_cache(page, 0);
+
+ return page_to_pa(page) + offset;
+}
+EXPORT_SYMBOL(dma_map_page);
+
+void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_unmap_page);
+
+void dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+}
+EXPORT_SYMBOL(dma_sync_single_for_cpu);
+
+void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
+ size_t size, enum dma_data_direction direction)
+{
+ unsigned long start = PFN_DOWN(dma_handle);
+ unsigned long end = PFN_DOWN(dma_handle + size - 1);
+ unsigned long i;
+
+ BUG_ON(!valid_dma_direction(direction));
+ for (i = start; i <= end; ++i)
+ homecache_flush_cache(pfn_to_page(i), 0);
+}
+EXPORT_SYMBOL(dma_sync_single_for_device);
+
+void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG_ON(!valid_dma_direction(direction));
+ WARN_ON(nelems == 0 || sg[0].length == 0);
+}
+EXPORT_SYMBOL(dma_sync_sg_for_cpu);
+
+/*
+ * Flush and invalidate cache for scatterlist.
+ */
+void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction direction)
+{
+ struct scatterlist *sg;
+ int i;
+
+ BUG_ON(!valid_dma_direction(direction));
+ WARN_ON(nelems == 0 || sglist->length == 0);
+
+ for_each_sg(sglist, sg, nelems, i) {
+ dma_sync_single_for_device(dev, sg->dma_address,
+ sg_dma_len(sg), direction);
+ }
+}
+EXPORT_SYMBOL(dma_sync_sg_for_device);
+
+void dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_cpu(dev, dma_handle + offset, size, direction);
+}
+EXPORT_SYMBOL(dma_sync_single_range_for_cpu);
+
+void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t dma_handle,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ dma_sync_single_for_device(dev, dma_handle + offset, size, direction);
+}
+EXPORT_SYMBOL(dma_sync_single_range_for_device);
+
+/*
+ * dma_alloc_noncoherent() returns non-cacheable memory, so there's no
+ * need to do any flushing here.
+ */
+void dma_cache_sync(void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+}
+EXPORT_SYMBOL(dma_cache_sync);
diff --git a/arch/tile/kernel/proc.c b/arch/tile/kernel/proc.c
new file mode 100644
index 000000000000..92ef925d2f8d
--- /dev/null
+++ b/arch/tile/kernel/proc.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/smp.h>
+#include <linux/seq_file.h>
+#include <linux/threads.h>
+#include <linux/cpumask.h>
+#include <linux/timex.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/sysctl.h>
+#include <linux/hardirq.h>
+#include <linux/mman.h>
+#include <linux/smp.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/sections.h>
+#include <asm/homecache.h>
+#include <arch/chip.h>
+
+
+/*
+ * Support /proc/cpuinfo
+ */
+
+#define cpu_to_ptr(n) ((void *)((long)(n)+1))
+#define ptr_to_cpu(p) ((long)(p) - 1)
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ int n = ptr_to_cpu(v);
+
+ if (n == 0) {
+ char buf[NR_CPUS*5];
+ cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
+ seq_printf(m, "cpu count\t: %d\n", num_online_cpus());
+ seq_printf(m, "cpu list\t: %s\n", buf);
+ seq_printf(m, "model name\t: %s\n", chip_model);
+ seq_printf(m, "flags\t\t:\n"); /* nothing for now */
+ seq_printf(m, "cpu MHz\t\t: %llu.%06llu\n",
+ get_clock_rate() / 1000000,
+ (get_clock_rate() % 1000000));
+ seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100);
+ }
+
+#ifdef CONFIG_SMP
+ if (!cpu_online(n))
+ return 0;
+#endif
+
+ seq_printf(m, "processor\t: %d\n", n);
+
+ /* Print only num_online_cpus() blank lines total. */
+ if (cpumask_next(n, cpu_online_mask) < nr_cpu_ids)
+ seq_printf(m, "\n");
+
+ return 0;
+}
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+ return *pos < nr_cpu_ids ? cpu_to_ptr(*pos) : NULL;
+}
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+ ++*pos;
+ return c_start(m, pos);
+}
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+const struct seq_operations cpuinfo_op = {
+ .start = c_start,
+ .next = c_next,
+ .stop = c_stop,
+ .show = show_cpuinfo,
+};
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c
new file mode 100644
index 000000000000..ed590ad0acdc
--- /dev/null
+++ b/arch/tile/kernel/process.c
@@ -0,0 +1,671 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/preempt.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/kprobes.h>
+#include <linux/elfcore.h>
+#include <linux/tick.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/compat.h>
+#include <linux/hardirq.h>
+#include <linux/syscalls.h>
+#include <linux/kernel.h>
+#include <asm/system.h>
+#include <asm/stack.h>
+#include <asm/homecache.h>
+#include <asm/syscalls.h>
+#ifdef CONFIG_HARDWALL
+#include <asm/hardwall.h>
+#endif
+#include <arch/chip.h>
+#include <arch/abi.h>
+
+
+/*
+ * Use the (x86) "idle=poll" option to prefer low latency when leaving the
+ * idle loop over low power while in the idle loop, e.g. if we have
+ * one thread per core and we want to get threads out of futex waits fast.
+ */
+static int no_idle_nap;
+static int __init idle_setup(char *str)
+{
+ if (!str)
+ return -EINVAL;
+
+ if (!strcmp(str, "poll")) {
+ pr_info("using polling idle threads.\n");
+ no_idle_nap = 1;
+ } else if (!strcmp(str, "halt"))
+ no_idle_nap = 0;
+ else
+ return -1;
+
+ return 0;
+}
+early_param("idle", idle_setup);
+
+/*
+ * The idle thread. There's no useful work to be
+ * done, so just try to conserve power and have a
+ * low exit latency (ie sit in a loop waiting for
+ * somebody to say that they'd like to reschedule)
+ */
+void cpu_idle(void)
+{
+ int cpu = smp_processor_id();
+
+
+ current_thread_info()->status |= TS_POLLING;
+
+ if (no_idle_nap) {
+ while (1) {
+ while (!need_resched())
+ cpu_relax();
+ schedule();
+ }
+ }
+
+ /* endless idle loop with no priority at all */
+ while (1) {
+ tick_nohz_stop_sched_tick(1);
+ while (!need_resched()) {
+ if (cpu_is_offline(cpu))
+ BUG(); /* no HOTPLUG_CPU */
+
+ local_irq_disable();
+ __get_cpu_var(irq_stat).idle_timestamp = jiffies;
+ current_thread_info()->status &= ~TS_POLLING;
+ /*
+ * TS_POLLING-cleared state must be visible before we
+ * test NEED_RESCHED:
+ */
+ smp_mb();
+
+ if (!need_resched())
+ _cpu_idle();
+ else
+ local_irq_enable();
+ current_thread_info()->status |= TS_POLLING;
+ }
+ tick_nohz_restart_sched_tick();
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+struct thread_info *alloc_thread_info(struct task_struct *task)
+{
+ struct page *page;
+ gfp_t flags = GFP_KERNEL;
+
+#ifdef CONFIG_DEBUG_STACK_USAGE
+ flags |= __GFP_ZERO;
+#endif
+
+ page = alloc_pages(flags, THREAD_SIZE_ORDER);
+ if (!page)
+ return NULL;
+
+ return (struct thread_info *)page_address(page);
+}
+
+/*
+ * Free a thread_info node, and all of its derivative
+ * data structures.
+ */
+void free_thread_info(struct thread_info *info)
+{
+ struct single_step_state *step_state = info->step_state;
+
+#ifdef CONFIG_HARDWALL
+ /*
+ * We free a thread_info from the context of the task that has
+ * been scheduled next, so the original task is already dead.
+ * Calling deactivate here just frees up the data structures.
+ * If the task we're freeing held the last reference to a
+ * hardwall fd, it would have been released prior to this point
+ * anyway via exit_files(), and "hardwall" would be NULL by now.
+ */
+ if (info->task->thread.hardwall)
+ hardwall_deactivate(info->task);
+#endif
+
+ if (step_state) {
+
+ /*
+ * FIXME: we don't munmap step_state->buffer
+ * because the mm_struct for this process (info->task->mm)
+ * has already been zeroed in exit_mm(). Keeping a
+ * reference to it here seems like a bad move, so this
+ * means we can't munmap() the buffer, and therefore if we
+ * ptrace multiple threads in a process, we will slowly
+ * leak user memory. (Note that as soon as the last
+ * thread in a process dies, we will reclaim all user
+ * memory including single-step buffers in the usual way.)
+ * We should either assign a kernel VA to this buffer
+ * somehow, or we should associate the buffer(s) with the
+ * mm itself so we can clean them up that way.
+ */
+ kfree(step_state);
+ }
+
+ free_page((unsigned long)info);
+}
+
+static void save_arch_state(struct thread_struct *t);
+
+int copy_thread(unsigned long clone_flags, unsigned long sp,
+ unsigned long stack_size,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs;
+ unsigned long ksp;
+
+ /*
+ * When creating a new kernel thread we pass sp as zero.
+ * Assign it to a reasonable value now that we have the stack.
+ */
+ if (sp == 0 && regs->ex1 == PL_ICS_EX1(KERNEL_PL, 0))
+ sp = KSTK_TOP(p);
+
+ /*
+ * Do not clone step state from the parent; each thread
+ * must make its own lazily.
+ */
+ task_thread_info(p)->step_state = NULL;
+
+ /*
+ * Start new thread in ret_from_fork so it schedules properly
+ * and then return from interrupt like the parent.
+ */
+ p->thread.pc = (unsigned long) ret_from_fork;
+
+ /* Save user stack top pointer so we can ID the stack vm area later. */
+ p->thread.usp0 = sp;
+
+ /* Record the pid of the process that created this one. */
+ p->thread.creator_pid = current->pid;
+
+ /*
+ * Copy the registers onto the kernel stack so the
+ * return-from-interrupt code will reload it into registers.
+ */
+ childregs = task_pt_regs(p);
+ *childregs = *regs;
+ childregs->regs[0] = 0; /* return value is zero */
+ childregs->sp = sp; /* override with new user stack pointer */
+
+ /*
+ * Copy the callee-saved registers from the passed pt_regs struct
+ * into the context-switch callee-saved registers area.
+ * We have to restore the callee-saved registers since we may
+ * be cloning a userspace task with userspace register state,
+ * and we won't be unwinding the same kernel frames to restore them.
+ * Zero out the C ABI save area to mark the top of the stack.
+ */
+ ksp = (unsigned long) childregs;
+ ksp -= C_ABI_SAVE_AREA_SIZE; /* interrupt-entry save area */
+ ((long *)ksp)[0] = ((long *)ksp)[1] = 0;
+ ksp -= CALLEE_SAVED_REGS_COUNT * sizeof(unsigned long);
+ memcpy((void *)ksp, &regs->regs[CALLEE_SAVED_FIRST_REG],
+ CALLEE_SAVED_REGS_COUNT * sizeof(unsigned long));
+ ksp -= C_ABI_SAVE_AREA_SIZE; /* __switch_to() save area */
+ ((long *)ksp)[0] = ((long *)ksp)[1] = 0;
+ p->thread.ksp = ksp;
+
+#if CHIP_HAS_TILE_DMA()
+ /*
+ * No DMA in the new thread. We model this on the fact that
+ * fork() clears the pending signals, alarms, and aio for the child.
+ */
+ memset(&p->thread.tile_dma_state, 0, sizeof(struct tile_dma_state));
+ memset(&p->thread.dma_async_tlb, 0, sizeof(struct async_tlb));
+#endif
+
+#if CHIP_HAS_SN_PROC()
+ /* Likewise, the new thread is not running static processor code. */
+ p->thread.sn_proc_running = 0;
+ memset(&p->thread.sn_async_tlb, 0, sizeof(struct async_tlb));
+#endif
+
+#if CHIP_HAS_PROC_STATUS_SPR()
+ /* New thread has its miscellaneous processor state bits clear. */
+ p->thread.proc_status = 0;
+#endif
+
+#ifdef CONFIG_HARDWALL
+ /* New thread does not own any networks. */
+ p->thread.hardwall = NULL;
+#endif
+
+
+ /*
+ * Start the new thread with the current architecture state
+ * (user interrupt masks, etc.).
+ */
+ save_arch_state(&p->thread);
+
+ return 0;
+}
+
+/*
+ * Return "current" if it looks plausible, or else a pointer to a dummy.
+ * This can be helpful if we are just trying to emit a clean panic.
+ */
+struct task_struct *validate_current(void)
+{
+ static struct task_struct corrupt = { .comm = "<corrupt>" };
+ struct task_struct *tsk = current;
+ if (unlikely((unsigned long)tsk < PAGE_OFFSET ||
+ (void *)tsk > high_memory ||
+ ((unsigned long)tsk & (__alignof__(*tsk) - 1)) != 0)) {
+ pr_err("Corrupt 'current' %p (sp %#lx)\n", tsk, stack_pointer);
+ tsk = &corrupt;
+ }
+ return tsk;
+}
+
+/* Take and return the pointer to the previous task, for schedule_tail(). */
+struct task_struct *sim_notify_fork(struct task_struct *prev)
+{
+ struct task_struct *tsk = current;
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK_PARENT |
+ (tsk->thread.creator_pid << _SIM_CONTROL_OPERATOR_BITS));
+ __insn_mtspr(SPR_SIM_CONTROL, SIM_CONTROL_OS_FORK |
+ (tsk->pid << _SIM_CONTROL_OPERATOR_BITS));
+ return prev;
+}
+
+int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
+{
+ struct pt_regs *ptregs = task_pt_regs(tsk);
+ elf_core_copy_regs(regs, ptregs);
+ return 1;
+}
+
+#if CHIP_HAS_TILE_DMA()
+
+/* Allow user processes to access the DMA SPRs */
+void grant_dma_mpls(void)
+{
+ __insn_mtspr(SPR_MPL_DMA_CPL_SET_0, 1);
+ __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_0, 1);
+}
+
+/* Forbid user processes from accessing the DMA SPRs */
+void restrict_dma_mpls(void)
+{
+ __insn_mtspr(SPR_MPL_DMA_CPL_SET_1, 1);
+ __insn_mtspr(SPR_MPL_DMA_NOTIFY_SET_1, 1);
+}
+
+/* Pause the DMA engine, then save off its state registers. */
+static void save_tile_dma_state(struct tile_dma_state *dma)
+{
+ unsigned long state = __insn_mfspr(SPR_DMA_USER_STATUS);
+ unsigned long post_suspend_state;
+
+ /* If we're running, suspend the engine. */
+ if ((state & DMA_STATUS_MASK) == SPR_DMA_STATUS__RUNNING_MASK)
+ __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__SUSPEND_MASK);
+
+ /*
+ * Wait for the engine to idle, then save regs. Note that we
+ * want to record the "running" bit from before suspension,
+ * and the "done" bit from after, so that we can properly
+ * distinguish a case where the user suspended the engine from
+ * the case where the kernel suspended as part of the context
+ * swap.
+ */
+ do {
+ post_suspend_state = __insn_mfspr(SPR_DMA_USER_STATUS);
+ } while (post_suspend_state & SPR_DMA_STATUS__BUSY_MASK);
+
+ dma->src = __insn_mfspr(SPR_DMA_SRC_ADDR);
+ dma->src_chunk = __insn_mfspr(SPR_DMA_SRC_CHUNK_ADDR);
+ dma->dest = __insn_mfspr(SPR_DMA_DST_ADDR);
+ dma->dest_chunk = __insn_mfspr(SPR_DMA_DST_CHUNK_ADDR);
+ dma->strides = __insn_mfspr(SPR_DMA_STRIDE);
+ dma->chunk_size = __insn_mfspr(SPR_DMA_CHUNK_SIZE);
+ dma->byte = __insn_mfspr(SPR_DMA_BYTE);
+ dma->status = (state & SPR_DMA_STATUS__RUNNING_MASK) |
+ (post_suspend_state & SPR_DMA_STATUS__DONE_MASK);
+}
+
+/* Restart a DMA that was running before we were context-switched out. */
+static void restore_tile_dma_state(struct thread_struct *t)
+{
+ const struct tile_dma_state *dma = &t->tile_dma_state;
+
+ /*
+ * The only way to restore the done bit is to run a zero
+ * length transaction.
+ */
+ if ((dma->status & SPR_DMA_STATUS__DONE_MASK) &&
+ !(__insn_mfspr(SPR_DMA_USER_STATUS) & SPR_DMA_STATUS__DONE_MASK)) {
+ __insn_mtspr(SPR_DMA_BYTE, 0);
+ __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
+ while (__insn_mfspr(SPR_DMA_USER_STATUS) &
+ SPR_DMA_STATUS__BUSY_MASK)
+ ;
+ }
+
+ __insn_mtspr(SPR_DMA_SRC_ADDR, dma->src);
+ __insn_mtspr(SPR_DMA_SRC_CHUNK_ADDR, dma->src_chunk);
+ __insn_mtspr(SPR_DMA_DST_ADDR, dma->dest);
+ __insn_mtspr(SPR_DMA_DST_CHUNK_ADDR, dma->dest_chunk);
+ __insn_mtspr(SPR_DMA_STRIDE, dma->strides);
+ __insn_mtspr(SPR_DMA_CHUNK_SIZE, dma->chunk_size);
+ __insn_mtspr(SPR_DMA_BYTE, dma->byte);
+
+ /*
+ * Restart the engine if we were running and not done.
+ * Clear a pending async DMA fault that we were waiting on return
+ * to user space to execute, since we expect the DMA engine
+ * to regenerate those faults for us now. Note that we don't
+ * try to clear the TIF_ASYNC_TLB flag, since it's relatively
+ * harmless if set, and it covers both DMA and the SN processor.
+ */
+ if ((dma->status & DMA_STATUS_MASK) == SPR_DMA_STATUS__RUNNING_MASK) {
+ t->dma_async_tlb.fault_num = 0;
+ __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
+ }
+}
+
+#endif
+
+static void save_arch_state(struct thread_struct *t)
+{
+#if CHIP_HAS_SPLIT_INTR_MASK()
+ t->interrupt_mask = __insn_mfspr(SPR_INTERRUPT_MASK_0_0) |
+ ((u64)__insn_mfspr(SPR_INTERRUPT_MASK_0_1) << 32);
+#else
+ t->interrupt_mask = __insn_mfspr(SPR_INTERRUPT_MASK_0);
+#endif
+ t->ex_context[0] = __insn_mfspr(SPR_EX_CONTEXT_0_0);
+ t->ex_context[1] = __insn_mfspr(SPR_EX_CONTEXT_0_1);
+ t->system_save[0] = __insn_mfspr(SPR_SYSTEM_SAVE_0_0);
+ t->system_save[1] = __insn_mfspr(SPR_SYSTEM_SAVE_0_1);
+ t->system_save[2] = __insn_mfspr(SPR_SYSTEM_SAVE_0_2);
+ t->system_save[3] = __insn_mfspr(SPR_SYSTEM_SAVE_0_3);
+ t->intctrl_0 = __insn_mfspr(SPR_INTCTRL_0_STATUS);
+#if CHIP_HAS_PROC_STATUS_SPR()
+ t->proc_status = __insn_mfspr(SPR_PROC_STATUS);
+#endif
+}
+
+static void restore_arch_state(const struct thread_struct *t)
+{
+#if CHIP_HAS_SPLIT_INTR_MASK()
+ __insn_mtspr(SPR_INTERRUPT_MASK_0_0, (u32) t->interrupt_mask);
+ __insn_mtspr(SPR_INTERRUPT_MASK_0_1, t->interrupt_mask >> 32);
+#else
+ __insn_mtspr(SPR_INTERRUPT_MASK_0, t->interrupt_mask);
+#endif
+ __insn_mtspr(SPR_EX_CONTEXT_0_0, t->ex_context[0]);
+ __insn_mtspr(SPR_EX_CONTEXT_0_1, t->ex_context[1]);
+ __insn_mtspr(SPR_SYSTEM_SAVE_0_0, t->system_save[0]);
+ __insn_mtspr(SPR_SYSTEM_SAVE_0_1, t->system_save[1]);
+ __insn_mtspr(SPR_SYSTEM_SAVE_0_2, t->system_save[2]);
+ __insn_mtspr(SPR_SYSTEM_SAVE_0_3, t->system_save[3]);
+ __insn_mtspr(SPR_INTCTRL_0_STATUS, t->intctrl_0);
+#if CHIP_HAS_PROC_STATUS_SPR()
+ __insn_mtspr(SPR_PROC_STATUS, t->proc_status);
+#endif
+#if CHIP_HAS_TILE_RTF_HWM()
+ /*
+ * Clear this whenever we switch back to a process in case
+ * the previous process was monkeying with it. Even if enabled
+ * in CBOX_MSR1 via TILE_RTF_HWM_MIN, it's still just a
+ * performance hint, so isn't worth a full save/restore.
+ */
+ __insn_mtspr(SPR_TILE_RTF_HWM, 0);
+#endif
+}
+
+
+void _prepare_arch_switch(struct task_struct *next)
+{
+#if CHIP_HAS_SN_PROC()
+ int snctl;
+#endif
+#if CHIP_HAS_TILE_DMA()
+ struct tile_dma_state *dma = &current->thread.tile_dma_state;
+ if (dma->enabled)
+ save_tile_dma_state(dma);
+#endif
+#if CHIP_HAS_SN_PROC()
+ /*
+ * Suspend the static network processor if it was running.
+ * We do not suspend the fabric itself, just like we don't
+ * try to suspend the UDN.
+ */
+ snctl = __insn_mfspr(SPR_SNCTL);
+ current->thread.sn_proc_running =
+ (snctl & SPR_SNCTL__FRZPROC_MASK) == 0;
+ if (current->thread.sn_proc_running)
+ __insn_mtspr(SPR_SNCTL, snctl | SPR_SNCTL__FRZPROC_MASK);
+#endif
+}
+
+
+struct task_struct *__sched _switch_to(struct task_struct *prev,
+ struct task_struct *next)
+{
+ /* DMA state is already saved; save off other arch state. */
+ save_arch_state(&prev->thread);
+
+#if CHIP_HAS_TILE_DMA()
+ /*
+ * Restore DMA in new task if desired.
+ * Note that it is only safe to restart here since interrupts
+ * are disabled, so we can't take any DMATLB miss or access
+ * interrupts before we have finished switching stacks.
+ */
+ if (next->thread.tile_dma_state.enabled) {
+ restore_tile_dma_state(&next->thread);
+ grant_dma_mpls();
+ } else {
+ restrict_dma_mpls();
+ }
+#endif
+
+ /* Restore other arch state. */
+ restore_arch_state(&next->thread);
+
+#if CHIP_HAS_SN_PROC()
+ /*
+ * Restart static network processor in the new process
+ * if it was running before.
+ */
+ if (next->thread.sn_proc_running) {
+ int snctl = __insn_mfspr(SPR_SNCTL);
+ __insn_mtspr(SPR_SNCTL, snctl & ~SPR_SNCTL__FRZPROC_MASK);
+ }
+#endif
+
+#ifdef CONFIG_HARDWALL
+ /* Enable or disable access to the network registers appropriately. */
+ if (prev->thread.hardwall != NULL) {
+ if (next->thread.hardwall == NULL)
+ restrict_network_mpls();
+ } else if (next->thread.hardwall != NULL) {
+ grant_network_mpls();
+ }
+#endif
+
+ /*
+ * Switch kernel SP, PC, and callee-saved registers.
+ * In the context of the new task, return the old task pointer
+ * (i.e. the task that actually called __switch_to).
+ * Pass the value to use for SYSTEM_SAVE_1_0 when we reset our sp.
+ */
+ return __switch_to(prev, next, next_current_ksp0(next));
+}
+
+long _sys_fork(struct pt_regs *regs)
+{
+ return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+}
+
+long _sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tidptr, void __user *child_tidptr,
+ struct pt_regs *regs)
+{
+ if (!newsp)
+ newsp = regs->sp;
+ return do_fork(clone_flags, newsp, regs, 0,
+ parent_tidptr, child_tidptr);
+}
+
+long _sys_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp,
+ regs, 0, NULL, NULL);
+}
+
+/*
+ * sys_execve() executes a new program.
+ */
+long _sys_execve(char __user *path, char __user *__user *argv,
+ char __user *__user *envp, struct pt_regs *regs)
+{
+ long error;
+ char *filename;
+
+ filename = getname(path);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+
+#ifdef CONFIG_COMPAT
+long _compat_sys_execve(char __user *path, compat_uptr_t __user *argv,
+ compat_uptr_t __user *envp, struct pt_regs *regs)
+{
+ long error;
+ char *filename;
+
+ filename = getname(path);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+ error = compat_do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+#endif
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ struct KBacktraceIterator kbt;
+
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ for (KBacktraceIterator_init(&kbt, p, NULL);
+ !KBacktraceIterator_end(&kbt);
+ KBacktraceIterator_next(&kbt)) {
+ if (!in_sched_functions(kbt.it.pc))
+ return kbt.it.pc;
+ }
+
+ return 0;
+}
+
+/*
+ * We pass in lr as zero (cleared in kernel_thread) and the caller
+ * part of the backtrace ABI on the stack also zeroed (in copy_thread)
+ * so that backtraces will stop with this function.
+ * Note that we don't use r0, since copy_thread() clears it.
+ */
+static void start_kernel_thread(int dummy, int (*fn)(int), int arg)
+{
+ do_exit(fn(arg));
+}
+
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ memset(&regs, 0, sizeof(regs));
+ regs.ex1 = PL_ICS_EX1(KERNEL_PL, 0); /* run at kernel PL, no ICS */
+ regs.pc = (long) start_kernel_thread;
+ regs.flags = PT_FLAGS_CALLER_SAVES; /* need to restore r1 and r2 */
+ regs.regs[1] = (long) fn; /* function pointer */
+ regs.regs[2] = (long) arg; /* parameter register */
+
+ /* Ok, create the new process.. */
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs,
+ 0, NULL, NULL);
+}
+EXPORT_SYMBOL(kernel_thread);
+
+/* Flush thread state. */
+void flush_thread(void)
+{
+ /* Nothing */
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+ /* Nothing */
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ struct task_struct *tsk = validate_current();
+ int i;
+
+ pr_err("\n");
+ pr_err(" Pid: %d, comm: %20s, CPU: %d\n",
+ tsk->pid, tsk->comm, smp_processor_id());
+#ifdef __tilegx__
+ for (i = 0; i < 51; i += 3)
+ pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
+ i, regs->regs[i], i+1, regs->regs[i+1],
+ i+2, regs->regs[i+2]);
+ pr_err(" r51: "REGFMT" r52: "REGFMT" tp : "REGFMT"\n",
+ regs->regs[51], regs->regs[52], regs->tp);
+ pr_err(" sp : "REGFMT" lr : "REGFMT"\n", regs->sp, regs->lr);
+#else
+ for (i = 0; i < 52; i += 3)
+ pr_err(" r%-2d: "REGFMT" r%-2d: "REGFMT
+ " r%-2d: "REGFMT" r%-2d: "REGFMT"\n",
+ i, regs->regs[i], i+1, regs->regs[i+1],
+ i+2, regs->regs[i+2], i+3, regs->regs[i+3]);
+ pr_err(" r52: "REGFMT" tp : "REGFMT" sp : "REGFMT" lr : "REGFMT"\n",
+ regs->regs[52], regs->tp, regs->sp, regs->lr);
+#endif
+ pr_err(" pc : "REGFMT" ex1: %ld faultnum: %ld\n",
+ regs->pc, regs->ex1, regs->faultnum);
+
+ dump_stack_regs(regs);
+}
diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c
new file mode 100644
index 000000000000..7161bd03d2fd
--- /dev/null
+++ b/arch/tile/kernel/ptrace.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Copied from i386: Ross Biro 1/23/92
+ */
+
+#include <linux/kernel.h>
+#include <linux/ptrace.h>
+#include <linux/kprobes.h>
+#include <linux/compat.h>
+#include <linux/uaccess.h>
+#include <asm/traps.h>
+
+void user_enable_single_step(struct task_struct *child)
+{
+ set_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+void user_disable_single_step(struct task_struct *child)
+{
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+}
+
+/*
+ * This routine will put a word on the process's privileged stack.
+ */
+static void putreg(struct task_struct *task,
+ unsigned long addr, unsigned long value)
+{
+ unsigned int regno = addr / sizeof(unsigned long);
+ struct pt_regs *childregs = task_pt_regs(task);
+ childregs->regs[regno] = value;
+ childregs->flags |= PT_FLAGS_RESTORE_REGS;
+}
+
+static unsigned long getreg(struct task_struct *task, unsigned long addr)
+{
+ unsigned int regno = addr / sizeof(unsigned long);
+ struct pt_regs *childregs = task_pt_regs(task);
+ return childregs->regs[regno];
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching..
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ clear_tsk_thread_flag(child, TIF_SINGLESTEP);
+
+ /*
+ * These two are currently unused, but will be set by arch_ptrace()
+ * and used in the syscall assembly when we do support them.
+ */
+ clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+}
+
+long arch_ptrace(struct task_struct *child, long request, long addr, long data)
+{
+ unsigned long __user *datap;
+ unsigned long tmp;
+ int i;
+ long ret = -EIO;
+
+#ifdef CONFIG_COMPAT
+ if (task_thread_info(current)->status & TS_COMPAT)
+ data = (u32)data;
+ if (task_thread_info(child)->status & TS_COMPAT)
+ addr = (u32)addr;
+#endif
+ datap = (unsigned long __user __force *)data;
+
+ switch (request) {
+
+ case PTRACE_PEEKUSR: /* Read register from pt_regs. */
+ if (addr & (sizeof(data)-1))
+ break;
+ if (addr < 0 || addr >= PTREGS_SIZE)
+ break;
+ tmp = getreg(child, addr); /* Read register */
+ ret = put_user(tmp, datap);
+ break;
+
+ case PTRACE_POKEUSR: /* Write register in pt_regs. */
+ if (addr & (sizeof(data)-1))
+ break;
+ if (addr < 0 || addr >= PTREGS_SIZE)
+ break;
+ putreg(child, addr, data); /* Write register */
+ ret = 0;
+ break;
+
+ case PTRACE_GETREGS: /* Get all registers from the child. */
+ if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE))
+ break;
+ for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
+ ret = __put_user(getreg(child, i), datap);
+ if (ret != 0)
+ break;
+ datap++;
+ }
+ break;
+
+ case PTRACE_SETREGS: /* Set all registers in the child. */
+ if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE))
+ break;
+ for (i = 0; i < PTREGS_SIZE; i += sizeof(long)) {
+ ret = __get_user(tmp, datap);
+ if (ret != 0)
+ break;
+ putreg(child, i, tmp);
+ datap++;
+ }
+ break;
+
+ case PTRACE_GETFPREGS: /* Get the child FPU state. */
+ case PTRACE_SETFPREGS: /* Set the child FPU state. */
+ break;
+
+ case PTRACE_SETOPTIONS:
+ /* Support TILE-specific ptrace options. */
+ child->ptrace &= ~PT_TRACE_MASK_TILE;
+ tmp = data & PTRACE_O_MASK_TILE;
+ data &= ~PTRACE_O_MASK_TILE;
+ ret = ptrace_request(child, request, addr, data);
+ if (tmp & PTRACE_O_TRACEMIGRATE)
+ child->ptrace |= PT_TRACE_MIGRATE;
+ break;
+
+ default:
+#ifdef CONFIG_COMPAT
+ if (task_thread_info(current)->status & TS_COMPAT) {
+ ret = compat_ptrace_request(child, request,
+ addr, data);
+ break;
+ }
+#endif
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_COMPAT
+/* Not used; we handle compat issues in arch_ptrace() directly. */
+long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
+ compat_ulong_t addr, compat_ulong_t data)
+{
+ BUG();
+}
+#endif
+
+void do_syscall_trace(void)
+{
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+
+ if (!(current->ptrace & PT_PTRACED))
+ return;
+
+ /*
+ * The 0x80 provides a way for the tracing parent to distinguish
+ * between a syscall stop and SIGTRAP delivery
+ */
+ ptrace_notify(SIGTRAP|((current->ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
+
+ /*
+ * this isn't the same as continuing with a signal, but it will do
+ * for normal use. strace only continues with a signal if the
+ * stopping signal is not SIGTRAP. -brl
+ */
+ if (current->exit_code) {
+ send_sig(current->exit_code, current, 1);
+ current->exit_code = 0;
+ }
+}
+
+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
+{
+ struct siginfo info;
+
+ memset(&info, 0, sizeof(info));
+ info.si_signo = SIGTRAP;
+ info.si_code = TRAP_BRKPT;
+ info.si_addr = (void __user *) regs->pc;
+
+ /* Send us the fakey SIGTRAP */
+ force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/* Handle synthetic interrupt delivered only by the simulator. */
+void __kprobes do_breakpoint(struct pt_regs* regs, int fault_num)
+{
+ send_sigtrap(current, regs, fault_num);
+}
diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c
new file mode 100644
index 000000000000..acd86d20beba
--- /dev/null
+++ b/arch/tile/kernel/reboot.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/stddef.h>
+#include <linux/reboot.h>
+#include <linux/smp.h>
+#include <linux/pm.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <hv/hypervisor.h>
+
+#ifndef CONFIG_SMP
+#define smp_send_stop()
+#endif
+
+void machine_halt(void)
+{
+ warn_early_printk();
+ raw_local_irq_disable_all();
+ smp_send_stop();
+ hv_halt();
+}
+
+void machine_power_off(void)
+{
+ warn_early_printk();
+ raw_local_irq_disable_all();
+ smp_send_stop();
+ hv_power_off();
+}
+
+void machine_restart(char *cmd)
+{
+ raw_local_irq_disable_all();
+ smp_send_stop();
+ hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd);
+}
+
+/* No interesting distinction to be made here. */
+void (*pm_power_off)(void) = NULL;
diff --git a/arch/tile/kernel/regs_32.S b/arch/tile/kernel/regs_32.S
new file mode 100644
index 000000000000..e88d6e122783
--- /dev/null
+++ b/arch/tile/kernel/regs_32.S
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
+#include <arch/spr_def.h>
+#include <asm/processor.h>
+
+/*
+ * See <asm/system.h>; called with prev and next task_struct pointers.
+ * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
+ *
+ * We want to save pc/sp in "prev", and get the new pc/sp from "next".
+ * We also need to save all the callee-saved registers on the stack.
+ *
+ * Intel enables/disables access to the hardware cycle counter in
+ * seccomp (secure computing) environments if necessary, based on
+ * has_secure_computing(). We might want to do this at some point,
+ * though it would require virtualizing the other SPRs under WORLD_ACCESS.
+ *
+ * Since we're saving to the stack, we omit sp from this list.
+ * And for parallels with other architectures, we save lr separately,
+ * in the thread_struct itself (as the "pc" field).
+ *
+ * This code also needs to be aligned with process.c copy_thread()
+ */
+
+#if CALLEE_SAVED_REGS_COUNT != 24
+# error Mismatch between <asm/system.h> and kernel/entry.S
+#endif
+#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 4)
+
+#define SAVE_REG(r) { sw r12, r; addi r12, r12, 4 }
+#define LOAD_REG(r) { lw r, r12; addi r12, r12, 4 }
+#define FOR_EACH_CALLEE_SAVED_REG(f) \
+ f(r30); f(r31); \
+ f(r32); f(r33); f(r34); f(r35); f(r36); f(r37); f(r38); f(r39); \
+ f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
+ f(r48); f(r49); f(r50); f(r51); f(r52);
+
+STD_ENTRY_SECTION(__switch_to, .sched.text)
+ {
+ move r10, sp
+ sw sp, lr
+ addi sp, sp, -FRAME_SIZE
+ }
+ {
+ addi r11, sp, 4
+ addi r12, sp, 8
+ }
+ {
+ sw r11, r10
+ addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
+ }
+ {
+ lw r13, r4 /* Load new sp to a temp register early. */
+ addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
+ }
+ FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
+ {
+ sw r3, sp
+ addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
+ }
+ {
+ sw r3, lr
+ addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
+ }
+ {
+ lw lr, r4
+ addi r12, r13, 8
+ }
+ {
+ /* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
+ move sp, r13
+ mtspr SYSTEM_SAVE_1_0, r2
+ }
+ FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
+.L__switch_to_pc:
+ {
+ addi sp, sp, FRAME_SIZE
+ jrp lr /* r0 is still valid here, so return it */
+ }
+ STD_ENDPROC(__switch_to)
+
+/* Return a suitable address for the backtracer for suspended threads */
+STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
+ lnk r0
+ {
+ addli r0, r0, .L__switch_to_pc - .
+ jrp lr
+ }
+ STD_ENDPROC(get_switch_to_pc)
+
+STD_ENTRY(get_pt_regs)
+ .irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
+ r8, r9, r10, r11, r12, r13, r14, r15, \
+ r16, r17, r18, r19, r20, r21, r22, r23, \
+ r24, r25, r26, r27, r28, r29, r30, r31, \
+ r32, r33, r34, r35, r36, r37, r38, r39, \
+ r40, r41, r42, r43, r44, r45, r46, r47, \
+ r48, r49, r50, r51, r52, tp, sp
+ {
+ sw r0, \reg
+ addi r0, r0, 4
+ }
+ .endr
+ {
+ sw r0, lr
+ addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
+ }
+ lnk r1
+ {
+ sw r0, r1
+ addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
+ }
+ mfspr r1, INTERRUPT_CRITICAL_SECTION
+ shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
+ ori r1, r1, KERNEL_PL
+ {
+ sw r0, r1
+ addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
+ }
+ {
+ sw r0, zero /* clear faultnum */
+ addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
+ }
+ {
+ sw r0, zero /* clear orig_r0 */
+ addli r0, r0, -PTREGS_OFFSET_ORIG_R0 /* restore r0 to base */
+ }
+ jrp lr
+ STD_ENDPROC(get_pt_regs)
diff --git a/arch/tile/kernel/relocate_kernel.S b/arch/tile/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..010b418515f8
--- /dev/null
+++ b/arch/tile/kernel/relocate_kernel.S
@@ -0,0 +1,280 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * copy new kernel into place and then call hv_reexec
+ *
+ */
+
+#include <linux/linkage.h>
+#include <arch/chip.h>
+#include <asm/page.h>
+#include <hv/hypervisor.h>
+
+#define ___hvb MEM_SV_INTRPT + HV_GLUE_START_CPA
+
+#define ___hv_dispatch(f) (___hvb + (HV_DISPATCH_ENTRY_SIZE * f))
+
+#define ___hv_console_putc ___hv_dispatch(HV_DISPATCH_CONSOLE_PUTC)
+#define ___hv_halt ___hv_dispatch(HV_DISPATCH_HALT)
+#define ___hv_reexec ___hv_dispatch(HV_DISPATCH_REEXEC)
+#define ___hv_flush_remote ___hv_dispatch(HV_DISPATCH_FLUSH_REMOTE)
+
+#undef RELOCATE_NEW_KERNEL_VERBOSE
+
+STD_ENTRY(relocate_new_kernel)
+
+ move r30, r0 /* page list */
+ move r31, r1 /* address of page we are on */
+ move r32, r2 /* start address of new kernel */
+
+ shri r1, r1, PAGE_SHIFT
+ addi r1, r1, 1
+ shli sp, r1, PAGE_SHIFT
+ addi sp, sp, -8
+ /* we now have a stack (whether we need one or not) */
+
+ moveli r40, lo16(___hv_console_putc)
+ auli r40, r40, ha16(___hv_console_putc)
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'r'
+ jalr r40
+
+ moveli r0, '_'
+ jalr r40
+
+ moveli r0, 'n'
+ jalr r40
+
+ moveli r0, '_'
+ jalr r40
+
+ moveli r0, 'k'
+ jalr r40
+
+ moveli r0, '\n'
+ jalr r40
+#endif
+
+ /*
+ * Throughout this code r30 is pointer to the element of page
+ * list we are working on.
+ *
+ * Normally we get to the next element of the page list by
+ * incrementing r30 by four. The exception is if the element
+ * on the page list is an IND_INDIRECTION in which case we use
+ * the element with the low bits masked off as the new value
+ * of r30.
+ *
+ * To get this started, we need the value passed to us (which
+ * will always be an IND_INDIRECTION) in memory somewhere with
+ * r30 pointing at it. To do that, we push the value passed
+ * to us on the stack and make r30 point to it.
+ */
+
+ sw sp, r30
+ move r30, sp
+ addi sp, sp, -8
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ /*
+ * On TILEPro, we need to flush all tiles' caches, since we may
+ * have been doing hash-for-home caching there. Note that we
+ * must do this _after_ we're completely done modifying any memory
+ * other than our output buffer (which we know is locally cached).
+ * We want the caches to be fully clean when we do the reexec,
+ * because the hypervisor is going to do this flush again at that
+ * point, and we don't want that second flush to overwrite any memory.
+ */
+ {
+ move r0, zero /* cache_pa */
+ move r1, zero
+ }
+ {
+ auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */
+ movei r3, -1 /* cache_cpumask; -1 means all client tiles */
+ }
+ {
+ move r4, zero /* tlb_va */
+ move r5, zero /* tlb_length */
+ }
+ {
+ move r6, zero /* tlb_pgsize */
+ move r7, zero /* tlb_cpumask */
+ }
+ {
+ move r8, zero /* asids */
+ moveli r20, lo16(___hv_flush_remote)
+ }
+ {
+ move r9, zero /* asidcount */
+ auli r20, r20, ha16(___hv_flush_remote)
+ }
+
+ jalr r20
+#endif
+
+ /* r33 is destination pointer, default to zero */
+
+ moveli r33, 0
+
+.Lloop: lw r10, r30
+
+ andi r9, r10, 0xf /* low 4 bits tell us what type it is */
+ xor r10, r10, r9 /* r10 is now value with low 4 bits stripped */
+
+ seqi r0, r9, 0x1 /* IND_DESTINATION */
+ bzt r0, .Ltry2
+
+ move r33, r10
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'd'
+ jalr r40
+#endif
+
+ addi r30, r30, 4
+ j .Lloop
+
+.Ltry2:
+ seqi r0, r9, 0x2 /* IND_INDIRECTION */
+ bzt r0, .Ltry4
+
+ move r30, r10
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'i'
+ jalr r40
+#endif
+
+ j .Lloop
+
+.Ltry4:
+ seqi r0, r9, 0x4 /* IND_DONE */
+ bzt r0, .Ltry8
+
+ mf
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 'D'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+#endif
+
+ move r0, r32
+ moveli r1, 0 /* arg to hv_reexec is 64 bits */
+
+ moveli r41, lo16(___hv_reexec)
+ auli r41, r41, ha16(___hv_reexec)
+
+ jalr r41
+
+ /* we should not get here */
+
+ moveli r0, '?'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+
+ j .Lhalt
+
+.Ltry8: seqi r0, r9, 0x8 /* IND_SOURCE */
+ bz r0, .Lerr /* unknown type */
+
+ /* copy page at r10 to page at r33 */
+
+ move r11, r33
+
+ moveli r0, lo16(PAGE_SIZE)
+ auli r0, r0, ha16(PAGE_SIZE)
+ add r33, r33, r0
+
+ /* copy word at r10 to word at r11 until r11 equals r33 */
+
+ /* We know page size must be multiple of 16, so we can unroll
+ * 16 times safely without any edge case checking.
+ *
+ * Issue a flush of the destination every 16 words to avoid
+ * incoherence when starting the new kernel. (Now this is
+ * just good paranoia because the hv_reexec call will also
+ * take care of this.)
+ */
+
+1:
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0; addi r11, r11, 4 }
+ { lw r0, r10; addi r10, r10, 4 }
+ { sw r11, r0 }
+ { flush r11 ; addi r11, r11, 4 }
+
+ seq r0, r33, r11
+ bzt r0, 1b
+
+#ifdef RELOCATE_NEW_KERNEL_VERBOSE
+ moveli r0, 's'
+ jalr r40
+#endif
+
+ addi r30, r30, 4
+ j .Lloop
+
+
+.Lerr: moveli r0, 'e'
+ jalr r40
+ moveli r0, 'r'
+ jalr r40
+ moveli r0, 'r'
+ jalr r40
+ moveli r0, '\n'
+ jalr r40
+.Lhalt:
+ moveli r41, lo16(___hv_halt)
+ auli r41, r41, ha16(___hv_halt)
+
+ jalr r41
+ STD_ENDPROC(relocate_new_kernel)
+
+ .section .rodata,"a"
+
+ .globl relocate_new_kernel_size
+relocate_new_kernel_size:
+ .long .Lend_relocate_new_kernel - relocate_new_kernel
diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c
new file mode 100644
index 000000000000..4dd21c1e6d5e
--- /dev/null
+++ b/arch/tile/kernel/setup.c
@@ -0,0 +1,1511 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mmzone.h>
+#include <linux/bootmem.h>
+#include <linux/module.h>
+#include <linux/node.h>
+#include <linux/cpu.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/kexec.h>
+#include <linux/pci.h>
+#include <linux/initrd.h>
+#include <linux/io.h>
+#include <linux/highmem.h>
+#include <linux/smp.h>
+#include <linux/timex.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/sections.h>
+#include <asm/cacheflush.h>
+#include <asm/cacheflush.h>
+#include <asm/pgalloc.h>
+#include <asm/mmu_context.h>
+#include <hv/hypervisor.h>
+#include <arch/interrupts.h>
+
+/* <linux/smp.h> doesn't provide this definition. */
+#ifndef CONFIG_SMP
+#define setup_max_cpus 1
+#endif
+
+static inline int ABS(int x) { return x >= 0 ? x : -x; }
+
+/* Chip information */
+char chip_model[64] __write_once;
+
+struct pglist_data node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+/* We only create bootmem data on node 0. */
+static bootmem_data_t __initdata node0_bdata;
+
+/* Information on the NUMA nodes that we compute early */
+unsigned long __cpuinitdata node_start_pfn[MAX_NUMNODES];
+unsigned long __cpuinitdata node_end_pfn[MAX_NUMNODES];
+unsigned long __initdata node_memmap_pfn[MAX_NUMNODES];
+unsigned long __initdata node_percpu_pfn[MAX_NUMNODES];
+unsigned long __initdata node_free_pfn[MAX_NUMNODES];
+
+#ifdef CONFIG_HIGHMEM
+/* Page frame index of end of lowmem on each controller. */
+unsigned long __cpuinitdata node_lowmem_end_pfn[MAX_NUMNODES];
+
+/* Number of pages that can be mapped into lowmem. */
+static unsigned long __initdata mappable_physpages;
+#endif
+
+/* Data on which physical memory controller corresponds to which NUMA node */
+int node_controller[MAX_NUMNODES] = { [0 ... MAX_NUMNODES-1] = -1 };
+
+#ifdef CONFIG_HIGHMEM
+/* Map information from VAs to PAs */
+unsigned long pbase_map[1 << (32 - HPAGE_SHIFT)]
+ __write_once __attribute__((aligned(L2_CACHE_BYTES)));
+EXPORT_SYMBOL(pbase_map);
+
+/* Map information from PAs to VAs */
+void *vbase_map[NR_PA_HIGHBIT_VALUES]
+ __write_once __attribute__((aligned(L2_CACHE_BYTES)));
+EXPORT_SYMBOL(vbase_map);
+#endif
+
+/* Node number as a function of the high PA bits */
+int highbits_to_node[NR_PA_HIGHBIT_VALUES] __write_once;
+EXPORT_SYMBOL(highbits_to_node);
+
+static unsigned int __initdata maxmem_pfn = -1U;
+static unsigned int __initdata maxnodemem_pfn[MAX_NUMNODES] = {
+ [0 ... MAX_NUMNODES-1] = -1U
+};
+static nodemask_t __initdata isolnodes;
+
+#ifdef CONFIG_PCI
+enum { DEFAULT_PCI_RESERVE_MB = 64 };
+static unsigned int __initdata pci_reserve_mb = DEFAULT_PCI_RESERVE_MB;
+unsigned long __initdata pci_reserve_start_pfn = -1U;
+unsigned long __initdata pci_reserve_end_pfn = -1U;
+#endif
+
+static int __init setup_maxmem(char *str)
+{
+ long maxmem_mb;
+ if (str == NULL || strict_strtol(str, 0, &maxmem_mb) != 0 ||
+ maxmem_mb == 0)
+ return -EINVAL;
+
+ maxmem_pfn = (maxmem_mb >> (HPAGE_SHIFT - 20)) <<
+ (HPAGE_SHIFT - PAGE_SHIFT);
+ pr_info("Forcing RAM used to no more than %dMB\n",
+ maxmem_pfn >> (20 - PAGE_SHIFT));
+ return 0;
+}
+early_param("maxmem", setup_maxmem);
+
+static int __init setup_maxnodemem(char *str)
+{
+ char *endp;
+ long maxnodemem_mb, node;
+
+ node = str ? simple_strtoul(str, &endp, 0) : INT_MAX;
+ if (node >= MAX_NUMNODES || *endp != ':' ||
+ strict_strtol(endp+1, 0, &maxnodemem_mb) != 0)
+ return -EINVAL;
+
+ maxnodemem_pfn[node] = (maxnodemem_mb >> (HPAGE_SHIFT - 20)) <<
+ (HPAGE_SHIFT - PAGE_SHIFT);
+ pr_info("Forcing RAM used on node %ld to no more than %dMB\n",
+ node, maxnodemem_pfn[node] >> (20 - PAGE_SHIFT));
+ return 0;
+}
+early_param("maxnodemem", setup_maxnodemem);
+
+static int __init setup_isolnodes(char *str)
+{
+ char buf[MAX_NUMNODES * 5];
+ if (str == NULL || nodelist_parse(str, isolnodes) != 0)
+ return -EINVAL;
+
+ nodelist_scnprintf(buf, sizeof(buf), isolnodes);
+ pr_info("Set isolnodes value to '%s'\n", buf);
+ return 0;
+}
+early_param("isolnodes", setup_isolnodes);
+
+#ifdef CONFIG_PCI
+static int __init setup_pci_reserve(char* str)
+{
+ unsigned long mb;
+
+ if (str == NULL || strict_strtoul(str, 0, &mb) != 0 ||
+ mb > 3 * 1024)
+ return -EINVAL;
+
+ pci_reserve_mb = mb;
+ pr_info("Reserving %dMB for PCIE root complex mappings\n",
+ pci_reserve_mb);
+ return 0;
+}
+early_param("pci_reserve", setup_pci_reserve);
+#endif
+
+#ifndef __tilegx__
+/*
+ * vmalloc=size forces the vmalloc area to be exactly 'size' bytes.
+ * This can be used to increase (or decrease) the vmalloc area.
+ */
+static int __init parse_vmalloc(char *arg)
+{
+ if (!arg)
+ return -EINVAL;
+
+ VMALLOC_RESERVE = (memparse(arg, &arg) + PGDIR_SIZE - 1) & PGDIR_MASK;
+
+ /* See validate_va() for more on this test. */
+ if ((long)_VMALLOC_START >= 0)
+ early_panic("\"vmalloc=%#lx\" value too large: maximum %#lx\n",
+ VMALLOC_RESERVE, _VMALLOC_END - 0x80000000UL);
+
+ return 0;
+}
+early_param("vmalloc", parse_vmalloc);
+#endif
+
+#ifdef CONFIG_HIGHMEM
+/*
+ * Determine for each controller where its lowmem is mapped and how
+ * much of it is mapped there. On controller zero, the first few
+ * megabytes are mapped at 0xfd000000 as code, so in principle we
+ * could start our data mappings higher up, but for now we don't
+ * bother, to avoid additional confusion.
+ *
+ * One question is whether, on systems with more than 768 Mb and
+ * controllers of different sizes, to map in a proportionate amount of
+ * each one, or to try to map the same amount from each controller.
+ * (E.g. if we have three controllers with 256MB, 1GB, and 256MB
+ * respectively, do we map 256MB from each, or do we map 128 MB, 512
+ * MB, and 128 MB respectively?) For now we use a proportionate
+ * solution like the latter.
+ *
+ * The VA/PA mapping demands that we align our decisions at 16 MB
+ * boundaries so that we can rapidly convert VA to PA.
+ */
+static void *__init setup_pa_va_mapping(void)
+{
+ unsigned long curr_pages = 0;
+ unsigned long vaddr = PAGE_OFFSET;
+ nodemask_t highonlynodes = isolnodes;
+ int i, j;
+
+ memset(pbase_map, -1, sizeof(pbase_map));
+ memset(vbase_map, -1, sizeof(vbase_map));
+
+ /* Node zero cannot be isolated for LOWMEM purposes. */
+ node_clear(0, highonlynodes);
+
+ /* Count up the number of pages on non-highonlynodes controllers. */
+ mappable_physpages = 0;
+ for_each_online_node(i) {
+ if (!node_isset(i, highonlynodes))
+ mappable_physpages +=
+ node_end_pfn[i] - node_start_pfn[i];
+ }
+
+ for_each_online_node(i) {
+ unsigned long start = node_start_pfn[i];
+ unsigned long end = node_end_pfn[i];
+ unsigned long size = end - start;
+ unsigned long vaddr_end;
+
+ if (node_isset(i, highonlynodes)) {
+ /* Mark this controller as having no lowmem. */
+ node_lowmem_end_pfn[i] = start;
+ continue;
+ }
+
+ curr_pages += size;
+ if (mappable_physpages > MAXMEM_PFN) {
+ vaddr_end = PAGE_OFFSET +
+ (((u64)curr_pages * MAXMEM_PFN /
+ mappable_physpages)
+ << PAGE_SHIFT);
+ } else {
+ vaddr_end = PAGE_OFFSET + (curr_pages << PAGE_SHIFT);
+ }
+ for (j = 0; vaddr < vaddr_end; vaddr += HPAGE_SIZE, ++j) {
+ unsigned long this_pfn =
+ start + (j << HUGETLB_PAGE_ORDER);
+ pbase_map[vaddr >> HPAGE_SHIFT] = this_pfn;
+ if (vbase_map[__pfn_to_highbits(this_pfn)] ==
+ (void *)-1)
+ vbase_map[__pfn_to_highbits(this_pfn)] =
+ (void *)(vaddr & HPAGE_MASK);
+ }
+ node_lowmem_end_pfn[i] = start + (j << HUGETLB_PAGE_ORDER);
+ BUG_ON(node_lowmem_end_pfn[i] > end);
+ }
+
+ /* Return highest address of any mapped memory. */
+ return (void *)vaddr;
+}
+#endif /* CONFIG_HIGHMEM */
+
+/*
+ * Register our most important memory mappings with the debug stub.
+ *
+ * This is up to 4 mappings for lowmem, one mapping per memory
+ * controller, plus one for our text segment.
+ */
+static void __cpuinit store_permanent_mappings(void)
+{
+ int i;
+
+ for_each_online_node(i) {
+ HV_PhysAddr pa = ((HV_PhysAddr)node_start_pfn[i]) << PAGE_SHIFT;
+#ifdef CONFIG_HIGHMEM
+ HV_PhysAddr high_mapped_pa = node_lowmem_end_pfn[i];
+#else
+ HV_PhysAddr high_mapped_pa = node_end_pfn[i];
+#endif
+
+ unsigned long pages = high_mapped_pa - node_start_pfn[i];
+ HV_VirtAddr addr = (HV_VirtAddr) __va(pa);
+ hv_store_mapping(addr, pages << PAGE_SHIFT, pa);
+ }
+
+ hv_store_mapping((HV_VirtAddr)_stext,
+ (uint32_t)(_einittext - _stext), 0);
+}
+
+/*
+ * Use hv_inquire_physical() to populate node_{start,end}_pfn[]
+ * and node_online_map, doing suitable sanity-checking.
+ * Also set min_low_pfn, max_low_pfn, and max_pfn.
+ */
+static void __init setup_memory(void)
+{
+ int i, j;
+ int highbits_seen[NR_PA_HIGHBIT_VALUES] = { 0 };
+#ifdef CONFIG_HIGHMEM
+ long highmem_pages;
+#endif
+#ifndef __tilegx__
+ int cap;
+#endif
+#if defined(CONFIG_HIGHMEM) || defined(__tilegx__)
+ long lowmem_pages;
+#endif
+
+ /* We are using a char to hold the cpu_2_node[] mapping */
+ BUG_ON(MAX_NUMNODES > 127);
+
+ /* Discover the ranges of memory available to us */
+ for (i = 0; ; ++i) {
+ unsigned long start, size, end, highbits;
+ HV_PhysAddrRange range = hv_inquire_physical(i);
+ if (range.size == 0)
+ break;
+#ifdef CONFIG_FLATMEM
+ if (i > 0) {
+ pr_err("Can't use discontiguous PAs: %#llx..%#llx\n",
+ range.size, range.start + range.size);
+ continue;
+ }
+#endif
+#ifndef __tilegx__
+ if ((unsigned long)range.start) {
+ pr_err("Range not at 4GB multiple: %#llx..%#llx\n",
+ range.start, range.start + range.size);
+ continue;
+ }
+#endif
+ if ((range.start & (HPAGE_SIZE-1)) != 0 ||
+ (range.size & (HPAGE_SIZE-1)) != 0) {
+ unsigned long long start_pa = range.start;
+ unsigned long long orig_size = range.size;
+ range.start = (start_pa + HPAGE_SIZE - 1) & HPAGE_MASK;
+ range.size -= (range.start - start_pa);
+ range.size &= HPAGE_MASK;
+ pr_err("Range not hugepage-aligned: %#llx..%#llx:"
+ " now %#llx-%#llx\n",
+ start_pa, start_pa + orig_size,
+ range.start, range.start + range.size);
+ }
+ highbits = __pa_to_highbits(range.start);
+ if (highbits >= NR_PA_HIGHBIT_VALUES) {
+ pr_err("PA high bits too high: %#llx..%#llx\n",
+ range.start, range.start + range.size);
+ continue;
+ }
+ if (highbits_seen[highbits]) {
+ pr_err("Range overlaps in high bits: %#llx..%#llx\n",
+ range.start, range.start + range.size);
+ continue;
+ }
+ highbits_seen[highbits] = 1;
+ if (PFN_DOWN(range.size) > maxnodemem_pfn[i]) {
+ int max_size = maxnodemem_pfn[i];
+ if (max_size > 0) {
+ pr_err("Maxnodemem reduced node %d to"
+ " %d pages\n", i, max_size);
+ range.size = PFN_PHYS(max_size);
+ } else {
+ pr_err("Maxnodemem disabled node %d\n", i);
+ continue;
+ }
+ }
+ if (num_physpages + PFN_DOWN(range.size) > maxmem_pfn) {
+ int max_size = maxmem_pfn - num_physpages;
+ if (max_size > 0) {
+ pr_err("Maxmem reduced node %d to %d pages\n",
+ i, max_size);
+ range.size = PFN_PHYS(max_size);
+ } else {
+ pr_err("Maxmem disabled node %d\n", i);
+ continue;
+ }
+ }
+ if (i >= MAX_NUMNODES) {
+ pr_err("Too many PA nodes (#%d): %#llx...%#llx\n",
+ i, range.size, range.size + range.start);
+ continue;
+ }
+
+ start = range.start >> PAGE_SHIFT;
+ size = range.size >> PAGE_SHIFT;
+ end = start + size;
+
+#ifndef __tilegx__
+ if (((HV_PhysAddr)end << PAGE_SHIFT) !=
+ (range.start + range.size)) {
+ pr_err("PAs too high to represent: %#llx..%#llx\n",
+ range.start, range.start + range.size);
+ continue;
+ }
+#endif
+#ifdef CONFIG_PCI
+ /*
+ * Blocks that overlap the pci reserved region must
+ * have enough space to hold the maximum percpu data
+ * region at the top of the range. If there isn't
+ * enough space above the reserved region, just
+ * truncate the node.
+ */
+ if (start <= pci_reserve_start_pfn &&
+ end > pci_reserve_start_pfn) {
+ unsigned int per_cpu_size =
+ __per_cpu_end - __per_cpu_start;
+ unsigned int percpu_pages =
+ NR_CPUS * (PFN_UP(per_cpu_size) >> PAGE_SHIFT);
+ if (end < pci_reserve_end_pfn + percpu_pages) {
+ end = pci_reserve_start_pfn;
+ pr_err("PCI mapping region reduced node %d to"
+ " %ld pages\n", i, end - start);
+ }
+ }
+#endif
+
+ for (j = __pfn_to_highbits(start);
+ j <= __pfn_to_highbits(end - 1); j++)
+ highbits_to_node[j] = i;
+
+ node_start_pfn[i] = start;
+ node_end_pfn[i] = end;
+ node_controller[i] = range.controller;
+ num_physpages += size;
+ max_pfn = end;
+
+ /* Mark node as online */
+ node_set(i, node_online_map);
+ node_set(i, node_possible_map);
+ }
+
+#ifndef __tilegx__
+ /*
+ * For 4KB pages, mem_map "struct page" data is 1% of the size
+ * of the physical memory, so can be quite big (640 MB for
+ * four 16G zones). These structures must be mapped in
+ * lowmem, and since we currently cap out at about 768 MB,
+ * it's impractical to try to use this much address space.
+ * For now, arbitrarily cap the amount of physical memory
+ * we're willing to use at 8 million pages (32GB of 4KB pages).
+ */
+ cap = 8 * 1024 * 1024; /* 8 million pages */
+ if (num_physpages > cap) {
+ int num_nodes = num_online_nodes();
+ int cap_each = cap / num_nodes;
+ unsigned long dropped_pages = 0;
+ for (i = 0; i < num_nodes; ++i) {
+ int size = node_end_pfn[i] - node_start_pfn[i];
+ if (size > cap_each) {
+ dropped_pages += (size - cap_each);
+ node_end_pfn[i] = node_start_pfn[i] + cap_each;
+ }
+ }
+ num_physpages -= dropped_pages;
+ pr_warning("Only using %ldMB memory;"
+ " ignoring %ldMB.\n",
+ num_physpages >> (20 - PAGE_SHIFT),
+ dropped_pages >> (20 - PAGE_SHIFT));
+ pr_warning("Consider using a larger page size.\n");
+ }
+#endif
+
+ /* Heap starts just above the last loaded address. */
+ min_low_pfn = PFN_UP((unsigned long)_end - PAGE_OFFSET);
+
+#ifdef CONFIG_HIGHMEM
+ /* Find where we map lowmem from each controller. */
+ high_memory = setup_pa_va_mapping();
+
+ /* Set max_low_pfn based on what node 0 can directly address. */
+ max_low_pfn = node_lowmem_end_pfn[0];
+
+ lowmem_pages = (mappable_physpages > MAXMEM_PFN) ?
+ MAXMEM_PFN : mappable_physpages;
+ highmem_pages = (long) (num_physpages - lowmem_pages);
+
+ pr_notice("%ldMB HIGHMEM available.\n",
+ pages_to_mb(highmem_pages > 0 ? highmem_pages : 0));
+ pr_notice("%ldMB LOWMEM available.\n",
+ pages_to_mb(lowmem_pages));
+#else
+ /* Set max_low_pfn based on what node 0 can directly address. */
+ max_low_pfn = node_end_pfn[0];
+
+#ifndef __tilegx__
+ if (node_end_pfn[0] > MAXMEM_PFN) {
+ pr_warning("Only using %ldMB LOWMEM.\n",
+ MAXMEM>>20);
+ pr_warning("Use a HIGHMEM enabled kernel.\n");
+ max_low_pfn = MAXMEM_PFN;
+ max_pfn = MAXMEM_PFN;
+ num_physpages = MAXMEM_PFN;
+ node_end_pfn[0] = MAXMEM_PFN;
+ } else {
+ pr_notice("%ldMB memory available.\n",
+ pages_to_mb(node_end_pfn[0]));
+ }
+ for (i = 1; i < MAX_NUMNODES; ++i) {
+ node_start_pfn[i] = 0;
+ node_end_pfn[i] = 0;
+ }
+ high_memory = __va(node_end_pfn[0]);
+#else
+ lowmem_pages = 0;
+ for (i = 0; i < MAX_NUMNODES; ++i) {
+ int pages = node_end_pfn[i] - node_start_pfn[i];
+ lowmem_pages += pages;
+ if (pages)
+ high_memory = pfn_to_kaddr(node_end_pfn[i]);
+ }
+ pr_notice("%ldMB memory available.\n",
+ pages_to_mb(lowmem_pages));
+#endif
+#endif
+}
+
+static void __init setup_bootmem_allocator(void)
+{
+ unsigned long bootmap_size, first_alloc_pfn, last_alloc_pfn;
+
+ /* Provide a node 0 bdata. */
+ NODE_DATA(0)->bdata = &node0_bdata;
+
+#ifdef CONFIG_PCI
+ /* Don't let boot memory alias the PCI region. */
+ last_alloc_pfn = min(max_low_pfn, pci_reserve_start_pfn);
+#else
+ last_alloc_pfn = max_low_pfn;
+#endif
+
+ /*
+ * Initialize the boot-time allocator (with low memory only):
+ * The first argument says where to put the bitmap, and the
+ * second says where the end of allocatable memory is.
+ */
+ bootmap_size = init_bootmem(min_low_pfn, last_alloc_pfn);
+
+ /*
+ * Let the bootmem allocator use all the space we've given it
+ * except for its own bitmap.
+ */
+ first_alloc_pfn = min_low_pfn + PFN_UP(bootmap_size);
+ if (first_alloc_pfn >= last_alloc_pfn)
+ early_panic("Not enough memory on controller 0 for bootmem\n");
+
+ free_bootmem(PFN_PHYS(first_alloc_pfn),
+ PFN_PHYS(last_alloc_pfn - first_alloc_pfn));
+
+#ifdef CONFIG_KEXEC
+ if (crashk_res.start != crashk_res.end)
+ reserve_bootmem(crashk_res.start,
+ crashk_res.end - crashk_res.start + 1, 0);
+#endif
+
+}
+
+void *__init alloc_remap(int nid, unsigned long size)
+{
+ int pages = node_end_pfn[nid] - node_start_pfn[nid];
+ void *map = pfn_to_kaddr(node_memmap_pfn[nid]);
+ BUG_ON(size != pages * sizeof(struct page));
+ memset(map, 0, size);
+ return map;
+}
+
+static int __init percpu_size(void)
+{
+ int size = ALIGN(__per_cpu_end - __per_cpu_start, PAGE_SIZE);
+#ifdef CONFIG_MODULES
+ if (size < PERCPU_ENOUGH_ROOM)
+ size = PERCPU_ENOUGH_ROOM;
+#endif
+ /* In several places we assume the per-cpu data fits on a huge page. */
+ BUG_ON(kdata_huge && size > HPAGE_SIZE);
+ return size;
+}
+
+static inline unsigned long alloc_bootmem_pfn(int size, unsigned long goal)
+{
+ void *kva = __alloc_bootmem(size, PAGE_SIZE, goal);
+ unsigned long pfn = kaddr_to_pfn(kva);
+ BUG_ON(goal && PFN_PHYS(pfn) != goal);
+ return pfn;
+}
+
+static void __init zone_sizes_init(void)
+{
+ unsigned long zones_size[MAX_NR_ZONES] = { 0 };
+ unsigned long node_percpu[MAX_NUMNODES] = { 0 };
+ int size = percpu_size();
+ int num_cpus = smp_height * smp_width;
+ int i;
+
+ for (i = 0; i < num_cpus; ++i)
+ node_percpu[cpu_to_node(i)] += size;
+
+ for_each_online_node(i) {
+ unsigned long start = node_start_pfn[i];
+ unsigned long end = node_end_pfn[i];
+#ifdef CONFIG_HIGHMEM
+ unsigned long lowmem_end = node_lowmem_end_pfn[i];
+#else
+ unsigned long lowmem_end = end;
+#endif
+ int memmap_size = (end - start) * sizeof(struct page);
+ node_free_pfn[i] = start;
+
+ /*
+ * Set aside pages for per-cpu data and the mem_map array.
+ *
+ * Since the per-cpu data requires special homecaching,
+ * if we are in kdata_huge mode, we put it at the end of
+ * the lowmem region. If we're not in kdata_huge mode,
+ * we take the per-cpu pages from the bottom of the
+ * controller, since that avoids fragmenting a huge page
+ * that users might want. We always take the memmap
+ * from the bottom of the controller, since with
+ * kdata_huge that lets it be under a huge TLB entry.
+ *
+ * If the user has requested isolnodes for a controller,
+ * though, there'll be no lowmem, so we just alloc_bootmem
+ * the memmap. There will be no percpu memory either.
+ */
+ if (__pfn_to_highbits(start) == 0) {
+ /* In low PAs, allocate via bootmem. */
+ unsigned long goal = 0;
+ node_memmap_pfn[i] =
+ alloc_bootmem_pfn(memmap_size, goal);
+ if (kdata_huge)
+ goal = PFN_PHYS(lowmem_end) - node_percpu[i];
+ if (node_percpu[i])
+ node_percpu_pfn[i] =
+ alloc_bootmem_pfn(node_percpu[i], goal);
+ } else if (cpu_isset(i, isolnodes)) {
+ node_memmap_pfn[i] = alloc_bootmem_pfn(memmap_size, 0);
+ BUG_ON(node_percpu[i] != 0);
+ } else {
+ /* In high PAs, just reserve some pages. */
+ node_memmap_pfn[i] = node_free_pfn[i];
+ node_free_pfn[i] += PFN_UP(memmap_size);
+ if (!kdata_huge) {
+ node_percpu_pfn[i] = node_free_pfn[i];
+ node_free_pfn[i] += PFN_UP(node_percpu[i]);
+ } else {
+ node_percpu_pfn[i] =
+ lowmem_end - PFN_UP(node_percpu[i]);
+ }
+ }
+
+#ifdef CONFIG_HIGHMEM
+ if (start > lowmem_end) {
+ zones_size[ZONE_NORMAL] = 0;
+ zones_size[ZONE_HIGHMEM] = end - start;
+ } else {
+ zones_size[ZONE_NORMAL] = lowmem_end - start;
+ zones_size[ZONE_HIGHMEM] = end - lowmem_end;
+ }
+#else
+ zones_size[ZONE_NORMAL] = end - start;
+#endif
+
+ /*
+ * Everyone shares node 0's bootmem allocator, but
+ * we use alloc_remap(), above, to put the actual
+ * struct page array on the individual controllers,
+ * which is most of the data that we actually care about.
+ * We can't place bootmem allocators on the other
+ * controllers since the bootmem allocator can only
+ * operate on 32-bit physical addresses.
+ */
+ NODE_DATA(i)->bdata = NODE_DATA(0)->bdata;
+
+ free_area_init_node(i, zones_size, start, NULL);
+ printk(KERN_DEBUG " DMA zone: %ld per-cpu pages\n",
+ PFN_UP(node_percpu[i]));
+
+ /* Track the type of memory on each node */
+ if (zones_size[ZONE_NORMAL])
+ node_set_state(i, N_NORMAL_MEMORY);
+#ifdef CONFIG_HIGHMEM
+ if (end != start)
+ node_set_state(i, N_HIGH_MEMORY);
+#endif
+
+ node_set_online(i);
+ }
+}
+
+#ifdef CONFIG_NUMA
+
+/* which logical CPUs are on which nodes */
+struct cpumask node_2_cpu_mask[MAX_NUMNODES] __write_once;
+EXPORT_SYMBOL(node_2_cpu_mask);
+
+/* which node each logical CPU is on */
+char cpu_2_node[NR_CPUS] __write_once __attribute__((aligned(L2_CACHE_BYTES)));
+EXPORT_SYMBOL(cpu_2_node);
+
+/* Return cpu_to_node() except for cpus not yet assigned, which return -1 */
+static int __init cpu_to_bound_node(int cpu, struct cpumask* unbound_cpus)
+{
+ if (!cpu_possible(cpu) || cpumask_test_cpu(cpu, unbound_cpus))
+ return -1;
+ else
+ return cpu_to_node(cpu);
+}
+
+/* Return number of immediately-adjacent tiles sharing the same NUMA node. */
+static int __init node_neighbors(int node, int cpu,
+ struct cpumask *unbound_cpus)
+{
+ int neighbors = 0;
+ int w = smp_width;
+ int h = smp_height;
+ int x = cpu % w;
+ int y = cpu / w;
+ if (x > 0 && cpu_to_bound_node(cpu-1, unbound_cpus) == node)
+ ++neighbors;
+ if (x < w-1 && cpu_to_bound_node(cpu+1, unbound_cpus) == node)
+ ++neighbors;
+ if (y > 0 && cpu_to_bound_node(cpu-w, unbound_cpus) == node)
+ ++neighbors;
+ if (y < h-1 && cpu_to_bound_node(cpu+w, unbound_cpus) == node)
+ ++neighbors;
+ return neighbors;
+}
+
+static void __init setup_numa_mapping(void)
+{
+ int distance[MAX_NUMNODES][NR_CPUS];
+ HV_Coord coord;
+ int cpu, node, cpus, i, x, y;
+ int num_nodes = num_online_nodes();
+ struct cpumask unbound_cpus;
+ nodemask_t default_nodes;
+
+ cpumask_clear(&unbound_cpus);
+
+ /* Get set of nodes we will use for defaults */
+ nodes_andnot(default_nodes, node_online_map, isolnodes);
+ if (nodes_empty(default_nodes)) {
+ BUG_ON(!node_isset(0, node_online_map));
+ pr_err("Forcing NUMA node zero available as a default node\n");
+ node_set(0, default_nodes);
+ }
+
+ /* Populate the distance[] array */
+ memset(distance, -1, sizeof(distance));
+ cpu = 0;
+ for (coord.y = 0; coord.y < smp_height; ++coord.y) {
+ for (coord.x = 0; coord.x < smp_width;
+ ++coord.x, ++cpu) {
+ BUG_ON(cpu >= nr_cpu_ids);
+ if (!cpu_possible(cpu)) {
+ cpu_2_node[cpu] = -1;
+ continue;
+ }
+ for_each_node_mask(node, default_nodes) {
+ HV_MemoryControllerInfo info =
+ hv_inquire_memory_controller(
+ coord, node_controller[node]);
+ distance[node][cpu] =
+ ABS(info.coord.x) + ABS(info.coord.y);
+ }
+ cpumask_set_cpu(cpu, &unbound_cpus);
+ }
+ }
+ cpus = cpu;
+
+ /*
+ * Round-robin through the NUMA nodes until all the cpus are
+ * assigned. We could be more clever here (e.g. create four
+ * sorted linked lists on the same set of cpu nodes, and pull
+ * off them in round-robin sequence, removing from all four
+ * lists each time) but given the relatively small numbers
+ * involved, O(n^2) seem OK for a one-time cost.
+ */
+ node = first_node(default_nodes);
+ while (!cpumask_empty(&unbound_cpus)) {
+ int best_cpu = -1;
+ int best_distance = INT_MAX;
+ for (cpu = 0; cpu < cpus; ++cpu) {
+ if (cpumask_test_cpu(cpu, &unbound_cpus)) {
+ /*
+ * Compute metric, which is how much
+ * closer the cpu is to this memory
+ * controller than the others, shifted
+ * up, and then the number of
+ * neighbors already in the node as an
+ * epsilon adjustment to try to keep
+ * the nodes compact.
+ */
+ int d = distance[node][cpu] * num_nodes;
+ for_each_node_mask(i, default_nodes) {
+ if (i != node)
+ d -= distance[i][cpu];
+ }
+ d *= 8; /* allow space for epsilon */
+ d -= node_neighbors(node, cpu, &unbound_cpus);
+ if (d < best_distance) {
+ best_cpu = cpu;
+ best_distance = d;
+ }
+ }
+ }
+ BUG_ON(best_cpu < 0);
+ cpumask_set_cpu(best_cpu, &node_2_cpu_mask[node]);
+ cpu_2_node[best_cpu] = node;
+ cpumask_clear_cpu(best_cpu, &unbound_cpus);
+ node = next_node(node, default_nodes);
+ if (node == MAX_NUMNODES)
+ node = first_node(default_nodes);
+ }
+
+ /* Print out node assignments and set defaults for disabled cpus */
+ cpu = 0;
+ for (y = 0; y < smp_height; ++y) {
+ printk(KERN_DEBUG "NUMA cpu-to-node row %d:", y);
+ for (x = 0; x < smp_width; ++x, ++cpu) {
+ if (cpu_to_node(cpu) < 0) {
+ pr_cont(" -");
+ cpu_2_node[cpu] = first_node(default_nodes);
+ } else {
+ pr_cont(" %d", cpu_to_node(cpu));
+ }
+ }
+ pr_cont("\n");
+ }
+}
+
+static struct cpu cpu_devices[NR_CPUS];
+
+static int __init topology_init(void)
+{
+ int i;
+
+ for_each_online_node(i)
+ register_one_node(i);
+
+ for_each_present_cpu(i)
+ register_cpu(&cpu_devices[i], i);
+
+ return 0;
+}
+
+subsys_initcall(topology_init);
+
+#else /* !CONFIG_NUMA */
+
+#define setup_numa_mapping() do { } while (0)
+
+#endif /* CONFIG_NUMA */
+
+/**
+ * setup_cpu() - Do all necessary per-cpu, tile-specific initialization.
+ * @boot: Is this the boot cpu?
+ *
+ * Called from setup_arch() on the boot cpu, or online_secondary().
+ */
+void __cpuinit setup_cpu(int boot)
+{
+ /* The boot cpu sets up its permanent mappings much earlier. */
+ if (!boot)
+ store_permanent_mappings();
+
+ /* Allow asynchronous TLB interrupts. */
+#if CHIP_HAS_TILE_DMA()
+ raw_local_irq_unmask(INT_DMATLB_MISS);
+ raw_local_irq_unmask(INT_DMATLB_ACCESS);
+#endif
+#if CHIP_HAS_SN_PROC()
+ raw_local_irq_unmask(INT_SNITLB_MISS);
+#endif
+
+ /*
+ * Allow user access to many generic SPRs, like the cycle
+ * counter, PASS/FAIL/DONE, INTERRUPT_CRITICAL_SECTION, etc.
+ */
+ __insn_mtspr(SPR_MPL_WORLD_ACCESS_SET_0, 1);
+
+#if CHIP_HAS_SN()
+ /* Static network is not restricted. */
+ __insn_mtspr(SPR_MPL_SN_ACCESS_SET_0, 1);
+#endif
+#if CHIP_HAS_SN_PROC()
+ __insn_mtspr(SPR_MPL_SN_NOTIFY_SET_0, 1);
+ __insn_mtspr(SPR_MPL_SN_CPL_SET_0, 1);
+#endif
+
+ /*
+ * Set the MPL for interrupt control 0 to user level.
+ * This includes access to the SYSTEM_SAVE and EX_CONTEXT SPRs,
+ * as well as the PL 0 interrupt mask.
+ */
+ __insn_mtspr(SPR_MPL_INTCTRL_0_SET_0, 1);
+
+ /* Initialize IRQ support for this cpu. */
+ setup_irq_regs();
+
+#ifdef CONFIG_HARDWALL
+ /* Reset the network state on this cpu. */
+ reset_network_state();
+#endif
+}
+
+static int __initdata set_initramfs_file;
+static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
+
+static int __init setup_initramfs_file(char *str)
+{
+ if (str == NULL)
+ return -EINVAL;
+ strncpy(initramfs_file, str, sizeof(initramfs_file) - 1);
+ set_initramfs_file = 1;
+
+ return 0;
+}
+early_param("initramfs_file", setup_initramfs_file);
+
+/*
+ * We look for an additional "initramfs.cpio.gz" file in the hvfs.
+ * If there is one, we allocate some memory for it and it will be
+ * unpacked to the initramfs after any built-in initramfs_data.
+ */
+static void __init load_hv_initrd(void)
+{
+ HV_FS_StatInfo stat;
+ int fd, rc;
+ void *initrd;
+
+ fd = hv_fs_findfile((HV_VirtAddr) initramfs_file);
+ if (fd == HV_ENOENT) {
+ if (set_initramfs_file)
+ pr_warning("No such hvfs initramfs file '%s'\n",
+ initramfs_file);
+ return;
+ }
+ BUG_ON(fd < 0);
+ stat = hv_fs_fstat(fd);
+ BUG_ON(stat.size < 0);
+ if (stat.flags & HV_FS_ISDIR) {
+ pr_warning("Ignoring hvfs file '%s': it's a directory.\n",
+ initramfs_file);
+ return;
+ }
+ initrd = alloc_bootmem_pages(stat.size);
+ rc = hv_fs_pread(fd, (HV_VirtAddr) initrd, stat.size, 0);
+ if (rc != stat.size) {
+ pr_err("Error reading %d bytes from hvfs file '%s': %d\n",
+ stat.size, initramfs_file, rc);
+ free_bootmem((unsigned long) initrd, stat.size);
+ return;
+ }
+ initrd_start = (unsigned long) initrd;
+ initrd_end = initrd_start + stat.size;
+}
+
+void __init free_initrd_mem(unsigned long begin, unsigned long end)
+{
+ free_bootmem(begin, end - begin);
+}
+
+static void __init validate_hv(void)
+{
+ /*
+ * It may already be too late, but let's check our built-in
+ * configuration against what the hypervisor is providing.
+ */
+ unsigned long glue_size = hv_sysconf(HV_SYSCONF_GLUE_SIZE);
+ int hv_page_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL);
+ int hv_hpage_size = hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE);
+ HV_ASIDRange asid_range;
+
+#ifndef CONFIG_SMP
+ HV_Topology topology = hv_inquire_topology();
+ BUG_ON(topology.coord.x != 0 || topology.coord.y != 0);
+ if (topology.width != 1 || topology.height != 1) {
+ pr_warning("Warning: booting UP kernel on %dx%d grid;"
+ " will ignore all but first tile.\n",
+ topology.width, topology.height);
+ }
+#endif
+
+ if (PAGE_OFFSET + HV_GLUE_START_CPA + glue_size > (unsigned long)_text)
+ early_panic("Hypervisor glue size %ld is too big!\n",
+ glue_size);
+ if (hv_page_size != PAGE_SIZE)
+ early_panic("Hypervisor page size %#x != our %#lx\n",
+ hv_page_size, PAGE_SIZE);
+ if (hv_hpage_size != HPAGE_SIZE)
+ early_panic("Hypervisor huge page size %#x != our %#lx\n",
+ hv_hpage_size, HPAGE_SIZE);
+
+#ifdef CONFIG_SMP
+ /*
+ * Some hypervisor APIs take a pointer to a bitmap array
+ * whose size is at least the number of cpus on the chip.
+ * We use a struct cpumask for this, so it must be big enough.
+ */
+ if ((smp_height * smp_width) > nr_cpu_ids)
+ early_panic("Hypervisor %d x %d grid too big for Linux"
+ " NR_CPUS %d\n", smp_height, smp_width,
+ nr_cpu_ids);
+#endif
+
+ /*
+ * Check that we're using allowed ASIDs, and initialize the
+ * various asid variables to their appropriate initial states.
+ */
+ asid_range = hv_inquire_asid(0);
+ __get_cpu_var(current_asid) = min_asid = asid_range.start;
+ max_asid = asid_range.start + asid_range.size - 1;
+
+ if (hv_confstr(HV_CONFSTR_CHIP_MODEL, (HV_VirtAddr)chip_model,
+ sizeof(chip_model)) < 0) {
+ pr_err("Warning: HV_CONFSTR_CHIP_MODEL not available\n");
+ strlcpy(chip_model, "unknown", sizeof(chip_model));
+ }
+}
+
+static void __init validate_va(void)
+{
+#ifndef __tilegx__ /* FIXME: GX: probably some validation relevant here */
+ /*
+ * Similarly, make sure we're only using allowed VAs.
+ * We assume we can contiguously use MEM_USER_INTRPT .. MEM_HV_INTRPT,
+ * and 0 .. KERNEL_HIGH_VADDR.
+ * In addition, make sure we CAN'T use the end of memory, since
+ * we use the last chunk of each pgd for the pgd_list.
+ */
+ int i, fc_fd_ok = 0;
+ unsigned long max_va = 0;
+ unsigned long list_va =
+ ((PGD_LIST_OFFSET / sizeof(pgd_t)) << PGDIR_SHIFT);
+
+ for (i = 0; ; ++i) {
+ HV_VirtAddrRange range = hv_inquire_virtual(i);
+ if (range.size == 0)
+ break;
+ if (range.start <= MEM_USER_INTRPT &&
+ range.start + range.size >= MEM_HV_INTRPT)
+ fc_fd_ok = 1;
+ if (range.start == 0)
+ max_va = range.size;
+ BUG_ON(range.start + range.size > list_va);
+ }
+ if (!fc_fd_ok)
+ early_panic("Hypervisor not configured for VAs 0xfc/0xfd\n");
+ if (max_va == 0)
+ early_panic("Hypervisor not configured for low VAs\n");
+ if (max_va < KERNEL_HIGH_VADDR)
+ early_panic("Hypervisor max VA %#lx smaller than %#lx\n",
+ max_va, KERNEL_HIGH_VADDR);
+
+ /* Kernel PCs must have their high bit set; see intvec.S. */
+ if ((long)VMALLOC_START >= 0)
+ early_panic(
+ "Linux VMALLOC region below the 2GB line (%#lx)!\n"
+ "Reconfigure the kernel with fewer NR_HUGE_VMAPS\n"
+ "or smaller VMALLOC_RESERVE.\n",
+ VMALLOC_START);
+#endif
+}
+
+/*
+ * cpu_lotar_map lists all the cpus that are valid for the supervisor
+ * to cache data on at a page level, i.e. what cpus can be placed in
+ * the LOTAR field of a PTE. It is equivalent to the set of possible
+ * cpus plus any other cpus that are willing to share their cache.
+ * It is set by hv_inquire_tiles(HV_INQ_TILES_LOTAR).
+ */
+struct cpumask __write_once cpu_lotar_map;
+EXPORT_SYMBOL(cpu_lotar_map);
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+/*
+ * hash_for_home_map lists all the tiles that hash-for-home data
+ * will be cached on. Note that this may includes tiles that are not
+ * valid for this supervisor to use otherwise (e.g. if a hypervisor
+ * device is being shared between multiple supervisors).
+ * It is set by hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE).
+ */
+struct cpumask hash_for_home_map;
+EXPORT_SYMBOL(hash_for_home_map);
+#endif
+
+/*
+ * cpu_cacheable_map lists all the cpus whose caches the hypervisor can
+ * flush on our behalf. It is set to cpu_possible_map OR'ed with
+ * hash_for_home_map, and it is what should be passed to
+ * hv_flush_remote() to flush all caches. Note that if there are
+ * dedicated hypervisor driver tiles that have authorized use of their
+ * cache, those tiles will only appear in cpu_lotar_map, NOT in
+ * cpu_cacheable_map, as they are a special case.
+ */
+struct cpumask __write_once cpu_cacheable_map;
+EXPORT_SYMBOL(cpu_cacheable_map);
+
+static __initdata struct cpumask disabled_map;
+
+static int __init disabled_cpus(char *str)
+{
+ int boot_cpu = smp_processor_id();
+
+ if (str == NULL || cpulist_parse_crop(str, &disabled_map) != 0)
+ return -EINVAL;
+ if (cpumask_test_cpu(boot_cpu, &disabled_map)) {
+ pr_err("disabled_cpus: can't disable boot cpu %d\n", boot_cpu);
+ cpumask_clear_cpu(boot_cpu, &disabled_map);
+ }
+ return 0;
+}
+
+early_param("disabled_cpus", disabled_cpus);
+
+void __init print_disabled_cpus(void)
+{
+ if (!cpumask_empty(&disabled_map)) {
+ char buf[100];
+ cpulist_scnprintf(buf, sizeof(buf), &disabled_map);
+ pr_info("CPUs not available for Linux: %s\n", buf);
+ }
+}
+
+static void __init setup_cpu_maps(void)
+{
+ struct cpumask hv_disabled_map, cpu_possible_init;
+ int boot_cpu = smp_processor_id();
+ int cpus, i, rc;
+
+ /* Learn which cpus are allowed by the hypervisor. */
+ rc = hv_inquire_tiles(HV_INQ_TILES_AVAIL,
+ (HV_VirtAddr) cpumask_bits(&cpu_possible_init),
+ sizeof(cpu_cacheable_map));
+ if (rc < 0)
+ early_panic("hv_inquire_tiles(AVAIL) failed: rc %d\n", rc);
+ if (!cpumask_test_cpu(boot_cpu, &cpu_possible_init))
+ early_panic("Boot CPU %d disabled by hypervisor!\n", boot_cpu);
+
+ /* Compute the cpus disabled by the hvconfig file. */
+ cpumask_complement(&hv_disabled_map, &cpu_possible_init);
+
+ /* Include them with the cpus disabled by "disabled_cpus". */
+ cpumask_or(&disabled_map, &disabled_map, &hv_disabled_map);
+
+ /*
+ * Disable every cpu after "setup_max_cpus". But don't mark
+ * as disabled the cpus that are outside of our initial rectangle,
+ * since that turns out to be confusing.
+ */
+ cpus = 1; /* this cpu */
+ cpumask_set_cpu(boot_cpu, &disabled_map); /* ignore this cpu */
+ for (i = 0; cpus < setup_max_cpus; ++i)
+ if (!cpumask_test_cpu(i, &disabled_map))
+ ++cpus;
+ for (; i < smp_height * smp_width; ++i)
+ cpumask_set_cpu(i, &disabled_map);
+ cpumask_clear_cpu(boot_cpu, &disabled_map); /* reset this cpu */
+ for (i = smp_height * smp_width; i < NR_CPUS; ++i)
+ cpumask_clear_cpu(i, &disabled_map);
+
+ /*
+ * Setup cpu_possible map as every cpu allocated to us, minus
+ * the results of any "disabled_cpus" settings.
+ */
+ cpumask_andnot(&cpu_possible_init, &cpu_possible_init, &disabled_map);
+ init_cpu_possible(&cpu_possible_init);
+
+ /* Learn which cpus are valid for LOTAR caching. */
+ rc = hv_inquire_tiles(HV_INQ_TILES_LOTAR,
+ (HV_VirtAddr) cpumask_bits(&cpu_lotar_map),
+ sizeof(cpu_lotar_map));
+ if (rc < 0) {
+ pr_err("warning: no HV_INQ_TILES_LOTAR; using AVAIL\n");
+ cpu_lotar_map = cpu_possible_map;
+ }
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ /* Retrieve set of CPUs used for hash-for-home caching */
+ rc = hv_inquire_tiles(HV_INQ_TILES_HFH_CACHE,
+ (HV_VirtAddr) hash_for_home_map.bits,
+ sizeof(hash_for_home_map));
+ if (rc < 0)
+ early_panic("hv_inquire_tiles(HFH_CACHE) failed: rc %d\n", rc);
+ cpumask_or(&cpu_cacheable_map, &cpu_possible_map, &hash_for_home_map);
+#else
+ cpu_cacheable_map = cpu_possible_map;
+#endif
+}
+
+
+static int __init dataplane(char *str)
+{
+ pr_warning("WARNING: dataplane support disabled in this kernel\n");
+ return 0;
+}
+
+early_param("dataplane", dataplane);
+
+#ifdef CONFIG_CMDLINE_BOOL
+static char __initdata builtin_cmdline[COMMAND_LINE_SIZE] = CONFIG_CMDLINE;
+#endif
+
+void __init setup_arch(char **cmdline_p)
+{
+ int len;
+
+#if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
+ len = hv_get_command_line((HV_VirtAddr) boot_command_line,
+ COMMAND_LINE_SIZE);
+ if (boot_command_line[0])
+ pr_warning("WARNING: ignoring dynamic command line \"%s\"\n",
+ boot_command_line);
+ strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
+#else
+ char *hv_cmdline;
+#if defined(CONFIG_CMDLINE_BOOL)
+ if (builtin_cmdline[0]) {
+ int builtin_len = strlcpy(boot_command_line, builtin_cmdline,
+ COMMAND_LINE_SIZE);
+ if (builtin_len < COMMAND_LINE_SIZE-1)
+ boot_command_line[builtin_len++] = ' ';
+ hv_cmdline = &boot_command_line[builtin_len];
+ len = COMMAND_LINE_SIZE - builtin_len;
+ } else
+#endif
+ {
+ hv_cmdline = boot_command_line;
+ len = COMMAND_LINE_SIZE;
+ }
+ len = hv_get_command_line((HV_VirtAddr) hv_cmdline, len);
+ if (len < 0 || len > COMMAND_LINE_SIZE)
+ early_panic("hv_get_command_line failed: %d\n", len);
+#endif
+
+ *cmdline_p = boot_command_line;
+
+ /* Set disabled_map and setup_max_cpus very early */
+ parse_early_param();
+
+ /* Make sure the kernel is compatible with the hypervisor. */
+ validate_hv();
+ validate_va();
+
+ setup_cpu_maps();
+
+
+#ifdef CONFIG_PCI
+ /*
+ * Initialize the PCI structures. This is done before memory
+ * setup so that we know whether or not a pci_reserve region
+ * is necessary.
+ */
+ if (tile_pci_init() == 0)
+ pci_reserve_mb = 0;
+
+ /* PCI systems reserve a region just below 4GB for mapping iomem. */
+ pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT));
+ pci_reserve_start_pfn = pci_reserve_end_pfn -
+ (pci_reserve_mb << (20 - PAGE_SHIFT));
+#endif
+
+ init_mm.start_code = (unsigned long) _text;
+ init_mm.end_code = (unsigned long) _etext;
+ init_mm.end_data = (unsigned long) _edata;
+ init_mm.brk = (unsigned long) _end;
+
+ setup_memory();
+ store_permanent_mappings();
+ setup_bootmem_allocator();
+
+ /*
+ * NOTE: before this point _nobody_ is allowed to allocate
+ * any memory using the bootmem allocator.
+ */
+
+ paging_init();
+ setup_numa_mapping();
+ zone_sizes_init();
+ set_page_homes();
+ setup_cpu(1);
+ setup_clock();
+ load_hv_initrd();
+}
+
+
+/*
+ * Set up per-cpu memory.
+ */
+
+unsigned long __per_cpu_offset[NR_CPUS] __write_once;
+EXPORT_SYMBOL(__per_cpu_offset);
+
+static size_t __initdata pfn_offset[MAX_NUMNODES] = { 0 };
+static unsigned long __initdata percpu_pfn[NR_CPUS] = { 0 };
+
+/*
+ * As the percpu code allocates pages, we return the pages from the
+ * end of the node for the specified cpu.
+ */
+static void *__init pcpu_fc_alloc(unsigned int cpu, size_t size, size_t align)
+{
+ int nid = cpu_to_node(cpu);
+ unsigned long pfn = node_percpu_pfn[nid] + pfn_offset[nid];
+
+ BUG_ON(size % PAGE_SIZE != 0);
+ pfn_offset[nid] += size / PAGE_SIZE;
+ if (percpu_pfn[cpu] == 0)
+ percpu_pfn[cpu] = pfn;
+ return pfn_to_kaddr(pfn);
+}
+
+/*
+ * Pages reserved for percpu memory are not freeable, and in any case we are
+ * on a short path to panic() in setup_per_cpu_area() at this point anyway.
+ */
+static void __init pcpu_fc_free(void *ptr, size_t size)
+{
+}
+
+/*
+ * Set up vmalloc page tables using bootmem for the percpu code.
+ */
+static void __init pcpu_fc_populate_pte(unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ BUG_ON(pgd_addr_invalid(addr));
+
+ pgd = swapper_pg_dir + pgd_index(addr);
+ pud = pud_offset(pgd, addr);
+ BUG_ON(!pud_present(*pud));
+ pmd = pmd_offset(pud, addr);
+ if (pmd_present(*pmd)) {
+ BUG_ON(pmd_huge_page(*pmd));
+ } else {
+ pte = __alloc_bootmem(L2_KERNEL_PGTABLE_SIZE,
+ HV_PAGE_TABLE_ALIGN, 0);
+ pmd_populate_kernel(&init_mm, pmd, pte);
+ }
+}
+
+void __init setup_per_cpu_areas(void)
+{
+ struct page *pg;
+ unsigned long delta, pfn, lowmem_va;
+ unsigned long size = percpu_size();
+ char *ptr;
+ int rc, cpu, i;
+
+ rc = pcpu_page_first_chunk(PERCPU_MODULE_RESERVE, pcpu_fc_alloc,
+ pcpu_fc_free, pcpu_fc_populate_pte);
+ if (rc < 0)
+ panic("Cannot initialize percpu area (err=%d)", rc);
+
+ delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+ for_each_possible_cpu(cpu) {
+ __per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
+
+ /* finv the copy out of cache so we can change homecache */
+ ptr = pcpu_base_addr + pcpu_unit_offsets[cpu];
+ __finv_buffer(ptr, size);
+ pfn = percpu_pfn[cpu];
+
+ /* Rewrite the page tables to cache on that cpu */
+ pg = pfn_to_page(pfn);
+ for (i = 0; i < size; i += PAGE_SIZE, ++pfn, ++pg) {
+
+ /* Update the vmalloc mapping and page home. */
+ pte_t *ptep =
+ virt_to_pte(NULL, (unsigned long)ptr + i);
+ pte_t pte = *ptep;
+ BUG_ON(pfn != pte_pfn(pte));
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
+ pte = set_remote_cache_cpu(pte, cpu);
+ set_pte(ptep, pte);
+
+ /* Update the lowmem mapping for consistency. */
+ lowmem_va = (unsigned long)pfn_to_kaddr(pfn);
+ ptep = virt_to_pte(NULL, lowmem_va);
+ if (pte_huge(*ptep)) {
+ printk(KERN_DEBUG "early shatter of huge page"
+ " at %#lx\n", lowmem_va);
+ shatter_pmd((pmd_t *)ptep);
+ ptep = virt_to_pte(NULL, lowmem_va);
+ BUG_ON(pte_huge(*ptep));
+ }
+ BUG_ON(pfn != pte_pfn(*ptep));
+ set_pte(ptep, pte);
+ }
+ }
+
+ /* Set our thread pointer appropriately. */
+ set_my_cpu_offset(__per_cpu_offset[smp_processor_id()]);
+
+ /* Make sure the finv's have completed. */
+ mb_incoherent();
+
+ /* Flush the TLB so we reference it properly from here on out. */
+ local_flush_tlb_all();
+}
+
+static struct resource data_resource = {
+ .name = "Kernel data",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+static struct resource code_resource = {
+ .name = "Kernel code",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM
+};
+
+/*
+ * We reserve all resources above 4GB so that PCI won't try to put
+ * mappings above 4GB; the standard allows that for some devices but
+ * the probing code trunates values to 32 bits.
+ */
+#ifdef CONFIG_PCI
+static struct resource* __init
+insert_non_bus_resource(void)
+{
+ struct resource *res =
+ kzalloc(sizeof(struct resource), GFP_ATOMIC);
+ res->name = "Non-Bus Physical Address Space";
+ res->start = (1ULL << 32);
+ res->end = -1LL;
+ res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ if (insert_resource(&iomem_resource, res)) {
+ kfree(res);
+ return NULL;
+ }
+ return res;
+}
+#endif
+
+static struct resource* __init
+insert_ram_resource(u64 start_pfn, u64 end_pfn)
+{
+ struct resource *res =
+ kzalloc(sizeof(struct resource), GFP_ATOMIC);
+ res->name = "System RAM";
+ res->start = start_pfn << PAGE_SHIFT;
+ res->end = (end_pfn << PAGE_SHIFT) - 1;
+ res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
+ if (insert_resource(&iomem_resource, res)) {
+ kfree(res);
+ return NULL;
+ }
+ return res;
+}
+
+/*
+ * Request address space for all standard resources
+ *
+ * If the system includes PCI root complex drivers, we need to create
+ * a window just below 4GB where PCI BARs can be mapped.
+ */
+static int __init request_standard_resources(void)
+{
+ int i;
+ enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET };
+
+ iomem_resource.end = -1LL;
+#ifdef CONFIG_PCI
+ insert_non_bus_resource();
+#endif
+
+ for_each_online_node(i) {
+ u64 start_pfn = node_start_pfn[i];
+ u64 end_pfn = node_end_pfn[i];
+
+#ifdef CONFIG_PCI
+ if (start_pfn <= pci_reserve_start_pfn &&
+ end_pfn > pci_reserve_start_pfn) {
+ if (end_pfn > pci_reserve_end_pfn)
+ insert_ram_resource(pci_reserve_end_pfn,
+ end_pfn);
+ end_pfn = pci_reserve_start_pfn;
+ }
+#endif
+ insert_ram_resource(start_pfn, end_pfn);
+ }
+
+ code_resource.start = __pa(_text - CODE_DELTA);
+ code_resource.end = __pa(_etext - CODE_DELTA)-1;
+ data_resource.start = __pa(_sdata);
+ data_resource.end = __pa(_end)-1;
+
+ insert_resource(&iomem_resource, &code_resource);
+ insert_resource(&iomem_resource, &data_resource);
+
+#ifdef CONFIG_KEXEC
+ insert_resource(&iomem_resource, &crashk_res);
+#endif
+
+ return 0;
+}
+
+subsys_initcall(request_standard_resources);
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c
new file mode 100644
index 000000000000..45b66a3c991f
--- /dev/null
+++ b/arch/tile/kernel/signal.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/personality.h>
+#include <linux/suspend.h>
+#include <linux/ptrace.h>
+#include <linux/elf.h>
+#include <linux/compat.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+#include <asm/processor.h>
+#include <asm/ucontext.h>
+#include <asm/sigframe.h>
+#include <asm/syscalls.h>
+#include <arch/interrupts.h>
+
+#define DEBUG_SIG 0
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+
+long _sys_sigaltstack(const stack_t __user *uss,
+ stack_t __user *uoss, struct pt_regs *regs)
+{
+ return do_sigaltstack(uss, uoss, regs->sp);
+}
+
+
+/*
+ * Do a signal return; undo the signal stack.
+ */
+
+int restore_sigcontext(struct pt_regs *regs,
+ struct sigcontext __user *sc, long *pr0)
+{
+ int err = 0;
+ int i;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
+ err |= __get_user(((long *)regs)[i],
+ &((long __user *)(&sc->regs))[i]);
+
+ regs->faultnum = INT_SWINT_1_SIGRETURN;
+
+ err |= __get_user(*pr0, &sc->regs.regs[0]);
+ return err;
+}
+
+/* sigreturn() returns long since it restores r0 in the interrupted code. */
+long _sys_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame =
+ (struct rt_sigframe __user *)(regs->sp);
+ sigset_t set;
+ long r0;
+
+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
+ goto badframe;
+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
+ goto badframe;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
+ goto badframe;
+
+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
+ goto badframe;
+
+ return r0;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+/*
+ * Set up a signal frame.
+ */
+
+int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
+{
+ int i, err = 0;
+
+ for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i)
+ err |= __put_user(((long *)regs)[i],
+ &((long __user *)(&sc->regs))[i]);
+
+ return err;
+}
+
+/*
+ * Determine which stack to use..
+ */
+static inline void __user *get_sigframe(struct k_sigaction *ka,
+ struct pt_regs *regs,
+ size_t frame_size)
+{
+ unsigned long sp;
+
+ /* Default to using normal stack */
+ sp = regs->sp;
+
+ /*
+ * If we are on the alternate signal stack and would overflow
+ * it, don't. Return an always-bogus address instead so we
+ * will die with SIGSEGV.
+ */
+ if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
+ return (void __user __force *)-1UL;
+
+ /* This is the X/Open sanctioned signal stack switching. */
+ if (ka->sa.sa_flags & SA_ONSTACK) {
+ if (sas_ss_flags(sp) == 0)
+ sp = current->sas_ss_sp + current->sas_ss_size;
+ }
+
+ sp -= frame_size;
+ /*
+ * Align the stack pointer according to the TILE ABI,
+ * i.e. so that on function entry (sp & 15) == 0.
+ */
+ sp &= -16UL;
+ return (void __user *) sp;
+}
+
+static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ unsigned long restorer;
+ struct rt_sigframe __user *frame;
+ int err = 0;
+ int usig;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto give_sigsegv;
+
+ usig = current_thread_info()->exec_domain
+ && current_thread_info()->exec_domain->signal_invmap
+ && sig < 32
+ ? current_thread_info()->exec_domain->signal_invmap[sig]
+ : sig;
+
+ /* Always write at least the signal number for the stack backtracer. */
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ /* At sigreturn time, restore the callee-save registers too. */
+ err |= copy_siginfo_to_user(&frame->info, info);
+ regs->flags |= PT_FLAGS_RESTORE_REGS;
+ } else {
+ err |= __put_user(info->si_signo, &frame->info.si_signo);
+ }
+
+ /* Create the ucontext. */
+ err |= __clear_user(&frame->save_area, sizeof(frame->save_area));
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(NULL, &frame->uc.uc_link);
+ err |= __put_user((void __user *)(current->sas_ss_sp),
+ &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(regs->sp),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+ if (err)
+ goto give_sigsegv;
+
+ restorer = VDSO_BASE;
+ if (ka->sa.sa_flags & SA_RESTORER)
+ restorer = (unsigned long) ka->sa.sa_restorer;
+
+ /*
+ * Set up registers for signal handler.
+ * Registers that we don't modify keep the value they had from
+ * user-space at the time we took the signal.
+ */
+ regs->pc = (unsigned long) ka->sa.sa_handler;
+ regs->ex1 = PL_ICS_EX1(USER_PL, 1); /* set crit sec in handler */
+ regs->sp = (unsigned long) frame;
+ regs->lr = restorer;
+ regs->regs[0] = (unsigned long) usig;
+
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ /* Need extra arguments, so mark to restore caller-saves. */
+ regs->regs[1] = (unsigned long) &frame->info;
+ regs->regs[2] = (unsigned long) &frame->uc;
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+ }
+
+ /*
+ * Notify any tracer that was single-stepping it.
+ * The tracer may want to single-step inside the
+ * handler too.
+ */
+ if (test_thread_flag(TIF_SINGLESTEP))
+ ptrace_notify(SIGTRAP);
+
+ return 0;
+
+give_sigsegv:
+ force_sigsegv(sig, current);
+ return -EFAULT;
+}
+
+/*
+ * OK, we're invoking a handler
+ */
+
+static int handle_signal(unsigned long sig, siginfo_t *info,
+ struct k_sigaction *ka, sigset_t *oldset,
+ struct pt_regs *regs)
+{
+ int ret;
+
+
+ /* Are we from a system call? */
+ if (regs->faultnum == INT_SWINT_1) {
+ /* If so, check system call restarting.. */
+ switch (regs->regs[0]) {
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ regs->regs[0] = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->regs[0] = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ /* Reload caller-saves to restore r0..r5 and r10. */
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+ regs->regs[0] = regs->orig_r0;
+ regs->pc -= 8;
+ }
+ }
+
+ /* Set up the stack frame */
+#ifdef CONFIG_COMPAT
+ if (is_compat_task())
+ ret = compat_setup_rt_frame(sig, ka, info, oldset, regs);
+ else
+#endif
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ret == 0) {
+ /* This code is only called from system calls or from
+ * the work_pending path in the return-to-user code, and
+ * either way we can re-enable interrupts unconditionally.
+ */
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked,
+ &current->blocked, &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+
+ return ret;
+}
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ */
+void do_signal(struct pt_regs *regs)
+{
+ siginfo_t info;
+ int signr;
+ struct k_sigaction ka;
+ sigset_t *oldset;
+
+ /*
+ * i386 will check if we're coming from kernel mode and bail out
+ * here. In my experience this just turns weird crashes into
+ * weird spin-hangs. But if we find a case where this seems
+ * helpful, we can reinstate the check on "!user_mode(regs)".
+ */
+
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK)
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ /* Whee! Actually deliver the signal. */
+ if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
+ /*
+ * A signal was successfully delivered; the saved
+ * sigmask will have been stored in the signal frame,
+ * and will be restored by sigreturn, so we can simply
+ * clear the TS_RESTORE_SIGMASK flag.
+ */
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ }
+
+ return;
+ }
+
+ /* Did we come from a system call? */
+ if (regs->faultnum == INT_SWINT_1) {
+ /* Restart the system call - no handlers present */
+ switch (regs->regs[0]) {
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+ regs->regs[0] = regs->orig_r0;
+ regs->pc -= 8;
+ break;
+
+ case -ERESTART_RESTARTBLOCK:
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+ regs->regs[TREG_SYSCALL_NR] = __NR_restart_syscall;
+ regs->pc -= 8;
+ break;
+ }
+ }
+
+ /* If there's no signal to deliver, just put the saved sigmask back. */
+ if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
+ current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+}
diff --git a/arch/tile/kernel/single_step.c b/arch/tile/kernel/single_step.c
new file mode 100644
index 000000000000..5ec4b9c651f2
--- /dev/null
+++ b/arch/tile/kernel/single_step.c
@@ -0,0 +1,663 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * A code-rewriter that enables instruction single-stepping.
+ * Derived from iLib's single-stepping code.
+ */
+
+#ifndef __tilegx__ /* No support for single-step yet. */
+
+/* These functions are only used on the TILE platform */
+#include <linux/slab.h>
+#include <linux/thread_info.h>
+#include <linux/uaccess.h>
+#include <linux/mman.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <asm/cacheflush.h>
+#include <asm/opcode-tile.h>
+#include <asm/opcode_constants.h>
+#include <arch/abi.h>
+
+#define signExtend17(val) sign_extend((val), 17)
+#define TILE_X1_MASK (0xffffffffULL << 31)
+
+int unaligned_printk;
+
+static int __init setup_unaligned_printk(char *str)
+{
+ long val;
+ if (strict_strtol(str, 0, &val) != 0)
+ return 0;
+ unaligned_printk = val;
+ pr_info("Printk for each unaligned data accesses is %s\n",
+ unaligned_printk ? "enabled" : "disabled");
+ return 1;
+}
+__setup("unaligned_printk=", setup_unaligned_printk);
+
+unsigned int unaligned_fixup_count;
+
+enum mem_op {
+ MEMOP_NONE,
+ MEMOP_LOAD,
+ MEMOP_STORE,
+ MEMOP_LOAD_POSTINCR,
+ MEMOP_STORE_POSTINCR
+};
+
+static inline tile_bundle_bits set_BrOff_X1(tile_bundle_bits n, int32_t offset)
+{
+ tile_bundle_bits result;
+
+ /* mask out the old offset */
+ tile_bundle_bits mask = create_BrOff_X1(-1);
+ result = n & (~mask);
+
+ /* or in the new offset */
+ result |= create_BrOff_X1(offset);
+
+ return result;
+}
+
+static inline tile_bundle_bits move_X1(tile_bundle_bits n, int dest, int src)
+{
+ tile_bundle_bits result;
+ tile_bundle_bits op;
+
+ result = n & (~TILE_X1_MASK);
+
+ op = create_Opcode_X1(SPECIAL_0_OPCODE_X1) |
+ create_RRROpcodeExtension_X1(OR_SPECIAL_0_OPCODE_X1) |
+ create_Dest_X1(dest) |
+ create_SrcB_X1(TREG_ZERO) |
+ create_SrcA_X1(src) ;
+
+ result |= op;
+ return result;
+}
+
+static inline tile_bundle_bits nop_X1(tile_bundle_bits n)
+{
+ return move_X1(n, TREG_ZERO, TREG_ZERO);
+}
+
+static inline tile_bundle_bits addi_X1(
+ tile_bundle_bits n, int dest, int src, int imm)
+{
+ n &= ~TILE_X1_MASK;
+
+ n |= (create_SrcA_X1(src) |
+ create_Dest_X1(dest) |
+ create_Imm8_X1(imm) |
+ create_S_X1(0) |
+ create_Opcode_X1(IMM_0_OPCODE_X1) |
+ create_ImmOpcodeExtension_X1(ADDI_IMM_0_OPCODE_X1));
+
+ return n;
+}
+
+static tile_bundle_bits rewrite_load_store_unaligned(
+ struct single_step_state *state,
+ tile_bundle_bits bundle,
+ struct pt_regs *regs,
+ enum mem_op mem_op,
+ int size, int sign_ext)
+{
+ unsigned char __user *addr;
+ int val_reg, addr_reg, err, val;
+
+ /* Get address and value registers */
+ if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
+ addr_reg = get_SrcA_Y2(bundle);
+ val_reg = get_SrcBDest_Y2(bundle);
+ } else if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
+ addr_reg = get_SrcA_X1(bundle);
+ val_reg = get_Dest_X1(bundle);
+ } else {
+ addr_reg = get_SrcA_X1(bundle);
+ val_reg = get_SrcB_X1(bundle);
+ }
+
+ /*
+ * If registers are not GPRs, don't try to handle it.
+ *
+ * FIXME: we could handle non-GPR loads by getting the real value
+ * from memory, writing it to the single step buffer, using a
+ * temp_reg to hold a pointer to that memory, then executing that
+ * instruction and resetting temp_reg. For non-GPR stores, it's a
+ * little trickier; we could use the single step buffer for that
+ * too, but we'd have to add some more state bits so that we could
+ * call back in here to copy that value to the real target. For
+ * now, we just handle the simple case.
+ */
+ if ((val_reg >= PTREGS_NR_GPRS &&
+ (val_reg != TREG_ZERO ||
+ mem_op == MEMOP_LOAD ||
+ mem_op == MEMOP_LOAD_POSTINCR)) ||
+ addr_reg >= PTREGS_NR_GPRS)
+ return bundle;
+
+ /* If it's aligned, don't handle it specially */
+ addr = (void __user *)regs->regs[addr_reg];
+ if (((unsigned long)addr % size) == 0)
+ return bundle;
+
+#ifndef __LITTLE_ENDIAN
+# error We assume little-endian representation with copy_xx_user size 2 here
+#endif
+ /* Handle unaligned load/store */
+ if (mem_op == MEMOP_LOAD || mem_op == MEMOP_LOAD_POSTINCR) {
+ unsigned short val_16;
+ switch (size) {
+ case 2:
+ err = copy_from_user(&val_16, addr, sizeof(val_16));
+ val = sign_ext ? ((short)val_16) : val_16;
+ break;
+ case 4:
+ err = copy_from_user(&val, addr, sizeof(val));
+ break;
+ default:
+ BUG();
+ }
+ if (err == 0) {
+ state->update_reg = val_reg;
+ state->update_value = val;
+ state->update = 1;
+ }
+ } else {
+ val = (val_reg == TREG_ZERO) ? 0 : regs->regs[val_reg];
+ err = copy_to_user(addr, &val, size);
+ }
+
+ if (err) {
+ siginfo_t info = {
+ .si_signo = SIGSEGV,
+ .si_code = SEGV_MAPERR,
+ .si_addr = addr
+ };
+ force_sig_info(info.si_signo, &info, current);
+ return (tile_bundle_bits) 0;
+ }
+
+ if (unaligned_fixup == 0) {
+ siginfo_t info = {
+ .si_signo = SIGBUS,
+ .si_code = BUS_ADRALN,
+ .si_addr = addr
+ };
+ force_sig_info(info.si_signo, &info, current);
+ return (tile_bundle_bits) 0;
+ }
+
+ if (unaligned_printk || unaligned_fixup_count == 0) {
+ pr_info("Process %d/%s: PC %#lx: Fixup of"
+ " unaligned %s at %#lx.\n",
+ current->pid, current->comm, regs->pc,
+ (mem_op == MEMOP_LOAD ||
+ mem_op == MEMOP_LOAD_POSTINCR) ?
+ "load" : "store",
+ (unsigned long)addr);
+ if (!unaligned_printk) {
+#define P pr_info
+P("\n");
+P("Unaligned fixups in the kernel will slow your application considerably.\n");
+P("To find them, write a \"1\" to /proc/sys/tile/unaligned_fixup/printk,\n");
+P("which requests the kernel show all unaligned fixups, or write a \"0\"\n");
+P("to /proc/sys/tile/unaligned_fixup/enabled, in which case each unaligned\n");
+P("access will become a SIGBUS you can debug. No further warnings will be\n");
+P("shown so as to avoid additional slowdown, but you can track the number\n");
+P("of fixups performed via /proc/sys/tile/unaligned_fixup/count.\n");
+P("Use the tile-addr2line command (see \"info addr2line\") to decode PCs.\n");
+P("\n");
+#undef P
+ }
+ }
+ ++unaligned_fixup_count;
+
+ if (bundle & TILE_BUNDLE_Y_ENCODING_MASK) {
+ /* Convert the Y2 instruction to a prefetch. */
+ bundle &= ~(create_SrcBDest_Y2(-1) |
+ create_Opcode_Y2(-1));
+ bundle |= (create_SrcBDest_Y2(TREG_ZERO) |
+ create_Opcode_Y2(LW_OPCODE_Y2));
+ /* Replace the load postincr with an addi */
+ } else if (mem_op == MEMOP_LOAD_POSTINCR) {
+ bundle = addi_X1(bundle, addr_reg, addr_reg,
+ get_Imm8_X1(bundle));
+ /* Replace the store postincr with an addi */
+ } else if (mem_op == MEMOP_STORE_POSTINCR) {
+ bundle = addi_X1(bundle, addr_reg, addr_reg,
+ get_Dest_Imm8_X1(bundle));
+ } else {
+ /* Convert the X1 instruction to a nop. */
+ bundle &= ~(create_Opcode_X1(-1) |
+ create_UnShOpcodeExtension_X1(-1) |
+ create_UnOpcodeExtension_X1(-1));
+ bundle |= (create_Opcode_X1(SHUN_0_OPCODE_X1) |
+ create_UnShOpcodeExtension_X1(
+ UN_0_SHUN_0_OPCODE_X1) |
+ create_UnOpcodeExtension_X1(
+ NOP_UN_0_SHUN_0_OPCODE_X1));
+ }
+
+ return bundle;
+}
+
+/**
+ * single_step_once() - entry point when single stepping has been triggered.
+ * @regs: The machine register state
+ *
+ * When we arrive at this routine via a trampoline, the single step
+ * engine copies the executing bundle to the single step buffer.
+ * If the instruction is a condition branch, then the target is
+ * reset to one past the next instruction. If the instruction
+ * sets the lr, then that is noted. If the instruction is a jump
+ * or call, then the new target pc is preserved and the current
+ * bundle instruction set to null.
+ *
+ * The necessary post-single-step rewriting information is stored in
+ * single_step_state-> We use data segment values because the
+ * stack will be rewound when we run the rewritten single-stepped
+ * instruction.
+ */
+void single_step_once(struct pt_regs *regs)
+{
+ extern tile_bundle_bits __single_step_ill_insn;
+ extern tile_bundle_bits __single_step_j_insn;
+ extern tile_bundle_bits __single_step_addli_insn;
+ extern tile_bundle_bits __single_step_auli_insn;
+ struct thread_info *info = (void *)current_thread_info();
+ struct single_step_state *state = info->step_state;
+ int is_single_step = test_ti_thread_flag(info, TIF_SINGLESTEP);
+ tile_bundle_bits __user *buffer, *pc;
+ tile_bundle_bits bundle;
+ int temp_reg;
+ int target_reg = TREG_LR;
+ int err;
+ enum mem_op mem_op = MEMOP_NONE;
+ int size = 0, sign_ext = 0; /* happy compiler */
+
+ asm(
+" .pushsection .rodata.single_step\n"
+" .align 8\n"
+" .globl __single_step_ill_insn\n"
+"__single_step_ill_insn:\n"
+" ill\n"
+" .globl __single_step_addli_insn\n"
+"__single_step_addli_insn:\n"
+" { nop; addli r0, zero, 0 }\n"
+" .globl __single_step_auli_insn\n"
+"__single_step_auli_insn:\n"
+" { nop; auli r0, r0, 0 }\n"
+" .globl __single_step_j_insn\n"
+"__single_step_j_insn:\n"
+" j .\n"
+" .popsection\n"
+ );
+
+ if (state == NULL) {
+ /* allocate a page of writable, executable memory */
+ state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
+ if (state == NULL) {
+ pr_err("Out of kernel memory trying to single-step\n");
+ return;
+ }
+
+ /* allocate a cache line of writable, executable memory */
+ down_write(&current->mm->mmap_sem);
+ buffer = (void __user *) do_mmap(NULL, 0, 64,
+ PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS,
+ 0);
+ up_write(&current->mm->mmap_sem);
+
+ if (IS_ERR((void __force *)buffer)) {
+ kfree(state);
+ pr_err("Out of kernel pages trying to single-step\n");
+ return;
+ }
+
+ state->buffer = buffer;
+ state->is_enabled = 0;
+
+ info->step_state = state;
+
+ /* Validate our stored instruction patterns */
+ BUG_ON(get_Opcode_X1(__single_step_addli_insn) !=
+ ADDLI_OPCODE_X1);
+ BUG_ON(get_Opcode_X1(__single_step_auli_insn) !=
+ AULI_OPCODE_X1);
+ BUG_ON(get_SrcA_X1(__single_step_addli_insn) != TREG_ZERO);
+ BUG_ON(get_Dest_X1(__single_step_addli_insn) != 0);
+ BUG_ON(get_JOffLong_X1(__single_step_j_insn) != 0);
+ }
+
+ /*
+ * If we are returning from a syscall, we still haven't hit the
+ * "ill" for the swint1 instruction. So back the PC up to be
+ * pointing at the swint1, but we'll actually return directly
+ * back to the "ill" so we come back in via SIGILL as if we
+ * had "executed" the swint1 without ever being in kernel space.
+ */
+ if (regs->faultnum == INT_SWINT_1)
+ regs->pc -= 8;
+
+ pc = (tile_bundle_bits __user *)(regs->pc);
+ if (get_user(bundle, pc) != 0) {
+ pr_err("Couldn't read instruction at %p trying to step\n", pc);
+ return;
+ }
+
+ /* We'll follow the instruction with 2 ill op bundles */
+ state->orig_pc = (unsigned long)pc;
+ state->next_pc = (unsigned long)(pc + 1);
+ state->branch_next_pc = 0;
+ state->update = 0;
+
+ if (!(bundle & TILE_BUNDLE_Y_ENCODING_MASK)) {
+ /* two wide, check for control flow */
+ int opcode = get_Opcode_X1(bundle);
+
+ switch (opcode) {
+ /* branches */
+ case BRANCH_OPCODE_X1:
+ {
+ int32_t offset = signExtend17(get_BrOff_X1(bundle));
+
+ /*
+ * For branches, we use a rewriting trick to let the
+ * hardware evaluate whether the branch is taken or
+ * untaken. We record the target offset and then
+ * rewrite the branch instruction to target 1 insn
+ * ahead if the branch is taken. We then follow the
+ * rewritten branch with two bundles, each containing
+ * an "ill" instruction. The supervisor examines the
+ * pc after the single step code is executed, and if
+ * the pc is the first ill instruction, then the
+ * branch (if any) was not taken. If the pc is the
+ * second ill instruction, then the branch was
+ * taken. The new pc is computed for these cases, and
+ * inserted into the registers for the thread. If
+ * the pc is the start of the single step code, then
+ * an exception or interrupt was taken before the
+ * code started processing, and the same "original"
+ * pc is restored. This change, different from the
+ * original implementation, has the advantage of
+ * executing a single user instruction.
+ */
+ state->branch_next_pc = (unsigned long)(pc + offset);
+
+ /* rewrite branch offset to go forward one bundle */
+ bundle = set_BrOff_X1(bundle, 2);
+ }
+ break;
+
+ /* jumps */
+ case JALB_OPCODE_X1:
+ case JALF_OPCODE_X1:
+ state->update = 1;
+ state->next_pc =
+ (unsigned long) (pc + get_JOffLong_X1(bundle));
+ break;
+
+ case JB_OPCODE_X1:
+ case JF_OPCODE_X1:
+ state->next_pc =
+ (unsigned long) (pc + get_JOffLong_X1(bundle));
+ bundle = nop_X1(bundle);
+ break;
+
+ case SPECIAL_0_OPCODE_X1:
+ switch (get_RRROpcodeExtension_X1(bundle)) {
+ /* jump-register */
+ case JALRP_SPECIAL_0_OPCODE_X1:
+ case JALR_SPECIAL_0_OPCODE_X1:
+ state->update = 1;
+ state->next_pc =
+ regs->regs[get_SrcA_X1(bundle)];
+ break;
+
+ case JRP_SPECIAL_0_OPCODE_X1:
+ case JR_SPECIAL_0_OPCODE_X1:
+ state->next_pc =
+ regs->regs[get_SrcA_X1(bundle)];
+ bundle = nop_X1(bundle);
+ break;
+
+ case LNK_SPECIAL_0_OPCODE_X1:
+ state->update = 1;
+ target_reg = get_Dest_X1(bundle);
+ break;
+
+ /* stores */
+ case SH_SPECIAL_0_OPCODE_X1:
+ mem_op = MEMOP_STORE;
+ size = 2;
+ break;
+
+ case SW_SPECIAL_0_OPCODE_X1:
+ mem_op = MEMOP_STORE;
+ size = 4;
+ break;
+ }
+ break;
+
+ /* loads and iret */
+ case SHUN_0_OPCODE_X1:
+ if (get_UnShOpcodeExtension_X1(bundle) ==
+ UN_0_SHUN_0_OPCODE_X1) {
+ switch (get_UnOpcodeExtension_X1(bundle)) {
+ case LH_UN_0_SHUN_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD;
+ size = 2;
+ sign_ext = 1;
+ break;
+
+ case LH_U_UN_0_SHUN_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD;
+ size = 2;
+ sign_ext = 0;
+ break;
+
+ case LW_UN_0_SHUN_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD;
+ size = 4;
+ break;
+
+ case IRET_UN_0_SHUN_0_OPCODE_X1:
+ {
+ unsigned long ex0_0 = __insn_mfspr(
+ SPR_EX_CONTEXT_0_0);
+ unsigned long ex0_1 = __insn_mfspr(
+ SPR_EX_CONTEXT_0_1);
+ /*
+ * Special-case it if we're iret'ing
+ * to PL0 again. Otherwise just let
+ * it run and it will generate SIGILL.
+ */
+ if (EX1_PL(ex0_1) == USER_PL) {
+ state->next_pc = ex0_0;
+ regs->ex1 = ex0_1;
+ bundle = nop_X1(bundle);
+ }
+ }
+ }
+ }
+ break;
+
+#if CHIP_HAS_WH64()
+ /* postincrement operations */
+ case IMM_0_OPCODE_X1:
+ switch (get_ImmOpcodeExtension_X1(bundle)) {
+ case LWADD_IMM_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD_POSTINCR;
+ size = 4;
+ break;
+
+ case LHADD_IMM_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD_POSTINCR;
+ size = 2;
+ sign_ext = 1;
+ break;
+
+ case LHADD_U_IMM_0_OPCODE_X1:
+ mem_op = MEMOP_LOAD_POSTINCR;
+ size = 2;
+ sign_ext = 0;
+ break;
+
+ case SWADD_IMM_0_OPCODE_X1:
+ mem_op = MEMOP_STORE_POSTINCR;
+ size = 4;
+ break;
+
+ case SHADD_IMM_0_OPCODE_X1:
+ mem_op = MEMOP_STORE_POSTINCR;
+ size = 2;
+ break;
+
+ default:
+ break;
+ }
+ break;
+#endif /* CHIP_HAS_WH64() */
+ }
+
+ if (state->update) {
+ /*
+ * Get an available register. We start with a
+ * bitmask with 1's for available registers.
+ * We truncate to the low 32 registers since
+ * we are guaranteed to have set bits in the
+ * low 32 bits, then use ctz to pick the first.
+ */
+ u32 mask = (u32) ~((1ULL << get_Dest_X0(bundle)) |
+ (1ULL << get_SrcA_X0(bundle)) |
+ (1ULL << get_SrcB_X0(bundle)) |
+ (1ULL << target_reg));
+ temp_reg = __builtin_ctz(mask);
+ state->update_reg = temp_reg;
+ state->update_value = regs->regs[temp_reg];
+ regs->regs[temp_reg] = (unsigned long) (pc+1);
+ regs->flags |= PT_FLAGS_RESTORE_REGS;
+ bundle = move_X1(bundle, target_reg, temp_reg);
+ }
+ } else {
+ int opcode = get_Opcode_Y2(bundle);
+
+ switch (opcode) {
+ /* loads */
+ case LH_OPCODE_Y2:
+ mem_op = MEMOP_LOAD;
+ size = 2;
+ sign_ext = 1;
+ break;
+
+ case LH_U_OPCODE_Y2:
+ mem_op = MEMOP_LOAD;
+ size = 2;
+ sign_ext = 0;
+ break;
+
+ case LW_OPCODE_Y2:
+ mem_op = MEMOP_LOAD;
+ size = 4;
+ break;
+
+ /* stores */
+ case SH_OPCODE_Y2:
+ mem_op = MEMOP_STORE;
+ size = 2;
+ break;
+
+ case SW_OPCODE_Y2:
+ mem_op = MEMOP_STORE;
+ size = 4;
+ break;
+ }
+ }
+
+ /*
+ * Check if we need to rewrite an unaligned load/store.
+ * Returning zero is a special value meaning we need to SIGSEGV.
+ */
+ if (mem_op != MEMOP_NONE && unaligned_fixup >= 0) {
+ bundle = rewrite_load_store_unaligned(state, bundle, regs,
+ mem_op, size, sign_ext);
+ if (bundle == 0)
+ return;
+ }
+
+ /* write the bundle to our execution area */
+ buffer = state->buffer;
+ err = __put_user(bundle, buffer++);
+
+ /*
+ * If we're really single-stepping, we take an INT_ILL after.
+ * If we're just handling an unaligned access, we can just
+ * jump directly back to where we were in user code.
+ */
+ if (is_single_step) {
+ err |= __put_user(__single_step_ill_insn, buffer++);
+ err |= __put_user(__single_step_ill_insn, buffer++);
+ } else {
+ long delta;
+
+ if (state->update) {
+ /* We have some state to update; do it inline */
+ int ha16;
+ bundle = __single_step_addli_insn;
+ bundle |= create_Dest_X1(state->update_reg);
+ bundle |= create_Imm16_X1(state->update_value);
+ err |= __put_user(bundle, buffer++);
+ bundle = __single_step_auli_insn;
+ bundle |= create_Dest_X1(state->update_reg);
+ bundle |= create_SrcA_X1(state->update_reg);
+ ha16 = (state->update_value + 0x8000) >> 16;
+ bundle |= create_Imm16_X1(ha16);
+ err |= __put_user(bundle, buffer++);
+ state->update = 0;
+ }
+
+ /* End with a jump back to the next instruction */
+ delta = ((regs->pc + TILE_BUNDLE_SIZE_IN_BYTES) -
+ (unsigned long)buffer) >>
+ TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES;
+ bundle = __single_step_j_insn;
+ bundle |= create_JOffLong_X1(delta);
+ err |= __put_user(bundle, buffer++);
+ }
+
+ if (err) {
+ pr_err("Fault when writing to single-step buffer\n");
+ return;
+ }
+
+ /*
+ * Flush the buffer.
+ * We do a local flush only, since this is a thread-specific buffer.
+ */
+ __flush_icache_range((unsigned long)state->buffer,
+ (unsigned long)buffer);
+
+ /* Indicate enabled */
+ state->is_enabled = is_single_step;
+ regs->pc = (unsigned long)state->buffer;
+
+ /* Fault immediately if we are coming back from a syscall. */
+ if (regs->faultnum == INT_SWINT_1)
+ regs->pc += 8;
+}
+
+#endif /* !__tilegx__ */
diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c
new file mode 100644
index 000000000000..1cb5ec79de04
--- /dev/null
+++ b/arch/tile/kernel/smp.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * TILE SMP support routines.
+ */
+
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <asm/cacheflush.h>
+
+HV_Topology smp_topology __write_once;
+EXPORT_SYMBOL(smp_topology);
+
+#if CHIP_HAS_IPI()
+static unsigned long __iomem *ipi_mappings[NR_CPUS];
+#endif
+
+
+/*
+ * Top-level send_IPI*() functions to send messages to other cpus.
+ */
+
+/* Set by smp_send_stop() to avoid recursive panics. */
+static int stopping_cpus;
+
+void send_IPI_single(int cpu, int tag)
+{
+ HV_Recipient recip = {
+ .y = cpu / smp_width,
+ .x = cpu % smp_width,
+ .state = HV_TO_BE_SENT
+ };
+ int rc = hv_send_message(&recip, 1, (HV_VirtAddr)&tag, sizeof(tag));
+ BUG_ON(rc <= 0);
+}
+
+void send_IPI_many(const struct cpumask *mask, int tag)
+{
+ HV_Recipient recip[NR_CPUS];
+ int cpu, sent;
+ int nrecip = 0;
+ int my_cpu = smp_processor_id();
+ for_each_cpu(cpu, mask) {
+ HV_Recipient *r;
+ BUG_ON(cpu == my_cpu);
+ r = &recip[nrecip++];
+ r->y = cpu / smp_width;
+ r->x = cpu % smp_width;
+ r->state = HV_TO_BE_SENT;
+ }
+ sent = 0;
+ while (sent < nrecip) {
+ int rc = hv_send_message(recip, nrecip,
+ (HV_VirtAddr)&tag, sizeof(tag));
+ if (rc <= 0) {
+ if (!stopping_cpus) /* avoid recursive panic */
+ panic("hv_send_message returned %d", rc);
+ break;
+ }
+ sent += rc;
+ }
+}
+
+void send_IPI_allbutself(int tag)
+{
+ struct cpumask mask;
+ cpumask_copy(&mask, cpu_online_mask);
+ cpumask_clear_cpu(smp_processor_id(), &mask);
+ send_IPI_many(&mask, tag);
+}
+
+
+/*
+ * Provide smp_call_function_mask, but also run function locally
+ * if specified in the mask.
+ */
+void on_each_cpu_mask(const struct cpumask *mask, void (*func)(void *),
+ void *info, bool wait)
+{
+ int cpu = get_cpu();
+ smp_call_function_many(mask, func, info, wait);
+ if (cpumask_test_cpu(cpu, mask)) {
+ local_irq_disable();
+ func(info);
+ local_irq_enable();
+ }
+ put_cpu();
+}
+
+
+/*
+ * Functions related to starting/stopping cpus.
+ */
+
+/* Handler to start the current cpu. */
+static void smp_start_cpu_interrupt(void)
+{
+ get_irq_regs()->pc = start_cpu_function_addr;
+}
+
+/* Handler to stop the current cpu. */
+static void smp_stop_cpu_interrupt(void)
+{
+ set_cpu_online(smp_processor_id(), 0);
+ raw_local_irq_disable_all();
+ for (;;)
+ asm("nap");
+}
+
+/* This function calls the 'stop' function on all other CPUs in the system. */
+void smp_send_stop(void)
+{
+ stopping_cpus = 1;
+ send_IPI_allbutself(MSG_TAG_STOP_CPU);
+}
+
+
+/*
+ * Dispatch code called from hv_message_intr() for HV_MSG_TILE hv messages.
+ */
+void evaluate_message(int tag)
+{
+ switch (tag) {
+ case MSG_TAG_START_CPU: /* Start up a cpu */
+ smp_start_cpu_interrupt();
+ break;
+
+ case MSG_TAG_STOP_CPU: /* Sent to shut down slave CPU's */
+ smp_stop_cpu_interrupt();
+ break;
+
+ case MSG_TAG_CALL_FUNCTION_MANY: /* Call function on cpumask */
+ generic_smp_call_function_interrupt();
+ break;
+
+ case MSG_TAG_CALL_FUNCTION_SINGLE: /* Call function on one other CPU */
+ generic_smp_call_function_single_interrupt();
+ break;
+
+ default:
+ panic("Unknown IPI message tag %d", tag);
+ break;
+ }
+}
+
+
+/*
+ * flush_icache_range() code uses smp_call_function().
+ */
+
+struct ipi_flush {
+ unsigned long start;
+ unsigned long end;
+};
+
+static void ipi_flush_icache_range(void *info)
+{
+ struct ipi_flush *flush = (struct ipi_flush *) info;
+ __flush_icache_range(flush->start, flush->end);
+}
+
+void flush_icache_range(unsigned long start, unsigned long end)
+{
+ struct ipi_flush flush = { start, end };
+ preempt_disable();
+ on_each_cpu(ipi_flush_icache_range, &flush, 1);
+ preempt_enable();
+}
+
+
+/* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
+static irqreturn_t handle_reschedule_ipi(int irq, void *token)
+{
+ /*
+ * Nothing to do here; when we return from interrupt, the
+ * rescheduling will occur there. But do bump the interrupt
+ * profiler count in the meantime.
+ */
+ __get_cpu_var(irq_stat).irq_resched_count++;
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction resched_action = {
+ .handler = handle_reschedule_ipi,
+ .name = "resched",
+ .dev_id = handle_reschedule_ipi /* unique token */,
+};
+
+void __init ipi_init(void)
+{
+#if CHIP_HAS_IPI()
+ int cpu;
+ /* Map IPI trigger MMIO addresses. */
+ for_each_possible_cpu(cpu) {
+ HV_Coord tile;
+ HV_PTE pte;
+ unsigned long offset;
+
+ tile.x = cpu_x(cpu);
+ tile.y = cpu_y(cpu);
+ if (hv_get_ipi_pte(tile, 1, &pte) != 0)
+ panic("Failed to initialize IPI for cpu %d\n", cpu);
+
+ offset = hv_pte_get_pfn(pte) << PAGE_SHIFT;
+ ipi_mappings[cpu] = ioremap_prot(offset, PAGE_SIZE, pte);
+ }
+#endif
+
+ /* Bind handle_reschedule_ipi() to IRQ_RESCHEDULE. */
+ tile_irq_activate(IRQ_RESCHEDULE, TILE_IRQ_PERCPU);
+ BUG_ON(setup_irq(IRQ_RESCHEDULE, &resched_action));
+}
+
+#if CHIP_HAS_IPI()
+
+void smp_send_reschedule(int cpu)
+{
+ WARN_ON(cpu_is_offline(cpu));
+
+ /*
+ * We just want to do an MMIO store. The traditional writeq()
+ * functions aren't really correct here, since they're always
+ * directed at the PCI shim. For now, just do a raw store,
+ * casting away the __iomem attribute.
+ */
+ ((unsigned long __force *)ipi_mappings[cpu])[IRQ_RESCHEDULE] = 0;
+}
+
+#else
+
+void smp_send_reschedule(int cpu)
+{
+ HV_Coord coord;
+
+ WARN_ON(cpu_is_offline(cpu));
+
+ coord.y = cpu_y(cpu);
+ coord.x = cpu_x(cpu);
+ hv_trigger_ipi(coord, IRQ_RESCHEDULE);
+}
+
+#endif /* CHIP_HAS_IPI() */
diff --git a/arch/tile/kernel/smpboot.c b/arch/tile/kernel/smpboot.c
new file mode 100644
index 000000000000..74d62d098edf
--- /dev/null
+++ b/arch/tile/kernel/smpboot.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/smp_lock.h>
+#include <linux/bootmem.h>
+#include <linux/notifier.h>
+#include <linux/cpu.h>
+#include <linux/percpu.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/irq.h>
+#include <asm/mmu_context.h>
+#include <asm/tlbflush.h>
+#include <asm/sections.h>
+
+/* State of each CPU. */
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
+
+/* The messaging code jumps to this pointer during boot-up */
+unsigned long start_cpu_function_addr;
+
+/* Called very early during startup to mark boot cpu as online */
+void __init smp_prepare_boot_cpu(void)
+{
+ int cpu = smp_processor_id();
+ set_cpu_online(cpu, 1);
+ set_cpu_present(cpu, 1);
+ __get_cpu_var(cpu_state) = CPU_ONLINE;
+
+ init_messaging();
+}
+
+static void start_secondary(void);
+
+/*
+ * Called at the top of init() to launch all the other CPUs.
+ * They run free to complete their initialization and then wait
+ * until they get an IPI from the boot cpu to come online.
+ */
+void __init smp_prepare_cpus(unsigned int max_cpus)
+{
+ long rc;
+ int cpu, cpu_count;
+ int boot_cpu = smp_processor_id();
+
+ current_thread_info()->cpu = boot_cpu;
+
+ /*
+ * Pin this task to the boot CPU while we bring up the others,
+ * just to make sure we don't uselessly migrate as they come up.
+ */
+ rc = sched_setaffinity(current->pid, cpumask_of(boot_cpu));
+ if (rc != 0)
+ pr_err("Couldn't set init affinity to boot cpu (%ld)\n", rc);
+
+ /* Print information about disabled and dataplane cpus. */
+ print_disabled_cpus();
+
+ /*
+ * Tell the messaging subsystem how to respond to the
+ * startup message. We use a level of indirection to avoid
+ * confusing the linker with the fact that the messaging
+ * subsystem is calling __init code.
+ */
+ start_cpu_function_addr = (unsigned long) &online_secondary;
+
+ /* Set up thread context for all new processors. */
+ cpu_count = 1;
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ struct task_struct *idle;
+
+ if (cpu == boot_cpu)
+ continue;
+
+ if (!cpu_possible(cpu)) {
+ /*
+ * Make this processor do nothing on boot.
+ * Note that we don't give the boot_pc function
+ * a stack, so it has to be assembly code.
+ */
+ per_cpu(boot_sp, cpu) = 0;
+ per_cpu(boot_pc, cpu) = (unsigned long) smp_nap;
+ continue;
+ }
+
+ /* Create a new idle thread to run start_secondary() */
+ idle = fork_idle(cpu);
+ if (IS_ERR(idle))
+ panic("failed fork for CPU %d", cpu);
+ idle->thread.pc = (unsigned long) start_secondary;
+
+ /* Make this thread the boot thread for this processor */
+ per_cpu(boot_sp, cpu) = task_ksp0(idle);
+ per_cpu(boot_pc, cpu) = idle->thread.pc;
+
+ ++cpu_count;
+ }
+ BUG_ON(cpu_count > (max_cpus ? max_cpus : 1));
+
+ /* Fire up the other tiles, if any */
+ init_cpu_present(cpu_possible_mask);
+ if (cpumask_weight(cpu_present_mask) > 1) {
+ mb(); /* make sure all data is visible to new processors */
+ hv_start_all_tiles();
+ }
+}
+
+static __initdata struct cpumask init_affinity;
+
+static __init int reset_init_affinity(void)
+{
+ long rc = sched_setaffinity(current->pid, &init_affinity);
+ if (rc != 0)
+ pr_warning("couldn't reset init affinity (%ld)\n",
+ rc);
+ return 0;
+}
+late_initcall(reset_init_affinity);
+
+static struct cpumask cpu_started __cpuinitdata;
+
+/*
+ * Activate a secondary processor. Very minimal; don't add anything
+ * to this path without knowing what you're doing, since SMP booting
+ * is pretty fragile.
+ */
+static void __cpuinit start_secondary(void)
+{
+ int cpuid = smp_processor_id();
+
+ /* Set our thread pointer appropriately. */
+ set_my_cpu_offset(__per_cpu_offset[cpuid]);
+
+ preempt_disable();
+
+ /*
+ * In large machines even this will slow us down, since we
+ * will be contending for for the printk spinlock.
+ */
+ /* printk(KERN_DEBUG "Initializing CPU#%d\n", cpuid); */
+
+ /* Initialize the current asid for our first page table. */
+ __get_cpu_var(current_asid) = min_asid;
+
+ /* Set up this thread as another owner of the init_mm */
+ atomic_inc(&init_mm.mm_count);
+ current->active_mm = &init_mm;
+ if (current->mm)
+ BUG();
+ enter_lazy_tlb(&init_mm, current);
+
+ /* Allow hypervisor messages to be received */
+ init_messaging();
+ local_irq_enable();
+
+ /* Indicate that we're ready to come up. */
+ /* Must not do this before we're ready to receive messages */
+ if (cpumask_test_and_set_cpu(cpuid, &cpu_started)) {
+ pr_warning("CPU#%d already started!\n", cpuid);
+ for (;;)
+ local_irq_enable();
+ }
+
+ smp_nap();
+}
+
+/*
+ * Bring a secondary processor online.
+ */
+void __cpuinit online_secondary(void)
+{
+ /*
+ * low-memory mappings have been cleared, flush them from
+ * the local TLBs too.
+ */
+ local_flush_tlb();
+
+ BUG_ON(in_interrupt());
+
+ /* This must be done before setting cpu_online_mask */
+ wmb();
+
+ /*
+ * We need to hold call_lock, so there is no inconsistency
+ * between the time smp_call_function() determines number of
+ * IPI recipients, and the time when the determination is made
+ * for which cpus receive the IPI. Holding this
+ * lock helps us to not include this cpu in a currently in progress
+ * smp_call_function().
+ */
+ ipi_call_lock();
+ set_cpu_online(smp_processor_id(), 1);
+ ipi_call_unlock();
+ __get_cpu_var(cpu_state) = CPU_ONLINE;
+
+ /* Set up tile-specific state for this cpu. */
+ setup_cpu(0);
+
+ /* Set up tile-timer clock-event device on this cpu */
+ setup_tile_timer();
+
+ preempt_enable();
+
+ cpu_idle();
+}
+
+int __cpuinit __cpu_up(unsigned int cpu)
+{
+ /* Wait 5s total for all CPUs for them to come online */
+ static int timeout;
+ for (; !cpumask_test_cpu(cpu, &cpu_started); timeout++) {
+ if (timeout >= 50000) {
+ pr_info("skipping unresponsive cpu%d\n", cpu);
+ local_irq_enable();
+ return -EIO;
+ }
+ udelay(100);
+ }
+
+ local_irq_enable();
+ per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
+
+ /* Unleash the CPU! */
+ send_IPI_single(cpu, MSG_TAG_START_CPU);
+ while (!cpumask_test_cpu(cpu, cpu_online_mask))
+ cpu_relax();
+ return 0;
+}
+
+static void panic_start_cpu(void)
+{
+ panic("Received a MSG_START_CPU IPI after boot finished.");
+}
+
+void __init smp_cpus_done(unsigned int max_cpus)
+{
+ int cpu, next, rc;
+
+ /* Reset the response to a (now illegal) MSG_START_CPU IPI. */
+ start_cpu_function_addr = (unsigned long) &panic_start_cpu;
+
+ cpumask_copy(&init_affinity, cpu_online_mask);
+
+ /*
+ * Pin ourselves to a single cpu in the initial affinity set
+ * so that kernel mappings for the rootfs are not in the dataplane,
+ * if set, and to avoid unnecessary migrating during bringup.
+ * Use the last cpu just in case the whole chip has been
+ * isolated from the scheduler, to keep init away from likely
+ * more useful user code. This also ensures that work scheduled
+ * via schedule_delayed_work() in the init routines will land
+ * on this cpu.
+ */
+ for (cpu = cpumask_first(&init_affinity);
+ (next = cpumask_next(cpu, &init_affinity)) < nr_cpu_ids;
+ cpu = next)
+ ;
+ rc = sched_setaffinity(current->pid, cpumask_of(cpu));
+ if (rc != 0)
+ pr_err("Couldn't set init affinity to cpu %d (%d)\n", cpu, rc);
+}
diff --git a/arch/tile/kernel/stack.c b/arch/tile/kernel/stack.c
new file mode 100644
index 000000000000..b6268d3ae869
--- /dev/null
+++ b/arch/tile/kernel/stack.c
@@ -0,0 +1,486 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/pfn.h>
+#include <linux/kallsyms.h>
+#include <linux/stacktrace.h>
+#include <linux/uaccess.h>
+#include <linux/mmzone.h>
+#include <asm/backtrace.h>
+#include <asm/page.h>
+#include <asm/tlbflush.h>
+#include <asm/ucontext.h>
+#include <asm/sigframe.h>
+#include <asm/stack.h>
+#include <arch/abi.h>
+#include <arch/interrupts.h>
+
+
+/* Is address on the specified kernel stack? */
+static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
+{
+ ulong kstack_base = (ulong) kbt->task->stack;
+ if (kstack_base == 0) /* corrupt task pointer; just follow stack... */
+ return sp >= PAGE_OFFSET && sp < (unsigned long)high_memory;
+ return sp >= kstack_base && sp < kstack_base + THREAD_SIZE;
+}
+
+/* Is address in the specified kernel code? */
+static int in_kernel_text(VirtualAddress address)
+{
+ return (address >= MEM_SV_INTRPT &&
+ address < MEM_SV_INTRPT + HPAGE_SIZE);
+}
+
+/* Is address valid for reading? */
+static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
+{
+ HV_PTE *l1_pgtable = kbt->pgtable;
+ HV_PTE *l2_pgtable;
+ unsigned long pfn;
+ HV_PTE pte;
+ struct page *page;
+
+ if (l1_pgtable == NULL)
+ return 0; /* can't read user space in other tasks */
+
+ pte = l1_pgtable[HV_L1_INDEX(address)];
+ if (!hv_pte_get_present(pte))
+ return 0;
+ pfn = hv_pte_get_pfn(pte);
+ if (pte_huge(pte)) {
+ if (!pfn_valid(pfn)) {
+ pr_err("huge page has bad pfn %#lx\n", pfn);
+ return 0;
+ }
+ return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
+ }
+
+ page = pfn_to_page(pfn);
+ if (PageHighMem(page)) {
+ pr_err("L2 page table not in LOWMEM (%#llx)\n",
+ HV_PFN_TO_CPA(pfn));
+ return 0;
+ }
+ l2_pgtable = (HV_PTE *)pfn_to_kaddr(pfn);
+ pte = l2_pgtable[HV_L2_INDEX(address)];
+ return hv_pte_get_present(pte) && hv_pte_get_readable(pte);
+}
+
+/* Callback for backtracer; basically a glorified memcpy */
+static bool read_memory_func(void *result, VirtualAddress address,
+ unsigned int size, void *vkbt)
+{
+ int retval;
+ struct KBacktraceIterator *kbt = (struct KBacktraceIterator *)vkbt;
+ if (in_kernel_text(address)) {
+ /* OK to read kernel code. */
+ } else if (address >= PAGE_OFFSET) {
+ /* We only tolerate kernel-space reads of this task's stack */
+ if (!in_kernel_stack(kbt, address))
+ return 0;
+ } else if (!valid_address(kbt, address)) {
+ return 0; /* invalid user-space address */
+ }
+ pagefault_disable();
+ retval = __copy_from_user_inatomic(result,
+ (void __user __force *)address,
+ size);
+ pagefault_enable();
+ return (retval == 0);
+}
+
+/* Return a pt_regs pointer for a valid fault handler frame */
+static struct pt_regs *valid_fault_handler(struct KBacktraceIterator* kbt)
+{
+#ifndef __tilegx__
+ const char *fault = NULL; /* happy compiler */
+ char fault_buf[64];
+ VirtualAddress sp = kbt->it.sp;
+ struct pt_regs *p;
+
+ if (!in_kernel_stack(kbt, sp))
+ return NULL;
+ if (!in_kernel_stack(kbt, sp + C_ABI_SAVE_AREA_SIZE + PTREGS_SIZE-1))
+ return NULL;
+ p = (struct pt_regs *)(sp + C_ABI_SAVE_AREA_SIZE);
+ if (p->faultnum == INT_SWINT_1 || p->faultnum == INT_SWINT_1_SIGRETURN)
+ fault = "syscall";
+ else {
+ if (kbt->verbose) { /* else we aren't going to use it */
+ snprintf(fault_buf, sizeof(fault_buf),
+ "interrupt %ld", p->faultnum);
+ fault = fault_buf;
+ }
+ }
+ if (EX1_PL(p->ex1) == KERNEL_PL &&
+ in_kernel_text(p->pc) &&
+ in_kernel_stack(kbt, p->sp) &&
+ p->sp >= sp) {
+ if (kbt->verbose)
+ pr_err(" <%s while in kernel mode>\n", fault);
+ } else if (EX1_PL(p->ex1) == USER_PL &&
+ p->pc < PAGE_OFFSET &&
+ p->sp < PAGE_OFFSET) {
+ if (kbt->verbose)
+ pr_err(" <%s while in user mode>\n", fault);
+ } else if (kbt->verbose) {
+ pr_err(" (odd fault: pc %#lx, sp %#lx, ex1 %#lx?)\n",
+ p->pc, p->sp, p->ex1);
+ p = NULL;
+ }
+ if (!kbt->profile || (INT_MASK(p->faultnum) & QUEUED_INTERRUPTS) == 0)
+ return p;
+#endif
+ return NULL;
+}
+
+/* Is the pc pointing to a sigreturn trampoline? */
+static int is_sigreturn(VirtualAddress pc)
+{
+ return (pc == VDSO_BASE);
+}
+
+/* Return a pt_regs pointer for a valid signal handler frame */
+static struct pt_regs *valid_sigframe(struct KBacktraceIterator* kbt)
+{
+ BacktraceIterator *b = &kbt->it;
+
+ if (b->pc == VDSO_BASE) {
+ struct rt_sigframe *frame;
+ unsigned long sigframe_top =
+ b->sp + sizeof(struct rt_sigframe) - 1;
+ if (!valid_address(kbt, b->sp) ||
+ !valid_address(kbt, sigframe_top)) {
+ if (kbt->verbose)
+ pr_err(" (odd signal: sp %#lx?)\n",
+ (unsigned long)(b->sp));
+ return NULL;
+ }
+ frame = (struct rt_sigframe *)b->sp;
+ if (kbt->verbose) {
+ pr_err(" <received signal %d>\n",
+ frame->info.si_signo);
+ }
+ return &frame->uc.uc_mcontext.regs;
+ }
+ return NULL;
+}
+
+static int KBacktraceIterator_is_sigreturn(struct KBacktraceIterator *kbt)
+{
+ return is_sigreturn(kbt->it.pc);
+}
+
+static int KBacktraceIterator_restart(struct KBacktraceIterator *kbt)
+{
+ struct pt_regs *p;
+
+ p = valid_fault_handler(kbt);
+ if (p == NULL)
+ p = valid_sigframe(kbt);
+ if (p == NULL)
+ return 0;
+ backtrace_init(&kbt->it, read_memory_func, kbt,
+ p->pc, p->lr, p->sp, p->regs[52]);
+ kbt->new_context = 1;
+ return 1;
+}
+
+/* Find a frame that isn't a sigreturn, if there is one. */
+static int KBacktraceIterator_next_item_inclusive(
+ struct KBacktraceIterator *kbt)
+{
+ for (;;) {
+ do {
+ if (!KBacktraceIterator_is_sigreturn(kbt))
+ return 1;
+ } while (backtrace_next(&kbt->it));
+
+ if (!KBacktraceIterator_restart(kbt))
+ return 0;
+ }
+}
+
+/*
+ * If the current sp is on a page different than what we recorded
+ * as the top-of-kernel-stack last time we context switched, we have
+ * probably blown the stack, and nothing is going to work out well.
+ * If we can at least get out a warning, that may help the debug,
+ * though we probably won't be able to backtrace into the code that
+ * actually did the recursive damage.
+ */
+static void validate_stack(struct pt_regs *regs)
+{
+ int cpu = smp_processor_id();
+ unsigned long ksp0 = get_current_ksp0();
+ unsigned long ksp0_base = ksp0 - THREAD_SIZE;
+ unsigned long sp = stack_pointer;
+
+ if (EX1_PL(regs->ex1) == KERNEL_PL && regs->sp >= ksp0) {
+ pr_err("WARNING: cpu %d: kernel stack page %#lx underrun!\n"
+ " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
+ cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
+ }
+
+ else if (sp < ksp0_base + sizeof(struct thread_info)) {
+ pr_err("WARNING: cpu %d: kernel stack page %#lx overrun!\n"
+ " sp %#lx (%#lx in caller), caller pc %#lx, lr %#lx\n",
+ cpu, ksp0_base, sp, regs->sp, regs->pc, regs->lr);
+ }
+}
+
+void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
+ struct task_struct *t, struct pt_regs *regs)
+{
+ VirtualAddress pc, lr, sp, r52;
+ int is_current;
+
+ /*
+ * Set up callback information. We grab the kernel stack base
+ * so we will allow reads of that address range, and if we're
+ * asking about the current process we grab the page table
+ * so we can check user accesses before trying to read them.
+ * We flush the TLB to avoid any weird skew issues.
+ */
+ is_current = (t == NULL);
+ kbt->is_current = is_current;
+ if (is_current)
+ t = validate_current();
+ kbt->task = t;
+ kbt->pgtable = NULL;
+ kbt->verbose = 0; /* override in caller if desired */
+ kbt->profile = 0; /* override in caller if desired */
+ kbt->end = 0;
+ kbt->new_context = 0;
+ if (is_current) {
+ HV_PhysAddr pgdir_pa = hv_inquire_context().page_table;
+ if (pgdir_pa == (unsigned long)swapper_pg_dir - PAGE_OFFSET) {
+ /*
+ * Not just an optimization: this also allows
+ * this to work at all before va/pa mappings
+ * are set up.
+ */
+ kbt->pgtable = swapper_pg_dir;
+ } else {
+ struct page *page = pfn_to_page(PFN_DOWN(pgdir_pa));
+ if (!PageHighMem(page))
+ kbt->pgtable = __va(pgdir_pa);
+ else
+ pr_err("page table not in LOWMEM"
+ " (%#llx)\n", pgdir_pa);
+ }
+ local_flush_tlb_all();
+ validate_stack(regs);
+ }
+
+ if (regs == NULL) {
+ if (is_current || t->state == TASK_RUNNING) {
+ /* Can't do this; we need registers */
+ kbt->end = 1;
+ return;
+ }
+ pc = get_switch_to_pc();
+ lr = t->thread.pc;
+ sp = t->thread.ksp;
+ r52 = 0;
+ } else {
+ pc = regs->pc;
+ lr = regs->lr;
+ sp = regs->sp;
+ r52 = regs->regs[52];
+ }
+
+ backtrace_init(&kbt->it, read_memory_func, kbt, pc, lr, sp, r52);
+ kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
+}
+EXPORT_SYMBOL(KBacktraceIterator_init);
+
+int KBacktraceIterator_end(struct KBacktraceIterator *kbt)
+{
+ return kbt->end;
+}
+EXPORT_SYMBOL(KBacktraceIterator_end);
+
+void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
+{
+ kbt->new_context = 0;
+ if (!backtrace_next(&kbt->it) &&
+ !KBacktraceIterator_restart(kbt)) {
+ kbt->end = 1;
+ return;
+ }
+
+ kbt->end = !KBacktraceIterator_next_item_inclusive(kbt);
+}
+EXPORT_SYMBOL(KBacktraceIterator_next);
+
+/*
+ * This method wraps the backtracer's more generic support.
+ * It is only invoked from the architecture-specific code; show_stack()
+ * and dump_stack() (in entry.S) are architecture-independent entry points.
+ */
+void tile_show_stack(struct KBacktraceIterator *kbt, int headers)
+{
+ int i;
+
+ if (headers) {
+ /*
+ * Add a blank line since if we are called from panic(),
+ * then bust_spinlocks() spit out a space in front of us
+ * and it will mess up our KERN_ERR.
+ */
+ pr_err("\n");
+ pr_err("Starting stack dump of tid %d, pid %d (%s)"
+ " on cpu %d at cycle %lld\n",
+ kbt->task->pid, kbt->task->tgid, kbt->task->comm,
+ smp_processor_id(), get_cycles());
+ }
+#ifdef __tilegx__
+ if (kbt->is_current) {
+ __insn_mtspr(SPR_SIM_CONTROL,
+ SIM_DUMP_SPR_ARG(SIM_DUMP_BACKTRACE));
+ }
+#endif
+ kbt->verbose = 1;
+ i = 0;
+ for (; !KBacktraceIterator_end(kbt); KBacktraceIterator_next(kbt)) {
+ char *modname;
+ const char *name;
+ unsigned long address = kbt->it.pc;
+ unsigned long offset, size;
+ char namebuf[KSYM_NAME_LEN+100];
+
+ if (address >= PAGE_OFFSET)
+ name = kallsyms_lookup(address, &size, &offset,
+ &modname, namebuf);
+ else
+ name = NULL;
+
+ if (!name)
+ namebuf[0] = '\0';
+ else {
+ size_t namelen = strlen(namebuf);
+ size_t remaining = (sizeof(namebuf) - 1) - namelen;
+ char *p = namebuf + namelen;
+ int rc = snprintf(p, remaining, "+%#lx/%#lx ",
+ offset, size);
+ if (modname && rc < remaining)
+ snprintf(p + rc, remaining - rc,
+ "[%s] ", modname);
+ namebuf[sizeof(namebuf)-1] = '\0';
+ }
+
+ pr_err(" frame %d: 0x%lx %s(sp 0x%lx)\n",
+ i++, address, namebuf, (unsigned long)(kbt->it.sp));
+
+ if (i >= 100) {
+ pr_err("Stack dump truncated"
+ " (%d frames)\n", i);
+ break;
+ }
+ }
+ if (headers)
+ pr_err("Stack dump complete\n");
+}
+EXPORT_SYMBOL(tile_show_stack);
+
+
+/* This is called from show_regs() and _dump_stack() */
+void dump_stack_regs(struct pt_regs *regs)
+{
+ struct KBacktraceIterator kbt;
+ KBacktraceIterator_init(&kbt, NULL, regs);
+ tile_show_stack(&kbt, 1);
+}
+EXPORT_SYMBOL(dump_stack_regs);
+
+static struct pt_regs *regs_to_pt_regs(struct pt_regs *regs,
+ ulong pc, ulong lr, ulong sp, ulong r52)
+{
+ memset(regs, 0, sizeof(struct pt_regs));
+ regs->pc = pc;
+ regs->lr = lr;
+ regs->sp = sp;
+ regs->regs[52] = r52;
+ return regs;
+}
+
+/* This is called from dump_stack() and just converts to pt_regs */
+void _dump_stack(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
+{
+ struct pt_regs regs;
+ dump_stack_regs(regs_to_pt_regs(&regs, pc, lr, sp, r52));
+}
+
+/* This is called from KBacktraceIterator_init_current() */
+void _KBacktraceIterator_init_current(struct KBacktraceIterator *kbt, ulong pc,
+ ulong lr, ulong sp, ulong r52)
+{
+ struct pt_regs regs;
+ KBacktraceIterator_init(kbt, NULL,
+ regs_to_pt_regs(&regs, pc, lr, sp, r52));
+}
+
+/* This is called only from kernel/sched.c, with esp == NULL */
+void show_stack(struct task_struct *task, unsigned long *esp)
+{
+ struct KBacktraceIterator kbt;
+ if (task == NULL || task == current)
+ KBacktraceIterator_init_current(&kbt);
+ else
+ KBacktraceIterator_init(&kbt, task, NULL);
+ tile_show_stack(&kbt, 0);
+}
+
+#ifdef CONFIG_STACKTRACE
+
+/* Support generic Linux stack API too */
+
+void save_stack_trace_tsk(struct task_struct *task, struct stack_trace *trace)
+{
+ struct KBacktraceIterator kbt;
+ int skip = trace->skip;
+ int i = 0;
+
+ if (task == NULL || task == current)
+ KBacktraceIterator_init_current(&kbt);
+ else
+ KBacktraceIterator_init(&kbt, task, NULL);
+ for (; !KBacktraceIterator_end(&kbt); KBacktraceIterator_next(&kbt)) {
+ if (skip) {
+ --skip;
+ continue;
+ }
+ if (i >= trace->max_entries || kbt.it.pc < PAGE_OFFSET)
+ break;
+ trace->entries[i++] = kbt.it.pc;
+ }
+ trace->nr_entries = i;
+}
+EXPORT_SYMBOL(save_stack_trace_tsk);
+
+void save_stack_trace(struct stack_trace *trace)
+{
+ save_stack_trace_tsk(NULL, trace);
+}
+
+#endif
+
+/* In entry.S */
+EXPORT_SYMBOL(KBacktraceIterator_init_current);
diff --git a/arch/tile/kernel/sys.c b/arch/tile/kernel/sys.c
new file mode 100644
index 000000000000..f0f87eab8c39
--- /dev/null
+++ b/arch/tile/kernel/sys.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/TILE
+ * platform.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/mempolicy.h>
+#include <linux/binfmts.h>
+#include <linux/fs.h>
+#include <linux/compat.h>
+#include <linux/uaccess.h>
+#include <linux/signal.h>
+#include <asm/syscalls.h>
+#include <asm/pgtable.h>
+#include <asm/homecache.h>
+#include <arch/chip.h>
+
+SYSCALL_DEFINE0(flush_cache)
+{
+ homecache_evict(cpumask_of(smp_processor_id()));
+ return 0;
+}
+
+/*
+ * Syscalls that pass 64-bit values on 32-bit systems normally
+ * pass them as (low,high) word packed into the immediately adjacent
+ * registers. If the low word naturally falls on an even register,
+ * our ABI makes it work correctly; if not, we adjust it here.
+ * Handling it here means we don't have to fix uclibc AND glibc AND
+ * any other standard libcs we want to support.
+ */
+
+#if !defined(__tilegx__) || defined(CONFIG_COMPAT)
+
+ssize_t sys32_readahead(int fd, u32 offset_lo, u32 offset_hi, u32 count)
+{
+ return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count);
+}
+
+long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len, int advice)
+{
+ return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
+ len, advice);
+}
+
+int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi, int advice)
+{
+ return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
+ ((loff_t)len_hi << 32) | len_lo, advice);
+}
+
+#endif /* 32-bit syscall wrappers */
+
+/* Note: used by the compat code even in 64-bit Linux. */
+SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, unsigned long, off_4k)
+{
+#define PAGE_ADJUST (PAGE_SHIFT - 12)
+ if (off_4k & ((1 << PAGE_ADJUST) - 1))
+ return -EINVAL;
+ return sys_mmap_pgoff(addr, len, prot, flags, fd,
+ off_4k >> PAGE_ADJUST);
+}
+
+#ifdef __tilegx__
+SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
+ unsigned long, prot, unsigned long, flags,
+ unsigned long, fd, off_t, offset)
+{
+ if (offset & ((1 << PAGE_SHIFT) - 1))
+ return -EINVAL;
+ return sys_mmap_pgoff(addr, len, prot, flags, fd,
+ offset >> PAGE_SHIFT);
+}
+#endif
+
+
+/* Provide the actual syscall number to call mapping. */
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+#ifndef __tilegx__
+/* See comments at the top of the file. */
+#define sys_fadvise64 sys32_fadvise64
+#define sys_fadvise64_64 sys32_fadvise64_64
+#define sys_readahead sys32_readahead
+#define sys_sync_file_range sys_sync_file_range2
+#endif
+
+/*
+ * Note that we can't include <linux/unistd.h> here since the header
+ * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
+ */
+void *sys_call_table[__NR_syscalls] = {
+ [0 ... __NR_syscalls-1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
diff --git a/arch/tile/kernel/tile-desc_32.c b/arch/tile/kernel/tile-desc_32.c
new file mode 100644
index 000000000000..69af0e150f78
--- /dev/null
+++ b/arch/tile/kernel/tile-desc_32.c
@@ -0,0 +1,2498 @@
+/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
+#define BFD_RELOC(x) -1
+
+/* Special registers. */
+#define TREG_LR 55
+#define TREG_SN 56
+#define TREG_ZERO 63
+
+/* FIXME: Rename this. */
+#include <asm/opcode-tile.h>
+
+#include <linux/stddef.h>
+
+const struct tile_opcode tile_opcodes[395] =
+{
+ { "bpt", TILE_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "info", TILE_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
+ { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
+ },
+ { "infol", TILE_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
+ { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "j", TILE_OPC_J, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jal", TILE_OPC_JAL, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 6 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "move", TILE_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 9, 10 }, { 11, 12 }, { 13, 14 }, { 0, } },
+ },
+ { "move.sn", TILE_OPC_MOVE_SN, 0x3, 2, TREG_SN, 1,
+ { { 7, 8 }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "movei", TILE_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
+ { { 7, 0 }, { 9, 1 }, { 11, 2 }, { 13, 3 }, { 0, } },
+ },
+ { "movei.sn", TILE_OPC_MOVEI_SN, 0x3, 2, TREG_SN, 1,
+ { { 7, 0 }, { 9, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "moveli", TILE_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
+ { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "moveli.sn", TILE_OPC_MOVELI_SN, 0x3, 2, TREG_SN, 1,
+ { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "movelis", TILE_OPC_MOVELIS, 0x3, 2, TREG_SN, 1,
+ { { 7, 4 }, { 9, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "prefetch", TILE_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 15 } },
+ },
+ { "raise", TILE_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "add", TILE_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "add.sn", TILE_OPC_ADD_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addb", TILE_OPC_ADDB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addb.sn", TILE_OPC_ADDB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addbs_u", TILE_OPC_ADDBS_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addbs_u.sn", TILE_OPC_ADDBS_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addh", TILE_OPC_ADDH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addh.sn", TILE_OPC_ADDH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addhs", TILE_OPC_ADDHS, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addhs.sn", TILE_OPC_ADDHS_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addi", TILE_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "addi.sn", TILE_OPC_ADDI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addib", TILE_OPC_ADDIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addib.sn", TILE_OPC_ADDIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addih", TILE_OPC_ADDIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addih.sn", TILE_OPC_ADDIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addli", TILE_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addli.sn", TILE_OPC_ADDLI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "addlis", TILE_OPC_ADDLIS, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adds", TILE_OPC_ADDS, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adds.sn", TILE_OPC_ADDS_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adiffb_u", TILE_OPC_ADIFFB_U, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adiffb_u.sn", TILE_OPC_ADIFFB_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adiffh", TILE_OPC_ADIFFH, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "adiffh.sn", TILE_OPC_ADIFFH_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "and", TILE_OPC_AND, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "and.sn", TILE_OPC_AND_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "andi", TILE_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "andi.sn", TILE_OPC_ANDI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "auli", TILE_OPC_AULI, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 4 }, { 9, 10, 5 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "avgb_u", TILE_OPC_AVGB_U, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "avgb_u.sn", TILE_OPC_AVGB_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "avgh", TILE_OPC_AVGH, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "avgh.sn", TILE_OPC_AVGH_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbns", TILE_OPC_BBNS, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbns.sn", TILE_OPC_BBNS_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbnst", TILE_OPC_BBNST, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbnst.sn", TILE_OPC_BBNST_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbs", TILE_OPC_BBS, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbs.sn", TILE_OPC_BBS_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbst", TILE_OPC_BBST, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bbst.sn", TILE_OPC_BBST_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgez", TILE_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgez.sn", TILE_OPC_BGEZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgezt", TILE_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgezt.sn", TILE_OPC_BGEZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgz", TILE_OPC_BGZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgz.sn", TILE_OPC_BGZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgzt", TILE_OPC_BGZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bgzt.sn", TILE_OPC_BGZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bitx", TILE_OPC_BITX, 0x5, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
+ },
+ { "bitx.sn", TILE_OPC_BITX_SN, 0x1, 2, TREG_SN, 1,
+ { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blez", TILE_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blez.sn", TILE_OPC_BLEZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blezt", TILE_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blezt.sn", TILE_OPC_BLEZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blz", TILE_OPC_BLZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blz.sn", TILE_OPC_BLZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blzt", TILE_OPC_BLZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "blzt.sn", TILE_OPC_BLZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bnz", TILE_OPC_BNZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bnz.sn", TILE_OPC_BNZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bnzt", TILE_OPC_BNZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bnzt.sn", TILE_OPC_BNZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bytex", TILE_OPC_BYTEX, 0x5, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
+ },
+ { "bytex.sn", TILE_OPC_BYTEX_SN, 0x1, 2, TREG_SN, 1,
+ { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bz", TILE_OPC_BZ, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bz.sn", TILE_OPC_BZ_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bzt", TILE_OPC_BZT, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "bzt.sn", TILE_OPC_BZT_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 10, 20 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "clz", TILE_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
+ },
+ { "clz.sn", TILE_OPC_CLZ_SN, 0x1, 2, TREG_SN, 1,
+ { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "crc32_32", TILE_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "crc32_32.sn", TILE_OPC_CRC32_32_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "crc32_8", TILE_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "crc32_8.sn", TILE_OPC_CRC32_8_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "ctz", TILE_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
+ },
+ { "ctz.sn", TILE_OPC_CTZ_SN, 0x1, 2, TREG_SN, 1,
+ { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "drain", TILE_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "dtlbpr", TILE_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "dword_align", TILE_OPC_DWORD_ALIGN, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "dword_align.sn", TILE_OPC_DWORD_ALIGN_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "finv", TILE_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "flush", TILE_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "fnop", TILE_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
+ { { }, { }, { }, { }, { 0, } },
+ },
+ { "icoh", TILE_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "ill", TILE_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { }, { 0, } },
+ },
+ { "inthb", TILE_OPC_INTHB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "inthb.sn", TILE_OPC_INTHB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "inthh", TILE_OPC_INTHH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "inthh.sn", TILE_OPC_INTHH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "intlb", TILE_OPC_INTLB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "intlb.sn", TILE_OPC_INTLB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "intlh", TILE_OPC_INTLH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "intlh.sn", TILE_OPC_INTLH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "inv", TILE_OPC_INV, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "iret", TILE_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jalb", TILE_OPC_JALB, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jalf", TILE_OPC_JALF, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jalr", TILE_OPC_JALR, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jalrp", TILE_OPC_JALRP, 0x2, 1, TREG_LR, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jb", TILE_OPC_JB, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jf", TILE_OPC_JF, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 22 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jr", TILE_OPC_JR, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "jrp", TILE_OPC_JRP, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lb", TILE_OPC_LB, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
+ },
+ { "lb.sn", TILE_OPC_LB_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lb_u", TILE_OPC_LB_U, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
+ },
+ { "lb_u.sn", TILE_OPC_LB_U_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lbadd", TILE_OPC_LBADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lbadd.sn", TILE_OPC_LBADD_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lbadd_u", TILE_OPC_LBADD_U, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lbadd_u.sn", TILE_OPC_LBADD_U_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lh", TILE_OPC_LH, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
+ },
+ { "lh.sn", TILE_OPC_LH_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lh_u", TILE_OPC_LH_U, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
+ },
+ { "lh_u.sn", TILE_OPC_LH_U_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lhadd", TILE_OPC_LHADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lhadd.sn", TILE_OPC_LHADD_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lhadd_u", TILE_OPC_LHADD_U, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lhadd_u.sn", TILE_OPC_LHADD_U_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lnk", TILE_OPC_LNK, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lnk.sn", TILE_OPC_LNK_SN, 0x2, 1, TREG_SN, 1,
+ { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lw", TILE_OPC_LW, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 23, 15 } },
+ },
+ { "lw.sn", TILE_OPC_LW_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lw_na", TILE_OPC_LW_NA, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lw_na.sn", TILE_OPC_LW_NA_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lwadd", TILE_OPC_LWADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lwadd.sn", TILE_OPC_LWADD_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lwadd_na", TILE_OPC_LWADD_NA, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "lwadd_na.sn", TILE_OPC_LWADD_NA_SN, 0x2, 3, TREG_SN, 1,
+ { { 0, }, { 9, 24, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxb_u", TILE_OPC_MAXB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxb_u.sn", TILE_OPC_MAXB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxh", TILE_OPC_MAXH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxh.sn", TILE_OPC_MAXH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxib_u", TILE_OPC_MAXIB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxib_u.sn", TILE_OPC_MAXIB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxih", TILE_OPC_MAXIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "maxih.sn", TILE_OPC_MAXIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mf", TILE_OPC_MF, 0x2, 0, TREG_ZERO, 1,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mfspr", TILE_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 25 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minb_u", TILE_OPC_MINB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minb_u.sn", TILE_OPC_MINB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minh", TILE_OPC_MINH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minh.sn", TILE_OPC_MINH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minib_u", TILE_OPC_MINIB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minib_u.sn", TILE_OPC_MINIB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minih", TILE_OPC_MINIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "minih.sn", TILE_OPC_MINIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mm", TILE_OPC_MM, 0x3, 5, TREG_ZERO, 1,
+ { { 7, 8, 16, 26, 27 }, { 9, 10, 17, 28, 29 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mnz", TILE_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "mnz.sn", TILE_OPC_MNZ_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mnzb", TILE_OPC_MNZB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mnzb.sn", TILE_OPC_MNZB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mnzh", TILE_OPC_MNZH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mnzh.sn", TILE_OPC_MNZH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mtspr", TILE_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 30, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhh_ss", TILE_OPC_MULHH_SS, 0x5, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulhh_ss.sn", TILE_OPC_MULHH_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhh_su", TILE_OPC_MULHH_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhh_su.sn", TILE_OPC_MULHH_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhh_uu", TILE_OPC_MULHH_UU, 0x5, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulhh_uu.sn", TILE_OPC_MULHH_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhha_ss", TILE_OPC_MULHHA_SS, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulhha_ss.sn", TILE_OPC_MULHHA_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhha_su", TILE_OPC_MULHHA_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhha_su.sn", TILE_OPC_MULHHA_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhha_uu", TILE_OPC_MULHHA_UU, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulhha_uu.sn", TILE_OPC_MULHHA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhhsa_uu", TILE_OPC_MULHHSA_UU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhhsa_uu.sn", TILE_OPC_MULHHSA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_ss", TILE_OPC_MULHL_SS, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_ss.sn", TILE_OPC_MULHL_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_su", TILE_OPC_MULHL_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_su.sn", TILE_OPC_MULHL_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_us", TILE_OPC_MULHL_US, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_us.sn", TILE_OPC_MULHL_US_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_uu", TILE_OPC_MULHL_UU, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhl_uu.sn", TILE_OPC_MULHL_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_ss", TILE_OPC_MULHLA_SS, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_ss.sn", TILE_OPC_MULHLA_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_su", TILE_OPC_MULHLA_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_su.sn", TILE_OPC_MULHLA_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_us", TILE_OPC_MULHLA_US, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_us.sn", TILE_OPC_MULHLA_US_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_uu", TILE_OPC_MULHLA_UU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhla_uu.sn", TILE_OPC_MULHLA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulhlsa_uu", TILE_OPC_MULHLSA_UU, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulhlsa_uu.sn", TILE_OPC_MULHLSA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulll_ss", TILE_OPC_MULLL_SS, 0x5, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulll_ss.sn", TILE_OPC_MULLL_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulll_su", TILE_OPC_MULLL_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulll_su.sn", TILE_OPC_MULLL_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulll_uu", TILE_OPC_MULLL_UU, 0x5, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 11, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mulll_uu.sn", TILE_OPC_MULLL_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mullla_ss", TILE_OPC_MULLLA_SS, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mullla_ss.sn", TILE_OPC_MULLLA_SS_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mullla_su", TILE_OPC_MULLLA_SU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mullla_su.sn", TILE_OPC_MULLLA_SU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mullla_uu", TILE_OPC_MULLLA_UU, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mullla_uu.sn", TILE_OPC_MULLLA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulllsa_uu", TILE_OPC_MULLLSA_UU, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mulllsa_uu.sn", TILE_OPC_MULLLSA_UU_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mvnz", TILE_OPC_MVNZ, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mvnz.sn", TILE_OPC_MVNZ_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mvz", TILE_OPC_MVZ, 0x5, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 31, 12, 18 }, { 0, }, { 0, } },
+ },
+ { "mvz.sn", TILE_OPC_MVZ_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mz", TILE_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "mz.sn", TILE_OPC_MZ_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mzb", TILE_OPC_MZB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mzb.sn", TILE_OPC_MZB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mzh", TILE_OPC_MZH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "mzh.sn", TILE_OPC_MZH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "nap", TILE_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "nop", TILE_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
+ { { }, { }, { }, { }, { 0, } },
+ },
+ { "nor", TILE_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "nor.sn", TILE_OPC_NOR_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "or", TILE_OPC_OR, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "or.sn", TILE_OPC_OR_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "ori", TILE_OPC_ORI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "ori.sn", TILE_OPC_ORI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packbs_u", TILE_OPC_PACKBS_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packbs_u.sn", TILE_OPC_PACKBS_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packhb", TILE_OPC_PACKHB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packhb.sn", TILE_OPC_PACKHB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packhs", TILE_OPC_PACKHS, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packhs.sn", TILE_OPC_PACKHS_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packlb", TILE_OPC_PACKLB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "packlb.sn", TILE_OPC_PACKLB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "pcnt", TILE_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
+ { { 7, 8 }, { 0, }, { 11, 12 }, { 0, }, { 0, } },
+ },
+ { "pcnt.sn", TILE_OPC_PCNT_SN, 0x1, 2, TREG_SN, 1,
+ { { 7, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "rl", TILE_OPC_RL, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "rl.sn", TILE_OPC_RL_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "rli", TILE_OPC_RLI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
+ },
+ { "rli.sn", TILE_OPC_RLI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "s1a", TILE_OPC_S1A, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "s1a.sn", TILE_OPC_S1A_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "s2a", TILE_OPC_S2A, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "s2a.sn", TILE_OPC_S2A_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "s3a", TILE_OPC_S3A, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "s3a.sn", TILE_OPC_S3A_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadab_u", TILE_OPC_SADAB_U, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadab_u.sn", TILE_OPC_SADAB_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadah", TILE_OPC_SADAH, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadah.sn", TILE_OPC_SADAH_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadah_u", TILE_OPC_SADAH_U, 0x1, 3, TREG_ZERO, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadah_u.sn", TILE_OPC_SADAH_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 21, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadb_u", TILE_OPC_SADB_U, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadb_u.sn", TILE_OPC_SADB_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadh", TILE_OPC_SADH, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadh.sn", TILE_OPC_SADH_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadh_u", TILE_OPC_SADH_U, 0x1, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sadh_u.sn", TILE_OPC_SADH_U_SN, 0x1, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sb", TILE_OPC_SB, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
+ },
+ { "sbadd", TILE_OPC_SBADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seq", TILE_OPC_SEQ, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "seq.sn", TILE_OPC_SEQ_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqb", TILE_OPC_SEQB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqb.sn", TILE_OPC_SEQB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqh", TILE_OPC_SEQH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqh.sn", TILE_OPC_SEQH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqi", TILE_OPC_SEQI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "seqi.sn", TILE_OPC_SEQI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqib", TILE_OPC_SEQIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqib.sn", TILE_OPC_SEQIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqih", TILE_OPC_SEQIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "seqih.sn", TILE_OPC_SEQIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sh", TILE_OPC_SH, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
+ },
+ { "shadd", TILE_OPC_SHADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shl", TILE_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "shl.sn", TILE_OPC_SHL_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlb", TILE_OPC_SHLB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlb.sn", TILE_OPC_SHLB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlh", TILE_OPC_SHLH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlh.sn", TILE_OPC_SHLH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shli", TILE_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
+ },
+ { "shli.sn", TILE_OPC_SHLI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlib", TILE_OPC_SHLIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlib.sn", TILE_OPC_SHLIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlih", TILE_OPC_SHLIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shlih.sn", TILE_OPC_SHLIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shr", TILE_OPC_SHR, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "shr.sn", TILE_OPC_SHR_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrb", TILE_OPC_SHRB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrb.sn", TILE_OPC_SHRB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrh", TILE_OPC_SHRH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrh.sn", TILE_OPC_SHRH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shri", TILE_OPC_SHRI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
+ },
+ { "shri.sn", TILE_OPC_SHRI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrib", TILE_OPC_SHRIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrib.sn", TILE_OPC_SHRIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrih", TILE_OPC_SHRIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "shrih.sn", TILE_OPC_SHRIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slt", TILE_OPC_SLT, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "slt.sn", TILE_OPC_SLT_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slt_u", TILE_OPC_SLT_U, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "slt_u.sn", TILE_OPC_SLT_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltb", TILE_OPC_SLTB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltb.sn", TILE_OPC_SLTB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltb_u", TILE_OPC_SLTB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltb_u.sn", TILE_OPC_SLTB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slte", TILE_OPC_SLTE, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "slte.sn", TILE_OPC_SLTE_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slte_u", TILE_OPC_SLTE_U, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "slte_u.sn", TILE_OPC_SLTE_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteb", TILE_OPC_SLTEB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteb.sn", TILE_OPC_SLTEB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteb_u", TILE_OPC_SLTEB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteb_u.sn", TILE_OPC_SLTEB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteh", TILE_OPC_SLTEH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteh.sn", TILE_OPC_SLTEH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteh_u", TILE_OPC_SLTEH_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slteh_u.sn", TILE_OPC_SLTEH_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slth", TILE_OPC_SLTH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slth.sn", TILE_OPC_SLTH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slth_u", TILE_OPC_SLTH_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slth_u.sn", TILE_OPC_SLTH_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slti", TILE_OPC_SLTI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "slti.sn", TILE_OPC_SLTI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "slti_u", TILE_OPC_SLTI_U, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 11, 12, 2 }, { 13, 14, 3 }, { 0, } },
+ },
+ { "slti_u.sn", TILE_OPC_SLTI_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltib", TILE_OPC_SLTIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltib.sn", TILE_OPC_SLTIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltib_u", TILE_OPC_SLTIB_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltib_u.sn", TILE_OPC_SLTIB_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltih", TILE_OPC_SLTIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltih.sn", TILE_OPC_SLTIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltih_u", TILE_OPC_SLTIH_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sltih_u.sn", TILE_OPC_SLTIH_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sne", TILE_OPC_SNE, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "sne.sn", TILE_OPC_SNE_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sneb", TILE_OPC_SNEB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sneb.sn", TILE_OPC_SNEB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sneh", TILE_OPC_SNEH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sneh.sn", TILE_OPC_SNEH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sra", TILE_OPC_SRA, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "sra.sn", TILE_OPC_SRA_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "srab", TILE_OPC_SRAB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "srab.sn", TILE_OPC_SRAB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "srah", TILE_OPC_SRAH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "srah.sn", TILE_OPC_SRAH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "srai", TILE_OPC_SRAI, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 11, 12, 34 }, { 13, 14, 35 }, { 0, } },
+ },
+ { "srai.sn", TILE_OPC_SRAI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sraib", TILE_OPC_SRAIB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sraib.sn", TILE_OPC_SRAIB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sraih", TILE_OPC_SRAIH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sraih.sn", TILE_OPC_SRAIH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 32 }, { 9, 10, 33 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sub", TILE_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "sub.sn", TILE_OPC_SUB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subb", TILE_OPC_SUBB, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subb.sn", TILE_OPC_SUBB_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subbs_u", TILE_OPC_SUBBS_U, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subbs_u.sn", TILE_OPC_SUBBS_U_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subh", TILE_OPC_SUBH, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subh.sn", TILE_OPC_SUBH_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subhs", TILE_OPC_SUBHS, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subhs.sn", TILE_OPC_SUBHS_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subs", TILE_OPC_SUBS, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "subs.sn", TILE_OPC_SUBS_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "sw", TILE_OPC_SW, 0x12, 2, TREG_ZERO, 1,
+ { { 0, }, { 10, 17 }, { 0, }, { 0, }, { 15, 36 } },
+ },
+ { "swadd", TILE_OPC_SWADD, 0x2, 3, TREG_ZERO, 1,
+ { { 0, }, { 24, 17, 37 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "swint0", TILE_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "swint1", TILE_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "swint2", TILE_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "swint3", TILE_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
+ { { 0, }, { }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tblidxb0", TILE_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
+ { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
+ },
+ { "tblidxb0.sn", TILE_OPC_TBLIDXB0_SN, 0x1, 2, TREG_SN, 1,
+ { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tblidxb1", TILE_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
+ { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
+ },
+ { "tblidxb1.sn", TILE_OPC_TBLIDXB1_SN, 0x1, 2, TREG_SN, 1,
+ { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tblidxb2", TILE_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
+ { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
+ },
+ { "tblidxb2.sn", TILE_OPC_TBLIDXB2_SN, 0x1, 2, TREG_SN, 1,
+ { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tblidxb3", TILE_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
+ { { 21, 8 }, { 0, }, { 31, 12 }, { 0, }, { 0, } },
+ },
+ { "tblidxb3.sn", TILE_OPC_TBLIDXB3_SN, 0x1, 2, TREG_SN, 1,
+ { { 21, 8 }, { 0, }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tns", TILE_OPC_TNS, 0x2, 2, TREG_ZERO, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "tns.sn", TILE_OPC_TNS_SN, 0x2, 2, TREG_SN, 1,
+ { { 0, }, { 9, 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "wh64", TILE_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
+ { { 0, }, { 10 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "xor", TILE_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 11, 12, 18 }, { 13, 14, 19 }, { 0, } },
+ },
+ { "xor.sn", TILE_OPC_XOR_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 16 }, { 9, 10, 17 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "xori", TILE_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { "xori.sn", TILE_OPC_XORI_SN, 0x3, 3, TREG_SN, 1,
+ { { 7, 8, 0 }, { 9, 10, 1 }, { 0, }, { 0, }, { 0, } },
+ },
+ { NULL, TILE_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
+ }
+};
+#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
+#define CHILD(array_index) (TILE_OPC_NONE + (array_index))
+
+static const unsigned short decode_X0_fsm[1153] =
+{
+ BITFIELD(22, 9) /* index 0 */,
+ CHILD(513), CHILD(530), CHILD(547), CHILD(564), CHILD(596), CHILD(613),
+ CHILD(630), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, CHILD(663), CHILD(680), CHILD(697), CHILD(714), CHILD(746),
+ CHILD(763), CHILD(780), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813), CHILD(813),
+ CHILD(813), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828),
+ CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(828), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(873), CHILD(878), CHILD(883),
+ CHILD(903), CHILD(908), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(913),
+ CHILD(918), CHILD(923), CHILD(943), CHILD(948), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, CHILD(953), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(988), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(993),
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, CHILD(1076), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(18, 4) /* index 513 */,
+ TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD,
+ TILE_OPC_ADIFFB_U, TILE_OPC_ADIFFH, TILE_OPC_AND, TILE_OPC_AVGB_U,
+ TILE_OPC_AVGH, TILE_OPC_CRC32_32, TILE_OPC_CRC32_8, TILE_OPC_INTHB,
+ TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH, TILE_OPC_MAXB_U,
+ BITFIELD(18, 4) /* index 530 */,
+ TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH, TILE_OPC_MNZB, TILE_OPC_MNZH,
+ TILE_OPC_MNZ, TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_SU, TILE_OPC_MULHHA_UU,
+ TILE_OPC_MULHHSA_UU, TILE_OPC_MULHH_SS, TILE_OPC_MULHH_SU,
+ TILE_OPC_MULHH_UU, TILE_OPC_MULHLA_SS, TILE_OPC_MULHLA_SU,
+ TILE_OPC_MULHLA_US,
+ BITFIELD(18, 4) /* index 547 */,
+ TILE_OPC_MULHLA_UU, TILE_OPC_MULHLSA_UU, TILE_OPC_MULHL_SS,
+ TILE_OPC_MULHL_SU, TILE_OPC_MULHL_US, TILE_OPC_MULHL_UU, TILE_OPC_MULLLA_SS,
+ TILE_OPC_MULLLA_SU, TILE_OPC_MULLLA_UU, TILE_OPC_MULLLSA_UU,
+ TILE_OPC_MULLL_SS, TILE_OPC_MULLL_SU, TILE_OPC_MULLL_UU, TILE_OPC_MVNZ,
+ TILE_OPC_MVZ, TILE_OPC_MZB,
+ BITFIELD(18, 4) /* index 564 */,
+ TILE_OPC_MZH, TILE_OPC_MZ, TILE_OPC_NOR, CHILD(581), TILE_OPC_PACKHB,
+ TILE_OPC_PACKLB, TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
+ TILE_OPC_SADAB_U, TILE_OPC_SADAH, TILE_OPC_SADAH_U, TILE_OPC_SADB_U,
+ TILE_OPC_SADH, TILE_OPC_SADH_U,
+ BITFIELD(12, 2) /* index 581 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(586),
+ BITFIELD(14, 2) /* index 586 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(591),
+ BITFIELD(16, 2) /* index 591 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+ BITFIELD(18, 4) /* index 596 */,
+ TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB, TILE_OPC_SHLH,
+ TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR, TILE_OPC_SLTB,
+ TILE_OPC_SLTB_U, TILE_OPC_SLTEB, TILE_OPC_SLTEB_U, TILE_OPC_SLTEH,
+ TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
+ BITFIELD(18, 4) /* index 613 */,
+ TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
+ TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
+ TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
+ TILE_OPC_XOR, TILE_OPC_DWORD_ALIGN,
+ BITFIELD(18, 3) /* index 630 */,
+ CHILD(639), CHILD(642), CHILD(645), CHILD(648), CHILD(651), CHILD(654),
+ CHILD(657), CHILD(660),
+ BITFIELD(21, 1) /* index 639 */,
+ TILE_OPC_ADDS, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 642 */,
+ TILE_OPC_SUBS, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 645 */,
+ TILE_OPC_ADDBS_U, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 648 */,
+ TILE_OPC_ADDHS, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 651 */,
+ TILE_OPC_SUBBS_U, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 654 */,
+ TILE_OPC_SUBHS, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 657 */,
+ TILE_OPC_PACKHS, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 660 */,
+ TILE_OPC_PACKBS_U, TILE_OPC_NONE,
+ BITFIELD(18, 4) /* index 663 */,
+ TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
+ TILE_OPC_ADIFFB_U_SN, TILE_OPC_ADIFFH_SN, TILE_OPC_AND_SN,
+ TILE_OPC_AVGB_U_SN, TILE_OPC_AVGH_SN, TILE_OPC_CRC32_32_SN,
+ TILE_OPC_CRC32_8_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN,
+ TILE_OPC_INTLB_SN, TILE_OPC_INTLH_SN, TILE_OPC_MAXB_U_SN,
+ BITFIELD(18, 4) /* index 680 */,
+ TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN, TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN,
+ TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN, TILE_OPC_MULHHA_SS_SN,
+ TILE_OPC_MULHHA_SU_SN, TILE_OPC_MULHHA_UU_SN, TILE_OPC_MULHHSA_UU_SN,
+ TILE_OPC_MULHH_SS_SN, TILE_OPC_MULHH_SU_SN, TILE_OPC_MULHH_UU_SN,
+ TILE_OPC_MULHLA_SS_SN, TILE_OPC_MULHLA_SU_SN, TILE_OPC_MULHLA_US_SN,
+ BITFIELD(18, 4) /* index 697 */,
+ TILE_OPC_MULHLA_UU_SN, TILE_OPC_MULHLSA_UU_SN, TILE_OPC_MULHL_SS_SN,
+ TILE_OPC_MULHL_SU_SN, TILE_OPC_MULHL_US_SN, TILE_OPC_MULHL_UU_SN,
+ TILE_OPC_MULLLA_SS_SN, TILE_OPC_MULLLA_SU_SN, TILE_OPC_MULLLA_UU_SN,
+ TILE_OPC_MULLLSA_UU_SN, TILE_OPC_MULLL_SS_SN, TILE_OPC_MULLL_SU_SN,
+ TILE_OPC_MULLL_UU_SN, TILE_OPC_MVNZ_SN, TILE_OPC_MVZ_SN, TILE_OPC_MZB_SN,
+ BITFIELD(18, 4) /* index 714 */,
+ TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN, CHILD(731),
+ TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN, TILE_OPC_S1A_SN,
+ TILE_OPC_S2A_SN, TILE_OPC_S3A_SN, TILE_OPC_SADAB_U_SN, TILE_OPC_SADAH_SN,
+ TILE_OPC_SADAH_U_SN, TILE_OPC_SADB_U_SN, TILE_OPC_SADH_SN,
+ TILE_OPC_SADH_U_SN,
+ BITFIELD(12, 2) /* index 731 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(736),
+ BITFIELD(14, 2) /* index 736 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(741),
+ BITFIELD(16, 2) /* index 741 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
+ BITFIELD(18, 4) /* index 746 */,
+ TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN, TILE_OPC_SHLB_SN,
+ TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN, TILE_OPC_SHRH_SN,
+ TILE_OPC_SHR_SN, TILE_OPC_SLTB_SN, TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN,
+ TILE_OPC_SLTEB_U_SN, TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN,
+ TILE_OPC_SLTE_SN,
+ BITFIELD(18, 4) /* index 763 */,
+ TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
+ TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
+ TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
+ TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN, TILE_OPC_XOR_SN, TILE_OPC_DWORD_ALIGN_SN,
+ BITFIELD(18, 3) /* index 780 */,
+ CHILD(789), CHILD(792), CHILD(795), CHILD(798), CHILD(801), CHILD(804),
+ CHILD(807), CHILD(810),
+ BITFIELD(21, 1) /* index 789 */,
+ TILE_OPC_ADDS_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 792 */,
+ TILE_OPC_SUBS_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 795 */,
+ TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 798 */,
+ TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 801 */,
+ TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 804 */,
+ TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 807 */,
+ TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
+ BITFIELD(21, 1) /* index 810 */,
+ TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(6, 2) /* index 813 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(818),
+ BITFIELD(8, 2) /* index 818 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(823),
+ BITFIELD(10, 2) /* index 823 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
+ BITFIELD(6, 2) /* index 828 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(833),
+ BITFIELD(8, 2) /* index 833 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(838),
+ BITFIELD(10, 2) /* index 838 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
+ BITFIELD(0, 2) /* index 843 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(848),
+ BITFIELD(2, 2) /* index 848 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(853),
+ BITFIELD(4, 2) /* index 853 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(858),
+ BITFIELD(6, 2) /* index 858 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(863),
+ BITFIELD(8, 2) /* index 863 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(868),
+ BITFIELD(10, 2) /* index 868 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
+ BITFIELD(20, 2) /* index 873 */,
+ TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI,
+ BITFIELD(20, 2) /* index 878 */,
+ TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MINIB_U, TILE_OPC_MINIH,
+ BITFIELD(20, 2) /* index 883 */,
+ CHILD(888), TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI,
+ BITFIELD(6, 2) /* index 888 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(893),
+ BITFIELD(8, 2) /* index 893 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(898),
+ BITFIELD(10, 2) /* index 898 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+ BITFIELD(20, 2) /* index 903 */,
+ TILE_OPC_SLTIB, TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U,
+ BITFIELD(20, 2) /* index 908 */,
+ TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(20, 2) /* index 913 */,
+ TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
+ BITFIELD(20, 2) /* index 918 */,
+ TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MINIB_U_SN,
+ TILE_OPC_MINIH_SN,
+ BITFIELD(20, 2) /* index 923 */,
+ CHILD(928), TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN,
+ BITFIELD(6, 2) /* index 928 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(933),
+ BITFIELD(8, 2) /* index 933 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(938),
+ BITFIELD(10, 2) /* index 938 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
+ BITFIELD(20, 2) /* index 943 */,
+ TILE_OPC_SLTIB_SN, TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN,
+ TILE_OPC_SLTIH_U_SN,
+ BITFIELD(20, 2) /* index 948 */,
+ TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(20, 2) /* index 953 */,
+ TILE_OPC_NONE, CHILD(958), TILE_OPC_XORI, TILE_OPC_NONE,
+ BITFIELD(0, 2) /* index 958 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(963),
+ BITFIELD(2, 2) /* index 963 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(968),
+ BITFIELD(4, 2) /* index 968 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(973),
+ BITFIELD(6, 2) /* index 973 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(978),
+ BITFIELD(8, 2) /* index 978 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(983),
+ BITFIELD(10, 2) /* index 983 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+ BITFIELD(20, 2) /* index 988 */,
+ TILE_OPC_NONE, TILE_OPC_ANDI_SN, TILE_OPC_XORI_SN, TILE_OPC_NONE,
+ BITFIELD(17, 5) /* index 993 */,
+ TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLIB, TILE_OPC_SHLIH, TILE_OPC_SHLI,
+ TILE_OPC_SHRIB, TILE_OPC_SHRIH, TILE_OPC_SHRI, TILE_OPC_SRAIB,
+ TILE_OPC_SRAIH, TILE_OPC_SRAI, CHILD(1026), TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(12, 4) /* index 1026 */,
+ TILE_OPC_NONE, CHILD(1043), CHILD(1046), CHILD(1049), CHILD(1052),
+ CHILD(1055), CHILD(1058), CHILD(1061), CHILD(1064), CHILD(1067),
+ CHILD(1070), CHILD(1073), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1043 */,
+ TILE_OPC_BITX, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1046 */,
+ TILE_OPC_BYTEX, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1049 */,
+ TILE_OPC_CLZ, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1052 */,
+ TILE_OPC_CTZ, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1055 */,
+ TILE_OPC_FNOP, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1058 */,
+ TILE_OPC_NOP, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1061 */,
+ TILE_OPC_PCNT, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1064 */,
+ TILE_OPC_TBLIDXB0, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1067 */,
+ TILE_OPC_TBLIDXB1, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1070 */,
+ TILE_OPC_TBLIDXB2, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1073 */,
+ TILE_OPC_TBLIDXB3, TILE_OPC_NONE,
+ BITFIELD(17, 5) /* index 1076 */,
+ TILE_OPC_NONE, TILE_OPC_RLI_SN, TILE_OPC_SHLIB_SN, TILE_OPC_SHLIH_SN,
+ TILE_OPC_SHLI_SN, TILE_OPC_SHRIB_SN, TILE_OPC_SHRIH_SN, TILE_OPC_SHRI_SN,
+ TILE_OPC_SRAIB_SN, TILE_OPC_SRAIH_SN, TILE_OPC_SRAI_SN, CHILD(1109),
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(12, 4) /* index 1109 */,
+ TILE_OPC_NONE, CHILD(1126), CHILD(1129), CHILD(1132), CHILD(1135),
+ CHILD(1055), CHILD(1058), CHILD(1138), CHILD(1141), CHILD(1144),
+ CHILD(1147), CHILD(1150), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1126 */,
+ TILE_OPC_BITX_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1129 */,
+ TILE_OPC_BYTEX_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1132 */,
+ TILE_OPC_CLZ_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1135 */,
+ TILE_OPC_CTZ_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1138 */,
+ TILE_OPC_PCNT_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1141 */,
+ TILE_OPC_TBLIDXB0_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1144 */,
+ TILE_OPC_TBLIDXB1_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1147 */,
+ TILE_OPC_TBLIDXB2_SN, TILE_OPC_NONE,
+ BITFIELD(16, 1) /* index 1150 */,
+ TILE_OPC_TBLIDXB3_SN, TILE_OPC_NONE,
+};
+
+static const unsigned short decode_X1_fsm[1540] =
+{
+ BITFIELD(54, 9) /* index 0 */,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, CHILD(513), CHILD(561), CHILD(594),
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(641), CHILD(689),
+ CHILD(722), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(766),
+ CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
+ CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
+ CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
+ CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
+ CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766), CHILD(766),
+ CHILD(766), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
+ CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
+ CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
+ CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
+ CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781), CHILD(781),
+ CHILD(781), CHILD(781), CHILD(781), CHILD(796), CHILD(796), CHILD(796),
+ CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
+ CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
+ CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
+ CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796),
+ CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(796), CHILD(826),
+ CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826),
+ CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826), CHILD(826),
+ CHILD(826), CHILD(826), CHILD(826), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843), CHILD(843),
+ CHILD(843), CHILD(860), CHILD(899), CHILD(923), CHILD(932), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, CHILD(941), CHILD(950), CHILD(974), CHILD(983),
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM,
+ TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, TILE_OPC_MM, CHILD(992),
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ CHILD(1334), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J, TILE_OPC_J,
+ TILE_OPC_J, TILE_OPC_J, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL, TILE_OPC_JAL,
+ TILE_OPC_JAL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(49, 5) /* index 513 */,
+ TILE_OPC_NONE, TILE_OPC_ADDB, TILE_OPC_ADDH, TILE_OPC_ADD, TILE_OPC_AND,
+ TILE_OPC_INTHB, TILE_OPC_INTHH, TILE_OPC_INTLB, TILE_OPC_INTLH,
+ TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR, TILE_OPC_LNK,
+ TILE_OPC_MAXB_U, TILE_OPC_MAXH, TILE_OPC_MINB_U, TILE_OPC_MINH,
+ TILE_OPC_MNZB, TILE_OPC_MNZH, TILE_OPC_MNZ, TILE_OPC_MZB, TILE_OPC_MZH,
+ TILE_OPC_MZ, TILE_OPC_NOR, CHILD(546), TILE_OPC_PACKHB, TILE_OPC_PACKLB,
+ TILE_OPC_RL, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_S3A,
+ BITFIELD(43, 2) /* index 546 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(551),
+ BITFIELD(45, 2) /* index 551 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(556),
+ BITFIELD(47, 2) /* index 556 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+ BITFIELD(49, 5) /* index 561 */,
+ TILE_OPC_SB, TILE_OPC_SEQB, TILE_OPC_SEQH, TILE_OPC_SEQ, TILE_OPC_SHLB,
+ TILE_OPC_SHLH, TILE_OPC_SHL, TILE_OPC_SHRB, TILE_OPC_SHRH, TILE_OPC_SHR,
+ TILE_OPC_SH, TILE_OPC_SLTB, TILE_OPC_SLTB_U, TILE_OPC_SLTEB,
+ TILE_OPC_SLTEB_U, TILE_OPC_SLTEH, TILE_OPC_SLTEH_U, TILE_OPC_SLTE,
+ TILE_OPC_SLTE_U, TILE_OPC_SLTH, TILE_OPC_SLTH_U, TILE_OPC_SLT,
+ TILE_OPC_SLT_U, TILE_OPC_SNEB, TILE_OPC_SNEH, TILE_OPC_SNE, TILE_OPC_SRAB,
+ TILE_OPC_SRAH, TILE_OPC_SRA, TILE_OPC_SUBB, TILE_OPC_SUBH, TILE_OPC_SUB,
+ BITFIELD(49, 4) /* index 594 */,
+ CHILD(611), CHILD(614), CHILD(617), CHILD(620), CHILD(623), CHILD(626),
+ CHILD(629), CHILD(632), CHILD(635), CHILD(638), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 611 */,
+ TILE_OPC_SW, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 614 */,
+ TILE_OPC_XOR, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 617 */,
+ TILE_OPC_ADDS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 620 */,
+ TILE_OPC_SUBS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 623 */,
+ TILE_OPC_ADDBS_U, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 626 */,
+ TILE_OPC_ADDHS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 629 */,
+ TILE_OPC_SUBBS_U, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 632 */,
+ TILE_OPC_SUBHS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 635 */,
+ TILE_OPC_PACKHS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 638 */,
+ TILE_OPC_PACKBS_U, TILE_OPC_NONE,
+ BITFIELD(49, 5) /* index 641 */,
+ TILE_OPC_NONE, TILE_OPC_ADDB_SN, TILE_OPC_ADDH_SN, TILE_OPC_ADD_SN,
+ TILE_OPC_AND_SN, TILE_OPC_INTHB_SN, TILE_OPC_INTHH_SN, TILE_OPC_INTLB_SN,
+ TILE_OPC_INTLH_SN, TILE_OPC_JALRP, TILE_OPC_JALR, TILE_OPC_JRP, TILE_OPC_JR,
+ TILE_OPC_LNK_SN, TILE_OPC_MAXB_U_SN, TILE_OPC_MAXH_SN, TILE_OPC_MINB_U_SN,
+ TILE_OPC_MINH_SN, TILE_OPC_MNZB_SN, TILE_OPC_MNZH_SN, TILE_OPC_MNZ_SN,
+ TILE_OPC_MZB_SN, TILE_OPC_MZH_SN, TILE_OPC_MZ_SN, TILE_OPC_NOR_SN,
+ CHILD(674), TILE_OPC_PACKHB_SN, TILE_OPC_PACKLB_SN, TILE_OPC_RL_SN,
+ TILE_OPC_S1A_SN, TILE_OPC_S2A_SN, TILE_OPC_S3A_SN,
+ BITFIELD(43, 2) /* index 674 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(679),
+ BITFIELD(45, 2) /* index 679 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, CHILD(684),
+ BITFIELD(47, 2) /* index 684 */,
+ TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_OR_SN, TILE_OPC_MOVE_SN,
+ BITFIELD(49, 5) /* index 689 */,
+ TILE_OPC_SB, TILE_OPC_SEQB_SN, TILE_OPC_SEQH_SN, TILE_OPC_SEQ_SN,
+ TILE_OPC_SHLB_SN, TILE_OPC_SHLH_SN, TILE_OPC_SHL_SN, TILE_OPC_SHRB_SN,
+ TILE_OPC_SHRH_SN, TILE_OPC_SHR_SN, TILE_OPC_SH, TILE_OPC_SLTB_SN,
+ TILE_OPC_SLTB_U_SN, TILE_OPC_SLTEB_SN, TILE_OPC_SLTEB_U_SN,
+ TILE_OPC_SLTEH_SN, TILE_OPC_SLTEH_U_SN, TILE_OPC_SLTE_SN,
+ TILE_OPC_SLTE_U_SN, TILE_OPC_SLTH_SN, TILE_OPC_SLTH_U_SN, TILE_OPC_SLT_SN,
+ TILE_OPC_SLT_U_SN, TILE_OPC_SNEB_SN, TILE_OPC_SNEH_SN, TILE_OPC_SNE_SN,
+ TILE_OPC_SRAB_SN, TILE_OPC_SRAH_SN, TILE_OPC_SRA_SN, TILE_OPC_SUBB_SN,
+ TILE_OPC_SUBH_SN, TILE_OPC_SUB_SN,
+ BITFIELD(49, 4) /* index 722 */,
+ CHILD(611), CHILD(739), CHILD(742), CHILD(745), CHILD(748), CHILD(751),
+ CHILD(754), CHILD(757), CHILD(760), CHILD(763), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 739 */,
+ TILE_OPC_XOR_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 742 */,
+ TILE_OPC_ADDS_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 745 */,
+ TILE_OPC_SUBS_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 748 */,
+ TILE_OPC_ADDBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 751 */,
+ TILE_OPC_ADDHS_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 754 */,
+ TILE_OPC_SUBBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 757 */,
+ TILE_OPC_SUBHS_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 760 */,
+ TILE_OPC_PACKHS_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 763 */,
+ TILE_OPC_PACKBS_U_SN, TILE_OPC_NONE,
+ BITFIELD(37, 2) /* index 766 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(771),
+ BITFIELD(39, 2) /* index 771 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, CHILD(776),
+ BITFIELD(41, 2) /* index 776 */,
+ TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_ADDLI_SN, TILE_OPC_MOVELI_SN,
+ BITFIELD(37, 2) /* index 781 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(786),
+ BITFIELD(39, 2) /* index 786 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, CHILD(791),
+ BITFIELD(41, 2) /* index 791 */,
+ TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_ADDLI, TILE_OPC_MOVELI,
+ BITFIELD(31, 2) /* index 796 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(801),
+ BITFIELD(33, 2) /* index 801 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(806),
+ BITFIELD(35, 2) /* index 806 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(811),
+ BITFIELD(37, 2) /* index 811 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(816),
+ BITFIELD(39, 2) /* index 816 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, CHILD(821),
+ BITFIELD(41, 2) /* index 821 */,
+ TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_AULI, TILE_OPC_INFOL,
+ BITFIELD(31, 4) /* index 826 */,
+ TILE_OPC_BZ, TILE_OPC_BZT, TILE_OPC_BNZ, TILE_OPC_BNZT, TILE_OPC_BGZ,
+ TILE_OPC_BGZT, TILE_OPC_BGEZ, TILE_OPC_BGEZT, TILE_OPC_BLZ, TILE_OPC_BLZT,
+ TILE_OPC_BLEZ, TILE_OPC_BLEZT, TILE_OPC_BBS, TILE_OPC_BBST, TILE_OPC_BBNS,
+ TILE_OPC_BBNST,
+ BITFIELD(31, 4) /* index 843 */,
+ TILE_OPC_BZ_SN, TILE_OPC_BZT_SN, TILE_OPC_BNZ_SN, TILE_OPC_BNZT_SN,
+ TILE_OPC_BGZ_SN, TILE_OPC_BGZT_SN, TILE_OPC_BGEZ_SN, TILE_OPC_BGEZT_SN,
+ TILE_OPC_BLZ_SN, TILE_OPC_BLZT_SN, TILE_OPC_BLEZ_SN, TILE_OPC_BLEZT_SN,
+ TILE_OPC_BBS_SN, TILE_OPC_BBST_SN, TILE_OPC_BBNS_SN, TILE_OPC_BBNST_SN,
+ BITFIELD(51, 3) /* index 860 */,
+ TILE_OPC_NONE, TILE_OPC_ADDIB, TILE_OPC_ADDIH, TILE_OPC_ADDI, CHILD(869),
+ TILE_OPC_MAXIB_U, TILE_OPC_MAXIH, TILE_OPC_MFSPR,
+ BITFIELD(31, 2) /* index 869 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(874),
+ BITFIELD(33, 2) /* index 874 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(879),
+ BITFIELD(35, 2) /* index 879 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(884),
+ BITFIELD(37, 2) /* index 884 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(889),
+ BITFIELD(39, 2) /* index 889 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(894),
+ BITFIELD(41, 2) /* index 894 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+ BITFIELD(51, 3) /* index 899 */,
+ TILE_OPC_MINIB_U, TILE_OPC_MINIH, TILE_OPC_MTSPR, CHILD(908),
+ TILE_OPC_SEQIB, TILE_OPC_SEQIH, TILE_OPC_SEQI, TILE_OPC_SLTIB,
+ BITFIELD(37, 2) /* index 908 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(913),
+ BITFIELD(39, 2) /* index 913 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(918),
+ BITFIELD(41, 2) /* index 918 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+ BITFIELD(51, 3) /* index 923 */,
+ TILE_OPC_SLTIB_U, TILE_OPC_SLTIH, TILE_OPC_SLTIH_U, TILE_OPC_SLTI,
+ TILE_OPC_SLTI_U, TILE_OPC_XORI, TILE_OPC_LBADD, TILE_OPC_LBADD_U,
+ BITFIELD(51, 3) /* index 932 */,
+ TILE_OPC_LHADD, TILE_OPC_LHADD_U, TILE_OPC_LWADD, TILE_OPC_LWADD_NA,
+ TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD, TILE_OPC_NONE,
+ BITFIELD(51, 3) /* index 941 */,
+ TILE_OPC_NONE, TILE_OPC_ADDIB_SN, TILE_OPC_ADDIH_SN, TILE_OPC_ADDI_SN,
+ TILE_OPC_ANDI_SN, TILE_OPC_MAXIB_U_SN, TILE_OPC_MAXIH_SN, TILE_OPC_MFSPR,
+ BITFIELD(51, 3) /* index 950 */,
+ TILE_OPC_MINIB_U_SN, TILE_OPC_MINIH_SN, TILE_OPC_MTSPR, CHILD(959),
+ TILE_OPC_SEQIB_SN, TILE_OPC_SEQIH_SN, TILE_OPC_SEQI_SN, TILE_OPC_SLTIB_SN,
+ BITFIELD(37, 2) /* index 959 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(964),
+ BITFIELD(39, 2) /* index 964 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, CHILD(969),
+ BITFIELD(41, 2) /* index 969 */,
+ TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_ORI_SN, TILE_OPC_MOVEI_SN,
+ BITFIELD(51, 3) /* index 974 */,
+ TILE_OPC_SLTIB_U_SN, TILE_OPC_SLTIH_SN, TILE_OPC_SLTIH_U_SN,
+ TILE_OPC_SLTI_SN, TILE_OPC_SLTI_U_SN, TILE_OPC_XORI_SN, TILE_OPC_LBADD_SN,
+ TILE_OPC_LBADD_U_SN,
+ BITFIELD(51, 3) /* index 983 */,
+ TILE_OPC_LHADD_SN, TILE_OPC_LHADD_U_SN, TILE_OPC_LWADD_SN,
+ TILE_OPC_LWADD_NA_SN, TILE_OPC_SBADD, TILE_OPC_SHADD, TILE_OPC_SWADD,
+ TILE_OPC_NONE,
+ BITFIELD(46, 7) /* index 992 */,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1121),
+ CHILD(1121), CHILD(1121), CHILD(1121), CHILD(1124), CHILD(1124),
+ CHILD(1124), CHILD(1124), CHILD(1127), CHILD(1127), CHILD(1127),
+ CHILD(1127), CHILD(1130), CHILD(1130), CHILD(1130), CHILD(1130),
+ CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1133), CHILD(1136),
+ CHILD(1136), CHILD(1136), CHILD(1136), CHILD(1139), CHILD(1139),
+ CHILD(1139), CHILD(1139), CHILD(1142), CHILD(1142), CHILD(1142),
+ CHILD(1142), CHILD(1145), CHILD(1145), CHILD(1145), CHILD(1145),
+ CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1148), CHILD(1151),
+ CHILD(1242), CHILD(1290), CHILD(1323), TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1121 */,
+ TILE_OPC_RLI, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1124 */,
+ TILE_OPC_SHLIB, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1127 */,
+ TILE_OPC_SHLIH, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1130 */,
+ TILE_OPC_SHLI, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1133 */,
+ TILE_OPC_SHRIB, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1136 */,
+ TILE_OPC_SHRIH, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1139 */,
+ TILE_OPC_SHRI, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1142 */,
+ TILE_OPC_SRAIB, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1145 */,
+ TILE_OPC_SRAIH, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1148 */,
+ TILE_OPC_SRAI, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 1151 */,
+ TILE_OPC_NONE, CHILD(1160), CHILD(1163), CHILD(1166), CHILD(1169),
+ CHILD(1172), CHILD(1175), CHILD(1178),
+ BITFIELD(53, 1) /* index 1160 */,
+ TILE_OPC_DRAIN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1163 */,
+ TILE_OPC_DTLBPR, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1166 */,
+ TILE_OPC_FINV, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1169 */,
+ TILE_OPC_FLUSH, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1172 */,
+ TILE_OPC_FNOP, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1175 */,
+ TILE_OPC_ICOH, TILE_OPC_NONE,
+ BITFIELD(31, 2) /* index 1178 */,
+ CHILD(1183), CHILD(1211), CHILD(1239), CHILD(1239),
+ BITFIELD(53, 1) /* index 1183 */,
+ CHILD(1186), TILE_OPC_NONE,
+ BITFIELD(33, 2) /* index 1186 */,
+ TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1191),
+ BITFIELD(35, 2) /* index 1191 */,
+ TILE_OPC_ILL, CHILD(1196), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(37, 2) /* index 1196 */,
+ TILE_OPC_ILL, CHILD(1201), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(39, 2) /* index 1201 */,
+ TILE_OPC_ILL, CHILD(1206), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(41, 2) /* index 1206 */,
+ TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_BPT, TILE_OPC_ILL,
+ BITFIELD(53, 1) /* index 1211 */,
+ CHILD(1214), TILE_OPC_NONE,
+ BITFIELD(33, 2) /* index 1214 */,
+ TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_ILL, CHILD(1219),
+ BITFIELD(35, 2) /* index 1219 */,
+ TILE_OPC_ILL, CHILD(1224), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(37, 2) /* index 1224 */,
+ TILE_OPC_ILL, CHILD(1229), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(39, 2) /* index 1229 */,
+ TILE_OPC_ILL, CHILD(1234), TILE_OPC_ILL, TILE_OPC_ILL,
+ BITFIELD(41, 2) /* index 1234 */,
+ TILE_OPC_ILL, TILE_OPC_ILL, TILE_OPC_RAISE, TILE_OPC_ILL,
+ BITFIELD(53, 1) /* index 1239 */,
+ TILE_OPC_ILL, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 1242 */,
+ CHILD(1251), CHILD(1254), CHILD(1257), CHILD(1275), CHILD(1278),
+ CHILD(1281), CHILD(1284), CHILD(1287),
+ BITFIELD(53, 1) /* index 1251 */,
+ TILE_OPC_INV, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1254 */,
+ TILE_OPC_IRET, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1257 */,
+ CHILD(1260), TILE_OPC_NONE,
+ BITFIELD(31, 2) /* index 1260 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1265),
+ BITFIELD(33, 2) /* index 1265 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(1270),
+ BITFIELD(35, 2) /* index 1270 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
+ BITFIELD(53, 1) /* index 1275 */,
+ TILE_OPC_LB_U, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1278 */,
+ TILE_OPC_LH, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1281 */,
+ TILE_OPC_LH_U, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1284 */,
+ TILE_OPC_LW, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1287 */,
+ TILE_OPC_MF, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 1290 */,
+ CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
+ CHILD(1314), CHILD(1317), CHILD(1320),
+ BITFIELD(53, 1) /* index 1299 */,
+ TILE_OPC_NAP, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1302 */,
+ TILE_OPC_NOP, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1305 */,
+ TILE_OPC_SWINT0, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1308 */,
+ TILE_OPC_SWINT1, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1311 */,
+ TILE_OPC_SWINT2, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1314 */,
+ TILE_OPC_SWINT3, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1317 */,
+ TILE_OPC_TNS, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1320 */,
+ TILE_OPC_WH64, TILE_OPC_NONE,
+ BITFIELD(43, 2) /* index 1323 */,
+ CHILD(1328), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(45, 1) /* index 1328 */,
+ CHILD(1331), TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1331 */,
+ TILE_OPC_LW_NA, TILE_OPC_NONE,
+ BITFIELD(46, 7) /* index 1334 */,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, CHILD(1463),
+ CHILD(1463), CHILD(1463), CHILD(1463), CHILD(1466), CHILD(1466),
+ CHILD(1466), CHILD(1466), CHILD(1469), CHILD(1469), CHILD(1469),
+ CHILD(1469), CHILD(1472), CHILD(1472), CHILD(1472), CHILD(1472),
+ CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1475), CHILD(1478),
+ CHILD(1478), CHILD(1478), CHILD(1478), CHILD(1481), CHILD(1481),
+ CHILD(1481), CHILD(1481), CHILD(1484), CHILD(1484), CHILD(1484),
+ CHILD(1484), CHILD(1487), CHILD(1487), CHILD(1487), CHILD(1487),
+ CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1490), CHILD(1151),
+ CHILD(1493), CHILD(1517), CHILD(1529), TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1463 */,
+ TILE_OPC_RLI_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1466 */,
+ TILE_OPC_SHLIB_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1469 */,
+ TILE_OPC_SHLIH_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1472 */,
+ TILE_OPC_SHLI_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1475 */,
+ TILE_OPC_SHRIB_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1478 */,
+ TILE_OPC_SHRIH_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1481 */,
+ TILE_OPC_SHRI_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1484 */,
+ TILE_OPC_SRAIB_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1487 */,
+ TILE_OPC_SRAIH_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1490 */,
+ TILE_OPC_SRAI_SN, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 1493 */,
+ CHILD(1251), CHILD(1254), CHILD(1502), CHILD(1505), CHILD(1508),
+ CHILD(1511), CHILD(1514), CHILD(1287),
+ BITFIELD(53, 1) /* index 1502 */,
+ TILE_OPC_LB_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1505 */,
+ TILE_OPC_LB_U_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1508 */,
+ TILE_OPC_LH_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1511 */,
+ TILE_OPC_LH_U_SN, TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1514 */,
+ TILE_OPC_LW_SN, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 1517 */,
+ CHILD(1299), CHILD(1302), CHILD(1305), CHILD(1308), CHILD(1311),
+ CHILD(1314), CHILD(1526), CHILD(1320),
+ BITFIELD(53, 1) /* index 1526 */,
+ TILE_OPC_TNS_SN, TILE_OPC_NONE,
+ BITFIELD(43, 2) /* index 1529 */,
+ CHILD(1534), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(45, 1) /* index 1534 */,
+ CHILD(1537), TILE_OPC_NONE,
+ BITFIELD(53, 1) /* index 1537 */,
+ TILE_OPC_LW_NA_SN, TILE_OPC_NONE,
+};
+
+static const unsigned short decode_Y0_fsm[168] =
+{
+ BITFIELD(27, 4) /* index 0 */,
+ TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
+ CHILD(57), CHILD(62), CHILD(67), TILE_OPC_ADDI, CHILD(72), CHILD(102),
+ TILE_OPC_SEQI, CHILD(117), TILE_OPC_SLTI, TILE_OPC_SLTI_U,
+ BITFIELD(18, 2) /* index 17 */,
+ TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
+ BITFIELD(18, 2) /* index 22 */,
+ TILE_OPC_MNZ, TILE_OPC_MVNZ, TILE_OPC_MVZ, TILE_OPC_MZ,
+ BITFIELD(18, 2) /* index 27 */,
+ TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
+ BITFIELD(12, 2) /* index 32 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
+ BITFIELD(14, 2) /* index 37 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
+ BITFIELD(16, 2) /* index 42 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+ BITFIELD(18, 2) /* index 47 */,
+ TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
+ BITFIELD(18, 2) /* index 52 */,
+ TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
+ BITFIELD(18, 2) /* index 57 */,
+ TILE_OPC_MULHLSA_UU, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
+ BITFIELD(18, 2) /* index 62 */,
+ TILE_OPC_MULHH_SS, TILE_OPC_MULHH_UU, TILE_OPC_MULLL_SS, TILE_OPC_MULLL_UU,
+ BITFIELD(18, 2) /* index 67 */,
+ TILE_OPC_MULHHA_SS, TILE_OPC_MULHHA_UU, TILE_OPC_MULLLA_SS,
+ TILE_OPC_MULLLA_UU,
+ BITFIELD(0, 2) /* index 72 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
+ BITFIELD(2, 2) /* index 77 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
+ BITFIELD(4, 2) /* index 82 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
+ BITFIELD(6, 2) /* index 87 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(92),
+ BITFIELD(8, 2) /* index 92 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(97),
+ BITFIELD(10, 2) /* index 97 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+ BITFIELD(6, 2) /* index 102 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(107),
+ BITFIELD(8, 2) /* index 107 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(112),
+ BITFIELD(10, 2) /* index 112 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+ BITFIELD(15, 5) /* index 117 */,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_RLI,
+ TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHLI,
+ TILE_OPC_SHLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SHRI, TILE_OPC_SHRI,
+ TILE_OPC_SHRI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI, TILE_OPC_SRAI,
+ CHILD(150), CHILD(159), TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(12, 3) /* index 150 */,
+ TILE_OPC_NONE, TILE_OPC_BITX, TILE_OPC_BYTEX, TILE_OPC_CLZ, TILE_OPC_CTZ,
+ TILE_OPC_FNOP, TILE_OPC_NOP, TILE_OPC_PCNT,
+ BITFIELD(12, 3) /* index 159 */,
+ TILE_OPC_TBLIDXB0, TILE_OPC_TBLIDXB1, TILE_OPC_TBLIDXB2, TILE_OPC_TBLIDXB3,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+};
+
+static const unsigned short decode_Y1_fsm[140] =
+{
+ BITFIELD(59, 4) /* index 0 */,
+ TILE_OPC_NONE, CHILD(17), CHILD(22), CHILD(27), CHILD(47), CHILD(52),
+ CHILD(57), TILE_OPC_ADDI, CHILD(62), CHILD(92), TILE_OPC_SEQI, CHILD(107),
+ TILE_OPC_SLTI, TILE_OPC_SLTI_U, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(49, 2) /* index 17 */,
+ TILE_OPC_ADD, TILE_OPC_S1A, TILE_OPC_S2A, TILE_OPC_SUB,
+ BITFIELD(49, 2) /* index 22 */,
+ TILE_OPC_NONE, TILE_OPC_MNZ, TILE_OPC_MZ, TILE_OPC_NONE,
+ BITFIELD(49, 2) /* index 27 */,
+ TILE_OPC_AND, TILE_OPC_NOR, CHILD(32), TILE_OPC_XOR,
+ BITFIELD(43, 2) /* index 32 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(37),
+ BITFIELD(45, 2) /* index 37 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, CHILD(42),
+ BITFIELD(47, 2) /* index 42 */,
+ TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_OR, TILE_OPC_MOVE,
+ BITFIELD(49, 2) /* index 47 */,
+ TILE_OPC_RL, TILE_OPC_SHL, TILE_OPC_SHR, TILE_OPC_SRA,
+ BITFIELD(49, 2) /* index 52 */,
+ TILE_OPC_SLTE, TILE_OPC_SLTE_U, TILE_OPC_SLT, TILE_OPC_SLT_U,
+ BITFIELD(49, 2) /* index 57 */,
+ TILE_OPC_NONE, TILE_OPC_S3A, TILE_OPC_SEQ, TILE_OPC_SNE,
+ BITFIELD(31, 2) /* index 62 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(67),
+ BITFIELD(33, 2) /* index 67 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(72),
+ BITFIELD(35, 2) /* index 72 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(77),
+ BITFIELD(37, 2) /* index 77 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(82),
+ BITFIELD(39, 2) /* index 82 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, CHILD(87),
+ BITFIELD(41, 2) /* index 87 */,
+ TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_ANDI, TILE_OPC_INFO,
+ BITFIELD(37, 2) /* index 92 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(97),
+ BITFIELD(39, 2) /* index 97 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, CHILD(102),
+ BITFIELD(41, 2) /* index 102 */,
+ TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_ORI, TILE_OPC_MOVEI,
+ BITFIELD(48, 3) /* index 107 */,
+ TILE_OPC_NONE, TILE_OPC_RLI, TILE_OPC_SHLI, TILE_OPC_SHRI, TILE_OPC_SRAI,
+ CHILD(116), TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(43, 3) /* index 116 */,
+ TILE_OPC_NONE, CHILD(125), CHILD(130), CHILD(135), TILE_OPC_NONE,
+ TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(46, 2) /* index 125 */,
+ TILE_OPC_FNOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(46, 2) /* index 130 */,
+ TILE_OPC_ILL, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+ BITFIELD(46, 2) /* index 135 */,
+ TILE_OPC_NOP, TILE_OPC_NONE, TILE_OPC_NONE, TILE_OPC_NONE,
+};
+
+static const unsigned short decode_Y2_fsm[24] =
+{
+ BITFIELD(56, 3) /* index 0 */,
+ CHILD(9), TILE_OPC_LB_U, TILE_OPC_LH, TILE_OPC_LH_U, TILE_OPC_LW,
+ TILE_OPC_SB, TILE_OPC_SH, TILE_OPC_SW,
+ BITFIELD(20, 2) /* index 9 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(14),
+ BITFIELD(22, 2) /* index 14 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, CHILD(19),
+ BITFIELD(24, 2) /* index 19 */,
+ TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_LB, TILE_OPC_PREFETCH,
+};
+
+#undef BITFIELD
+#undef CHILD
+const unsigned short * const
+tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS] =
+{
+ decode_X0_fsm,
+ decode_X1_fsm,
+ decode_Y0_fsm,
+ decode_Y1_fsm,
+ decode_Y2_fsm
+};
+const struct tile_operand tile_operands[43] =
+{
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X0),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_X0, get_Imm8_X0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_X1),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_X1, get_Imm8_X1
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y0),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_Y0, get_Imm8_Y0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM8_Y1),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_Y1, get_Imm8_Y1
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X0),
+ 16, 1, 0, 0, 0, 0,
+ create_Imm16_X0, get_Imm16_X0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_IMM16_X1),
+ 16, 1, 0, 0, 0, 0,
+ create_Imm16_X1, get_Imm16_X1
+ },
+ {
+ TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_JOFFLONG_X1),
+ 29, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+ create_JOffLong_X1, get_JOffLong_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_X0, get_Dest_X0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_X0, get_SrcA_X0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_X1, get_Dest_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_X1, get_SrcA_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_Y0, get_Dest_Y0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y0, get_SrcA_Y0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_Dest_Y1, get_Dest_Y1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y1, get_SrcA_Y1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcA_Y2, get_SrcA_Y2
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_X0, get_SrcB_X0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_X1, get_SrcB_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_Y0, get_SrcB_Y0
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcB_Y1, get_SrcB_Y1
+ },
+ {
+ TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_BROFF_X1),
+ 17, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+ create_BrOff_X1, get_BrOff_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_Dest_X0, get_Dest_X0
+ },
+ {
+ TILE_OP_TYPE_ADDRESS, BFD_RELOC(NONE),
+ 28, 1, 0, 0, 1, TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+ create_JOff_X1, get_JOff_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 0, 1, 0, 0,
+ create_SrcBDest_Y2, get_SrcBDest_Y2
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_SrcA_X1, get_SrcA_X1
+ },
+ {
+ TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MF_IMM15_X1),
+ 15, 0, 0, 0, 0, 0,
+ create_MF_Imm15_X1, get_MF_Imm15_X1
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X0),
+ 5, 0, 0, 0, 0, 0,
+ create_MMStart_X0, get_MMStart_X0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X0),
+ 5, 0, 0, 0, 0, 0,
+ create_MMEnd_X0, get_MMEnd_X0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMSTART_X1),
+ 5, 0, 0, 0, 0, 0,
+ create_MMStart_X1, get_MMStart_X1
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_MMEND_X1),
+ 5, 0, 0, 0, 0, 0,
+ create_MMEnd_X1, get_MMEnd_X1
+ },
+ {
+ TILE_OP_TYPE_SPR, BFD_RELOC(TILE_MT_IMM15_X1),
+ 15, 0, 0, 0, 0, 0,
+ create_MT_Imm15_X1, get_MT_Imm15_X1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 1, 0, 0,
+ create_Dest_Y0, get_Dest_Y0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X0),
+ 5, 0, 0, 0, 0, 0,
+ create_ShAmt_X0, get_ShAmt_X0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_X1),
+ 5, 0, 0, 0, 0, 0,
+ create_ShAmt_X1, get_ShAmt_X1
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y0),
+ 5, 0, 0, 0, 0, 0,
+ create_ShAmt_Y0, get_ShAmt_Y0
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SHAMT_Y1),
+ 5, 0, 0, 0, 0, 0,
+ create_ShAmt_Y1, get_ShAmt_Y1
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 6, 0, 1, 0, 0, 0,
+ create_SrcBDest_Y2, get_SrcBDest_Y2
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+ 8, 1, 0, 0, 0, 0,
+ create_Dest_Imm8_X1, get_Dest_Imm8_X1
+ },
+ {
+ TILE_OP_TYPE_ADDRESS, BFD_RELOC(TILE_SN_BROFF),
+ 10, 1, 0, 0, 1, TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES,
+ create_BrOff_SN, get_BrOff_SN
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_UIMM8),
+ 8, 0, 0, 0, 0, 0,
+ create_Imm8_SN, get_Imm8_SN
+ },
+ {
+ TILE_OP_TYPE_IMMEDIATE, BFD_RELOC(TILE_SN_IMM8),
+ 8, 1, 0, 0, 0, 0,
+ create_Imm8_SN, get_Imm8_SN
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 2, 0, 0, 1, 0, 0,
+ create_Dest_SN, get_Dest_SN
+ },
+ {
+ TILE_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+ 2, 0, 1, 0, 0, 0,
+ create_Src_SN, get_Src_SN
+ }
+};
+
+
+
+
+/* Given a set of bundle bits and the lookup FSM for a specific pipe,
+ * returns which instruction the bundle contains in that pipe.
+ */
+static const struct tile_opcode *
+find_opcode(tile_bundle_bits bits, const unsigned short *table)
+{
+ int index = 0;
+
+ while (1)
+ {
+ unsigned short bitspec = table[index];
+ unsigned int bitfield =
+ ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
+
+ unsigned short next = table[index + 1 + bitfield];
+ if (next <= TILE_OPC_NONE)
+ return &tile_opcodes[next];
+
+ index = next - TILE_OPC_NONE;
+ }
+}
+
+
+int
+parse_insn_tile(tile_bundle_bits bits,
+ unsigned int pc,
+ struct tile_decoded_instruction
+ decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE])
+{
+ int num_instructions = 0;
+ int pipe;
+
+ int min_pipe, max_pipe;
+ if ((bits & TILE_BUNDLE_Y_ENCODING_MASK) == 0)
+ {
+ min_pipe = TILE_PIPELINE_X0;
+ max_pipe = TILE_PIPELINE_X1;
+ }
+ else
+ {
+ min_pipe = TILE_PIPELINE_Y0;
+ max_pipe = TILE_PIPELINE_Y2;
+ }
+
+ /* For each pipe, find an instruction that fits. */
+ for (pipe = min_pipe; pipe <= max_pipe; pipe++)
+ {
+ const struct tile_opcode *opc;
+ struct tile_decoded_instruction *d;
+ int i;
+
+ d = &decoded[num_instructions++];
+ opc = find_opcode (bits, tile_bundle_decoder_fsms[pipe]);
+ d->opcode = opc;
+
+ /* Decode each operand, sign extending, etc. as appropriate. */
+ for (i = 0; i < opc->num_operands; i++)
+ {
+ const struct tile_operand *op =
+ &tile_operands[opc->operands[pipe][i]];
+ int opval = op->extract (bits);
+ if (op->is_signed)
+ {
+ /* Sign-extend the operand. */
+ int shift = (int)((sizeof(int) * 8) - op->num_bits);
+ opval = (opval << shift) >> shift;
+ }
+
+ /* Adjust PC-relative scaled branch offsets. */
+ if (op->type == TILE_OP_TYPE_ADDRESS)
+ {
+ opval *= TILE_BUNDLE_SIZE_IN_BYTES;
+ opval += (int)pc;
+ }
+
+ /* Record the final value. */
+ d->operands[i] = op;
+ d->operand_values[i] = opval;
+ }
+ }
+
+ return num_instructions;
+}
diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
new file mode 100644
index 000000000000..b9ab25a889b5
--- /dev/null
+++ b/arch/tile/kernel/time.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Support the cycle counter clocksource and tile timer clock event device.
+ */
+
+#include <linux/time.h>
+#include <linux/timex.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/hardirq.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/delay.h>
+#include <asm/irq_regs.h>
+#include <asm/traps.h>
+#include <hv/hypervisor.h>
+#include <arch/interrupts.h>
+#include <arch/spr_def.h>
+
+
+/*
+ * Define the cycle counter clock source.
+ */
+
+/* How many cycles per second we are running at. */
+static cycles_t cycles_per_sec __write_once;
+
+/*
+ * We set up shift and multiply values with a minsec of five seconds,
+ * since our timer counter counts down 31 bits at a frequency of
+ * no less than 500 MHz. See @minsec for clocks_calc_mult_shift().
+ * We could use a different value for the 64-bit free-running
+ * cycle counter, but we use the same one for consistency, and since
+ * we will be reasonably precise with this value anyway.
+ */
+#define TILE_MINSEC 5
+
+cycles_t get_clock_rate(void)
+{
+ return cycles_per_sec;
+}
+
+#if CHIP_HAS_SPLIT_CYCLE()
+cycles_t get_cycles(void)
+{
+ unsigned int high = __insn_mfspr(SPR_CYCLE_HIGH);
+ unsigned int low = __insn_mfspr(SPR_CYCLE_LOW);
+ unsigned int high2 = __insn_mfspr(SPR_CYCLE_HIGH);
+
+ while (unlikely(high != high2)) {
+ low = __insn_mfspr(SPR_CYCLE_LOW);
+ high = high2;
+ high2 = __insn_mfspr(SPR_CYCLE_HIGH);
+ }
+
+ return (((cycles_t)high) << 32) | low;
+}
+#endif
+
+static cycles_t clocksource_get_cycles(struct clocksource *cs)
+{
+ return get_cycles();
+}
+
+static struct clocksource cycle_counter_cs = {
+ .name = "cycle counter",
+ .rating = 300,
+ .read = clocksource_get_cycles,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+/*
+ * Called very early from setup_arch() to set cycles_per_sec.
+ * We initialize it early so we can use it to set up loops_per_jiffy.
+ */
+void __init setup_clock(void)
+{
+ cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED);
+ clocksource_calc_mult_shift(&cycle_counter_cs, cycles_per_sec,
+ TILE_MINSEC);
+}
+
+void __init calibrate_delay(void)
+{
+ loops_per_jiffy = get_clock_rate() / HZ;
+ pr_info("Clock rate yields %lu.%02lu BogoMIPS (lpj=%lu)\n",
+ loops_per_jiffy/(500000/HZ),
+ (loops_per_jiffy/(5000/HZ)) % 100, loops_per_jiffy);
+}
+
+/* Called fairly late in init/main.c, but before we go smp. */
+void __init time_init(void)
+{
+ /* Initialize and register the clock source. */
+ clocksource_register(&cycle_counter_cs);
+
+ /* Start up the tile-timer interrupt source on the boot cpu. */
+ setup_tile_timer();
+}
+
+
+/*
+ * Define the tile timer clock event device. The timer is driven by
+ * the TILE_TIMER_CONTROL register, which consists of a 31-bit down
+ * counter, plus bit 31, which signifies that the counter has wrapped
+ * from zero to (2**31) - 1. The INT_TILE_TIMER interrupt will be
+ * raised as long as bit 31 is set.
+ */
+
+#define MAX_TICK 0x7fffffff /* we have 31 bits of countdown timer */
+
+static int tile_timer_set_next_event(unsigned long ticks,
+ struct clock_event_device *evt)
+{
+ BUG_ON(ticks > MAX_TICK);
+ __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks);
+ raw_local_irq_unmask_now(INT_TILE_TIMER);
+ return 0;
+}
+
+/*
+ * Whenever anyone tries to change modes, we just mask interrupts
+ * and wait for the next event to get set.
+ */
+static void tile_timer_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ raw_local_irq_mask_now(INT_TILE_TIMER);
+}
+
+/*
+ * Set min_delta_ns to 1 microsecond, since it takes about
+ * that long to fire the interrupt.
+ */
+static DEFINE_PER_CPU(struct clock_event_device, tile_timer) = {
+ .name = "tile timer",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .min_delta_ns = 1000,
+ .rating = 100,
+ .irq = -1,
+ .set_next_event = tile_timer_set_next_event,
+ .set_mode = tile_timer_set_mode,
+};
+
+void __cpuinit setup_tile_timer(void)
+{
+ struct clock_event_device *evt = &__get_cpu_var(tile_timer);
+
+ /* Fill in fields that are speed-specific. */
+ clockevents_calc_mult_shift(evt, cycles_per_sec, TILE_MINSEC);
+ evt->max_delta_ns = clockevent_delta2ns(MAX_TICK, evt);
+
+ /* Mark as being for this cpu only. */
+ evt->cpumask = cpumask_of(smp_processor_id());
+
+ /* Start out with timer not firing. */
+ raw_local_irq_mask_now(INT_TILE_TIMER);
+
+ /* Register tile timer. */
+ clockevents_register_device(evt);
+}
+
+/* Called from the interrupt vector. */
+void do_timer_interrupt(struct pt_regs *regs, int fault_num)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+ struct clock_event_device *evt = &__get_cpu_var(tile_timer);
+
+ /*
+ * Mask the timer interrupt here, since we are a oneshot timer
+ * and there are now by definition no events pending.
+ */
+ raw_local_irq_mask(INT_TILE_TIMER);
+
+ /* Track time spent here in an interrupt context */
+ irq_enter();
+
+ /* Track interrupt count. */
+ __get_cpu_var(irq_stat).irq_timer_count++;
+
+ /* Call the generic timer handler */
+ evt->event_handler(evt);
+
+ /*
+ * Track time spent against the current process again and
+ * process any softirqs if they are waiting.
+ */
+ irq_exit();
+
+ set_irq_regs(old_regs);
+}
+
+/*
+ * Scheduler clock - returns current time in nanosec units.
+ * Note that with LOCKDEP, this is called during lockdep_init(), and
+ * we will claim that sched_clock() is zero for a little while, until
+ * we run setup_clock(), above.
+ */
+unsigned long long sched_clock(void)
+{
+ return clocksource_cyc2ns(get_cycles(),
+ cycle_counter_cs.mult,
+ cycle_counter_cs.shift);
+}
+
+int setup_profiling_timer(unsigned int multiplier)
+{
+ return -EINVAL;
+}
diff --git a/arch/tile/kernel/tlb.c b/arch/tile/kernel/tlb.c
new file mode 100644
index 000000000000..2dffc1044d83
--- /dev/null
+++ b/arch/tile/kernel/tlb.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
+#include <hv/hypervisor.h>
+
+/* From tlbflush.h */
+DEFINE_PER_CPU(int, current_asid);
+int min_asid, max_asid;
+
+/*
+ * Note that we flush the L1I (for VM_EXEC pages) as well as the TLB
+ * so that when we are unmapping an executable page, we also flush it.
+ * Combined with flushing the L1I at context switch time, this means
+ * we don't have to do any other icache flushes.
+ */
+
+void flush_tlb_mm(struct mm_struct *mm)
+{
+ HV_Remote_ASID asids[NR_CPUS];
+ int i = 0, cpu;
+ for_each_cpu(cpu, &mm->cpu_vm_mask) {
+ HV_Remote_ASID *asid = &asids[i++];
+ asid->y = cpu / smp_topology.width;
+ asid->x = cpu % smp_topology.width;
+ asid->asid = per_cpu(current_asid, cpu);
+ }
+ flush_remote(0, HV_FLUSH_EVICT_L1I, &mm->cpu_vm_mask,
+ 0, 0, 0, NULL, asids, i);
+}
+
+void flush_tlb_current_task(void)
+{
+ flush_tlb_mm(current->mm);
+}
+
+void flush_tlb_page_mm(const struct vm_area_struct *vma, struct mm_struct *mm,
+ unsigned long va)
+{
+ unsigned long size = hv_page_size(vma);
+ int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
+ flush_remote(0, cache, &mm->cpu_vm_mask,
+ va, size, size, &mm->cpu_vm_mask, NULL, 0);
+}
+
+void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
+{
+ flush_tlb_page_mm(vma, vma->vm_mm, va);
+}
+EXPORT_SYMBOL(flush_tlb_page);
+
+void flush_tlb_range(const struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ unsigned long size = hv_page_size(vma);
+ struct mm_struct *mm = vma->vm_mm;
+ int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
+ flush_remote(0, cache, &mm->cpu_vm_mask, start, end - start, size,
+ &mm->cpu_vm_mask, NULL, 0);
+}
+
+void flush_tlb_all(void)
+{
+ int i;
+ for (i = 0; ; ++i) {
+ HV_VirtAddrRange r = hv_inquire_virtual(i);
+ if (r.size == 0)
+ break;
+ flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
+ r.start, r.size, PAGE_SIZE, cpu_online_mask,
+ NULL, 0);
+ flush_remote(0, 0, NULL,
+ r.start, r.size, HPAGE_SIZE, cpu_online_mask,
+ NULL, 0);
+ }
+}
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+ flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
+ start, end - start, PAGE_SIZE, cpu_online_mask, NULL, 0);
+}
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c
new file mode 100644
index 000000000000..3870abbeeaa2
--- /dev/null
+++ b/arch/tile/kernel/traps.c
@@ -0,0 +1,317 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kprobes.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/uaccess.h>
+#include <linux/ptrace.h>
+#include <asm/opcode-tile.h>
+#include <asm/opcode_constants.h>
+#include <asm/stack.h>
+#include <asm/traps.h>
+
+#include <arch/interrupts.h>
+#include <arch/spr_def.h>
+
+void __init trap_init(void)
+{
+ /* Nothing needed here since we link code at .intrpt1 */
+}
+
+int unaligned_fixup = 1;
+
+static int __init setup_unaligned_fixup(char *str)
+{
+ /*
+ * Say "=-1" to completely disable it. If you just do "=0", we
+ * will still parse the instruction, then fire a SIGBUS with
+ * the correct address from inside the single_step code.
+ */
+ long val;
+ if (strict_strtol(str, 0, &val) != 0)
+ return 0;
+ unaligned_fixup = val;
+ pr_info("Fixups for unaligned data accesses are %s\n",
+ unaligned_fixup >= 0 ?
+ (unaligned_fixup ? "enabled" : "disabled") :
+ "completely disabled");
+ return 1;
+}
+__setup("unaligned_fixup=", setup_unaligned_fixup);
+
+#if CHIP_HAS_TILE_DMA()
+
+static int dma_disabled;
+
+static int __init nodma(char *str)
+{
+ pr_info("User-space DMA is disabled\n");
+ dma_disabled = 1;
+ return 1;
+}
+__setup("nodma", nodma);
+
+/* How to decode SPR_GPV_REASON */
+#define IRET_ERROR (1U << 31)
+#define MT_ERROR (1U << 30)
+#define MF_ERROR (1U << 29)
+#define SPR_INDEX ((1U << 15) - 1)
+#define SPR_MPL_SHIFT 9 /* starting bit position for MPL encoded in SPR */
+
+/*
+ * See if this GPV is just to notify the kernel of SPR use and we can
+ * retry the user instruction after adjusting some MPLs suitably.
+ */
+static int retry_gpv(unsigned int gpv_reason)
+{
+ int mpl;
+
+ if (gpv_reason & IRET_ERROR)
+ return 0;
+
+ BUG_ON((gpv_reason & (MT_ERROR|MF_ERROR)) == 0);
+ mpl = (gpv_reason & SPR_INDEX) >> SPR_MPL_SHIFT;
+ if (mpl == INT_DMA_NOTIFY && !dma_disabled) {
+ /* User is turning on DMA. Allow it and retry. */
+ printk(KERN_DEBUG "Process %d/%s is now enabled for DMA\n",
+ current->pid, current->comm);
+ BUG_ON(current->thread.tile_dma_state.enabled);
+ current->thread.tile_dma_state.enabled = 1;
+ grant_dma_mpls();
+ return 1;
+ }
+
+ return 0;
+}
+
+#endif /* CHIP_HAS_TILE_DMA() */
+
+#ifdef __tilegx__
+#define bundle_bits tilegx_bundle_bits
+#else
+#define bundle_bits tile_bundle_bits
+#endif
+
+extern bundle_bits bpt_code;
+
+asm(".pushsection .rodata.bpt_code,\"a\";"
+ ".align 8;"
+ "bpt_code: bpt;"
+ ".size bpt_code,.-bpt_code;"
+ ".popsection");
+
+static int special_ill(bundle_bits bundle, int *sigp, int *codep)
+{
+ int sig, code, maxcode;
+
+ if (bundle == bpt_code) {
+ *sigp = SIGTRAP;
+ *codep = TRAP_BRKPT;
+ return 1;
+ }
+
+ /* If it's a "raise" bundle, then "ill" must be in pipe X1. */
+#ifdef __tilegx__
+ if ((bundle & TILEGX_BUNDLE_MODE_MASK) != 0)
+ return 0;
+ if (get_Opcode_X1(bundle) != UNARY_OPCODE_X1)
+ return 0;
+ if (get_UnaryOpcodeExtension_X1(bundle) != ILL_UNARY_OPCODE_X1)
+ return 0;
+#else
+ if (bundle & TILE_BUNDLE_Y_ENCODING_MASK)
+ return 0;
+ if (get_Opcode_X1(bundle) != SHUN_0_OPCODE_X1)
+ return 0;
+ if (get_UnShOpcodeExtension_X1(bundle) != UN_0_SHUN_0_OPCODE_X1)
+ return 0;
+ if (get_UnOpcodeExtension_X1(bundle) != ILL_UN_0_SHUN_0_OPCODE_X1)
+ return 0;
+#endif
+
+ /* Check that the magic distinguishers are set to mean "raise". */
+ if (get_Dest_X1(bundle) != 29 || get_SrcA_X1(bundle) != 37)
+ return 0;
+
+ /* There must be an "addli zero, zero, VAL" in X0. */
+ if (get_Opcode_X0(bundle) != ADDLI_OPCODE_X0)
+ return 0;
+ if (get_Dest_X0(bundle) != TREG_ZERO)
+ return 0;
+ if (get_SrcA_X0(bundle) != TREG_ZERO)
+ return 0;
+
+ /*
+ * Validate the proposed signal number and si_code value.
+ * Note that we embed these in the static instruction itself
+ * so that we perturb the register state as little as possible
+ * at the time of the actual fault; it's unlikely you'd ever
+ * need to dynamically choose which kind of fault to raise
+ * from user space.
+ */
+ sig = get_Imm16_X0(bundle) & 0x3f;
+ switch (sig) {
+ case SIGILL:
+ maxcode = NSIGILL;
+ break;
+ case SIGFPE:
+ maxcode = NSIGFPE;
+ break;
+ case SIGSEGV:
+ maxcode = NSIGSEGV;
+ break;
+ case SIGBUS:
+ maxcode = NSIGBUS;
+ break;
+ case SIGTRAP:
+ maxcode = NSIGTRAP;
+ break;
+ default:
+ return 0;
+ }
+ code = (get_Imm16_X0(bundle) >> 6) & 0xf;
+ if (code <= 0 || code > maxcode)
+ return 0;
+
+ /* Make it the requested signal. */
+ *sigp = sig;
+ *codep = code | __SI_FAULT;
+ return 1;
+}
+
+void __kprobes do_trap(struct pt_regs *regs, int fault_num,
+ unsigned long reason)
+{
+ siginfo_t info = { 0 };
+ int signo, code;
+ unsigned long address;
+ bundle_bits instr;
+
+ /* Re-enable interrupts. */
+ local_irq_enable();
+
+ /*
+ * If it hits in kernel mode and we can't fix it up, just exit the
+ * current process and hope for the best.
+ */
+ if (!user_mode(regs)) {
+ if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */
+ return;
+ pr_alert("Kernel took bad trap %d at PC %#lx\n",
+ fault_num, regs->pc);
+ if (fault_num == INT_GPV)
+ pr_alert("GPV_REASON is %#lx\n", reason);
+ show_regs(regs);
+ do_exit(SIGKILL); /* FIXME: implement i386 die() */
+ return;
+ }
+
+ switch (fault_num) {
+ case INT_ILL:
+ if (copy_from_user(&instr, (void __user *)regs->pc,
+ sizeof(instr))) {
+ pr_err("Unreadable instruction for INT_ILL:"
+ " %#lx\n", regs->pc);
+ do_exit(SIGKILL);
+ return;
+ }
+ if (!special_ill(instr, &signo, &code)) {
+ signo = SIGILL;
+ code = ILL_ILLOPC;
+ }
+ address = regs->pc;
+ break;
+ case INT_GPV:
+#if CHIP_HAS_TILE_DMA()
+ if (retry_gpv(reason))
+ return;
+#endif
+ /*FALLTHROUGH*/
+ case INT_UDN_ACCESS:
+ case INT_IDN_ACCESS:
+#if CHIP_HAS_SN()
+ case INT_SN_ACCESS:
+#endif
+ signo = SIGILL;
+ code = ILL_PRVREG;
+ address = regs->pc;
+ break;
+ case INT_SWINT_3:
+ case INT_SWINT_2:
+ case INT_SWINT_0:
+ signo = SIGILL;
+ code = ILL_ILLTRP;
+ address = regs->pc;
+ break;
+ case INT_UNALIGN_DATA:
+#ifndef __tilegx__ /* FIXME: GX: no single-step yet */
+ if (unaligned_fixup >= 0) {
+ struct single_step_state *state =
+ current_thread_info()->step_state;
+ if (!state ||
+ (void __user *)(regs->pc) != state->buffer) {
+ single_step_once(regs);
+ return;
+ }
+ }
+#endif
+ signo = SIGBUS;
+ code = BUS_ADRALN;
+ address = 0;
+ break;
+ case INT_DOUBLE_FAULT:
+ /*
+ * For double fault, "reason" is actually passed as
+ * SYSTEM_SAVE_1_2, the hypervisor's double-fault info, so
+ * we can provide the original fault number rather than
+ * the uninteresting "INT_DOUBLE_FAULT" so the user can
+ * learn what actually struck while PL0 ICS was set.
+ */
+ fault_num = reason;
+ signo = SIGILL;
+ code = ILL_DBLFLT;
+ address = regs->pc;
+ break;
+#ifdef __tilegx__
+ case INT_ILL_TRANS:
+ signo = SIGSEGV;
+ code = SEGV_MAPERR;
+ if (reason & SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK)
+ address = regs->pc;
+ else
+ address = 0; /* FIXME: GX: single-step for address */
+ break;
+#endif
+ default:
+ panic("Unexpected do_trap interrupt number %d", fault_num);
+ return;
+ }
+
+ info.si_signo = signo;
+ info.si_code = code;
+ info.si_addr = (void __user *)address;
+ if (signo == SIGILL)
+ info.si_trapno = fault_num;
+ force_sig_info(signo, &info, current);
+}
+
+void kernel_double_fault(int dummy, ulong pc, ulong lr, ulong sp, ulong r52)
+{
+ _dump_stack(dummy, pc, lr, sp, r52);
+ pr_emerg("Double fault: exiting\n");
+ machine_halt();
+}
diff --git a/arch/tile/kernel/vmlinux.lds.S b/arch/tile/kernel/vmlinux.lds.S
new file mode 100644
index 000000000000..25fdc0c1839a
--- /dev/null
+++ b/arch/tile/kernel/vmlinux.lds.S
@@ -0,0 +1,98 @@
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
+#include <asm/cache.h>
+#include <asm/thread_info.h>
+#include <hv/hypervisor.h>
+
+/* Text loads starting from the supervisor interrupt vector address. */
+#define TEXT_OFFSET MEM_SV_INTRPT
+
+OUTPUT_ARCH(tile)
+ENTRY(_start)
+jiffies = jiffies_64;
+
+PHDRS
+{
+ intrpt1 PT_LOAD ;
+ text PT_LOAD ;
+ data PT_LOAD ;
+}
+SECTIONS
+{
+ /* Text is loaded with a different VA than data; start with text. */
+ #undef LOAD_OFFSET
+ #define LOAD_OFFSET TEXT_OFFSET
+
+ /* Interrupt vectors */
+ .intrpt1 (LOAD_OFFSET) : AT ( 0 ) /* put at the start of physical memory */
+ {
+ _text = .;
+ _stext = .;
+ *(.intrpt1)
+ } :intrpt1 =0
+
+ /* Hypervisor call vectors */
+ #include "hvglue.lds"
+
+ /* Now the real code */
+ . = ALIGN(0x20000);
+ .text : AT (ADDR(.text) - LOAD_OFFSET) {
+ HEAD_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ __fix_text_end = .; /* tile-cpack won't rearrange before this */
+ TEXT_TEXT
+ *(.text.*)
+ *(.coldtext*)
+ *(.fixup)
+ *(.gnu.warning)
+ } :text =0
+ _etext = .;
+
+ /* "Init" is divided into two areas with very different virtual addresses. */
+ INIT_TEXT_SECTION(PAGE_SIZE)
+
+ /* Now we skip back to PAGE_OFFSET for the data. */
+ . = (. - TEXT_OFFSET + PAGE_OFFSET);
+ #undef LOAD_OFFSET
+ #define LOAD_OFFSET PAGE_OFFSET
+
+ . = ALIGN(PAGE_SIZE);
+ VMLINUX_SYMBOL(_sinitdata) = .;
+ .init.page : AT (ADDR(.init.page) - LOAD_OFFSET) {
+ *(.init.page)
+ } :data =0
+ INIT_DATA_SECTION(16)
+ PERCPU(PAGE_SIZE)
+ . = ALIGN(PAGE_SIZE);
+ VMLINUX_SYMBOL(_einitdata) = .;
+
+ _sdata = .; /* Start of data section */
+
+ RO_DATA_SECTION(PAGE_SIZE)
+
+ /* initially writeable, then read-only */
+ . = ALIGN(PAGE_SIZE);
+ __w1data_begin = .;
+ .w1data : AT(ADDR(.w1data) - LOAD_OFFSET) {
+ VMLINUX_SYMBOL(__w1data_begin) = .;
+ *(.w1data)
+ VMLINUX_SYMBOL(__w1data_end) = .;
+ }
+
+ RW_DATA_SECTION(L2_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
+
+ _edata = .;
+
+ EXCEPTION_TABLE(L2_CACHE_BYTES)
+ NOTES
+
+
+ BSS_SECTION(8, PAGE_SIZE, 1)
+ _end = . ;
+
+ STABS_DEBUG
+ DWARF_DEBUG
+
+ DISCARDS
+}
diff --git a/arch/tile/lib/Makefile b/arch/tile/lib/Makefile
new file mode 100644
index 000000000000..438af38bc9eb
--- /dev/null
+++ b/arch/tile/lib/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for TILE-specific library files..
+#
+
+lib-y = cacheflush.o checksum.o cpumask.o delay.o \
+ mb_incoherent.o uaccess.o \
+ memcpy_$(BITS).o memchr_$(BITS).o memmove_$(BITS).o memset_$(BITS).o \
+ strchr_$(BITS).o strlen_$(BITS).o
+
+ifneq ($(CONFIG_TILEGX),y)
+lib-y += atomic_32.o atomic_asm_32.o memcpy_tile64.o
+endif
+
+lib-$(CONFIG_SMP) += spinlock_$(BITS).o usercopy_$(BITS).o
+
+obj-$(CONFIG_MODULES) += exports.o
diff --git a/arch/tile/lib/atomic_32.c b/arch/tile/lib/atomic_32.c
new file mode 100644
index 000000000000..8040b42a8eea
--- /dev/null
+++ b/arch/tile/lib/atomic_32.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/cache.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <asm/atomic.h>
+#include <asm/futex.h>
+#include <arch/chip.h>
+
+/* See <asm/atomic_32.h> */
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+
+/*
+ * A block of memory containing locks for atomic ops. Each instance of this
+ * struct will be homed on a different CPU.
+ */
+struct atomic_locks_on_cpu {
+ int lock[ATOMIC_HASH_L2_SIZE];
+} __attribute__((aligned(ATOMIC_HASH_L2_SIZE * 4)));
+
+static DEFINE_PER_CPU(struct atomic_locks_on_cpu, atomic_lock_pool);
+
+/* The locks we'll use until __init_atomic_per_cpu is called. */
+static struct atomic_locks_on_cpu __initdata initial_atomic_locks;
+
+/* Hash into this vector to get a pointer to lock for the given atomic. */
+struct atomic_locks_on_cpu *atomic_lock_ptr[ATOMIC_HASH_L1_SIZE]
+ __write_once = {
+ [0 ... ATOMIC_HASH_L1_SIZE-1] (&initial_atomic_locks)
+};
+
+#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+/* This page is remapped on startup to be hash-for-home. */
+int atomic_locks[PAGE_SIZE / sizeof(int) /* Only ATOMIC_HASH_SIZE is used */]
+ __attribute__((aligned(PAGE_SIZE), section(".bss.page_aligned")));
+
+#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+static inline int *__atomic_hashed_lock(volatile void *v)
+{
+ /* NOTE: this code must match "sys_cmpxchg" in kernel/intvec.S */
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ unsigned long i =
+ (unsigned long) v & ((PAGE_SIZE-1) & -sizeof(long long));
+ unsigned long n = __insn_crc32_32(0, i);
+
+ /* Grab high bits for L1 index. */
+ unsigned long l1_index = n >> ((sizeof(n) * 8) - ATOMIC_HASH_L1_SHIFT);
+ /* Grab low bits for L2 index. */
+ unsigned long l2_index = n & (ATOMIC_HASH_L2_SIZE - 1);
+
+ return &atomic_lock_ptr[l1_index]->lock[l2_index];
+#else
+ /*
+ * Use bits [3, 3 + ATOMIC_HASH_SHIFT) as the lock index.
+ * Using mm works here because atomic_locks is page aligned.
+ */
+ unsigned long ptr = __insn_mm((unsigned long)v >> 1,
+ (unsigned long)atomic_locks,
+ 2, (ATOMIC_HASH_SHIFT + 2) - 1);
+ return (int *)ptr;
+#endif
+}
+
+#ifdef CONFIG_SMP
+/* Return whether the passed pointer is a valid atomic lock pointer. */
+static int is_atomic_lock(int *p)
+{
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ int i;
+ for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
+
+ if (p >= &atomic_lock_ptr[i]->lock[0] &&
+ p < &atomic_lock_ptr[i]->lock[ATOMIC_HASH_L2_SIZE]) {
+ return 1;
+ }
+ }
+ return 0;
+#else
+ return p >= &atomic_locks[0] && p < &atomic_locks[ATOMIC_HASH_SIZE];
+#endif
+}
+
+void __atomic_fault_unlock(int *irqlock_word)
+{
+ BUG_ON(!is_atomic_lock(irqlock_word));
+ BUG_ON(*irqlock_word != 1);
+ *irqlock_word = 0;
+}
+
+#endif /* CONFIG_SMP */
+
+static inline int *__atomic_setup(volatile void *v)
+{
+ /* Issue a load to the target to bring it into cache. */
+ *(volatile int *)v;
+ return __atomic_hashed_lock(v);
+}
+
+int _atomic_xchg(atomic_t *v, int n)
+{
+ return __atomic_xchg(&v->counter, __atomic_setup(v), n).val;
+}
+EXPORT_SYMBOL(_atomic_xchg);
+
+int _atomic_xchg_add(atomic_t *v, int i)
+{
+ return __atomic_xchg_add(&v->counter, __atomic_setup(v), i).val;
+}
+EXPORT_SYMBOL(_atomic_xchg_add);
+
+int _atomic_xchg_add_unless(atomic_t *v, int a, int u)
+{
+ /*
+ * Note: argument order is switched here since it is easier
+ * to use the first argument consistently as the "old value"
+ * in the assembly, as is done for _atomic_cmpxchg().
+ */
+ return __atomic_xchg_add_unless(&v->counter, __atomic_setup(v), u, a)
+ .val;
+}
+EXPORT_SYMBOL(_atomic_xchg_add_unless);
+
+int _atomic_cmpxchg(atomic_t *v, int o, int n)
+{
+ return __atomic_cmpxchg(&v->counter, __atomic_setup(v), o, n).val;
+}
+EXPORT_SYMBOL(_atomic_cmpxchg);
+
+unsigned long _atomic_or(volatile unsigned long *p, unsigned long mask)
+{
+ return __atomic_or((int *)p, __atomic_setup(p), mask).val;
+}
+EXPORT_SYMBOL(_atomic_or);
+
+unsigned long _atomic_andn(volatile unsigned long *p, unsigned long mask)
+{
+ return __atomic_andn((int *)p, __atomic_setup(p), mask).val;
+}
+EXPORT_SYMBOL(_atomic_andn);
+
+unsigned long _atomic_xor(volatile unsigned long *p, unsigned long mask)
+{
+ return __atomic_xor((int *)p, __atomic_setup(p), mask).val;
+}
+EXPORT_SYMBOL(_atomic_xor);
+
+
+u64 _atomic64_xchg(atomic64_t *v, u64 n)
+{
+ return __atomic64_xchg(&v->counter, __atomic_setup(v), n);
+}
+EXPORT_SYMBOL(_atomic64_xchg);
+
+u64 _atomic64_xchg_add(atomic64_t *v, u64 i)
+{
+ return __atomic64_xchg_add(&v->counter, __atomic_setup(v), i);
+}
+EXPORT_SYMBOL(_atomic64_xchg_add);
+
+u64 _atomic64_xchg_add_unless(atomic64_t *v, u64 a, u64 u)
+{
+ /*
+ * Note: argument order is switched here since it is easier
+ * to use the first argument consistently as the "old value"
+ * in the assembly, as is done for _atomic_cmpxchg().
+ */
+ return __atomic64_xchg_add_unless(&v->counter, __atomic_setup(v),
+ u, a);
+}
+EXPORT_SYMBOL(_atomic64_xchg_add_unless);
+
+u64 _atomic64_cmpxchg(atomic64_t *v, u64 o, u64 n)
+{
+ return __atomic64_cmpxchg(&v->counter, __atomic_setup(v), o, n);
+}
+EXPORT_SYMBOL(_atomic64_cmpxchg);
+
+
+static inline int *__futex_setup(int __user *v)
+{
+ /*
+ * Issue a prefetch to the counter to bring it into cache.
+ * As for __atomic_setup, but we can't do a read into the L1
+ * since it might fault; instead we do a prefetch into the L2.
+ */
+ __insn_prefetch(v);
+ return __atomic_hashed_lock((int __force *)v);
+}
+
+struct __get_user futex_set(int __user *v, int i)
+{
+ return __atomic_xchg((int __force *)v, __futex_setup(v), i);
+}
+
+struct __get_user futex_add(int __user *v, int n)
+{
+ return __atomic_xchg_add((int __force *)v, __futex_setup(v), n);
+}
+
+struct __get_user futex_or(int __user *v, int n)
+{
+ return __atomic_or((int __force *)v, __futex_setup(v), n);
+}
+
+struct __get_user futex_andn(int __user *v, int n)
+{
+ return __atomic_andn((int __force *)v, __futex_setup(v), n);
+}
+
+struct __get_user futex_xor(int __user *v, int n)
+{
+ return __atomic_xor((int __force *)v, __futex_setup(v), n);
+}
+
+struct __get_user futex_cmpxchg(int __user *v, int o, int n)
+{
+ return __atomic_cmpxchg((int __force *)v, __futex_setup(v), o, n);
+}
+
+/*
+ * If any of the atomic or futex routines hit a bad address (not in
+ * the page tables at kernel PL) this routine is called. The futex
+ * routines are never used on kernel space, and the normal atomics and
+ * bitops are never used on user space. So a fault on kernel space
+ * must be fatal, but a fault on userspace is a futex fault and we
+ * need to return -EFAULT. Note that the context this routine is
+ * invoked in is the context of the "_atomic_xxx()" routines called
+ * by the functions in this file.
+ */
+struct __get_user __atomic_bad_address(int __user *addr)
+{
+ if (unlikely(!access_ok(VERIFY_WRITE, addr, sizeof(int))))
+ panic("Bad address used for kernel atomic op: %p\n", addr);
+ return (struct __get_user) { .err = -EFAULT };
+}
+
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+static int __init noatomichash(char *str)
+{
+ pr_warning("noatomichash is deprecated.\n");
+ return 1;
+}
+__setup("noatomichash", noatomichash);
+#endif
+
+void __init __init_atomic_per_cpu(void)
+{
+#if ATOMIC_LOCKS_FOUND_VIA_TABLE()
+
+ unsigned int i;
+ int actual_cpu;
+
+ /*
+ * Before this is called from setup, we just have one lock for
+ * all atomic objects/operations. Here we replace the
+ * elements of atomic_lock_ptr so that they point at per_cpu
+ * integers. This seemingly over-complex approach stems from
+ * the fact that DEFINE_PER_CPU defines an entry for each cpu
+ * in the grid, not each cpu from 0..ATOMIC_HASH_SIZE-1. But
+ * for efficient hashing of atomics to their locks we want a
+ * compile time constant power of 2 for the size of this
+ * table, so we use ATOMIC_HASH_SIZE.
+ *
+ * Here we populate atomic_lock_ptr from the per cpu
+ * atomic_lock_pool, interspersing by actual cpu so that
+ * subsequent elements are homed on consecutive cpus.
+ */
+
+ actual_cpu = cpumask_first(cpu_possible_mask);
+
+ for (i = 0; i < ATOMIC_HASH_L1_SIZE; ++i) {
+ /*
+ * Preincrement to slightly bias against using cpu 0,
+ * which has plenty of stuff homed on it already.
+ */
+ actual_cpu = cpumask_next(actual_cpu, cpu_possible_mask);
+ if (actual_cpu >= nr_cpu_ids)
+ actual_cpu = cpumask_first(cpu_possible_mask);
+
+ atomic_lock_ptr[i] = &per_cpu(atomic_lock_pool, actual_cpu);
+ }
+
+#else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+ /* Validate power-of-two and "bigger than cpus" assumption */
+ BUG_ON(ATOMIC_HASH_SIZE & (ATOMIC_HASH_SIZE-1));
+ BUG_ON(ATOMIC_HASH_SIZE < nr_cpu_ids);
+
+ /*
+ * On TILEPro we prefer to use a single hash-for-home
+ * page, since this means atomic operations are less
+ * likely to encounter a TLB fault and thus should
+ * in general perform faster. You may wish to disable
+ * this in situations where few hash-for-home tiles
+ * are configured.
+ */
+ BUG_ON((unsigned long)atomic_locks % PAGE_SIZE != 0);
+
+ /* The locks must all fit on one page. */
+ BUG_ON(ATOMIC_HASH_SIZE * sizeof(int) > PAGE_SIZE);
+
+ /*
+ * We use the page offset of the atomic value's address as
+ * an index into atomic_locks, excluding the low 3 bits.
+ * That should not produce more indices than ATOMIC_HASH_SIZE.
+ */
+ BUG_ON((PAGE_SIZE >> 3) > ATOMIC_HASH_SIZE);
+
+#endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
+
+ /* The futex code makes this assumption, so we validate it here. */
+ BUG_ON(sizeof(atomic_t) != sizeof(int));
+}
diff --git a/arch/tile/lib/atomic_asm_32.S b/arch/tile/lib/atomic_asm_32.S
new file mode 100644
index 000000000000..5a5514b77e78
--- /dev/null
+++ b/arch/tile/lib/atomic_asm_32.S
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Support routines for atomic operations. Each function takes:
+ *
+ * r0: address to manipulate
+ * r1: pointer to atomic lock guarding this operation (for FUTEX_LOCK_REG)
+ * r2: new value to write, or for cmpxchg/add_unless, value to compare against
+ * r3: (cmpxchg/xchg_add_unless) new value to write or add;
+ * (atomic64 ops) high word of value to write
+ * r4/r5: (cmpxchg64/add_unless64) new value to write or add
+ *
+ * The 32-bit routines return a "struct __get_user" so that the futex code
+ * has an opportunity to return -EFAULT to the user if needed.
+ * The 64-bit routines just return a "long long" with the value,
+ * since they are only used from kernel space and don't expect to fault.
+ * Support for 16-bit ops is included in the framework but we don't provide
+ * any (x86_64 has an atomic_inc_short(), so we might want to some day).
+ *
+ * Note that the caller is advised to issue a suitable L1 or L2
+ * prefetch on the address being manipulated to avoid extra stalls.
+ * In addition, the hot path is on two icache lines, and we start with
+ * a jump to the second line to make sure they are both in cache so
+ * that we never stall waiting on icache fill while holding the lock.
+ * (This doesn't work out with most 64-bit ops, since they consume
+ * too many bundles, so may take an extra i-cache stall.)
+ *
+ * These routines set the INTERRUPT_CRITICAL_SECTION bit, just
+ * like sys_cmpxchg(), so that NMIs like PERF_COUNT will not interrupt
+ * the code, just page faults.
+ *
+ * If the load or store faults in a way that can be directly fixed in
+ * the do_page_fault_ics() handler (e.g. a vmalloc reference) we fix it
+ * directly, return to the instruction that faulted, and retry it.
+ *
+ * If the load or store faults in a way that potentially requires us
+ * to release the atomic lock, then retry (e.g. a migrating PTE), we
+ * reset the PC in do_page_fault_ics() to the "tns" instruction so
+ * that on return we will reacquire the lock and restart the op. We
+ * are somewhat overloading the exception_table_entry notion by doing
+ * this, since those entries are not normally used for migrating PTEs.
+ *
+ * If the main page fault handler discovers a bad address, it will see
+ * the PC pointing to the "tns" instruction (due to the earlier
+ * exception_table_entry processing in do_page_fault_ics), and
+ * re-reset the PC to the fault handler, atomic_bad_address(), which
+ * effectively takes over from the atomic op and can either return a
+ * bad "struct __get_user" (for user addresses) or can just panic (for
+ * bad kernel addresses).
+ *
+ * Note that if the value we would store is the same as what we
+ * loaded, we bypass the load. Other platforms with true atomics can
+ * make the guarantee that a non-atomic __clear_bit(), for example,
+ * can safely race with an atomic test_and_set_bit(); this example is
+ * from bit_spinlock.h in slub_lock() / slub_unlock(). We can't do
+ * that on Tile since the "atomic" op is really just a
+ * read/modify/write, and can race with the non-atomic
+ * read/modify/write. However, if we can short-circuit the write when
+ * it is not needed, in the atomic case, we avoid the race.
+ */
+
+#include <linux/linkage.h>
+#include <asm/atomic.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+ .section .text.atomic,"ax"
+ENTRY(__start_atomic_asm_code)
+
+ .macro atomic_op, name, bitwidth, body
+ .align 64
+STD_ENTRY_SECTION(__atomic\name, .text.atomic)
+ {
+ movei r24, 1
+ j 4f /* branch to second cache line */
+ }
+1: {
+ .ifc \bitwidth,16
+ lh r22, r0
+ .else
+ lw r22, r0
+ addi r28, r0, 4
+ .endif
+ }
+ .ifc \bitwidth,64
+ lw r23, r28
+ .endif
+ \body /* set r24, and r25 if 64-bit */
+ {
+ seq r26, r22, r24
+ seq r27, r23, r25
+ }
+ .ifc \bitwidth,64
+ bbnst r27, 2f
+ .endif
+ bbs r26, 3f /* skip write-back if it's the same value */
+2: {
+ .ifc \bitwidth,16
+ sh r0, r24
+ .else
+ sw r0, r24
+ .endif
+ }
+ .ifc \bitwidth,64
+ sw r28, r25
+ .endif
+ mf
+3: {
+ move r0, r22
+ .ifc \bitwidth,64
+ move r1, r23
+ .else
+ move r1, zero
+ .endif
+ sw ATOMIC_LOCK_REG_NAME, zero
+ }
+ mtspr INTERRUPT_CRITICAL_SECTION, zero
+ jrp lr
+4: {
+ move ATOMIC_LOCK_REG_NAME, r1
+ mtspr INTERRUPT_CRITICAL_SECTION, r24
+ }
+#ifndef CONFIG_SMP
+ j 1b /* no atomic locks */
+#else
+ {
+ tns r21, ATOMIC_LOCK_REG_NAME
+ moveli r23, 2048 /* maximum backoff time in cycles */
+ }
+ {
+ bzt r21, 1b /* branch if lock acquired */
+ moveli r25, 32 /* starting backoff time in cycles */
+ }
+5: mtspr INTERRUPT_CRITICAL_SECTION, zero
+ mfspr r26, CYCLE_LOW /* get start point for this backoff */
+6: mfspr r22, CYCLE_LOW /* test to see if we've backed off enough */
+ sub r22, r22, r26
+ slt r22, r22, r25
+ bbst r22, 6b
+ {
+ mtspr INTERRUPT_CRITICAL_SECTION, r24
+ shli r25, r25, 1 /* double the backoff; retry the tns */
+ }
+ {
+ tns r21, ATOMIC_LOCK_REG_NAME
+ slt r26, r23, r25 /* is the proposed backoff too big? */
+ }
+ {
+ bzt r21, 1b /* branch if lock acquired */
+ mvnz r25, r26, r23
+ }
+ j 5b
+#endif
+ STD_ENDPROC(__atomic\name)
+ .ifc \bitwidth,32
+ .pushsection __ex_table,"a"
+ .word 1b, __atomic\name
+ .word 2b, __atomic\name
+ .word __atomic\name, __atomic_bad_address
+ .popsection
+ .endif
+ .endm
+
+atomic_op _cmpxchg, 32, "seq r26, r22, r2; { bbns r26, 3f; move r24, r3 }"
+atomic_op _xchg, 32, "move r24, r2"
+atomic_op _xchg_add, 32, "add r24, r22, r2"
+atomic_op _xchg_add_unless, 32, \
+ "sne r26, r22, r2; { bbns r26, 3f; add r24, r22, r3 }"
+atomic_op _or, 32, "or r24, r22, r2"
+atomic_op _andn, 32, "nor r2, r2, zero; and r24, r22, r2"
+atomic_op _xor, 32, "xor r24, r22, r2"
+
+atomic_op 64_cmpxchg, 64, "{ seq r26, r22, r2; seq r27, r23, r3 }; \
+ { bbns r26, 3f; move r24, r4 }; { bbns r27, 3f; move r25, r5 }"
+atomic_op 64_xchg, 64, "{ move r24, r2; move r25, r3 }"
+atomic_op 64_xchg_add, 64, "{ add r24, r22, r2; add r25, r23, r3 }; \
+ slt_u r26, r24, r22; add r25, r25, r26"
+atomic_op 64_xchg_add_unless, 64, \
+ "{ sne r26, r22, r2; sne r27, r23, r3 }; \
+ { bbns r26, 3f; add r24, r22, r4 }; \
+ { bbns r27, 3f; add r25, r23, r5 }; \
+ slt_u r26, r24, r22; add r25, r25, r26"
+
+ jrp lr /* happy backtracer */
+
+ENTRY(__end_atomic_asm_code)
diff --git a/arch/tile/lib/cacheflush.c b/arch/tile/lib/cacheflush.c
new file mode 100644
index 000000000000..11b6164c2097
--- /dev/null
+++ b/arch/tile/lib/cacheflush.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <asm/page.h>
+#include <asm/cacheflush.h>
+#include <arch/icache.h>
+
+
+void __flush_icache_range(unsigned long start, unsigned long end)
+{
+ invalidate_icache((const void *)start, end - start, PAGE_SIZE);
+}
diff --git a/arch/tile/lib/checksum.c b/arch/tile/lib/checksum.c
new file mode 100644
index 000000000000..e4bab5bd3f31
--- /dev/null
+++ b/arch/tile/lib/checksum.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ * Support code for the main lib/checksum.c.
+ */
+
+#include <net/checksum.h>
+#include <linux/module.h>
+
+static inline unsigned int longto16(unsigned long x)
+{
+ unsigned long ret;
+#ifdef __tilegx__
+ ret = __insn_v2sadu(x, 0);
+ ret = __insn_v2sadu(ret, 0);
+#else
+ ret = __insn_sadh_u(x, 0);
+ ret = __insn_sadh_u(ret, 0);
+#endif
+ return ret;
+}
+
+__wsum do_csum(const unsigned char *buff, int len)
+{
+ int odd, count;
+ unsigned long result = 0;
+
+ if (len <= 0)
+ goto out;
+ odd = 1 & (unsigned long) buff;
+ if (odd) {
+ result = (*buff << 8);
+ len--;
+ buff++;
+ }
+ count = len >> 1; /* nr of 16-bit words.. */
+ if (count) {
+ if (2 & (unsigned long) buff) {
+ result += *(const unsigned short *)buff;
+ count--;
+ len -= 2;
+ buff += 2;
+ }
+ count >>= 1; /* nr of 32-bit words.. */
+ if (count) {
+#ifdef __tilegx__
+ if (4 & (unsigned long) buff) {
+ unsigned int w = *(const unsigned int *)buff;
+ result = __insn_v2sadau(result, w, 0);
+ count--;
+ len -= 4;
+ buff += 4;
+ }
+ count >>= 1; /* nr of 64-bit words.. */
+#endif
+
+ /*
+ * This algorithm could wrap around for very
+ * large buffers, but those should be impossible.
+ */
+ BUG_ON(count >= 65530);
+
+ while (count) {
+ unsigned long w = *(const unsigned long *)buff;
+ count--;
+ buff += sizeof(w);
+#ifdef __tilegx__
+ result = __insn_v2sadau(result, w, 0);
+#else
+ result = __insn_sadah_u(result, w, 0);
+#endif
+ }
+#ifdef __tilegx__
+ if (len & 4) {
+ unsigned int w = *(const unsigned int *)buff;
+ result = __insn_v2sadau(result, w, 0);
+ buff += 4;
+ }
+#endif
+ }
+ if (len & 2) {
+ result += *(const unsigned short *) buff;
+ buff += 2;
+ }
+ }
+ if (len & 1)
+ result += *buff;
+ result = longto16(result);
+ if (odd)
+ result = swab16(result);
+out:
+ return result;
+}
diff --git a/arch/tile/lib/cpumask.c b/arch/tile/lib/cpumask.c
new file mode 100644
index 000000000000..fdc403614d12
--- /dev/null
+++ b/arch/tile/lib/cpumask.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <linux/smp.h>
+
+/*
+ * Allow cropping out bits beyond the end of the array.
+ * Move to "lib" directory if more clients want to use this routine.
+ */
+int bitmap_parselist_crop(const char *bp, unsigned long *maskp, int nmaskbits)
+{
+ unsigned a, b;
+
+ bitmap_zero(maskp, nmaskbits);
+ do {
+ if (!isdigit(*bp))
+ return -EINVAL;
+ a = simple_strtoul(bp, (char **)&bp, 10);
+ b = a;
+ if (*bp == '-') {
+ bp++;
+ if (!isdigit(*bp))
+ return -EINVAL;
+ b = simple_strtoul(bp, (char **)&bp, 10);
+ }
+ if (!(a <= b))
+ return -EINVAL;
+ if (b >= nmaskbits)
+ b = nmaskbits-1;
+ while (a <= b) {
+ set_bit(a, maskp);
+ a++;
+ }
+ if (*bp == ',')
+ bp++;
+ } while (*bp != '\0' && *bp != '\n');
+ return 0;
+}
diff --git a/arch/tile/lib/delay.c b/arch/tile/lib/delay.c
new file mode 100644
index 000000000000..5801b03c13ef
--- /dev/null
+++ b/arch/tile/lib/delay.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/thread_info.h>
+#include <asm/fixmap.h>
+#include <hv/hypervisor.h>
+
+void __udelay(unsigned long usecs)
+{
+ hv_nanosleep(usecs * 1000);
+}
+EXPORT_SYMBOL(__udelay);
+
+void __ndelay(unsigned long nsecs)
+{
+ hv_nanosleep(nsecs);
+}
+EXPORT_SYMBOL(__ndelay);
+
+/* FIXME: should be declared in a header somewhere. */
+EXPORT_SYMBOL(__delay);
diff --git a/arch/tile/lib/exports.c b/arch/tile/lib/exports.c
new file mode 100644
index 000000000000..6bc7b52b4aa0
--- /dev/null
+++ b/arch/tile/lib/exports.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Exports from assembler code and from libtile-cc.
+ */
+
+#include <linux/module.h>
+
+/* arch/tile/lib/usercopy.S */
+#include <linux/uaccess.h>
+EXPORT_SYMBOL(__get_user_1);
+EXPORT_SYMBOL(__get_user_2);
+EXPORT_SYMBOL(__get_user_4);
+EXPORT_SYMBOL(__get_user_8);
+EXPORT_SYMBOL(__put_user_1);
+EXPORT_SYMBOL(__put_user_2);
+EXPORT_SYMBOL(__put_user_4);
+EXPORT_SYMBOL(__put_user_8);
+EXPORT_SYMBOL(strnlen_user_asm);
+EXPORT_SYMBOL(strncpy_from_user_asm);
+EXPORT_SYMBOL(clear_user_asm);
+
+/* arch/tile/kernel/entry.S */
+#include <linux/kernel.h>
+#include <asm/processor.h>
+EXPORT_SYMBOL(current_text_addr);
+EXPORT_SYMBOL(dump_stack);
+
+/* arch/tile/lib/__memcpy.S */
+/* NOTE: on TILE64, these symbols appear in arch/tile/lib/memcpy_tile64.c */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(__copy_to_user_inatomic);
+EXPORT_SYMBOL(__copy_from_user_inatomic);
+EXPORT_SYMBOL(__copy_from_user_zeroing);
+
+/* hypervisor glue */
+#include <hv/hypervisor.h>
+EXPORT_SYMBOL(hv_dev_open);
+EXPORT_SYMBOL(hv_dev_pread);
+EXPORT_SYMBOL(hv_dev_pwrite);
+EXPORT_SYMBOL(hv_dev_close);
+
+/* -ltile-cc */
+uint32_t __udivsi3(uint32_t dividend, uint32_t divisor);
+EXPORT_SYMBOL(__udivsi3);
+int32_t __divsi3(int32_t dividend, int32_t divisor);
+EXPORT_SYMBOL(__divsi3);
+uint64_t __udivdi3(uint64_t dividend, uint64_t divisor);
+EXPORT_SYMBOL(__udivdi3);
+int64_t __divdi3(int64_t dividend, int64_t divisor);
+EXPORT_SYMBOL(__divdi3);
+uint32_t __umodsi3(uint32_t dividend, uint32_t divisor);
+EXPORT_SYMBOL(__umodsi3);
+int32_t __modsi3(int32_t dividend, int32_t divisor);
+EXPORT_SYMBOL(__modsi3);
+uint64_t __umoddi3(uint64_t dividend, uint64_t divisor);
+EXPORT_SYMBOL(__umoddi3);
+int64_t __moddi3(int64_t dividend, int64_t divisor);
+EXPORT_SYMBOL(__moddi3);
+#ifndef __tilegx__
+uint64_t __ll_mul(uint64_t n0, uint64_t n1);
+EXPORT_SYMBOL(__ll_mul);
+#endif
+#ifndef __tilegx__
+int64_t __muldi3(int64_t, int64_t);
+EXPORT_SYMBOL(__muldi3);
+uint64_t __lshrdi3(uint64_t, unsigned int);
+EXPORT_SYMBOL(__lshrdi3);
+#endif
diff --git a/arch/tile/lib/mb_incoherent.S b/arch/tile/lib/mb_incoherent.S
new file mode 100644
index 000000000000..989ad7b68d5a
--- /dev/null
+++ b/arch/tile/lib/mb_incoherent.S
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Assembly code for invoking the HV's fence_incoherent syscall.
+ */
+
+#include <linux/linkage.h>
+#include <hv/syscall_public.h>
+#include <arch/abi.h>
+#include <arch/chip.h>
+
+#if !CHIP_HAS_MF_WAITS_FOR_VICTIMS()
+
+/*
+ * Invoke the hypervisor's fence_incoherent syscall, which guarantees
+ * that all victims for cachelines homed on this tile have reached memory.
+ */
+STD_ENTRY(__mb_incoherent)
+ moveli TREG_SYSCALL_NR_NAME, HV_SYS_fence_incoherent
+ swint2
+ jrp lr
+ STD_ENDPROC(__mb_incoherent)
+
+#endif
diff --git a/arch/tile/lib/memchr_32.c b/arch/tile/lib/memchr_32.c
new file mode 100644
index 000000000000..6235283b4859
--- /dev/null
+++ b/arch/tile/lib/memchr_32.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+void *memchr(const void *s, int c, size_t n)
+{
+ /* Get an aligned pointer. */
+ const uintptr_t s_int = (uintptr_t) s;
+ const uint32_t *p = (const uint32_t *)(s_int & -4);
+
+ /* Create four copies of the byte for which we are looking. */
+ const uint32_t goal = 0x01010101 * (uint8_t) c;
+
+ /* Read the first word, but munge it so that bytes before the array
+ * will not match goal.
+ *
+ * Note that this shift count expression works because we know
+ * shift counts are taken mod 32.
+ */
+ const uint32_t before_mask = (1 << (s_int << 3)) - 1;
+ uint32_t v = (*p | before_mask) ^ (goal & before_mask);
+
+ /* Compute the address of the last byte. */
+ const char *const last_byte_ptr = (const char *)s + n - 1;
+
+ /* Compute the address of the word containing the last byte. */
+ const uint32_t *const last_word_ptr =
+ (const uint32_t *)((uintptr_t) last_byte_ptr & -4);
+
+ uint32_t bits;
+ char *ret;
+
+ if (__builtin_expect(n == 0, 0)) {
+ /* Don't dereference any memory if the array is empty. */
+ return NULL;
+ }
+
+ while ((bits = __insn_seqb(v, goal)) == 0) {
+ if (__builtin_expect(p == last_word_ptr, 0)) {
+ /* We already read the last word in the array,
+ * so give up.
+ */
+ return NULL;
+ }
+ v = *++p;
+ }
+
+ /* We found a match, but it might be in a byte past the end
+ * of the array.
+ */
+ ret = ((char *)p) + (__insn_ctz(bits) >> 3);
+ return (ret <= last_byte_ptr) ? ret : NULL;
+}
+EXPORT_SYMBOL(memchr);
diff --git a/arch/tile/lib/memcpy_32.S b/arch/tile/lib/memcpy_32.S
new file mode 100644
index 000000000000..f92984bf60ec
--- /dev/null
+++ b/arch/tile/lib/memcpy_32.S
@@ -0,0 +1,628 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This file shares the implementation of the userspace memcpy and
+ * the kernel's memcpy, copy_to_user and copy_from_user.
+ */
+
+#include <arch/chip.h>
+
+#if CHIP_HAS_WH64() || defined(MEMCPY_TEST_WH64)
+#define MEMCPY_USE_WH64
+#endif
+
+
+#include <linux/linkage.h>
+
+/* On TILE64, we wrap these functions via arch/tile/lib/memcpy_tile64.c */
+#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
+#define memcpy __memcpy_asm
+#define __copy_to_user_inatomic __copy_to_user_inatomic_asm
+#define __copy_from_user_inatomic __copy_from_user_inatomic_asm
+#define __copy_from_user_zeroing __copy_from_user_zeroing_asm
+#endif
+
+#define IS_MEMCPY 0
+#define IS_COPY_FROM_USER 1
+#define IS_COPY_FROM_USER_ZEROING 2
+#define IS_COPY_TO_USER -1
+
+ .section .text.memcpy_common, "ax"
+ .align 64
+
+/* Use this to preface each bundle that can cause an exception so
+ * the kernel can clean up properly. The special cleanup code should
+ * not use these, since it knows what it is doing.
+ */
+#define EX \
+ .pushsection __ex_table, "a"; \
+ .word 9f, memcpy_common_fixup; \
+ .popsection; \
+ 9
+
+
+/* __copy_from_user_inatomic takes the kernel target address in r0,
+ * the user source in r1, and the bytes to copy in r2.
+ * It returns the number of uncopiable bytes (hopefully zero) in r0.
+ */
+ENTRY(__copy_from_user_inatomic)
+.type __copy_from_user_inatomic, @function
+ FEEDBACK_ENTER_EXPLICIT(__copy_from_user_inatomic, \
+ .text.memcpy_common, \
+ .Lend_memcpy_common - __copy_from_user_inatomic)
+ { movei r29, IS_COPY_FROM_USER; j memcpy_common }
+ .size __copy_from_user_inatomic, . - __copy_from_user_inatomic
+
+/* __copy_from_user_zeroing is like __copy_from_user_inatomic, but
+ * any uncopiable bytes are zeroed in the target.
+ */
+ENTRY(__copy_from_user_zeroing)
+.type __copy_from_user_zeroing, @function
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
+ { movei r29, IS_COPY_FROM_USER_ZEROING; j memcpy_common }
+ .size __copy_from_user_zeroing, . - __copy_from_user_zeroing
+
+/* __copy_to_user_inatomic takes the user target address in r0,
+ * the kernel source in r1, and the bytes to copy in r2.
+ * It returns the number of uncopiable bytes (hopefully zero) in r0.
+ */
+ENTRY(__copy_to_user_inatomic)
+.type __copy_to_user_inatomic, @function
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
+ { movei r29, IS_COPY_TO_USER; j memcpy_common }
+ .size __copy_to_user_inatomic, . - __copy_to_user_inatomic
+
+ENTRY(memcpy)
+.type memcpy, @function
+ FEEDBACK_REENTER(__copy_from_user_inatomic)
+ { movei r29, IS_MEMCPY }
+ .size memcpy, . - memcpy
+ /* Fall through */
+
+ .type memcpy_common, @function
+memcpy_common:
+ /* On entry, r29 holds one of the IS_* macro values from above. */
+
+
+ /* r0 is the dest, r1 is the source, r2 is the size. */
+
+ /* Save aside original dest so we can return it at the end. */
+ { sw sp, lr; move r23, r0; or r4, r0, r1 }
+
+ /* Check for an empty size. */
+ { bz r2, .Ldone; andi r4, r4, 3 }
+
+ /* Save aside original values in case of a fault. */
+ { move r24, r1; move r25, r2 }
+ move r27, lr
+
+ /* Check for an unaligned source or dest. */
+ { bnz r4, .Lcopy_unaligned_maybe_many; addli r4, r2, -256 }
+
+.Lcheck_aligned_copy_size:
+ /* If we are copying < 256 bytes, branch to simple case. */
+ { blzt r4, .Lcopy_8_check; slti_u r8, r2, 8 }
+
+ /* Copying >= 256 bytes, so jump to complex prefetching loop. */
+ { andi r6, r1, 63; j .Lcopy_many }
+
+/*
+ *
+ * Aligned 4 byte at a time copy loop
+ *
+ */
+
+.Lcopy_8_loop:
+ /* Copy two words at a time to hide load latency. */
+EX: { lw r3, r1; addi r1, r1, 4; slti_u r8, r2, 16 }
+EX: { lw r4, r1; addi r1, r1, 4 }
+EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
+EX: { sw r0, r4; addi r0, r0, 4; addi r2, r2, -4 }
+.Lcopy_8_check:
+ { bzt r8, .Lcopy_8_loop; slti_u r4, r2, 4 }
+
+ /* Copy odd leftover word, if any. */
+ { bnzt r4, .Lcheck_odd_stragglers }
+EX: { lw r3, r1; addi r1, r1, 4 }
+EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
+
+.Lcheck_odd_stragglers:
+ { bnz r2, .Lcopy_unaligned_few }
+
+.Ldone:
+ /* For memcpy return original dest address, else zero. */
+ { mz r0, r29, r23; jrp lr }
+
+
+/*
+ *
+ * Prefetching multiple cache line copy handler (for large transfers).
+ *
+ */
+
+ /* Copy words until r1 is cache-line-aligned. */
+.Lalign_loop:
+EX: { lw r3, r1; addi r1, r1, 4 }
+ { andi r6, r1, 63 }
+EX: { sw r0, r3; addi r0, r0, 4; addi r2, r2, -4 }
+.Lcopy_many:
+ { bnzt r6, .Lalign_loop; addi r9, r0, 63 }
+
+ { addi r3, r1, 60; andi r9, r9, -64 }
+
+#ifdef MEMCPY_USE_WH64
+ /* No need to prefetch dst, we'll just do the wh64
+ * right before we copy a line.
+ */
+#endif
+
+EX: { lw r5, r3; addi r3, r3, 64; movei r4, 1 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, .; move r27, lr }
+EX: { lw r6, r3; addi r3, r3, 64 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+EX: { lw r7, r3; addi r3, r3, 64 }
+#ifndef MEMCPY_USE_WH64
+ /* Prefetch the dest */
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ /* Use a real load to cause a TLB miss if necessary. We aren't using
+ * r28, so this should be fine.
+ */
+EX: { lw r28, r9; addi r9, r9, 64 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ { prefetch r9; addi r9, r9, 64 }
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bnzt zero, . }
+ { prefetch r9; addi r9, r9, 64 }
+#endif
+ /* Intentionally stall for a few cycles to leave L2 cache alone. */
+ { bz zero, .Lbig_loop2 }
+
+ /* On entry to this loop:
+ * - r0 points to the start of dst line 0
+ * - r1 points to start of src line 0
+ * - r2 >= (256 - 60), only the first time the loop trips.
+ * - r3 contains r1 + 128 + 60 [pointer to end of source line 2]
+ * This is our prefetch address. When we get near the end
+ * rather than prefetching off the end this is changed to point
+ * to some "safe" recently loaded address.
+ * - r5 contains *(r1 + 60) [i.e. last word of source line 0]
+ * - r6 contains *(r1 + 64 + 60) [i.e. last word of source line 1]
+ * - r9 contains ((r0 + 63) & -64)
+ * [start of next dst cache line.]
+ */
+
+.Lbig_loop:
+ { jal .Lcopy_line2; add r15, r1, r2 }
+
+.Lbig_loop2:
+ /* Copy line 0, first stalling until r5 is ready. */
+EX: { move r12, r5; lw r16, r1 }
+ { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
+ /* Prefetch several lines ahead. */
+EX: { lw r5, r3; addi r3, r3, 64 }
+ { jal .Lcopy_line }
+
+ /* Copy line 1, first stalling until r6 is ready. */
+EX: { move r12, r6; lw r16, r1 }
+ { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
+ /* Prefetch several lines ahead. */
+EX: { lw r6, r3; addi r3, r3, 64 }
+ { jal .Lcopy_line }
+
+ /* Copy line 2, first stalling until r7 is ready. */
+EX: { move r12, r7; lw r16, r1 }
+ { bz r4, .Lcopy_8_check; slti_u r8, r2, 8 }
+ /* Prefetch several lines ahead. */
+EX: { lw r7, r3; addi r3, r3, 64 }
+ /* Use up a caches-busy cycle by jumping back to the top of the
+ * loop. Might as well get it out of the way now.
+ */
+ { j .Lbig_loop }
+
+
+ /* On entry:
+ * - r0 points to the destination line.
+ * - r1 points to the source line.
+ * - r3 is the next prefetch address.
+ * - r9 holds the last address used for wh64.
+ * - r12 = WORD_15
+ * - r16 = WORD_0.
+ * - r17 == r1 + 16.
+ * - r27 holds saved lr to restore.
+ *
+ * On exit:
+ * - r0 is incremented by 64.
+ * - r1 is incremented by 64, unless that would point to a word
+ * beyond the end of the source array, in which case it is redirected
+ * to point to an arbitrary word already in the cache.
+ * - r2 is decremented by 64.
+ * - r3 is unchanged, unless it points to a word beyond the
+ * end of the source array, in which case it is redirected
+ * to point to an arbitrary word already in the cache.
+ * Redirecting is OK since if we are that close to the end
+ * of the array we will not come back to this subroutine
+ * and use the contents of the prefetched address.
+ * - r4 is nonzero iff r2 >= 64.
+ * - r9 is incremented by 64, unless it points beyond the
+ * end of the last full destination cache line, in which
+ * case it is redirected to a "safe address" that can be
+ * clobbered (sp - 64)
+ * - lr contains the value in r27.
+ */
+
+/* r26 unused */
+
+.Lcopy_line:
+ /* TODO: when r3 goes past the end, we would like to redirect it
+ * to prefetch the last partial cache line (if any) just once, for the
+ * benefit of the final cleanup loop. But we don't want to
+ * prefetch that line more than once, or subsequent prefetches
+ * will go into the RTF. But then .Lbig_loop should unconditionally
+ * branch to top of loop to execute final prefetch, and its
+ * nop should become a conditional branch.
+ */
+
+ /* We need two non-memory cycles here to cover the resources
+ * used by the loads initiated by the caller.
+ */
+ { add r15, r1, r2 }
+.Lcopy_line2:
+ { slt_u r13, r3, r15; addi r17, r1, 16 }
+
+ /* NOTE: this will stall for one cycle as L1 is busy. */
+
+ /* Fill second L1D line. */
+EX: { lw r17, r17; addi r1, r1, 48; mvz r3, r13, r1 } /* r17 = WORD_4 */
+
+#ifdef MEMCPY_TEST_WH64
+ /* Issue a fake wh64 that clobbers the destination words
+ * with random garbage, for testing.
+ */
+ { movei r19, 64; crc32_32 r10, r2, r9 }
+.Lwh64_test_loop:
+EX: { sw r9, r10; addi r9, r9, 4; addi r19, r19, -4 }
+ { bnzt r19, .Lwh64_test_loop; crc32_32 r10, r10, r19 }
+#elif CHIP_HAS_WH64()
+ /* Prepare destination line for writing. */
+EX: { wh64 r9; addi r9, r9, 64 }
+#else
+ /* Prefetch dest line */
+ { prefetch r9; addi r9, r9, 64 }
+#endif
+ /* Load seven words that are L1D hits to cover wh64 L2 usage. */
+
+ /* Load the three remaining words from the last L1D line, which
+ * we know has already filled the L1D.
+ */
+EX: { lw r4, r1; addi r1, r1, 4; addi r20, r1, 16 } /* r4 = WORD_12 */
+EX: { lw r8, r1; addi r1, r1, 4; slt_u r13, r20, r15 }/* r8 = WORD_13 */
+EX: { lw r11, r1; addi r1, r1, -52; mvz r20, r13, r1 } /* r11 = WORD_14 */
+
+ /* Load the three remaining words from the first L1D line, first
+ * stalling until it has filled by "looking at" r16.
+ */
+EX: { lw r13, r1; addi r1, r1, 4; move zero, r16 } /* r13 = WORD_1 */
+EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_2 */
+EX: { lw r15, r1; addi r1, r1, 8; addi r10, r0, 60 } /* r15 = WORD_3 */
+
+ /* Load second word from the second L1D line, first
+ * stalling until it has filled by "looking at" r17.
+ */
+EX: { lw r19, r1; addi r1, r1, 4; move zero, r17 } /* r19 = WORD_5 */
+
+ /* Store last word to the destination line, potentially dirtying it
+ * for the first time, which keeps the L2 busy for two cycles.
+ */
+EX: { sw r10, r12 } /* store(WORD_15) */
+
+ /* Use two L1D hits to cover the sw L2 access above. */
+EX: { lw r10, r1; addi r1, r1, 4 } /* r10 = WORD_6 */
+EX: { lw r12, r1; addi r1, r1, 4 } /* r12 = WORD_7 */
+
+ /* Fill third L1D line. */
+EX: { lw r18, r1; addi r1, r1, 4 } /* r18 = WORD_8 */
+
+ /* Store first L1D line. */
+EX: { sw r0, r16; addi r0, r0, 4; add r16, r0, r2 } /* store(WORD_0) */
+EX: { sw r0, r13; addi r0, r0, 4; andi r16, r16, -64 } /* store(WORD_1) */
+EX: { sw r0, r14; addi r0, r0, 4; slt_u r16, r9, r16 } /* store(WORD_2) */
+#ifdef MEMCPY_USE_WH64
+EX: { sw r0, r15; addi r0, r0, 4; addi r13, sp, -64 } /* store(WORD_3) */
+#else
+ /* Back up the r9 to a cache line we are already storing to
+ * if it gets past the end of the dest vector. Strictly speaking,
+ * we don't need to back up to the start of a cache line, but it's free
+ * and tidy, so why not?
+ */
+EX: { sw r0, r15; addi r0, r0, 4; andi r13, r0, -64 } /* store(WORD_3) */
+#endif
+ /* Store second L1D line. */
+EX: { sw r0, r17; addi r0, r0, 4; mvz r9, r16, r13 }/* store(WORD_4) */
+EX: { sw r0, r19; addi r0, r0, 4 } /* store(WORD_5) */
+EX: { sw r0, r10; addi r0, r0, 4 } /* store(WORD_6) */
+EX: { sw r0, r12; addi r0, r0, 4 } /* store(WORD_7) */
+
+EX: { lw r13, r1; addi r1, r1, 4; move zero, r18 } /* r13 = WORD_9 */
+EX: { lw r14, r1; addi r1, r1, 4 } /* r14 = WORD_10 */
+EX: { lw r15, r1; move r1, r20 } /* r15 = WORD_11 */
+
+ /* Store third L1D line. */
+EX: { sw r0, r18; addi r0, r0, 4 } /* store(WORD_8) */
+EX: { sw r0, r13; addi r0, r0, 4 } /* store(WORD_9) */
+EX: { sw r0, r14; addi r0, r0, 4 } /* store(WORD_10) */
+EX: { sw r0, r15; addi r0, r0, 4 } /* store(WORD_11) */
+
+ /* Store rest of fourth L1D line. */
+EX: { sw r0, r4; addi r0, r0, 4 } /* store(WORD_12) */
+ {
+EX: sw r0, r8 /* store(WORD_13) */
+ addi r0, r0, 4
+ /* Will r2 be > 64 after we subtract 64 below? */
+ shri r4, r2, 7
+ }
+ {
+EX: sw r0, r11 /* store(WORD_14) */
+ addi r0, r0, 8
+ /* Record 64 bytes successfully copied. */
+ addi r2, r2, -64
+ }
+
+ { jrp lr; move lr, r27 }
+
+ /* Convey to the backtrace library that the stack frame is size
+ * zero, and the real return address is on the stack rather than
+ * in 'lr'.
+ */
+ { info 8 }
+
+ .align 64
+.Lcopy_unaligned_maybe_many:
+ /* Skip the setup overhead if we aren't copying many bytes. */
+ { slti_u r8, r2, 20; sub r4, zero, r0 }
+ { bnzt r8, .Lcopy_unaligned_few; andi r4, r4, 3 }
+ { bz r4, .Ldest_is_word_aligned; add r18, r1, r2 }
+
+/*
+ *
+ * unaligned 4 byte at a time copy handler.
+ *
+ */
+
+ /* Copy single bytes until r0 == 0 mod 4, so we can store words. */
+.Lalign_dest_loop:
+EX: { lb_u r3, r1; addi r1, r1, 1; addi r4, r4, -1 }
+EX: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
+ { bnzt r4, .Lalign_dest_loop; andi r3, r1, 3 }
+
+ /* If source and dest are now *both* aligned, do an aligned copy. */
+ { bz r3, .Lcheck_aligned_copy_size; addli r4, r2, -256 }
+
+.Ldest_is_word_aligned:
+
+#if CHIP_HAS_DWORD_ALIGN()
+EX: { andi r8, r0, 63; lwadd_na r6, r1, 4}
+ { slti_u r9, r2, 64; bz r8, .Ldest_is_L2_line_aligned }
+
+ /* This copies unaligned words until either there are fewer
+ * than 4 bytes left to copy, or until the destination pointer
+ * is cache-aligned, whichever comes first.
+ *
+ * On entry:
+ * - r0 is the next store address.
+ * - r1 points 4 bytes past the load address corresponding to r0.
+ * - r2 >= 4
+ * - r6 is the next aligned word loaded.
+ */
+.Lcopy_unaligned_src_words:
+EX: { lwadd_na r7, r1, 4; slti_u r8, r2, 4 + 4 }
+ /* stall */
+ { dword_align r6, r7, r1; slti_u r9, r2, 64 + 4 }
+EX: { swadd r0, r6, 4; addi r2, r2, -4 }
+ { bnz r8, .Lcleanup_unaligned_words; andi r8, r0, 63 }
+ { bnzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
+
+ /* On entry:
+ * - r0 is the next store address.
+ * - r1 points 4 bytes past the load address corresponding to r0.
+ * - r2 >= 4 (# of bytes left to store).
+ * - r6 is the next aligned src word value.
+ * - r9 = (r2 < 64U).
+ * - r18 points one byte past the end of source memory.
+ */
+.Ldest_is_L2_line_aligned:
+
+ {
+ /* Not a full cache line remains. */
+ bnz r9, .Lcleanup_unaligned_words
+ move r7, r6
+ }
+
+ /* r2 >= 64 */
+
+ /* Kick off two prefetches, but don't go past the end. */
+ { addi r3, r1, 63 - 4; addi r8, r1, 64 + 63 - 4 }
+ { prefetch r3; move r3, r8; slt_u r8, r8, r18 }
+ { mvz r3, r8, r1; addi r8, r3, 64 }
+ { prefetch r3; move r3, r8; slt_u r8, r8, r18 }
+ { mvz r3, r8, r1; movei r17, 0 }
+
+.Lcopy_unaligned_line:
+ /* Prefetch another line. */
+ { prefetch r3; addi r15, r1, 60; addi r3, r3, 64 }
+ /* Fire off a load of the last word we are about to copy. */
+EX: { lw_na r15, r15; slt_u r8, r3, r18 }
+
+EX: { mvz r3, r8, r1; wh64 r0 }
+
+ /* This loop runs twice.
+ *
+ * On entry:
+ * - r17 is even before the first iteration, and odd before
+ * the second. It is incremented inside the loop. Encountering
+ * an even value at the end of the loop makes it stop.
+ */
+.Lcopy_half_an_unaligned_line:
+EX: {
+ /* Stall until the last byte is ready. In the steady state this
+ * guarantees all words to load below will be in the L2 cache, which
+ * avoids shunting the loads to the RTF.
+ */
+ move zero, r15
+ lwadd_na r7, r1, 16
+ }
+EX: { lwadd_na r11, r1, 12 }
+EX: { lwadd_na r14, r1, -24 }
+EX: { lwadd_na r8, r1, 4 }
+EX: { lwadd_na r9, r1, 4 }
+EX: {
+ lwadd_na r10, r1, 8
+ /* r16 = (r2 < 64), after we subtract 32 from r2 below. */
+ slti_u r16, r2, 64 + 32
+ }
+EX: { lwadd_na r12, r1, 4; addi r17, r17, 1 }
+EX: { lwadd_na r13, r1, 8; dword_align r6, r7, r1 }
+EX: { swadd r0, r6, 4; dword_align r7, r8, r1 }
+EX: { swadd r0, r7, 4; dword_align r8, r9, r1 }
+EX: { swadd r0, r8, 4; dword_align r9, r10, r1 }
+EX: { swadd r0, r9, 4; dword_align r10, r11, r1 }
+EX: { swadd r0, r10, 4; dword_align r11, r12, r1 }
+EX: { swadd r0, r11, 4; dword_align r12, r13, r1 }
+EX: { swadd r0, r12, 4; dword_align r13, r14, r1 }
+EX: { swadd r0, r13, 4; addi r2, r2, -32 }
+ { move r6, r14; bbst r17, .Lcopy_half_an_unaligned_line }
+
+ { bzt r16, .Lcopy_unaligned_line; move r7, r6 }
+
+ /* On entry:
+ * - r0 is the next store address.
+ * - r1 points 4 bytes past the load address corresponding to r0.
+ * - r2 >= 0 (# of bytes left to store).
+ * - r7 is the next aligned src word value.
+ */
+.Lcleanup_unaligned_words:
+ /* Handle any trailing bytes. */
+ { bz r2, .Lcopy_unaligned_done; slti_u r8, r2, 4 }
+ { bzt r8, .Lcopy_unaligned_src_words; move r6, r7 }
+
+ /* Move r1 back to the point where it corresponds to r0. */
+ { addi r1, r1, -4 }
+
+#else /* !CHIP_HAS_DWORD_ALIGN() */
+
+ /* Compute right/left shift counts and load initial source words. */
+ { andi r5, r1, -4; andi r3, r1, 3 }
+EX: { lw r6, r5; addi r5, r5, 4; shli r3, r3, 3 }
+EX: { lw r7, r5; addi r5, r5, 4; sub r4, zero, r3 }
+
+ /* Load and store one word at a time, using shifts and ORs
+ * to correct for the misaligned src.
+ */
+.Lcopy_unaligned_src_loop:
+ { shr r6, r6, r3; shl r8, r7, r4 }
+EX: { lw r7, r5; or r8, r8, r6; move r6, r7 }
+EX: { sw r0, r8; addi r0, r0, 4; addi r2, r2, -4 }
+ { addi r5, r5, 4; slti_u r8, r2, 8 }
+ { bzt r8, .Lcopy_unaligned_src_loop; addi r1, r1, 4 }
+
+ { bz r2, .Lcopy_unaligned_done }
+#endif /* !CHIP_HAS_DWORD_ALIGN() */
+
+ /* Fall through */
+
+/*
+ *
+ * 1 byte at a time copy handler.
+ *
+ */
+
+.Lcopy_unaligned_few:
+EX: { lb_u r3, r1; addi r1, r1, 1 }
+EX: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
+ { bnzt r2, .Lcopy_unaligned_few }
+
+.Lcopy_unaligned_done:
+
+ /* For memcpy return original dest address, else zero. */
+ { mz r0, r29, r23; jrp lr }
+
+.Lend_memcpy_common:
+ .size memcpy_common, .Lend_memcpy_common - memcpy_common
+
+ .section .fixup,"ax"
+memcpy_common_fixup:
+ .type memcpy_common_fixup, @function
+
+ /* Skip any bytes we already successfully copied.
+ * r2 (num remaining) is correct, but r0 (dst) and r1 (src)
+ * may not be quite right because of unrolling and prefetching.
+ * So we need to recompute their values as the address just
+ * after the last byte we are sure was successfully loaded and
+ * then stored.
+ */
+
+ /* Determine how many bytes we successfully copied. */
+ { sub r3, r25, r2 }
+
+ /* Add this to the original r0 and r1 to get their new values. */
+ { add r0, r23, r3; add r1, r24, r3 }
+
+ { bzt r29, memcpy_fixup_loop }
+ { blzt r29, copy_to_user_fixup_loop }
+
+copy_from_user_fixup_loop:
+ /* Try copying the rest one byte at a time, expecting a load fault. */
+.Lcfu: { lb_u r3, r1; addi r1, r1, 1 }
+ { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
+ { bnzt r2, copy_from_user_fixup_loop }
+
+.Lcopy_from_user_fixup_zero_remainder:
+ { bbs r29, 2f } /* low bit set means IS_COPY_FROM_USER */
+ /* byte-at-a-time loop faulted, so zero the rest. */
+ { move r3, r2; bz r2, 2f /* should be impossible, but handle it. */ }
+1: { sb r0, zero; addi r0, r0, 1; addi r3, r3, -1 }
+ { bnzt r3, 1b }
+2: move lr, r27
+ { move r0, r2; jrp lr }
+
+copy_to_user_fixup_loop:
+ /* Try copying the rest one byte at a time, expecting a store fault. */
+ { lb_u r3, r1; addi r1, r1, 1 }
+.Lctu: { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
+ { bnzt r2, copy_to_user_fixup_loop }
+.Lcopy_to_user_fixup_done:
+ move lr, r27
+ { move r0, r2; jrp lr }
+
+memcpy_fixup_loop:
+ /* Try copying the rest one byte at a time. We expect a disastrous
+ * fault to happen since we are in fixup code, but let it happen.
+ */
+ { lb_u r3, r1; addi r1, r1, 1 }
+ { sb r0, r3; addi r0, r0, 1; addi r2, r2, -1 }
+ { bnzt r2, memcpy_fixup_loop }
+ /* This should be unreachable, we should have faulted again.
+ * But be paranoid and handle it in case some interrupt changed
+ * the TLB or something.
+ */
+ move lr, r27
+ { move r0, r23; jrp lr }
+
+ .size memcpy_common_fixup, . - memcpy_common_fixup
+
+ .section __ex_table,"a"
+ .word .Lcfu, .Lcopy_from_user_fixup_zero_remainder
+ .word .Lctu, .Lcopy_to_user_fixup_done
diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c
new file mode 100644
index 000000000000..dfedea7b266b
--- /dev/null
+++ b/arch/tile/lib/memcpy_tile64.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/string.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/fixmap.h>
+#include <asm/kmap_types.h>
+#include <asm/tlbflush.h>
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
+
+
+#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
+
+/* Defined in memcpy.S */
+extern unsigned long __memcpy_asm(void *to, const void *from, unsigned long n);
+extern unsigned long __copy_to_user_inatomic_asm(
+ void __user *to, const void *from, unsigned long n);
+extern unsigned long __copy_from_user_inatomic_asm(
+ void *to, const void __user *from, unsigned long n);
+extern unsigned long __copy_from_user_zeroing_asm(
+ void *to, const void __user *from, unsigned long n);
+
+typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long);
+
+/* Size above which to consider TLB games for performance */
+#define LARGE_COPY_CUTOFF 2048
+
+/* Communicate to the simulator what we are trying to do. */
+#define sim_allow_multiple_caching(b) \
+ __insn_mtspr(SPR_SIM_CONTROL, \
+ SIM_CONTROL_ALLOW_MULTIPLE_CACHING | ((b) << _SIM_CONTROL_OPERATOR_BITS))
+
+/*
+ * Copy memory by briefly enabling incoherent cacheline-at-a-time mode.
+ *
+ * We set up our own source and destination PTEs that we fully control.
+ * This is the only way to guarantee that we don't race with another
+ * thread that is modifying the PTE; we can't afford to try the
+ * copy_{to,from}_user() technique of catching the interrupt, since
+ * we must run with interrupts disabled to avoid the risk of some
+ * other code seeing the incoherent data in our cache. (Recall that
+ * our cache is indexed by PA, so even if the other code doesn't use
+ * our KM_MEMCPY virtual addresses, they'll still hit in cache using
+ * the normal VAs that aren't supposed to hit in cache.)
+ */
+static void memcpy_multicache(void *dest, const void *source,
+ pte_t dst_pte, pte_t src_pte, int len)
+{
+ int idx;
+ unsigned long flags, newsrc, newdst;
+ pmd_t *pmdp;
+ pte_t *ptep;
+ int cpu = get_cpu();
+
+ /*
+ * Disable interrupts so that we don't recurse into memcpy()
+ * in an interrupt handler, nor accidentally reference
+ * the PA of the source from an interrupt routine. Also
+ * notify the simulator that we're playing games so we don't
+ * generate spurious coherency warnings.
+ */
+ local_irq_save(flags);
+ sim_allow_multiple_caching(1);
+
+ /* Set up the new dest mapping */
+ idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0;
+ newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1));
+ pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst);
+ ptep = pte_offset_kernel(pmdp, newdst);
+ if (pte_val(*ptep) != pte_val(dst_pte)) {
+ set_pte(ptep, dst_pte);
+ local_flush_tlb_page(NULL, newdst, PAGE_SIZE);
+ }
+
+ /* Set up the new source mapping */
+ idx += (KM_MEMCPY0 - KM_MEMCPY1);
+ src_pte = hv_pte_set_nc(src_pte);
+ src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */
+ newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1));
+ pmdp = pmd_offset(pud_offset(pgd_offset_k(newsrc), newsrc), newsrc);
+ ptep = pte_offset_kernel(pmdp, newsrc);
+ *ptep = src_pte; /* set_pte() would be confused by this */
+ local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
+
+ /* Actually move the data. */
+ __memcpy_asm((void *)newdst, (const void *)newsrc, len);
+
+ /*
+ * Remap the source as locally-cached and not OLOC'ed so that
+ * we can inval without also invaling the remote cpu's cache.
+ * This also avoids known errata with inv'ing cacheable oloc data.
+ */
+ src_pte = hv_pte_set_mode(src_pte, HV_PTE_MODE_CACHE_NO_L3);
+ src_pte = hv_pte_set_writable(src_pte); /* need write access for inv */
+ *ptep = src_pte; /* set_pte() would be confused by this */
+ local_flush_tlb_page(NULL, newsrc, PAGE_SIZE);
+
+ /*
+ * Do the actual invalidation, covering the full L2 cache line
+ * at the end since __memcpy_asm() is somewhat aggressive.
+ */
+ __inv_buffer((void *)newsrc, len);
+
+ /*
+ * We're done: notify the simulator that all is back to normal,
+ * and re-enable interrupts and pre-emption.
+ */
+ sim_allow_multiple_caching(0);
+ local_irq_restore(flags);
+ put_cpu();
+}
+
+/*
+ * Identify large copies from remotely-cached memory, and copy them
+ * via memcpy_multicache() if they look good, otherwise fall back
+ * to the particular kind of copying passed as the memcpy_t function.
+ */
+static unsigned long fast_copy(void *dest, const void *source, int len,
+ memcpy_t func)
+{
+ /*
+ * Check if it's big enough to bother with. We may end up doing a
+ * small copy via TLB manipulation if we're near a page boundary,
+ * but presumably we'll make it up when we hit the second page.
+ */
+ while (len >= LARGE_COPY_CUTOFF) {
+ int copy_size, bytes_left_on_page;
+ pte_t *src_ptep, *dst_ptep;
+ pte_t src_pte, dst_pte;
+ struct page *src_page, *dst_page;
+
+ /* Is the source page oloc'ed to a remote cpu? */
+retry_source:
+ src_ptep = virt_to_pte(current->mm, (unsigned long)source);
+ if (src_ptep == NULL)
+ break;
+ src_pte = *src_ptep;
+ if (!hv_pte_get_present(src_pte) ||
+ !hv_pte_get_readable(src_pte) ||
+ hv_pte_get_mode(src_pte) != HV_PTE_MODE_CACHE_TILE_L3)
+ break;
+ if (get_remote_cache_cpu(src_pte) == smp_processor_id())
+ break;
+ src_page = pfn_to_page(hv_pte_get_pfn(src_pte));
+ get_page(src_page);
+ if (pte_val(src_pte) != pte_val(*src_ptep)) {
+ put_page(src_page);
+ goto retry_source;
+ }
+ if (pte_huge(src_pte)) {
+ /* Adjust the PTE to correspond to a small page */
+ int pfn = hv_pte_get_pfn(src_pte);
+ pfn += (((unsigned long)source & (HPAGE_SIZE-1))
+ >> PAGE_SHIFT);
+ src_pte = pfn_pte(pfn, src_pte);
+ src_pte = pte_mksmall(src_pte);
+ }
+
+ /* Is the destination page writable? */
+retry_dest:
+ dst_ptep = virt_to_pte(current->mm, (unsigned long)dest);
+ if (dst_ptep == NULL) {
+ put_page(src_page);
+ break;
+ }
+ dst_pte = *dst_ptep;
+ if (!hv_pte_get_present(dst_pte) ||
+ !hv_pte_get_writable(dst_pte)) {
+ put_page(src_page);
+ break;
+ }
+ dst_page = pfn_to_page(hv_pte_get_pfn(dst_pte));
+ if (dst_page == src_page) {
+ /*
+ * Source and dest are on the same page; this
+ * potentially exposes us to incoherence if any
+ * part of src and dest overlap on a cache line.
+ * Just give up rather than trying to be precise.
+ */
+ put_page(src_page);
+ break;
+ }
+ get_page(dst_page);
+ if (pte_val(dst_pte) != pte_val(*dst_ptep)) {
+ put_page(dst_page);
+ goto retry_dest;
+ }
+ if (pte_huge(dst_pte)) {
+ /* Adjust the PTE to correspond to a small page */
+ int pfn = hv_pte_get_pfn(dst_pte);
+ pfn += (((unsigned long)dest & (HPAGE_SIZE-1))
+ >> PAGE_SHIFT);
+ dst_pte = pfn_pte(pfn, dst_pte);
+ dst_pte = pte_mksmall(dst_pte);
+ }
+
+ /* All looks good: create a cachable PTE and copy from it */
+ copy_size = len;
+ bytes_left_on_page =
+ PAGE_SIZE - (((int)source) & (PAGE_SIZE-1));
+ if (copy_size > bytes_left_on_page)
+ copy_size = bytes_left_on_page;
+ bytes_left_on_page =
+ PAGE_SIZE - (((int)dest) & (PAGE_SIZE-1));
+ if (copy_size > bytes_left_on_page)
+ copy_size = bytes_left_on_page;
+ memcpy_multicache(dest, source, dst_pte, src_pte, copy_size);
+
+ /* Release the pages */
+ put_page(dst_page);
+ put_page(src_page);
+
+ /* Continue on the next page */
+ dest += copy_size;
+ source += copy_size;
+ len -= copy_size;
+ }
+
+ return func(dest, source, len);
+}
+
+void *memcpy(void *to, const void *from, __kernel_size_t n)
+{
+ if (n < LARGE_COPY_CUTOFF)
+ return (void *)__memcpy_asm(to, from, n);
+ else
+ return (void *)fast_copy(to, from, n, __memcpy_asm);
+}
+
+unsigned long __copy_to_user_inatomic(void __user *to, const void *from,
+ unsigned long n)
+{
+ if (n < LARGE_COPY_CUTOFF)
+ return __copy_to_user_inatomic_asm(to, from, n);
+ else
+ return fast_copy(to, from, n, __copy_to_user_inatomic_asm);
+}
+
+unsigned long __copy_from_user_inatomic(void *to, const void __user *from,
+ unsigned long n)
+{
+ if (n < LARGE_COPY_CUTOFF)
+ return __copy_from_user_inatomic_asm(to, from, n);
+ else
+ return fast_copy(to, from, n, __copy_from_user_inatomic_asm);
+}
+
+unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
+ unsigned long n)
+{
+ if (n < LARGE_COPY_CUTOFF)
+ return __copy_from_user_zeroing_asm(to, from, n);
+ else
+ return fast_copy(to, from, n, __copy_from_user_zeroing_asm);
+}
+
+#endif /* !CHIP_HAS_COHERENT_LOCAL_CACHE() */
diff --git a/arch/tile/lib/memmove_32.c b/arch/tile/lib/memmove_32.c
new file mode 100644
index 000000000000..fd615ae6ade7
--- /dev/null
+++ b/arch/tile/lib/memmove_32.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+ if ((const char *)src >= (char *)dest + n
+ || (char *)dest >= (const char *)src + n) {
+ /* We found no overlap, so let memcpy do all the heavy
+ * lifting (prefetching, etc.)
+ */
+ return memcpy(dest, src, n);
+ }
+
+ if (n != 0) {
+ const uint8_t *in;
+ uint8_t x;
+ uint8_t *out;
+ int stride;
+
+ if (src < dest) {
+ /* copy backwards */
+ in = (const uint8_t *)src + n - 1;
+ out = (uint8_t *)dest + n - 1;
+ stride = -1;
+ } else {
+ /* copy forwards */
+ in = (const uint8_t *)src;
+ out = (uint8_t *)dest;
+ stride = 1;
+ }
+
+ /* Manually software-pipeline this loop. */
+ x = *in;
+ in += stride;
+
+ while (--n != 0) {
+ *out = x;
+ out += stride;
+ x = *in;
+ in += stride;
+ }
+
+ *out = x;
+ }
+
+ return dest;
+}
+EXPORT_SYMBOL(memmove);
diff --git a/arch/tile/lib/memset_32.c b/arch/tile/lib/memset_32.c
new file mode 100644
index 000000000000..bfde5d864df1
--- /dev/null
+++ b/arch/tile/lib/memset_32.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <arch/chip.h>
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+
+void *memset(void *s, int c, size_t n)
+{
+ uint32_t *out32;
+ int n32;
+ uint32_t v16, v32;
+ uint8_t *out8 = s;
+#if !CHIP_HAS_WH64()
+ int ahead32;
+#else
+ int to_align32;
+#endif
+
+ /* Experimentation shows that a trivial tight loop is a win up until
+ * around a size of 20, where writing a word at a time starts to win.
+ */
+#define BYTE_CUTOFF 20
+
+#if BYTE_CUTOFF < 3
+ /* This must be at least at least this big, or some code later
+ * on doesn't work.
+ */
+#error "BYTE_CUTOFF is too small"
+#endif
+
+ if (n < BYTE_CUTOFF) {
+ /* Strangely, this turns out to be the tightest way to
+ * write this loop.
+ */
+ if (n != 0) {
+ do {
+ /* Strangely, combining these into one line
+ * performs worse.
+ */
+ *out8 = c;
+ out8++;
+ } while (--n != 0);
+ }
+
+ return s;
+ }
+
+#if !CHIP_HAS_WH64()
+ /* Use a spare issue slot to start prefetching the first cache
+ * line early. This instruction is free as the store can be buried
+ * in otherwise idle issue slots doing ALU ops.
+ */
+ __insn_prefetch(out8);
+
+ /* We prefetch the end so that a short memset that spans two cache
+ * lines gets some prefetching benefit. Again we believe this is free
+ * to issue.
+ */
+ __insn_prefetch(&out8[n - 1]);
+#endif /* !CHIP_HAS_WH64() */
+
+
+ /* Align 'out8'. We know n >= 3 so this won't write past the end. */
+ while (((uintptr_t) out8 & 3) != 0) {
+ *out8++ = c;
+ --n;
+ }
+
+ /* Align 'n'. */
+ while (n & 3)
+ out8[--n] = c;
+
+ out32 = (uint32_t *) out8;
+ n32 = n >> 2;
+
+ /* Tile input byte out to 32 bits. */
+ v16 = __insn_intlb(c, c);
+ v32 = __insn_intlh(v16, v16);
+
+ /* This must be at least 8 or the following loop doesn't work. */
+#define CACHE_LINE_SIZE_IN_WORDS (CHIP_L2_LINE_SIZE() / 4)
+
+#if !CHIP_HAS_WH64()
+
+ ahead32 = CACHE_LINE_SIZE_IN_WORDS;
+
+ /* We already prefetched the first and last cache lines, so
+ * we only need to do more prefetching if we are storing
+ * to more than two cache lines.
+ */
+ if (n32 > CACHE_LINE_SIZE_IN_WORDS * 2) {
+ int i;
+
+ /* Prefetch the next several cache lines.
+ * This is the setup code for the software-pipelined
+ * loop below.
+ */
+#define MAX_PREFETCH 5
+ ahead32 = n32 & -CACHE_LINE_SIZE_IN_WORDS;
+ if (ahead32 > MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS)
+ ahead32 = MAX_PREFETCH * CACHE_LINE_SIZE_IN_WORDS;
+
+ for (i = CACHE_LINE_SIZE_IN_WORDS;
+ i < ahead32; i += CACHE_LINE_SIZE_IN_WORDS)
+ __insn_prefetch(&out32[i]);
+ }
+
+ if (n32 > ahead32) {
+ while (1) {
+ int j;
+
+ /* Prefetch by reading one word several cache lines
+ * ahead. Since loads are non-blocking this will
+ * cause the full cache line to be read while we are
+ * finishing earlier cache lines. Using a store
+ * here causes microarchitectural performance
+ * problems where a victimizing store miss goes to
+ * the head of the retry FIFO and locks the pipe for
+ * a few cycles. So a few subsequent stores in this
+ * loop go into the retry FIFO, and then later
+ * stores see other stores to the same cache line
+ * are already in the retry FIFO and themselves go
+ * into the retry FIFO, filling it up and grinding
+ * to a halt waiting for the original miss to be
+ * satisfied.
+ */
+ __insn_prefetch(&out32[ahead32]);
+
+#if 1
+#if CACHE_LINE_SIZE_IN_WORDS % 4 != 0
+#error "Unhandled CACHE_LINE_SIZE_IN_WORDS"
+#endif
+
+ n32 -= CACHE_LINE_SIZE_IN_WORDS;
+
+ /* Save icache space by only partially unrolling
+ * this loop.
+ */
+ for (j = CACHE_LINE_SIZE_IN_WORDS / 4; j > 0; j--) {
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ }
+#else
+ /* Unfortunately, due to a code generator flaw this
+ * allocates a separate register for each of these
+ * stores, which requires a large number of spills,
+ * which makes this procedure enormously bigger
+ * (something like 70%)
+ */
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ n32 -= 16;
+#endif
+
+ /* To save compiled code size, reuse this loop even
+ * when we run out of prefetching to do by dropping
+ * ahead32 down.
+ */
+ if (n32 <= ahead32) {
+ /* Not even a full cache line left,
+ * so stop now.
+ */
+ if (n32 < CACHE_LINE_SIZE_IN_WORDS)
+ break;
+
+ /* Choose a small enough value that we don't
+ * prefetch past the end. There's no sense
+ * in touching cache lines we don't have to.
+ */
+ ahead32 = CACHE_LINE_SIZE_IN_WORDS - 1;
+ }
+ }
+ }
+
+#else /* CHIP_HAS_WH64() */
+
+ /* Determine how many words we need to emit before the 'out32'
+ * pointer becomes aligned modulo the cache line size.
+ */
+ to_align32 =
+ (-((uintptr_t)out32 >> 2)) & (CACHE_LINE_SIZE_IN_WORDS - 1);
+
+ /* Only bother aligning and using wh64 if there is at least
+ * one full cache line to process. This check also prevents
+ * overrunning the end of the buffer with alignment words.
+ */
+ if (to_align32 <= n32 - CACHE_LINE_SIZE_IN_WORDS) {
+ int lines_left;
+
+ /* Align out32 mod the cache line size so we can use wh64. */
+ n32 -= to_align32;
+ for (; to_align32 != 0; to_align32--) {
+ *out32 = v32;
+ out32++;
+ }
+
+ /* Use unsigned divide to turn this into a right shift. */
+ lines_left = (unsigned)n32 / CACHE_LINE_SIZE_IN_WORDS;
+
+ do {
+ /* Only wh64 a few lines at a time, so we don't
+ * exceed the maximum number of victim lines.
+ */
+ int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS())
+ ? lines_left
+ : CHIP_MAX_OUTSTANDING_VICTIMS());
+ uint32_t *wh = out32;
+ int i = x;
+ int j;
+
+ lines_left -= x;
+
+ do {
+ __insn_wh64(wh);
+ wh += CACHE_LINE_SIZE_IN_WORDS;
+ } while (--i);
+
+ for (j = x * (CACHE_LINE_SIZE_IN_WORDS / 4);
+ j != 0; j--) {
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ *out32++ = v32;
+ }
+ } while (lines_left != 0);
+
+ /* We processed all full lines above, so only this many
+ * words remain to be processed.
+ */
+ n32 &= CACHE_LINE_SIZE_IN_WORDS - 1;
+ }
+
+#endif /* CHIP_HAS_WH64() */
+
+ /* Now handle any leftover values. */
+ if (n32 != 0) {
+ do {
+ *out32 = v32;
+ out32++;
+ } while (--n32 != 0);
+ }
+
+ return s;
+}
+EXPORT_SYMBOL(memset);
diff --git a/arch/tile/lib/spinlock_32.c b/arch/tile/lib/spinlock_32.c
new file mode 100644
index 000000000000..485e24d62c6b
--- /dev/null
+++ b/arch/tile/lib/spinlock_32.c
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+
+#include "spinlock_common.h"
+
+void arch_spin_lock(arch_spinlock_t *lock)
+{
+ int my_ticket;
+ int iterations = 0;
+ int delta;
+
+ while ((my_ticket = __insn_tns((void *)&lock->next_ticket)) & 1)
+ delay_backoff(iterations++);
+
+ /* Increment the next ticket number, implicitly releasing tns lock. */
+ lock->next_ticket = my_ticket + TICKET_QUANTUM;
+
+ /* Wait until it's our turn. */
+ while ((delta = my_ticket - lock->current_ticket) != 0)
+ relax((128 / CYCLES_PER_RELAX_LOOP) * delta);
+}
+EXPORT_SYMBOL(arch_spin_lock);
+
+int arch_spin_trylock(arch_spinlock_t *lock)
+{
+ /*
+ * Grab a ticket; no need to retry if it's busy, we'll just
+ * treat that the same as "locked", since someone else
+ * will lock it momentarily anyway.
+ */
+ int my_ticket = __insn_tns((void *)&lock->next_ticket);
+
+ if (my_ticket == lock->current_ticket) {
+ /* Not currently locked, so lock it by keeping this ticket. */
+ lock->next_ticket = my_ticket + TICKET_QUANTUM;
+ /* Success! */
+ return 1;
+ }
+
+ if (!(my_ticket & 1)) {
+ /* Release next_ticket. */
+ lock->next_ticket = my_ticket;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(arch_spin_trylock);
+
+void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+ u32 iterations = 0;
+ while (arch_spin_is_locked(lock))
+ delay_backoff(iterations++);
+}
+EXPORT_SYMBOL(arch_spin_unlock_wait);
+
+/*
+ * The low byte is always reserved to be the marker for a "tns" operation
+ * since the low bit is set to "1" by a tns. The next seven bits are
+ * zeroes. The next byte holds the "next" writer value, i.e. the ticket
+ * available for the next task that wants to write. The third byte holds
+ * the current writer value, i.e. the writer who holds the current ticket.
+ * If current == next == 0, there are no interested writers.
+ */
+#define WR_NEXT_SHIFT _WR_NEXT_SHIFT
+#define WR_CURR_SHIFT _WR_CURR_SHIFT
+#define WR_WIDTH _WR_WIDTH
+#define WR_MASK ((1 << WR_WIDTH) - 1)
+
+/*
+ * The last eight bits hold the active reader count. This has to be
+ * zero before a writer can start to write.
+ */
+#define RD_COUNT_SHIFT _RD_COUNT_SHIFT
+#define RD_COUNT_WIDTH _RD_COUNT_WIDTH
+#define RD_COUNT_MASK ((1 << RD_COUNT_WIDTH) - 1)
+
+
+/* Lock the word, spinning until there are no tns-ers. */
+static inline u32 get_rwlock(arch_rwlock_t *rwlock)
+{
+ u32 iterations = 0;
+ for (;;) {
+ u32 val = __insn_tns((int *)&rwlock->lock);
+ if (unlikely(val & 1)) {
+ delay_backoff(iterations++);
+ continue;
+ }
+ return val;
+ }
+}
+
+int arch_read_trylock_slow(arch_rwlock_t *rwlock)
+{
+ u32 val = get_rwlock(rwlock);
+ int locked = (val << RD_COUNT_WIDTH) == 0;
+ rwlock->lock = val + (locked << RD_COUNT_SHIFT);
+ return locked;
+}
+EXPORT_SYMBOL(arch_read_trylock_slow);
+
+void arch_read_unlock_slow(arch_rwlock_t *rwlock)
+{
+ u32 val = get_rwlock(rwlock);
+ rwlock->lock = val - (1 << RD_COUNT_SHIFT);
+}
+EXPORT_SYMBOL(arch_read_unlock_slow);
+
+void arch_write_unlock_slow(arch_rwlock_t *rwlock, u32 val)
+{
+ u32 eq, mask = 1 << WR_CURR_SHIFT;
+ while (unlikely(val & 1)) {
+ /* Limited backoff since we are the highest-priority task. */
+ relax(4);
+ val = __insn_tns((int *)&rwlock->lock);
+ }
+ val = __insn_addb(val, mask);
+ eq = __insn_seqb(val, val << (WR_CURR_SHIFT - WR_NEXT_SHIFT));
+ val = __insn_mz(eq & mask, val);
+ rwlock->lock = val;
+}
+EXPORT_SYMBOL(arch_write_unlock_slow);
+
+/*
+ * We spin until everything but the reader bits (which are in the high
+ * part of the word) are zero, i.e. no active or waiting writers, no tns.
+ *
+ * ISSUE: This approach can permanently starve readers. A reader who sees
+ * a writer could instead take a ticket lock (just like a writer would),
+ * and atomically enter read mode (with 1 reader) when it gets the ticket.
+ * This way both readers and writers will always make forward progress
+ * in a finite time.
+ */
+void arch_read_lock_slow(arch_rwlock_t *rwlock, u32 val)
+{
+ u32 iterations = 0;
+ do {
+ if (!(val & 1))
+ rwlock->lock = val;
+ delay_backoff(iterations++);
+ val = __insn_tns((int *)&rwlock->lock);
+ } while ((val << RD_COUNT_WIDTH) != 0);
+ rwlock->lock = val + (1 << RD_COUNT_SHIFT);
+}
+EXPORT_SYMBOL(arch_read_lock_slow);
+
+void arch_write_lock_slow(arch_rwlock_t *rwlock, u32 val)
+{
+ /*
+ * The trailing underscore on this variable (and curr_ below)
+ * reminds us that the high bits are garbage; we mask them out
+ * when we compare them.
+ */
+ u32 my_ticket_;
+
+ /* Take out the next ticket; this will also stop would-be readers. */
+ if (val & 1)
+ val = get_rwlock(rwlock);
+ rwlock->lock = __insn_addb(val, 1 << WR_NEXT_SHIFT);
+
+ /* Extract my ticket value from the original word. */
+ my_ticket_ = val >> WR_NEXT_SHIFT;
+
+ /*
+ * Wait until the "current" field matches our ticket, and
+ * there are no remaining readers.
+ */
+ for (;;) {
+ u32 curr_ = val >> WR_CURR_SHIFT;
+ u32 readers = val >> RD_COUNT_SHIFT;
+ u32 delta = ((my_ticket_ - curr_) & WR_MASK) + !!readers;
+ if (likely(delta == 0))
+ break;
+
+ /* Delay based on how many lock-holders are still out there. */
+ relax((256 / CYCLES_PER_RELAX_LOOP) * delta);
+
+ /*
+ * Get a non-tns value to check; we don't need to tns
+ * it ourselves. Since we're not tns'ing, we retry
+ * more rapidly to get a valid value.
+ */
+ while ((val = rwlock->lock) & 1)
+ relax(4);
+ }
+}
+EXPORT_SYMBOL(arch_write_lock_slow);
+
+int __tns_atomic_acquire(atomic_t *lock)
+{
+ int ret;
+ u32 iterations = 0;
+
+ BUG_ON(__insn_mfspr(SPR_INTERRUPT_CRITICAL_SECTION));
+ __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 1);
+
+ while ((ret = __insn_tns((void *)&lock->counter)) == 1)
+ delay_backoff(iterations++);
+ return ret;
+}
+
+void __tns_atomic_release(atomic_t *p, int v)
+{
+ p->counter = v;
+ __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0);
+}
diff --git a/arch/tile/lib/spinlock_common.h b/arch/tile/lib/spinlock_common.h
new file mode 100644
index 000000000000..c10109809132
--- /dev/null
+++ b/arch/tile/lib/spinlock_common.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ * This file is included into spinlock_32.c or _64.c.
+ */
+
+/*
+ * The mfspr in __spinlock_relax() is 5 or 6 cycles plus 2 for loop
+ * overhead.
+ */
+#ifdef __tilegx__
+#define CYCLES_PER_RELAX_LOOP 7
+#else
+#define CYCLES_PER_RELAX_LOOP 8
+#endif
+
+/*
+ * Idle the core for CYCLES_PER_RELAX_LOOP * iterations cycles.
+ */
+static inline void
+relax(int iterations)
+{
+ for (/*above*/; iterations > 0; iterations--)
+ __insn_mfspr(SPR_PASS);
+ barrier();
+}
+
+/* Perform bounded exponential backoff.*/
+static void delay_backoff(int iterations)
+{
+ u32 exponent, loops;
+
+ /*
+ * 2^exponent is how many times we go around the loop,
+ * which takes 8 cycles. We want to start with a 16- to 31-cycle
+ * loop, so we need to go around minimum 2 = 2^1 times, so we
+ * bias the original value up by 1.
+ */
+ exponent = iterations + 1;
+
+ /*
+ * Don't allow exponent to exceed 7, so we have 128 loops,
+ * or 1,024 (to 2,047) cycles, as our maximum.
+ */
+ if (exponent > 8)
+ exponent = 8;
+
+ loops = 1 << exponent;
+
+ /* Add a randomness factor so two cpus never get in lock step. */
+ loops += __insn_crc32_32(stack_pointer, get_cycles_low()) &
+ (loops - 1);
+
+ relax(1 << exponent);
+}
diff --git a/arch/tile/lib/strchr_32.c b/arch/tile/lib/strchr_32.c
new file mode 100644
index 000000000000..c94e6f7ae7b5
--- /dev/null
+++ b/arch/tile/lib/strchr_32.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#undef strchr
+
+char *strchr(const char *s, int c)
+{
+ int z, g;
+
+ /* Get an aligned pointer. */
+ const uintptr_t s_int = (uintptr_t) s;
+ const uint32_t *p = (const uint32_t *)(s_int & -4);
+
+ /* Create four copies of the byte for which we are looking. */
+ const uint32_t goal = 0x01010101 * (uint8_t) c;
+
+ /* Read the first aligned word, but force bytes before the string to
+ * match neither zero nor goal (we make sure the high bit of each
+ * byte is 1, and the low 7 bits are all the opposite of the goal
+ * byte).
+ *
+ * Note that this shift count expression works because we know shift
+ * counts are taken mod 32.
+ */
+ const uint32_t before_mask = (1 << (s_int << 3)) - 1;
+ uint32_t v = (*p | before_mask) ^ (goal & __insn_shrib(before_mask, 1));
+
+ uint32_t zero_matches, goal_matches;
+ while (1) {
+ /* Look for a terminating '\0'. */
+ zero_matches = __insn_seqb(v, 0);
+
+ /* Look for the goal byte. */
+ goal_matches = __insn_seqb(v, goal);
+
+ if (__builtin_expect(zero_matches | goal_matches, 0))
+ break;
+
+ v = *++p;
+ }
+
+ z = __insn_ctz(zero_matches);
+ g = __insn_ctz(goal_matches);
+
+ /* If we found c before '\0' we got a match. Note that if c == '\0'
+ * then g == z, and we correctly return the address of the '\0'
+ * rather than NULL.
+ */
+ return (g <= z) ? ((char *)p) + (g >> 3) : NULL;
+}
+EXPORT_SYMBOL(strchr);
diff --git a/arch/tile/lib/strlen_32.c b/arch/tile/lib/strlen_32.c
new file mode 100644
index 000000000000..f26f88e11e4a
--- /dev/null
+++ b/arch/tile/lib/strlen_32.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+size_t strlen(const char *s)
+{
+ /* Get an aligned pointer. */
+ const uintptr_t s_int = (uintptr_t) s;
+ const uint32_t *p = (const uint32_t *)(s_int & -4);
+
+ /* Read the first word, but force bytes before the string to be nonzero.
+ * This expression works because we know shift counts are taken mod 32.
+ */
+ uint32_t v = *p | ((1 << (s_int << 3)) - 1);
+
+ uint32_t bits;
+ while ((bits = __insn_seqb(v, 0)) == 0)
+ v = *++p;
+
+ return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
+}
+EXPORT_SYMBOL(strlen);
diff --git a/arch/tile/lib/uaccess.c b/arch/tile/lib/uaccess.c
new file mode 100644
index 000000000000..f8d398c9ee7f
--- /dev/null
+++ b/arch/tile/lib/uaccess.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/uaccess.h>
+#include <linux/module.h>
+
+int __range_ok(unsigned long addr, unsigned long size)
+{
+ unsigned long limit = current_thread_info()->addr_limit.seg;
+ return !((addr < limit && size <= limit - addr) ||
+ is_arch_mappable_range(addr, size));
+}
+EXPORT_SYMBOL(__range_ok);
+
+#ifdef CONFIG_DEBUG_COPY_FROM_USER
+void copy_from_user_overflow(void)
+{
+ WARN(1, "Buffer overflow detected!\n");
+}
+EXPORT_SYMBOL(copy_from_user_overflow);
+#endif
diff --git a/arch/tile/lib/usercopy_32.S b/arch/tile/lib/usercopy_32.S
new file mode 100644
index 000000000000..979f76d83746
--- /dev/null
+++ b/arch/tile/lib/usercopy_32.S
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <arch/chip.h>
+
+/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
+
+ .pushsection .fixup,"ax"
+
+get_user_fault:
+ { move r0, zero; move r1, zero }
+ { movei r2, -EFAULT; jrp lr }
+ ENDPROC(get_user_fault)
+
+put_user_fault:
+ { movei r0, -EFAULT; jrp lr }
+ ENDPROC(put_user_fault)
+
+ .popsection
+
+/*
+ * __get_user_N functions take a pointer in r0, and return 0 in r2
+ * on success, with the value in r0; or else -EFAULT in r2.
+ */
+#define __get_user_N(bytes, LOAD) \
+ STD_ENTRY(__get_user_##bytes); \
+1: { LOAD r0, r0; move r1, zero; move r2, zero }; \
+ jrp lr; \
+ STD_ENDPROC(__get_user_##bytes); \
+ .pushsection __ex_table,"a"; \
+ .word 1b, get_user_fault; \
+ .popsection
+
+__get_user_N(1, lb_u)
+__get_user_N(2, lh_u)
+__get_user_N(4, lw)
+
+/*
+ * __get_user_8 takes a pointer in r0, and returns 0 in r2
+ * on success, with the value in r0/r1; or else -EFAULT in r2.
+ */
+ STD_ENTRY(__get_user_8);
+1: { lw r0, r0; addi r1, r0, 4 };
+2: { lw r1, r1; move r2, zero };
+ jrp lr;
+ STD_ENDPROC(__get_user_8);
+ .pushsection __ex_table,"a";
+ .word 1b, get_user_fault;
+ .word 2b, get_user_fault;
+ .popsection
+
+/*
+ * __put_user_N functions take a value in r0 and a pointer in r1,
+ * and return 0 in r0 on success or -EFAULT on failure.
+ */
+#define __put_user_N(bytes, STORE) \
+ STD_ENTRY(__put_user_##bytes); \
+1: { STORE r1, r0; move r0, zero }; \
+ jrp lr; \
+ STD_ENDPROC(__put_user_##bytes); \
+ .pushsection __ex_table,"a"; \
+ .word 1b, put_user_fault; \
+ .popsection
+
+__put_user_N(1, sb)
+__put_user_N(2, sh)
+__put_user_N(4, sw)
+
+/*
+ * __put_user_8 takes a value in r0/r1 and a pointer in r2,
+ * and returns 0 in r0 on success or -EFAULT on failure.
+ */
+STD_ENTRY(__put_user_8)
+1: { sw r2, r0; addi r2, r2, 4 }
+2: { sw r2, r1; move r0, zero }
+ jrp lr
+ STD_ENDPROC(__put_user_8)
+ .pushsection __ex_table,"a"
+ .word 1b, put_user_fault
+ .word 2b, put_user_fault
+ .popsection
+
+
+/*
+ * strnlen_user_asm takes the pointer in r0, and the length bound in r1.
+ * It returns the length, including the terminating NUL, or zero on exception.
+ * If length is greater than the bound, returns one plus the bound.
+ */
+STD_ENTRY(strnlen_user_asm)
+ { bz r1, 2f; addi r3, r0, -1 } /* bias down to include NUL */
+1: { lb_u r4, r0; addi r1, r1, -1 }
+ bz r4, 2f
+ { bnzt r1, 1b; addi r0, r0, 1 }
+2: { sub r0, r0, r3; jrp lr }
+ STD_ENDPROC(strnlen_user_asm)
+ .pushsection .fixup,"ax"
+strnlen_user_fault:
+ { move r0, zero; jrp lr }
+ ENDPROC(strnlen_user_fault)
+ .section __ex_table,"a"
+ .word 1b, strnlen_user_fault
+ .popsection
+
+/*
+ * strncpy_from_user_asm takes the kernel target pointer in r0,
+ * the userspace source pointer in r1, and the length bound (including
+ * the trailing NUL) in r2. On success, it returns the string length
+ * (not including the trailing NUL), or -EFAULT on failure.
+ */
+STD_ENTRY(strncpy_from_user_asm)
+ { bz r2, 2f; move r3, r0 }
+1: { lb_u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
+ { sb r0, r4; addi r0, r0, 1 }
+ bz r2, 2f
+ bnzt r4, 1b
+ addi r0, r0, -1 /* don't count the trailing NUL */
+2: { sub r0, r0, r3; jrp lr }
+ STD_ENDPROC(strncpy_from_user_asm)
+ .pushsection .fixup,"ax"
+strncpy_from_user_fault:
+ { movei r0, -EFAULT; jrp lr }
+ ENDPROC(strncpy_from_user_fault)
+ .section __ex_table,"a"
+ .word 1b, strncpy_from_user_fault
+ .popsection
+
+/*
+ * clear_user_asm takes the user target address in r0 and the
+ * number of bytes to zero in r1.
+ * It returns the number of uncopiable bytes (hopefully zero) in r0.
+ * Note that we don't use a separate .fixup section here since we fall
+ * through into the "fixup" code as the last straight-line bundle anyway.
+ */
+STD_ENTRY(clear_user_asm)
+ { bz r1, 2f; or r2, r0, r1 }
+ andi r2, r2, 3
+ bzt r2, .Lclear_aligned_user_asm
+1: { sb r0, zero; addi r0, r0, 1; addi r1, r1, -1 }
+ bnzt r1, 1b
+2: { move r0, r1; jrp lr }
+ .pushsection __ex_table,"a"
+ .word 1b, 2b
+ .popsection
+
+.Lclear_aligned_user_asm:
+1: { sw r0, zero; addi r0, r0, 4; addi r1, r1, -4 }
+ bnzt r1, 1b
+2: { move r0, r1; jrp lr }
+ STD_ENDPROC(clear_user_asm)
+ .pushsection __ex_table,"a"
+ .word 1b, 2b
+ .popsection
+
+/*
+ * flush_user_asm takes the user target address in r0 and the
+ * number of bytes to flush in r1.
+ * It returns the number of unflushable bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(flush_user_asm)
+ bz r1, 2f
+ { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+ { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+ { and r0, r0, r2; and r1, r1, r2 }
+ { sub r1, r1, r0 }
+1: { flush r0; addi r1, r1, -CHIP_FLUSH_STRIDE() }
+ { addi r0, r0, CHIP_FLUSH_STRIDE(); bnzt r1, 1b }
+2: { move r0, r1; jrp lr }
+ STD_ENDPROC(flush_user_asm)
+ .pushsection __ex_table,"a"
+ .word 1b, 2b
+ .popsection
+
+/*
+ * inv_user_asm takes the user target address in r0 and the
+ * number of bytes to invalidate in r1.
+ * It returns the number of not inv'able bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(inv_user_asm)
+ bz r1, 2f
+ { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+ { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+ { and r0, r0, r2; and r1, r1, r2 }
+ { sub r1, r1, r0 }
+1: { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
+ { addi r0, r0, CHIP_INV_STRIDE(); bnzt r1, 1b }
+2: { move r0, r1; jrp lr }
+ STD_ENDPROC(inv_user_asm)
+ .pushsection __ex_table,"a"
+ .word 1b, 2b
+ .popsection
+
+/*
+ * finv_user_asm takes the user target address in r0 and the
+ * number of bytes to flush-invalidate in r1.
+ * It returns the number of not finv'able bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(finv_user_asm)
+ bz r1, 2f
+ { movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+ { sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+ { and r0, r0, r2; and r1, r1, r2 }
+ { sub r1, r1, r0 }
+1: { finv r0; addi r1, r1, -CHIP_FINV_STRIDE() }
+ { addi r0, r0, CHIP_FINV_STRIDE(); bnzt r1, 1b }
+2: { move r0, r1; jrp lr }
+ STD_ENDPROC(finv_user_asm)
+ .pushsection __ex_table,"a"
+ .word 1b, 2b
+ .popsection
diff --git a/arch/tile/mm/Makefile b/arch/tile/mm/Makefile
new file mode 100644
index 000000000000..e252aeddc17d
--- /dev/null
+++ b/arch/tile/mm/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for the linux tile-specific parts of the memory manager.
+#
+
+obj-y := init.o pgtable.o fault.o extable.o elf.o \
+ mmap.o homecache.o migrate_$(BITS).o
+
+obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
new file mode 100644
index 000000000000..55e58e93bfc5
--- /dev/null
+++ b/arch/tile/mm/elf.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/binfmts.h>
+#include <linux/compat.h>
+#include <linux/mman.h>
+#include <linux/elf.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+
+/* Notify a running simulator, if any, that an exec just occurred. */
+static void sim_notify_exec(const char *binary_name)
+{
+ unsigned char c;
+ do {
+ c = *binary_name++;
+ __insn_mtspr(SPR_SIM_CONTROL,
+ (SIM_CONTROL_OS_EXEC
+ | (c << _SIM_CONTROL_OPERATOR_BITS)));
+
+ } while (c);
+}
+
+static int notify_exec(void)
+{
+ int retval = 0; /* failure */
+ struct vm_area_struct *vma = current->mm->mmap;
+ while (vma) {
+ if ((vma->vm_flags & VM_EXECUTABLE) && vma->vm_file)
+ break;
+ vma = vma->vm_next;
+ }
+ if (vma) {
+ char *buf = (char *) __get_free_page(GFP_KERNEL);
+ if (buf) {
+ char *path = d_path(&vma->vm_file->f_path,
+ buf, PAGE_SIZE);
+ if (!IS_ERR(path)) {
+ sim_notify_exec(path);
+ retval = 1;
+ }
+ free_page((unsigned long)buf);
+ }
+ }
+ return retval;
+}
+
+/* Notify a running simulator, if any, that we loaded an interpreter. */
+static void sim_notify_interp(unsigned long load_addr)
+{
+ size_t i;
+ for (i = 0; i < sizeof(load_addr); i++) {
+ unsigned char c = load_addr >> (i * 8);
+ __insn_mtspr(SPR_SIM_CONTROL,
+ (SIM_CONTROL_OS_INTERP
+ | (c << _SIM_CONTROL_OPERATOR_BITS)));
+ }
+}
+
+
+/* Kernel address of page used to map read-only kernel data into userspace. */
+static void *vdso_page;
+
+/* One-entry array used for install_special_mapping. */
+static struct page *vdso_pages[1];
+
+static int __init vdso_setup(void)
+{
+ vdso_page = (void *)get_zeroed_page(GFP_ATOMIC);
+ memcpy(vdso_page, __rt_sigreturn, __rt_sigreturn_end - __rt_sigreturn);
+ vdso_pages[0] = virt_to_page(vdso_page);
+ return 0;
+}
+device_initcall(vdso_setup);
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_private_data == vdso_pages)
+ return "[vdso]";
+#ifndef __tilegx__
+ if (vma->vm_start == MEM_USER_INTRPT)
+ return "[intrpt]";
+#endif
+ return NULL;
+}
+
+int arch_setup_additional_pages(struct linux_binprm *bprm,
+ int executable_stack)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long vdso_base;
+ int retval = 0;
+
+ /*
+ * Notify the simulator that an exec just occurred.
+ * If we can't find the filename of the mapping, just use
+ * whatever was passed as the linux_binprm filename.
+ */
+ if (!notify_exec())
+ sim_notify_exec(bprm->filename);
+
+ down_write(&mm->mmap_sem);
+
+ /*
+ * MAYWRITE to allow gdb to COW and set breakpoints
+ *
+ * Make sure the vDSO gets into every core dump. Dumping its
+ * contents makes post-mortem fully interpretable later
+ * without matching up the same kernel and hardware config to
+ * see what PC values meant.
+ */
+ vdso_base = VDSO_BASE;
+ retval = install_special_mapping(mm, vdso_base, PAGE_SIZE,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC|
+ VM_ALWAYSDUMP,
+ vdso_pages);
+
+#ifndef __tilegx__
+ /*
+ * Set up a user-interrupt mapping here; the user can't
+ * create one themselves since it is above TASK_SIZE.
+ * We make it unwritable by default, so the model for adding
+ * interrupt vectors always involves an mprotect.
+ */
+ if (!retval) {
+ unsigned long addr = MEM_USER_INTRPT;
+ addr = mmap_region(NULL, addr, INTRPT_SIZE,
+ MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE,
+ VM_READ|VM_EXEC|
+ VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC, 0);
+ if (addr > (unsigned long) -PAGE_SIZE)
+ retval = (int) addr;
+ }
+#endif
+
+ up_write(&mm->mmap_sem);
+
+ return retval;
+}
+
+
+void elf_plat_init(struct pt_regs *regs, unsigned long load_addr)
+{
+ /* Zero all registers. */
+ memset(regs, 0, sizeof(*regs));
+
+ /* Report the interpreter's load address. */
+ sim_notify_interp(load_addr);
+}
diff --git a/arch/tile/mm/extable.c b/arch/tile/mm/extable.c
new file mode 100644
index 000000000000..4fb0acb9d154
--- /dev/null
+++ b/arch/tile/mm/extable.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/uaccess.h>
+
+int fixup_exception(struct pt_regs *regs)
+{
+ const struct exception_table_entry *fixup;
+
+ fixup = search_exception_tables(regs->pc);
+ if (fixup) {
+ regs->pc = fixup->fixup;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/arch/tile/mm/fault.c b/arch/tile/mm/fault.c
new file mode 100644
index 000000000000..0011f06b4fe2
--- /dev/null
+++ b/arch/tile/mm/fault.c
@@ -0,0 +1,867 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * From i386 code copyright (C) 1995 Linus Torvalds
+ */
+
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h> /* For unblank_screen() */
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/kprobes.h>
+#include <linux/hugetlb.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+#include <asm/system.h>
+#include <asm/pgalloc.h>
+#include <asm/sections.h>
+#include <asm/traps.h>
+#include <asm/syscalls.h>
+
+#include <arch/interrupts.h>
+
+static noinline void force_sig_info_fault(int si_signo, int si_code,
+ unsigned long address, int fault_num, struct task_struct *tsk)
+{
+ siginfo_t info;
+
+ if (unlikely(tsk->pid < 2)) {
+ panic("Signal %d (code %d) at %#lx sent to %s!",
+ si_signo, si_code & 0xffff, address,
+ tsk->pid ? "init" : "the idle task");
+ }
+
+ info.si_signo = si_signo;
+ info.si_errno = 0;
+ info.si_code = si_code;
+ info.si_addr = (void __user *)address;
+ info.si_trapno = fault_num;
+ force_sig_info(si_signo, &info, tsk);
+}
+
+#ifndef __tilegx__
+/*
+ * Synthesize the fault a PL0 process would get by doing a word-load of
+ * an unaligned address or a high kernel address. Called indirectly
+ * from sys_cmpxchg() in kernel/intvec.S.
+ */
+int _sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *regs)
+{
+ if (address >= PAGE_OFFSET)
+ force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
+ INT_DTLB_MISS, current);
+ else
+ force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
+ INT_UNALIGN_DATA, current);
+
+ /*
+ * Adjust pc to point at the actual instruction, which is unusual
+ * for syscalls normally, but is appropriate when we are claiming
+ * that a syscall swint1 caused a page fault or bus error.
+ */
+ regs->pc -= 8;
+
+ /*
+ * Mark this as a caller-save interrupt, like a normal page fault,
+ * so that when we go through the signal handler path we will
+ * properly restore r0, r1, and r2 for the signal handler arguments.
+ */
+ regs->flags |= PT_FLAGS_CALLER_SAVES;
+
+ return 0;
+}
+#endif
+
+static inline pmd_t *vmalloc_sync_one(pgd_t *pgd, unsigned long address)
+{
+ unsigned index = pgd_index(address);
+ pgd_t *pgd_k;
+ pud_t *pud, *pud_k;
+ pmd_t *pmd, *pmd_k;
+
+ pgd += index;
+ pgd_k = init_mm.pgd + index;
+
+ if (!pgd_present(*pgd_k))
+ return NULL;
+
+ pud = pud_offset(pgd, address);
+ pud_k = pud_offset(pgd_k, address);
+ if (!pud_present(*pud_k))
+ return NULL;
+
+ pmd = pmd_offset(pud, address);
+ pmd_k = pmd_offset(pud_k, address);
+ if (!pmd_present(*pmd_k))
+ return NULL;
+ if (!pmd_present(*pmd)) {
+ set_pmd(pmd, *pmd_k);
+ arch_flush_lazy_mmu_mode();
+ } else
+ BUG_ON(pmd_ptfn(*pmd) != pmd_ptfn(*pmd_k));
+ return pmd_k;
+}
+
+/*
+ * Handle a fault on the vmalloc or module mapping area
+ */
+static inline int vmalloc_fault(pgd_t *pgd, unsigned long address)
+{
+ pmd_t *pmd_k;
+ pte_t *pte_k;
+
+ /* Make sure we are in vmalloc area */
+ if (!(address >= VMALLOC_START && address < VMALLOC_END))
+ return -1;
+
+ /*
+ * Synchronize this task's top level page-table
+ * with the 'reference' page table.
+ */
+ pmd_k = vmalloc_sync_one(pgd, address);
+ if (!pmd_k)
+ return -1;
+ if (pmd_huge(*pmd_k))
+ return 0; /* support TILE huge_vmap() API */
+ pte_k = pte_offset_kernel(pmd_k, address);
+ if (!pte_present(*pte_k))
+ return -1;
+ return 0;
+}
+
+/* Wait until this PTE has completed migration. */
+static void wait_for_migration(pte_t *pte)
+{
+ if (pte_migrating(*pte)) {
+ /*
+ * Wait until the migrater fixes up this pte.
+ * We scale the loop count by the clock rate so we'll wait for
+ * a few seconds here.
+ */
+ int retries = 0;
+ int bound = get_clock_rate();
+ while (pte_migrating(*pte)) {
+ barrier();
+ if (++retries > bound)
+ panic("Hit migrating PTE (%#llx) and"
+ " page PFN %#lx still migrating",
+ pte->val, pte_pfn(*pte));
+ }
+ }
+}
+
+/*
+ * It's not generally safe to use "current" to get the page table pointer,
+ * since we might be running an oprofile interrupt in the middle of a
+ * task switch.
+ */
+static pgd_t *get_current_pgd(void)
+{
+ HV_Context ctx = hv_inquire_context();
+ unsigned long pgd_pfn = ctx.page_table >> PAGE_SHIFT;
+ struct page *pgd_page = pfn_to_page(pgd_pfn);
+ BUG_ON(PageHighMem(pgd_page)); /* oops, HIGHPTE? */
+ return (pgd_t *) __va(ctx.page_table);
+}
+
+/*
+ * We can receive a page fault from a migrating PTE at any time.
+ * Handle it by just waiting until the fault resolves.
+ *
+ * It's also possible to get a migrating kernel PTE that resolves
+ * itself during the downcall from hypervisor to Linux. We just check
+ * here to see if the PTE seems valid, and if so we retry it.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may be in an
+ * interrupt or a critical region, and must do as little as possible.
+ * Similarly, we can't use atomic ops here, since we may be handling a
+ * fault caused by an atomic op access.
+ */
+static int handle_migrating_pte(pgd_t *pgd, int fault_num,
+ unsigned long address,
+ int is_kernel_mode, int write)
+{
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t pteval;
+
+ if (pgd_addr_invalid(address))
+ return 0;
+
+ pgd += pgd_index(address);
+ pud = pud_offset(pgd, address);
+ if (!pud || !pud_present(*pud))
+ return 0;
+ pmd = pmd_offset(pud, address);
+ if (!pmd || !pmd_present(*pmd))
+ return 0;
+ pte = pmd_huge_page(*pmd) ? ((pte_t *)pmd) :
+ pte_offset_kernel(pmd, address);
+ pteval = *pte;
+ if (pte_migrating(pteval)) {
+ wait_for_migration(pte);
+ return 1;
+ }
+
+ if (!is_kernel_mode || !pte_present(pteval))
+ return 0;
+ if (fault_num == INT_ITLB_MISS) {
+ if (pte_exec(pteval))
+ return 1;
+ } else if (write) {
+ if (pte_write(pteval))
+ return 1;
+ } else {
+ if (pte_read(pteval))
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * This routine is responsible for faulting in user pages.
+ * It passes the work off to one of the appropriate routines.
+ * It returns true if the fault was successfully handled.
+ */
+static int handle_page_fault(struct pt_regs *regs,
+ int fault_num,
+ int is_page_fault,
+ unsigned long address,
+ int write)
+{
+ struct task_struct *tsk;
+ struct mm_struct *mm;
+ struct vm_area_struct *vma;
+ unsigned long stack_offset;
+ int fault;
+ int si_code;
+ int is_kernel_mode;
+ pgd_t *pgd;
+
+ /* on TILE, protection faults are always writes */
+ if (!is_page_fault)
+ write = 1;
+
+ is_kernel_mode = (EX1_PL(regs->ex1) != USER_PL);
+
+ tsk = validate_current();
+
+ /*
+ * Check to see if we might be overwriting the stack, and bail
+ * out if so. The page fault code is a relatively likely
+ * place to get trapped in an infinite regress, and once we
+ * overwrite the whole stack, it becomes very hard to recover.
+ */
+ stack_offset = stack_pointer & (THREAD_SIZE-1);
+ if (stack_offset < THREAD_SIZE / 8) {
+ pr_alert("Potential stack overrun: sp %#lx\n",
+ stack_pointer);
+ show_regs(regs);
+ pr_alert("Killing current process %d/%s\n",
+ tsk->pid, tsk->comm);
+ do_group_exit(SIGKILL);
+ }
+
+ /*
+ * Early on, we need to check for migrating PTE entries;
+ * see homecache.c. If we find a migrating PTE, we wait until
+ * the backing page claims to be done migrating, then we procede.
+ * For kernel PTEs, we rewrite the PTE and return and retry.
+ * Otherwise, we treat the fault like a normal "no PTE" fault,
+ * rather than trying to patch up the existing PTE.
+ */
+ pgd = get_current_pgd();
+ if (handle_migrating_pte(pgd, fault_num, address,
+ is_kernel_mode, write))
+ return 1;
+
+ si_code = SEGV_MAPERR;
+
+ /*
+ * We fault-in kernel-space virtual memory on-demand. The
+ * 'reference' page table is init_mm.pgd.
+ *
+ * NOTE! We MUST NOT take any locks for this case. We may
+ * be in an interrupt or a critical region, and should
+ * only copy the information from the master page table,
+ * nothing more.
+ *
+ * This verifies that the fault happens in kernel space
+ * and that the fault was not a protection fault.
+ */
+ if (unlikely(address >= TASK_SIZE &&
+ !is_arch_mappable_range(address, 0))) {
+ if (is_kernel_mode && is_page_fault &&
+ vmalloc_fault(pgd, address) >= 0)
+ return 1;
+ /*
+ * Don't take the mm semaphore here. If we fixup a prefetch
+ * fault we could otherwise deadlock.
+ */
+ mm = NULL; /* happy compiler */
+ vma = NULL;
+ goto bad_area_nosemaphore;
+ }
+
+ /*
+ * If we're trying to touch user-space addresses, we must
+ * be either at PL0, or else with interrupts enabled in the
+ * kernel, so either way we can re-enable interrupts here.
+ */
+ local_irq_enable();
+
+ mm = tsk->mm;
+
+ /*
+ * If we're in an interrupt, have no user context or are running in an
+ * atomic region then we must not take the fault.
+ */
+ if (in_atomic() || !mm) {
+ vma = NULL; /* happy compiler */
+ goto bad_area_nosemaphore;
+ }
+
+ /*
+ * When running in the kernel we expect faults to occur only to
+ * addresses in user space. All other faults represent errors in the
+ * kernel and should generate an OOPS. Unfortunately, in the case of an
+ * erroneous fault occurring in a code path which already holds mmap_sem
+ * we will deadlock attempting to validate the fault against the
+ * address space. Luckily the kernel only validly references user
+ * space from well defined areas of code, which are listed in the
+ * exceptions table.
+ *
+ * As the vast majority of faults will be valid we will only perform
+ * the source reference check when there is a possibility of a deadlock.
+ * Attempt to lock the address space, if we cannot we then validate the
+ * source. If this is invalid we can skip the address space check,
+ * thus avoiding the deadlock.
+ */
+ if (!down_read_trylock(&mm->mmap_sem)) {
+ if (is_kernel_mode &&
+ !search_exception_tables(regs->pc)) {
+ vma = NULL; /* happy compiler */
+ goto bad_area_nosemaphore;
+ }
+ down_read(&mm->mmap_sem);
+ }
+
+ vma = find_vma(mm, address);
+ if (!vma)
+ goto bad_area;
+ if (vma->vm_start <= address)
+ goto good_area;
+ if (!(vma->vm_flags & VM_GROWSDOWN))
+ goto bad_area;
+ if (regs->sp < PAGE_OFFSET) {
+ /*
+ * accessing the stack below sp is always a bug.
+ */
+ if (address < regs->sp)
+ goto bad_area;
+ }
+ if (expand_stack(vma, address))
+ goto bad_area;
+
+/*
+ * Ok, we have a good vm_area for this memory access, so
+ * we can handle it..
+ */
+good_area:
+ si_code = SEGV_ACCERR;
+ if (fault_num == INT_ITLB_MISS) {
+ if (!(vma->vm_flags & VM_EXEC))
+ goto bad_area;
+ } else if (write) {
+#ifdef TEST_VERIFY_AREA
+ if (!is_page_fault && regs->cs == KERNEL_CS)
+ pr_err("WP fault at "REGFMT"\n", regs->eip);
+#endif
+ if (!(vma->vm_flags & VM_WRITE))
+ goto bad_area;
+ } else {
+ if (!is_page_fault || !(vma->vm_flags & VM_READ))
+ goto bad_area;
+ }
+
+ survive:
+ /*
+ * If for any reason at all we couldn't handle the fault,
+ * make sure we exit gracefully rather than endlessly redo
+ * the fault.
+ */
+ fault = handle_mm_fault(mm, vma, address, write);
+ if (unlikely(fault & VM_FAULT_ERROR)) {
+ if (fault & VM_FAULT_OOM)
+ goto out_of_memory;
+ else if (fault & VM_FAULT_SIGBUS)
+ goto do_sigbus;
+ BUG();
+ }
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+
+#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
+ /*
+ * If this was an asynchronous fault,
+ * restart the appropriate engine.
+ */
+ switch (fault_num) {
+#if CHIP_HAS_TILE_DMA()
+ case INT_DMATLB_MISS:
+ case INT_DMATLB_MISS_DWNCL:
+ case INT_DMATLB_ACCESS:
+ case INT_DMATLB_ACCESS_DWNCL:
+ __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__REQUEST_MASK);
+ break;
+#endif
+#if CHIP_HAS_SN_PROC()
+ case INT_SNITLB_MISS:
+ case INT_SNITLB_MISS_DWNCL:
+ __insn_mtspr(SPR_SNCTL,
+ __insn_mfspr(SPR_SNCTL) &
+ ~SPR_SNCTL__FRZPROC_MASK);
+ break;
+#endif
+ }
+#endif
+
+ up_read(&mm->mmap_sem);
+ return 1;
+
+/*
+ * Something tried to access memory that isn't in our memory map..
+ * Fix it, but check if it's kernel or user first..
+ */
+bad_area:
+ up_read(&mm->mmap_sem);
+
+bad_area_nosemaphore:
+ /* User mode accesses just cause a SIGSEGV */
+ if (!is_kernel_mode) {
+ /*
+ * It's possible to have interrupts off here.
+ */
+ local_irq_enable();
+
+ force_sig_info_fault(SIGSEGV, si_code, address,
+ fault_num, tsk);
+ return 0;
+ }
+
+no_context:
+ /* Are we prepared to handle this kernel fault? */
+ if (fixup_exception(regs))
+ return 0;
+
+/*
+ * Oops. The kernel tried to access some bad page. We'll have to
+ * terminate things with extreme prejudice.
+ */
+
+ bust_spinlocks(1);
+
+ /* FIXME: no lookup_address() yet */
+#ifdef SUPPORT_LOOKUP_ADDRESS
+ if (fault_num == INT_ITLB_MISS) {
+ pte_t *pte = lookup_address(address);
+
+ if (pte && pte_present(*pte) && !pte_exec_kernel(*pte))
+ pr_crit("kernel tried to execute"
+ " non-executable page - exploit attempt?"
+ " (uid: %d)\n", current->uid);
+ }
+#endif
+ if (address < PAGE_SIZE)
+ pr_alert("Unable to handle kernel NULL pointer dereference\n");
+ else
+ pr_alert("Unable to handle kernel paging request\n");
+ pr_alert(" at virtual address "REGFMT", pc "REGFMT"\n",
+ address, regs->pc);
+
+ show_regs(regs);
+
+ if (unlikely(tsk->pid < 2)) {
+ panic("Kernel page fault running %s!",
+ tsk->pid ? "init" : "the idle task");
+ }
+
+ /*
+ * More FIXME: we should probably copy the i386 here and
+ * implement a generic die() routine. Not today.
+ */
+#ifdef SUPPORT_DIE
+ die("Oops", regs);
+#endif
+ bust_spinlocks(1);
+
+ do_group_exit(SIGKILL);
+
+/*
+ * We ran out of memory, or some other thing happened to us that made
+ * us unable to handle the page fault gracefully.
+ */
+out_of_memory:
+ up_read(&mm->mmap_sem);
+ if (is_global_init(tsk)) {
+ yield();
+ down_read(&mm->mmap_sem);
+ goto survive;
+ }
+ pr_alert("VM: killing process %s\n", tsk->comm);
+ if (!is_kernel_mode)
+ do_group_exit(SIGKILL);
+ goto no_context;
+
+do_sigbus:
+ up_read(&mm->mmap_sem);
+
+ /* Kernel mode? Handle exceptions or die */
+ if (is_kernel_mode)
+ goto no_context;
+
+ force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
+ return 0;
+}
+
+#ifndef __tilegx__
+
+/* We must release ICS before panicking or we won't get anywhere. */
+#define ics_panic(fmt, ...) do { \
+ __insn_mtspr(SPR_INTERRUPT_CRITICAL_SECTION, 0); \
+ panic(fmt, __VA_ARGS__); \
+} while (0)
+
+/*
+ * When we take an ITLB or DTLB fault or access violation in the
+ * supervisor while the critical section bit is set, the hypervisor is
+ * reluctant to write new values into the EX_CONTEXT_1_x registers,
+ * since that might indicate we have not yet squirreled the SPR
+ * contents away and can thus safely take a recursive interrupt.
+ * Accordingly, the hypervisor passes us the PC via SYSTEM_SAVE_1_2.
+ */
+struct intvec_state do_page_fault_ics(struct pt_regs *regs, int fault_num,
+ unsigned long address,
+ unsigned long info)
+{
+ unsigned long pc = info & ~1;
+ int write = info & 1;
+ pgd_t *pgd = get_current_pgd();
+
+ /* Retval is 1 at first since we will handle the fault fully. */
+ struct intvec_state state = {
+ do_page_fault, fault_num, address, write, 1
+ };
+
+ /* Validate that we are plausibly in the right routine. */
+ if ((pc & 0x7) != 0 || pc < PAGE_OFFSET ||
+ (fault_num != INT_DTLB_MISS &&
+ fault_num != INT_DTLB_ACCESS)) {
+ unsigned long old_pc = regs->pc;
+ regs->pc = pc;
+ ics_panic("Bad ICS page fault args:"
+ " old PC %#lx, fault %d/%d at %#lx\n",
+ old_pc, fault_num, write, address);
+ }
+
+ /* We might be faulting on a vmalloc page, so check that first. */
+ if (fault_num != INT_DTLB_ACCESS && vmalloc_fault(pgd, address) >= 0)
+ return state;
+
+ /*
+ * If we faulted with ICS set in sys_cmpxchg, we are providing
+ * a user syscall service that should generate a signal on
+ * fault. We didn't set up a kernel stack on initial entry to
+ * sys_cmpxchg, but instead had one set up by the fault, which
+ * (because sys_cmpxchg never releases ICS) came to us via the
+ * SYSTEM_SAVE_1_2 mechanism, and thus EX_CONTEXT_1_[01] are
+ * still referencing the original user code. We release the
+ * atomic lock and rewrite pt_regs so that it appears that we
+ * came from user-space directly, and after we finish the
+ * fault we'll go back to user space and re-issue the swint.
+ * This way the backtrace information is correct if we need to
+ * emit a stack dump at any point while handling this.
+ *
+ * Must match register use in sys_cmpxchg().
+ */
+ if (pc >= (unsigned long) sys_cmpxchg &&
+ pc < (unsigned long) __sys_cmpxchg_end) {
+#ifdef CONFIG_SMP
+ /* Don't unlock before we could have locked. */
+ if (pc >= (unsigned long)__sys_cmpxchg_grab_lock) {
+ int *lock_ptr = (int *)(regs->regs[ATOMIC_LOCK_REG]);
+ __atomic_fault_unlock(lock_ptr);
+ }
+#endif
+ regs->sp = regs->regs[27];
+ }
+
+ /*
+ * We can also fault in the atomic assembly, in which
+ * case we use the exception table to do the first-level fixup.
+ * We may re-fixup again in the real fault handler if it
+ * turns out the faulting address is just bad, and not,
+ * for example, migrating.
+ */
+ else if (pc >= (unsigned long) __start_atomic_asm_code &&
+ pc < (unsigned long) __end_atomic_asm_code) {
+ const struct exception_table_entry *fixup;
+#ifdef CONFIG_SMP
+ /* Unlock the atomic lock. */
+ int *lock_ptr = (int *)(regs->regs[ATOMIC_LOCK_REG]);
+ __atomic_fault_unlock(lock_ptr);
+#endif
+ fixup = search_exception_tables(pc);
+ if (!fixup)
+ ics_panic("ICS atomic fault not in table:"
+ " PC %#lx, fault %d", pc, fault_num);
+ regs->pc = fixup->fixup;
+ regs->ex1 = PL_ICS_EX1(KERNEL_PL, 0);
+ }
+
+ /*
+ * NOTE: the one other type of access that might bring us here
+ * are the memory ops in __tns_atomic_acquire/__tns_atomic_release,
+ * but we don't have to check specially for them since we can
+ * always safely return to the address of the fault and retry,
+ * since no separate atomic locks are involved.
+ */
+
+ /*
+ * Now that we have released the atomic lock (if necessary),
+ * it's safe to spin if the PTE that caused the fault was migrating.
+ */
+ if (fault_num == INT_DTLB_ACCESS)
+ write = 1;
+ if (handle_migrating_pte(pgd, fault_num, address, 1, write))
+ return state;
+
+ /* Return zero so that we continue on with normal fault handling. */
+ state.retval = 0;
+ return state;
+}
+
+#endif /* !__tilegx__ */
+
+/*
+ * This routine handles page faults. It determines the address, and the
+ * problem, and then passes it handle_page_fault() for normal DTLB and
+ * ITLB issues, and for DMA or SN processor faults when we are in user
+ * space. For the latter, if we're in kernel mode, we just save the
+ * interrupt away appropriately and return immediately. We can't do
+ * page faults for user code while in kernel mode.
+ */
+void do_page_fault(struct pt_regs *regs, int fault_num,
+ unsigned long address, unsigned long write)
+{
+ int is_page_fault;
+
+ /* This case should have been handled by do_page_fault_ics(). */
+ BUG_ON(write & ~1);
+
+#if CHIP_HAS_TILE_DMA()
+ /*
+ * If it's a DMA fault, suspend the transfer while we're
+ * handling the miss; we'll restart after it's handled. If we
+ * don't suspend, it's possible that this process could swap
+ * out and back in, and restart the engine since the DMA is
+ * still 'running'.
+ */
+ if (fault_num == INT_DMATLB_MISS ||
+ fault_num == INT_DMATLB_ACCESS ||
+ fault_num == INT_DMATLB_MISS_DWNCL ||
+ fault_num == INT_DMATLB_ACCESS_DWNCL) {
+ __insn_mtspr(SPR_DMA_CTR, SPR_DMA_CTR__SUSPEND_MASK);
+ while (__insn_mfspr(SPR_DMA_USER_STATUS) &
+ SPR_DMA_STATUS__BUSY_MASK)
+ ;
+ }
+#endif
+
+ /* Validate fault num and decide if this is a first-time page fault. */
+ switch (fault_num) {
+ case INT_ITLB_MISS:
+ case INT_DTLB_MISS:
+#if CHIP_HAS_TILE_DMA()
+ case INT_DMATLB_MISS:
+ case INT_DMATLB_MISS_DWNCL:
+#endif
+#if CHIP_HAS_SN_PROC()
+ case INT_SNITLB_MISS:
+ case INT_SNITLB_MISS_DWNCL:
+#endif
+ is_page_fault = 1;
+ break;
+
+ case INT_DTLB_ACCESS:
+#if CHIP_HAS_TILE_DMA()
+ case INT_DMATLB_ACCESS:
+ case INT_DMATLB_ACCESS_DWNCL:
+#endif
+ is_page_fault = 0;
+ break;
+
+ default:
+ panic("Bad fault number %d in do_page_fault", fault_num);
+ }
+
+ if (EX1_PL(regs->ex1) != USER_PL) {
+ struct async_tlb *async;
+ switch (fault_num) {
+#if CHIP_HAS_TILE_DMA()
+ case INT_DMATLB_MISS:
+ case INT_DMATLB_ACCESS:
+ case INT_DMATLB_MISS_DWNCL:
+ case INT_DMATLB_ACCESS_DWNCL:
+ async = &current->thread.dma_async_tlb;
+ break;
+#endif
+#if CHIP_HAS_SN_PROC()
+ case INT_SNITLB_MISS:
+ case INT_SNITLB_MISS_DWNCL:
+ async = &current->thread.sn_async_tlb;
+ break;
+#endif
+ default:
+ async = NULL;
+ }
+ if (async) {
+
+ /*
+ * No vmalloc check required, so we can allow
+ * interrupts immediately at this point.
+ */
+ local_irq_enable();
+
+ set_thread_flag(TIF_ASYNC_TLB);
+ if (async->fault_num != 0) {
+ panic("Second async fault %d;"
+ " old fault was %d (%#lx/%ld)",
+ fault_num, async->fault_num,
+ address, write);
+ }
+ BUG_ON(fault_num == 0);
+ async->fault_num = fault_num;
+ async->is_fault = is_page_fault;
+ async->is_write = write;
+ async->address = address;
+ return;
+ }
+ }
+
+ handle_page_fault(regs, fault_num, is_page_fault, address, write);
+}
+
+
+#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
+/*
+ * Check an async_tlb structure to see if a deferred fault is waiting,
+ * and if so pass it to the page-fault code.
+ */
+static void handle_async_page_fault(struct pt_regs *regs,
+ struct async_tlb *async)
+{
+ if (async->fault_num) {
+ /*
+ * Clear async->fault_num before calling the page-fault
+ * handler so that if we re-interrupt before returning
+ * from the function we have somewhere to put the
+ * information from the new interrupt.
+ */
+ int fault_num = async->fault_num;
+ async->fault_num = 0;
+ handle_page_fault(regs, fault_num, async->is_fault,
+ async->address, async->is_write);
+ }
+}
+#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
+
+
+/*
+ * This routine effectively re-issues asynchronous page faults
+ * when we are returning to user space.
+ */
+void do_async_page_fault(struct pt_regs *regs)
+{
+ /*
+ * Clear thread flag early. If we re-interrupt while processing
+ * code here, we will reset it and recall this routine before
+ * returning to user space.
+ */
+ clear_thread_flag(TIF_ASYNC_TLB);
+
+#if CHIP_HAS_TILE_DMA()
+ handle_async_page_fault(regs, &current->thread.dma_async_tlb);
+#endif
+#if CHIP_HAS_SN_PROC()
+ handle_async_page_fault(regs, &current->thread.sn_async_tlb);
+#endif
+}
+
+void vmalloc_sync_all(void)
+{
+#ifdef __tilegx__
+ /* Currently all L1 kernel pmd's are static and shared. */
+ BUG_ON(pgd_index(VMALLOC_END) != pgd_index(VMALLOC_START));
+#else
+ /*
+ * Note that races in the updates of insync and start aren't
+ * problematic: insync can only get set bits added, and updates to
+ * start are only improving performance (without affecting correctness
+ * if undone).
+ */
+ static DECLARE_BITMAP(insync, PTRS_PER_PGD);
+ static unsigned long start = PAGE_OFFSET;
+ unsigned long address;
+
+ BUILD_BUG_ON(PAGE_OFFSET & ~PGDIR_MASK);
+ for (address = start; address >= PAGE_OFFSET; address += PGDIR_SIZE) {
+ if (!test_bit(pgd_index(address), insync)) {
+ unsigned long flags;
+ struct list_head *pos;
+
+ spin_lock_irqsave(&pgd_lock, flags);
+ list_for_each(pos, &pgd_list)
+ if (!vmalloc_sync_one(list_to_pgd(pos),
+ address)) {
+ /* Must be at first entry in list. */
+ BUG_ON(pos != pgd_list.next);
+ break;
+ }
+ spin_unlock_irqrestore(&pgd_lock, flags);
+ if (pos != pgd_list.next)
+ set_bit(pgd_index(address), insync);
+ }
+ if (address == start && test_bit(pgd_index(address), insync))
+ start = address + PGDIR_SIZE;
+ }
+#endif
+}
diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c
new file mode 100644
index 000000000000..ff1cdff5114d
--- /dev/null
+++ b/arch/tile/mm/highmem.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/highmem.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <asm/homecache.h>
+
+#define kmap_get_pte(vaddr) \
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
+ (vaddr)), (vaddr))
+
+
+void *kmap(struct page *page)
+{
+ void *kva;
+ unsigned long flags;
+ pte_t *ptep;
+
+ might_sleep();
+ if (!PageHighMem(page))
+ return page_address(page);
+ kva = kmap_high(page);
+
+ /*
+ * Rewrite the PTE under the lock. This ensures that the page
+ * is not currently migrating.
+ */
+ ptep = kmap_get_pte((unsigned long)kva);
+ flags = homecache_kpte_lock();
+ set_pte_at(&init_mm, kva, ptep, mk_pte(page, page_to_kpgprot(page)));
+ homecache_kpte_unlock(flags);
+
+ return kva;
+}
+EXPORT_SYMBOL(kmap);
+
+void kunmap(struct page *page)
+{
+ if (in_interrupt())
+ BUG();
+ if (!PageHighMem(page))
+ return;
+ kunmap_high(page);
+}
+EXPORT_SYMBOL(kunmap);
+
+static void debug_kmap_atomic_prot(enum km_type type)
+{
+#ifdef CONFIG_DEBUG_HIGHMEM
+ static unsigned warn_count = 10;
+
+ if (unlikely(warn_count == 0))
+ return;
+
+ if (unlikely(in_interrupt())) {
+ if (in_irq()) {
+ if (type != KM_IRQ0 && type != KM_IRQ1 &&
+ type != KM_BIO_SRC_IRQ &&
+ /* type != KM_BIO_DST_IRQ && */
+ type != KM_BOUNCE_READ) {
+ WARN_ON(1);
+ warn_count--;
+ }
+ } else if (!irqs_disabled()) { /* softirq */
+ if (type != KM_IRQ0 && type != KM_IRQ1 &&
+ type != KM_SOFTIRQ0 && type != KM_SOFTIRQ1 &&
+ type != KM_SKB_SUNRPC_DATA &&
+ type != KM_SKB_DATA_SOFTIRQ &&
+ type != KM_BOUNCE_READ) {
+ WARN_ON(1);
+ warn_count--;
+ }
+ }
+ }
+
+ if (type == KM_IRQ0 || type == KM_IRQ1 || type == KM_BOUNCE_READ ||
+ type == KM_BIO_SRC_IRQ /* || type == KM_BIO_DST_IRQ */) {
+ if (!irqs_disabled()) {
+ WARN_ON(1);
+ warn_count--;
+ }
+ } else if (type == KM_SOFTIRQ0 || type == KM_SOFTIRQ1) {
+ if (irq_count() == 0 && !irqs_disabled()) {
+ WARN_ON(1);
+ warn_count--;
+ }
+ }
+#endif
+}
+
+/*
+ * Describe a single atomic mapping of a page on a given cpu at a
+ * given address, and allow it to be linked into a list.
+ */
+struct atomic_mapped_page {
+ struct list_head list;
+ struct page *page;
+ int cpu;
+ unsigned long va;
+};
+
+static spinlock_t amp_lock = __SPIN_LOCK_UNLOCKED(&amp_lock);
+static struct list_head amp_list = LIST_HEAD_INIT(amp_list);
+
+/*
+ * Combining this structure with a per-cpu declaration lets us give
+ * each cpu an atomic_mapped_page structure per type.
+ */
+struct kmap_amps {
+ struct atomic_mapped_page per_type[KM_TYPE_NR];
+};
+static DEFINE_PER_CPU(struct kmap_amps, amps);
+
+/*
+ * Add a page and va, on this cpu, to the list of kmap_atomic pages,
+ * and write the new pte to memory. Writing the new PTE under the
+ * lock guarantees that it is either on the list before migration starts
+ * (if we won the race), or set_pte() sets the migrating bit in the PTE
+ * (if we lost the race). And doing it under the lock guarantees
+ * that when kmap_atomic_fix_one_pte() comes along, it finds a valid
+ * PTE in memory, iff the mapping is still on the amp_list.
+ *
+ * Finally, doing it under the lock lets us safely examine the page
+ * to see if it is immutable or not, for the generic kmap_atomic() case.
+ * If we examine it earlier we are exposed to a race where it looks
+ * writable earlier, but becomes immutable before we write the PTE.
+ */
+static void kmap_atomic_register(struct page *page, enum km_type type,
+ unsigned long va, pte_t *ptep, pte_t pteval)
+{
+ unsigned long flags;
+ struct atomic_mapped_page *amp;
+
+ flags = homecache_kpte_lock();
+ spin_lock(&amp_lock);
+
+ /* With interrupts disabled, now fill in the per-cpu info. */
+ amp = &__get_cpu_var(amps).per_type[type];
+ amp->page = page;
+ amp->cpu = smp_processor_id();
+ amp->va = va;
+
+ /* For generic kmap_atomic(), choose the PTE writability now. */
+ if (!pte_read(pteval))
+ pteval = mk_pte(page, page_to_kpgprot(page));
+
+ list_add(&amp->list, &amp_list);
+ set_pte(ptep, pteval);
+ arch_flush_lazy_mmu_mode();
+
+ spin_unlock(&amp_lock);
+ homecache_kpte_unlock(flags);
+}
+
+/*
+ * Remove a page and va, on this cpu, from the list of kmap_atomic pages.
+ * Linear-time search, but we count on the lists being short.
+ * We don't need to adjust the PTE under the lock (as opposed to the
+ * kmap_atomic_register() case), since we're just unconditionally
+ * zeroing the PTE after it's off the list.
+ */
+static void kmap_atomic_unregister(struct page *page, unsigned long va)
+{
+ unsigned long flags;
+ struct atomic_mapped_page *amp;
+ int cpu = smp_processor_id();
+ spin_lock_irqsave(&amp_lock, flags);
+ list_for_each_entry(amp, &amp_list, list) {
+ if (amp->page == page && amp->cpu == cpu && amp->va == va)
+ break;
+ }
+ BUG_ON(&amp->list == &amp_list);
+ list_del(&amp->list);
+ spin_unlock_irqrestore(&amp_lock, flags);
+}
+
+/* Helper routine for kmap_atomic_fix_kpte(), below. */
+static void kmap_atomic_fix_one_kpte(struct atomic_mapped_page *amp,
+ int finished)
+{
+ pte_t *ptep = kmap_get_pte(amp->va);
+ if (!finished) {
+ set_pte(ptep, pte_mkmigrate(*ptep));
+ flush_remote(0, 0, NULL, amp->va, PAGE_SIZE, PAGE_SIZE,
+ cpumask_of(amp->cpu), NULL, 0);
+ } else {
+ /*
+ * Rewrite a default kernel PTE for this page.
+ * We rely on the fact that set_pte() writes the
+ * present+migrating bits last.
+ */
+ pte_t pte = mk_pte(amp->page, page_to_kpgprot(amp->page));
+ set_pte(ptep, pte);
+ }
+}
+
+/*
+ * This routine is a helper function for homecache_fix_kpte(); see
+ * its comments for more information on the "finished" argument here.
+ *
+ * Note that we hold the lock while doing the remote flushes, which
+ * will stall any unrelated cpus trying to do kmap_atomic operations.
+ * We could just update the PTEs under the lock, and save away copies
+ * of the structs (or just the va+cpu), then flush them after we
+ * release the lock, but it seems easier just to do it all under the lock.
+ */
+void kmap_atomic_fix_kpte(struct page *page, int finished)
+{
+ struct atomic_mapped_page *amp;
+ unsigned long flags;
+ spin_lock_irqsave(&amp_lock, flags);
+ list_for_each_entry(amp, &amp_list, list) {
+ if (amp->page == page)
+ kmap_atomic_fix_one_kpte(amp, finished);
+ }
+ spin_unlock_irqrestore(&amp_lock, flags);
+}
+
+/*
+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap
+ * because the kmap code must perform a global TLB invalidation when
+ * the kmap pool wraps.
+ *
+ * Note that they may be slower than on x86 (etc.) because unlike on
+ * those platforms, we do have to take a global lock to map and unmap
+ * pages on Tile (see above).
+ *
+ * When holding an atomic kmap is is not legal to sleep, so atomic
+ * kmaps are appropriate for short, tight code paths only.
+ */
+void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
+{
+ enum fixed_addresses idx;
+ unsigned long vaddr;
+ pte_t *pte;
+
+ /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
+ pagefault_disable();
+
+ /* Avoid icache flushes by disallowing atomic executable mappings. */
+ BUG_ON(pte_exec(prot));
+
+ if (!PageHighMem(page))
+ return page_address(page);
+
+ debug_kmap_atomic_prot(type);
+
+ idx = type + KM_TYPE_NR*smp_processor_id();
+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
+ pte = kmap_get_pte(vaddr);
+ BUG_ON(!pte_none(*pte));
+
+ /* Register that this page is mapped atomically on this cpu. */
+ kmap_atomic_register(page, type, vaddr, pte, mk_pte(page, prot));
+
+ return (void *)vaddr;
+}
+EXPORT_SYMBOL(kmap_atomic_prot);
+
+void *kmap_atomic(struct page *page, enum km_type type)
+{
+ /* PAGE_NONE is a magic value that tells us to check immutability. */
+ return kmap_atomic_prot(page, type, PAGE_NONE);
+}
+EXPORT_SYMBOL(kmap_atomic);
+
+void kunmap_atomic(void *kvaddr, enum km_type type)
+{
+ unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK;
+ enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
+
+ /*
+ * Force other mappings to Oops if they try to access this pte without
+ * first remapping it. Keeping stale mappings around is a bad idea.
+ */
+ if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) {
+ pte_t *pte = kmap_get_pte(vaddr);
+ pte_t pteval = *pte;
+ BUG_ON(!pte_present(pteval) && !pte_migrating(pteval));
+ kmap_atomic_unregister(pte_page(pteval), vaddr);
+ kpte_clear_flush(pte, vaddr);
+ } else {
+ /* Must be a lowmem page */
+ BUG_ON(vaddr < PAGE_OFFSET);
+ BUG_ON(vaddr >= (unsigned long)high_memory);
+ }
+
+ arch_flush_lazy_mmu_mode();
+ pagefault_enable();
+}
+EXPORT_SYMBOL(kunmap_atomic);
+
+/*
+ * This API is supposed to allow us to map memory without a "struct page".
+ * Currently we don't support this, though this may change in the future.
+ */
+void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
+{
+ return kmap_atomic(pfn_to_page(pfn), type);
+}
+void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
+{
+ return kmap_atomic_prot(pfn_to_page(pfn), type, prot);
+}
+
+struct page *kmap_atomic_to_page(void *ptr)
+{
+ pte_t *pte;
+ unsigned long vaddr = (unsigned long)ptr;
+
+ if (vaddr < FIXADDR_START)
+ return virt_to_page(ptr);
+
+ pte = kmap_get_pte(vaddr);
+ return pte_page(*pte);
+}
diff --git a/arch/tile/mm/homecache.c b/arch/tile/mm/homecache.c
new file mode 100644
index 000000000000..97c478e7be27
--- /dev/null
+++ b/arch/tile/mm/homecache.c
@@ -0,0 +1,433 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This code maintains the "home" for each page in the system.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/bootmem.h>
+#include <linux/rmap.h>
+#include <linux/pagemap.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/sysctl.h>
+#include <linux/pagevec.h>
+#include <linux/ptrace.h>
+#include <linux/timex.h>
+#include <linux/cache.h>
+#include <linux/smp.h>
+
+#include <asm/page.h>
+#include <asm/sections.h>
+#include <asm/tlbflush.h>
+#include <asm/pgalloc.h>
+#include <asm/homecache.h>
+
+#include "migrate.h"
+
+
+#if CHIP_HAS_COHERENT_LOCAL_CACHE()
+
+/*
+ * The noallocl2 option suppresses all use of the L2 cache to cache
+ * locally from a remote home. There's no point in using it if we
+ * don't have coherent local caching, though.
+ */
+static int __write_once noallocl2;
+static int __init set_noallocl2(char *str)
+{
+ noallocl2 = 1;
+ return 0;
+}
+early_param("noallocl2", set_noallocl2);
+
+#else
+
+#define noallocl2 0
+
+#endif
+
+/* Provide no-op versions of these routines to keep flush_remote() cleaner. */
+#define mark_caches_evicted_start() 0
+#define mark_caches_evicted_finish(mask, timestamp) do {} while (0)
+
+
+/*
+ * Update the irq_stat for cpus that we are going to interrupt
+ * with TLB or cache flushes. Also handle removing dataplane cpus
+ * from the TLB flush set, and setting dataplane_tlb_state instead.
+ */
+static void hv_flush_update(const struct cpumask *cache_cpumask,
+ struct cpumask *tlb_cpumask,
+ unsigned long tlb_va, unsigned long tlb_length,
+ HV_Remote_ASID *asids, int asidcount)
+{
+ struct cpumask mask;
+ int i, cpu;
+
+ cpumask_clear(&mask);
+ if (cache_cpumask)
+ cpumask_or(&mask, &mask, cache_cpumask);
+ if (tlb_cpumask && tlb_length) {
+ cpumask_or(&mask, &mask, tlb_cpumask);
+ }
+
+ for (i = 0; i < asidcount; ++i)
+ cpumask_set_cpu(asids[i].y * smp_width + asids[i].x, &mask);
+
+ /*
+ * Don't bother to update atomically; losing a count
+ * here is not that critical.
+ */
+ for_each_cpu(cpu, &mask)
+ ++per_cpu(irq_stat, cpu).irq_hv_flush_count;
+}
+
+/*
+ * This wrapper function around hv_flush_remote() does several things:
+ *
+ * - Provides a return value error-checking panic path, since
+ * there's never any good reason for hv_flush_remote() to fail.
+ * - Accepts a 32-bit PFN rather than a 64-bit PA, which generally
+ * is the type that Linux wants to pass around anyway.
+ * - Centralizes the mark_caches_evicted() handling.
+ * - Canonicalizes that lengths of zero make cpumasks NULL.
+ * - Handles deferring TLB flushes for dataplane tiles.
+ * - Tracks remote interrupts in the per-cpu irq_cpustat_t.
+ *
+ * Note that we have to wait until the cache flush completes before
+ * updating the per-cpu last_cache_flush word, since otherwise another
+ * concurrent flush can race, conclude the flush has already
+ * completed, and start to use the page while it's still dirty
+ * remotely (running concurrently with the actual evict, presumably).
+ */
+void flush_remote(unsigned long cache_pfn, unsigned long cache_control,
+ const struct cpumask *cache_cpumask_orig,
+ HV_VirtAddr tlb_va, unsigned long tlb_length,
+ unsigned long tlb_pgsize,
+ const struct cpumask *tlb_cpumask_orig,
+ HV_Remote_ASID *asids, int asidcount)
+{
+ int rc;
+ int timestamp = 0; /* happy compiler */
+ struct cpumask cache_cpumask_copy, tlb_cpumask_copy;
+ struct cpumask *cache_cpumask, *tlb_cpumask;
+ HV_PhysAddr cache_pa;
+ char cache_buf[NR_CPUS*5], tlb_buf[NR_CPUS*5];
+
+ mb(); /* provided just to simplify "magic hypervisor" mode */
+
+ /*
+ * Canonicalize and copy the cpumasks.
+ */
+ if (cache_cpumask_orig && cache_control) {
+ cpumask_copy(&cache_cpumask_copy, cache_cpumask_orig);
+ cache_cpumask = &cache_cpumask_copy;
+ } else {
+ cpumask_clear(&cache_cpumask_copy);
+ cache_cpumask = NULL;
+ }
+ if (cache_cpumask == NULL)
+ cache_control = 0;
+ if (tlb_cpumask_orig && tlb_length) {
+ cpumask_copy(&tlb_cpumask_copy, tlb_cpumask_orig);
+ tlb_cpumask = &tlb_cpumask_copy;
+ } else {
+ cpumask_clear(&tlb_cpumask_copy);
+ tlb_cpumask = NULL;
+ }
+
+ hv_flush_update(cache_cpumask, tlb_cpumask, tlb_va, tlb_length,
+ asids, asidcount);
+ cache_pa = (HV_PhysAddr)cache_pfn << PAGE_SHIFT;
+ if (cache_control & HV_FLUSH_EVICT_L2)
+ timestamp = mark_caches_evicted_start();
+ rc = hv_flush_remote(cache_pa, cache_control,
+ cpumask_bits(cache_cpumask),
+ tlb_va, tlb_length, tlb_pgsize,
+ cpumask_bits(tlb_cpumask),
+ asids, asidcount);
+ if (cache_control & HV_FLUSH_EVICT_L2)
+ mark_caches_evicted_finish(cache_cpumask, timestamp);
+ if (rc == 0)
+ return;
+ cpumask_scnprintf(cache_buf, sizeof(cache_buf), &cache_cpumask_copy);
+ cpumask_scnprintf(tlb_buf, sizeof(tlb_buf), &tlb_cpumask_copy);
+
+ pr_err("hv_flush_remote(%#llx, %#lx, %p [%s],"
+ " %#lx, %#lx, %#lx, %p [%s], %p, %d) = %d\n",
+ cache_pa, cache_control, cache_cpumask, cache_buf,
+ (unsigned long)tlb_va, tlb_length, tlb_pgsize,
+ tlb_cpumask, tlb_buf,
+ asids, asidcount, rc);
+ panic("Unsafe to continue.");
+}
+
+void homecache_evict(const struct cpumask *mask)
+{
+ flush_remote(0, HV_FLUSH_EVICT_L2, mask, 0, 0, 0, NULL, NULL, 0);
+}
+
+/* Return a mask of the cpus whose caches currently own these pages. */
+static void homecache_mask(struct page *page, int pages,
+ struct cpumask *home_mask)
+{
+ int i;
+ cpumask_clear(home_mask);
+ for (i = 0; i < pages; ++i) {
+ int home = page_home(&page[i]);
+ if (home == PAGE_HOME_IMMUTABLE ||
+ home == PAGE_HOME_INCOHERENT) {
+ cpumask_copy(home_mask, cpu_possible_mask);
+ return;
+ }
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (home == PAGE_HOME_HASH) {
+ cpumask_or(home_mask, home_mask, &hash_for_home_map);
+ continue;
+ }
+#endif
+ if (home == PAGE_HOME_UNCACHED)
+ continue;
+ BUG_ON(home < 0 || home >= NR_CPUS);
+ cpumask_set_cpu(home, home_mask);
+ }
+}
+
+/*
+ * Return the passed length, or zero if it's long enough that we
+ * believe we should evict the whole L2 cache.
+ */
+static unsigned long cache_flush_length(unsigned long length)
+{
+ return (length >= CHIP_L2_CACHE_SIZE()) ? HV_FLUSH_EVICT_L2 : length;
+}
+
+/* On the simulator, confirm lines have been evicted everywhere. */
+static void validate_lines_evicted(unsigned long pfn, size_t length)
+{
+ sim_syscall(SIM_SYSCALL_VALIDATE_LINES_EVICTED,
+ (HV_PhysAddr)pfn << PAGE_SHIFT, length);
+}
+
+/* Flush a page out of whatever cache(s) it is in. */
+void homecache_flush_cache(struct page *page, int order)
+{
+ int pages = 1 << order;
+ int length = cache_flush_length(pages * PAGE_SIZE);
+ unsigned long pfn = page_to_pfn(page);
+ struct cpumask home_mask;
+
+ homecache_mask(page, pages, &home_mask);
+ flush_remote(pfn, length, &home_mask, 0, 0, 0, NULL, NULL, 0);
+ validate_lines_evicted(pfn, pages * PAGE_SIZE);
+}
+
+
+/* Report the home corresponding to a given PTE. */
+static int pte_to_home(pte_t pte)
+{
+ if (hv_pte_get_nc(pte))
+ return PAGE_HOME_IMMUTABLE;
+ switch (hv_pte_get_mode(pte)) {
+ case HV_PTE_MODE_CACHE_TILE_L3:
+ return get_remote_cache_cpu(pte);
+ case HV_PTE_MODE_CACHE_NO_L3:
+ return PAGE_HOME_INCOHERENT;
+ case HV_PTE_MODE_UNCACHED:
+ return PAGE_HOME_UNCACHED;
+#if CHIP_HAS_CBOX_HOME_MAP()
+ case HV_PTE_MODE_CACHE_HASH_L3:
+ return PAGE_HOME_HASH;
+#endif
+ }
+ panic("Bad PTE %#llx\n", pte.val);
+}
+
+/* Update the home of a PTE if necessary (can also be used for a pgprot_t). */
+pte_t pte_set_home(pte_t pte, int home)
+{
+ /* Check for non-linear file mapping "PTEs" and pass them through. */
+ if (pte_file(pte))
+ return pte;
+
+#if CHIP_HAS_MMIO()
+ /* Check for MMIO mappings and pass them through. */
+ if (hv_pte_get_mode(pte) == HV_PTE_MODE_MMIO)
+ return pte;
+#endif
+
+
+ /*
+ * Only immutable pages get NC mappings. If we have a
+ * non-coherent PTE, but the underlying page is not
+ * immutable, it's likely the result of a forced
+ * caching setting running up against ptrace setting
+ * the page to be writable underneath. In this case,
+ * just keep the PTE coherent.
+ */
+ if (hv_pte_get_nc(pte) && home != PAGE_HOME_IMMUTABLE) {
+ pte = hv_pte_clear_nc(pte);
+ pr_err("non-immutable page incoherently referenced: %#llx\n",
+ pte.val);
+ }
+
+ switch (home) {
+
+ case PAGE_HOME_UNCACHED:
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED);
+ break;
+
+ case PAGE_HOME_INCOHERENT:
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
+ break;
+
+ case PAGE_HOME_IMMUTABLE:
+ /*
+ * We could home this page anywhere, since it's immutable,
+ * but by default just home it to follow "hash_default".
+ */
+ BUG_ON(hv_pte_get_writable(pte));
+ if (pte_get_forcecache(pte)) {
+ /* Upgrade "force any cpu" to "No L3" for immutable. */
+ if (hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_TILE_L3
+ && pte_get_anyhome(pte)) {
+ pte = hv_pte_set_mode(pte,
+ HV_PTE_MODE_CACHE_NO_L3);
+ }
+ } else
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (hash_default)
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
+ else
+#endif
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_NO_L3);
+ pte = hv_pte_set_nc(pte);
+ break;
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ case PAGE_HOME_HASH:
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_HASH_L3);
+ break;
+#endif
+
+ default:
+ BUG_ON(home < 0 || home >= NR_CPUS ||
+ !cpu_is_valid_lotar(home));
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_CACHE_TILE_L3);
+ pte = set_remote_cache_cpu(pte, home);
+ break;
+ }
+
+#if CHIP_HAS_NC_AND_NOALLOC_BITS()
+ if (noallocl2)
+ pte = hv_pte_set_no_alloc_l2(pte);
+
+ /* Simplify "no local and no l3" to "uncached" */
+ if (hv_pte_get_no_alloc_l2(pte) && hv_pte_get_no_alloc_l1(pte) &&
+ hv_pte_get_mode(pte) == HV_PTE_MODE_CACHE_NO_L3) {
+ pte = hv_pte_set_mode(pte, HV_PTE_MODE_UNCACHED);
+ }
+#endif
+
+ /* Checking this case here gives a better panic than from the hv. */
+ BUG_ON(hv_pte_get_mode(pte) == 0);
+
+ return pte;
+}
+
+/*
+ * The routines in this section are the "static" versions of the normal
+ * dynamic homecaching routines; they just set the home cache
+ * of a kernel page once, and require a full-chip cache/TLB flush,
+ * so they're not suitable for anything but infrequent use.
+ */
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+static inline int initial_page_home(void) { return PAGE_HOME_HASH; }
+#else
+static inline int initial_page_home(void) { return 0; }
+#endif
+
+int page_home(struct page *page)
+{
+ if (PageHighMem(page)) {
+ return initial_page_home();
+ } else {
+ unsigned long kva = (unsigned long)page_address(page);
+ return pte_to_home(*virt_to_pte(NULL, kva));
+ }
+}
+
+void homecache_change_page_home(struct page *page, int order, int home)
+{
+ int i, pages = (1 << order);
+ unsigned long kva;
+
+ BUG_ON(PageHighMem(page));
+ BUG_ON(page_count(page) > 1);
+ BUG_ON(page_mapcount(page) != 0);
+ kva = (unsigned long) page_address(page);
+ flush_remote(0, HV_FLUSH_EVICT_L2, &cpu_cacheable_map,
+ kva, pages * PAGE_SIZE, PAGE_SIZE, cpu_online_mask,
+ NULL, 0);
+
+ for (i = 0; i < pages; ++i, kva += PAGE_SIZE) {
+ pte_t *ptep = virt_to_pte(NULL, kva);
+ pte_t pteval = *ptep;
+ BUG_ON(!pte_present(pteval) || pte_huge(pteval));
+ *ptep = pte_set_home(pteval, home);
+ }
+}
+
+struct page *homecache_alloc_pages(gfp_t gfp_mask,
+ unsigned int order, int home)
+{
+ struct page *page;
+ BUG_ON(gfp_mask & __GFP_HIGHMEM); /* must be lowmem */
+ page = alloc_pages(gfp_mask, order);
+ if (page)
+ homecache_change_page_home(page, order, home);
+ return page;
+}
+
+struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
+ unsigned int order, int home)
+{
+ struct page *page;
+ BUG_ON(gfp_mask & __GFP_HIGHMEM); /* must be lowmem */
+ page = alloc_pages_node(nid, gfp_mask, order);
+ if (page)
+ homecache_change_page_home(page, order, home);
+ return page;
+}
+
+void homecache_free_pages(unsigned long addr, unsigned int order)
+{
+ struct page *page;
+
+ if (addr == 0)
+ return;
+
+ VM_BUG_ON(!virt_addr_valid((void *)addr));
+ page = virt_to_page((void *)addr);
+ if (put_page_testzero(page)) {
+ int pages = (1 << order);
+ homecache_change_page_home(page, order, initial_page_home());
+ while (pages--)
+ __free_page(page++);
+ }
+}
diff --git a/arch/tile/mm/hugetlbpage.c b/arch/tile/mm/hugetlbpage.c
new file mode 100644
index 000000000000..24688b697a8d
--- /dev/null
+++ b/arch/tile/mm/hugetlbpage.c
@@ -0,0 +1,343 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * TILE Huge TLB Page Support for Kernel.
+ * Taken from i386 hugetlb implementation:
+ * Copyright (C) 2002, Rohit Seth <rohit.seth@intel.com>
+ */
+
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/pagemap.h>
+#include <linux/smp_lock.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/sysctl.h>
+#include <linux/mman.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+
+pte_t *huge_pte_alloc(struct mm_struct *mm,
+ unsigned long addr, unsigned long sz)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pte_t *pte = NULL;
+
+ /* We do not yet support multiple huge page sizes. */
+ BUG_ON(sz != PMD_SIZE);
+
+ pgd = pgd_offset(mm, addr);
+ pud = pud_alloc(mm, pgd, addr);
+ if (pud)
+ pte = (pte_t *) pmd_alloc(mm, pud, addr);
+ BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte));
+
+ return pte;
+}
+
+pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd = NULL;
+
+ pgd = pgd_offset(mm, addr);
+ if (pgd_present(*pgd)) {
+ pud = pud_offset(pgd, addr);
+ if (pud_present(*pud))
+ pmd = pmd_offset(pud, addr);
+ }
+ return (pte_t *) pmd;
+}
+
+#ifdef HUGETLB_TEST
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ int write)
+{
+ unsigned long start = address;
+ int length = 1;
+ int nr;
+ struct page *page;
+ struct vm_area_struct *vma;
+
+ vma = find_vma(mm, addr);
+ if (!vma || !is_vm_hugetlb_page(vma))
+ return ERR_PTR(-EINVAL);
+
+ pte = huge_pte_offset(mm, address);
+
+ /* hugetlb should be locked, and hence, prefaulted */
+ WARN_ON(!pte || pte_none(*pte));
+
+ page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
+
+ WARN_ON(!PageHead(page));
+
+ return page;
+}
+
+int pmd_huge(pmd_t pmd)
+{
+ return 0;
+}
+
+int pud_huge(pud_t pud)
+{
+ return 0;
+}
+
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ pmd_t *pmd, int write)
+{
+ return NULL;
+}
+
+#else
+
+struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
+ int write)
+{
+ return ERR_PTR(-EINVAL);
+}
+
+int pmd_huge(pmd_t pmd)
+{
+ return !!(pmd_val(pmd) & _PAGE_HUGE_PAGE);
+}
+
+int pud_huge(pud_t pud)
+{
+ return !!(pud_val(pud) & _PAGE_HUGE_PAGE);
+}
+
+struct page *follow_huge_pmd(struct mm_struct *mm, unsigned long address,
+ pmd_t *pmd, int write)
+{
+ struct page *page;
+
+ page = pte_page(*(pte_t *)pmd);
+ if (page)
+ page += ((address & ~PMD_MASK) >> PAGE_SHIFT);
+ return page;
+}
+
+struct page *follow_huge_pud(struct mm_struct *mm, unsigned long address,
+ pud_t *pud, int write)
+{
+ struct page *page;
+
+ page = pte_page(*(pte_t *)pud);
+ if (page)
+ page += ((address & ~PUD_MASK) >> PAGE_SHIFT);
+ return page;
+}
+
+int huge_pmd_unshare(struct mm_struct *mm, unsigned long *addr, pte_t *ptep)
+{
+ return 0;
+}
+
+#endif
+
+#ifdef HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags)
+{
+ struct hstate *h = hstate_file(file);
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ unsigned long start_addr;
+
+ if (len > mm->cached_hole_size) {
+ start_addr = mm->free_area_cache;
+ } else {
+ start_addr = TASK_UNMAPPED_BASE;
+ mm->cached_hole_size = 0;
+ }
+
+full_search:
+ addr = ALIGN(start_addr, huge_page_size(h));
+
+ for (vma = find_vma(mm, addr); ; vma = vma->vm_next) {
+ /* At this point: (!vma || addr < vma->vm_end). */
+ if (TASK_SIZE - len < addr) {
+ /*
+ * Start a new search - just in case we missed
+ * some holes.
+ */
+ if (start_addr != TASK_UNMAPPED_BASE) {
+ start_addr = TASK_UNMAPPED_BASE;
+ mm->cached_hole_size = 0;
+ goto full_search;
+ }
+ return -ENOMEM;
+ }
+ if (!vma || addr + len <= vma->vm_start) {
+ mm->free_area_cache = addr + len;
+ return addr;
+ }
+ if (addr + mm->cached_hole_size < vma->vm_start)
+ mm->cached_hole_size = vma->vm_start - addr;
+ addr = ALIGN(vma->vm_end, huge_page_size(h));
+ }
+}
+
+static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
+ unsigned long addr0, unsigned long len,
+ unsigned long pgoff, unsigned long flags)
+{
+ struct hstate *h = hstate_file(file);
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma, *prev_vma;
+ unsigned long base = mm->mmap_base, addr = addr0;
+ unsigned long largest_hole = mm->cached_hole_size;
+ int first_time = 1;
+
+ /* don't allow allocations above current base */
+ if (mm->free_area_cache > base)
+ mm->free_area_cache = base;
+
+ if (len <= largest_hole) {
+ largest_hole = 0;
+ mm->free_area_cache = base;
+ }
+try_again:
+ /* make sure it can fit in the remaining address space */
+ if (mm->free_area_cache < len)
+ goto fail;
+
+ /* either no address requested or cant fit in requested address hole */
+ addr = (mm->free_area_cache - len) & huge_page_mask(h);
+ do {
+ /*
+ * Lookup failure means no vma is above this address,
+ * i.e. return with success:
+ */
+ vma = find_vma_prev(mm, addr, &prev_vma);
+ if (!vma) {
+ return addr;
+ break;
+ }
+
+ /*
+ * new region fits between prev_vma->vm_end and
+ * vma->vm_start, use it:
+ */
+ if (addr + len <= vma->vm_start &&
+ (!prev_vma || (addr >= prev_vma->vm_end))) {
+ /* remember the address as a hint for next time */
+ mm->cached_hole_size = largest_hole;
+ mm->free_area_cache = addr;
+ return addr;
+ } else {
+ /* pull free_area_cache down to the first hole */
+ if (mm->free_area_cache == vma->vm_end) {
+ mm->free_area_cache = vma->vm_start;
+ mm->cached_hole_size = largest_hole;
+ }
+ }
+
+ /* remember the largest hole we saw so far */
+ if (addr + largest_hole < vma->vm_start)
+ largest_hole = vma->vm_start - addr;
+
+ /* try just below the current vma->vm_start */
+ addr = (vma->vm_start - len) & huge_page_mask(h);
+
+ } while (len <= vma->vm_start);
+
+fail:
+ /*
+ * if hint left us with no space for the requested
+ * mapping then try again:
+ */
+ if (first_time) {
+ mm->free_area_cache = base;
+ largest_hole = 0;
+ first_time = 0;
+ goto try_again;
+ }
+ /*
+ * A failed mmap() very likely causes application failure,
+ * so fall back to the bottom-up function here. This scenario
+ * can happen with large stack limits and large mmap()
+ * allocations.
+ */
+ mm->free_area_cache = TASK_UNMAPPED_BASE;
+ mm->cached_hole_size = ~0UL;
+ addr = hugetlb_get_unmapped_area_bottomup(file, addr0,
+ len, pgoff, flags);
+
+ /*
+ * Restore the topdown base:
+ */
+ mm->free_area_cache = base;
+ mm->cached_hole_size = ~0UL;
+
+ return addr;
+}
+
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+ unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+ struct hstate *h = hstate_file(file);
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+
+ if (len & ~huge_page_mask(h))
+ return -EINVAL;
+ if (len > TASK_SIZE)
+ return -ENOMEM;
+
+ if (flags & MAP_FIXED) {
+ if (prepare_hugepage_range(file, addr, len))
+ return -EINVAL;
+ return addr;
+ }
+
+ if (addr) {
+ addr = ALIGN(addr, huge_page_size(h));
+ vma = find_vma(mm, addr);
+ if (TASK_SIZE - len >= addr &&
+ (!vma || addr + len <= vma->vm_start))
+ return addr;
+ }
+ if (current->mm->get_unmapped_area == arch_get_unmapped_area)
+ return hugetlb_get_unmapped_area_bottomup(file, addr, len,
+ pgoff, flags);
+ else
+ return hugetlb_get_unmapped_area_topdown(file, addr, len,
+ pgoff, flags);
+}
+
+static __init int setup_hugepagesz(char *opt)
+{
+ unsigned long ps = memparse(opt, &opt);
+ if (ps == PMD_SIZE) {
+ hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT);
+ } else if (ps == PUD_SIZE) {
+ hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT);
+ } else {
+ pr_err("hugepagesz: Unsupported page size %lu M\n",
+ ps >> 20);
+ return 0;
+ }
+ return 1;
+}
+__setup("hugepagesz=", setup_hugepagesz);
+
+#endif /*HAVE_ARCH_HUGETLB_UNMAPPED_AREA*/
diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c
new file mode 100644
index 000000000000..d89c9eacd162
--- /dev/null
+++ b/arch/tile/mm/init.c
@@ -0,0 +1,1085 @@
+/*
+ * Copyright (C) 1995 Linus Torvalds
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <linux/hugetlb.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/init.h>
+#include <linux/highmem.h>
+#include <linux/pagemap.h>
+#include <linux/poison.h>
+#include <linux/bootmem.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/efi.h>
+#include <linux/memory_hotplug.h>
+#include <linux/uaccess.h>
+#include <asm/mmu_context.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/dma.h>
+#include <asm/fixmap.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/sections.h>
+#include <asm/setup.h>
+#include <asm/homecache.h>
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
+
+#include "migrate.h"
+
+/*
+ * We could set FORCE_MAX_ZONEORDER to "(HPAGE_SHIFT - PAGE_SHIFT + 1)"
+ * in the Tile Kconfig, but this generates configure warnings.
+ * Do it here and force people to get it right to compile this file.
+ * The problem is that with 4KB small pages and 16MB huge pages,
+ * the default value doesn't allow us to group enough small pages
+ * together to make up a huge page.
+ */
+#if CONFIG_FORCE_MAX_ZONEORDER < HPAGE_SHIFT - PAGE_SHIFT + 1
+# error "Change FORCE_MAX_ZONEORDER in arch/tile/Kconfig to match page size"
+#endif
+
+#define clear_pgd(pmdptr) (*(pmdptr) = hv_pte(0))
+
+#ifndef __tilegx__
+unsigned long VMALLOC_RESERVE = CONFIG_VMALLOC_RESERVE;
+#endif
+
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+/* Create an L2 page table */
+static pte_t * __init alloc_pte(void)
+{
+ return __alloc_bootmem(L2_KERNEL_PGTABLE_SIZE, HV_PAGE_TABLE_ALIGN, 0);
+}
+
+/*
+ * L2 page tables per controller. We allocate these all at once from
+ * the bootmem allocator and store them here. This saves on kernel L2
+ * page table memory, compared to allocating a full 64K page per L2
+ * page table, and also means that in cases where we use huge pages,
+ * we are guaranteed to later be able to shatter those huge pages and
+ * switch to using these page tables instead, without requiring
+ * further allocation. Each l2_ptes[] entry points to the first page
+ * table for the first hugepage-size piece of memory on the
+ * controller; other page tables are just indexed directly, i.e. the
+ * L2 page tables are contiguous in memory for each controller.
+ */
+static pte_t *l2_ptes[MAX_NUMNODES];
+static int num_l2_ptes[MAX_NUMNODES];
+
+static void init_prealloc_ptes(int node, int pages)
+{
+ BUG_ON(pages & (HV_L2_ENTRIES-1));
+ if (pages) {
+ num_l2_ptes[node] = pages;
+ l2_ptes[node] = __alloc_bootmem(pages * sizeof(pte_t),
+ HV_PAGE_TABLE_ALIGN, 0);
+ }
+}
+
+pte_t *get_prealloc_pte(unsigned long pfn)
+{
+ int node = pfn_to_nid(pfn);
+ pfn &= ~(-1UL << (NR_PA_HIGHBIT_SHIFT - PAGE_SHIFT));
+ BUG_ON(node >= MAX_NUMNODES);
+ BUG_ON(pfn >= num_l2_ptes[node]);
+ return &l2_ptes[node][pfn];
+}
+
+/*
+ * What caching do we expect pages from the heap to have when
+ * they are allocated during bootup? (Once we've installed the
+ * "real" swapper_pg_dir.)
+ */
+static int initial_heap_home(void)
+{
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (hash_default)
+ return PAGE_HOME_HASH;
+#endif
+ return smp_processor_id();
+}
+
+/*
+ * Place a pointer to an L2 page table in a middle page
+ * directory entry.
+ */
+static void __init assign_pte(pmd_t *pmd, pte_t *page_table)
+{
+ phys_addr_t pa = __pa(page_table);
+ unsigned long l2_ptfn = pa >> HV_LOG2_PAGE_TABLE_ALIGN;
+ pte_t pteval = hv_pte_set_ptfn(__pgprot(_PAGE_TABLE), l2_ptfn);
+ BUG_ON((pa & (HV_PAGE_TABLE_ALIGN-1)) != 0);
+ pteval = pte_set_home(pteval, initial_heap_home());
+ *(pte_t *)pmd = pteval;
+ if (page_table != (pte_t *)pmd_page_vaddr(*pmd))
+ BUG();
+}
+
+#ifdef __tilegx__
+
+#if HV_L1_SIZE != HV_L2_SIZE
+# error Rework assumption that L1 and L2 page tables are same size.
+#endif
+
+/* Since pmd_t arrays and pte_t arrays are the same size, just use casts. */
+static inline pmd_t *alloc_pmd(void)
+{
+ return (pmd_t *)alloc_pte();
+}
+
+static inline void assign_pmd(pud_t *pud, pmd_t *pmd)
+{
+ assign_pte((pmd_t *)pud, (pte_t *)pmd);
+}
+
+#endif /* __tilegx__ */
+
+/* Replace the given pmd with a full PTE table. */
+void __init shatter_pmd(pmd_t *pmd)
+{
+ pte_t *pte = get_prealloc_pte(pte_pfn(*(pte_t *)pmd));
+ assign_pte(pmd, pte);
+}
+
+#ifdef CONFIG_HIGHMEM
+/*
+ * This function initializes a certain range of kernel virtual memory
+ * with new bootmem page tables, everywhere page tables are missing in
+ * the given range.
+ */
+
+/*
+ * NOTE: The pagetables are allocated contiguous on the physical space
+ * so we can cache the place of the first one and move around without
+ * checking the pgd every time.
+ */
+static void __init page_table_range_init(unsigned long start,
+ unsigned long end, pgd_t *pgd_base)
+{
+ pgd_t *pgd;
+ int pgd_idx;
+ unsigned long vaddr;
+
+ vaddr = start;
+ pgd_idx = pgd_index(vaddr);
+ pgd = pgd_base + pgd_idx;
+
+ for ( ; (pgd_idx < PTRS_PER_PGD) && (vaddr != end); pgd++, pgd_idx++) {
+ pmd_t *pmd = pmd_offset(pud_offset(pgd, vaddr), vaddr);
+ if (pmd_none(*pmd))
+ assign_pte(pmd, alloc_pte());
+ vaddr += PMD_SIZE;
+ }
+}
+#endif /* CONFIG_HIGHMEM */
+
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+
+static int __initdata ktext_hash = 1; /* .text pages */
+static int __initdata kdata_hash = 1; /* .data and .bss pages */
+int __write_once hash_default = 1; /* kernel allocator pages */
+EXPORT_SYMBOL(hash_default);
+int __write_once kstack_hash = 1; /* if no homecaching, use h4h */
+#endif /* CHIP_HAS_CBOX_HOME_MAP */
+
+/*
+ * CPUs to use to for striping the pages of kernel data. If hash-for-home
+ * is available, this is only relevant if kcache_hash sets up the
+ * .data and .bss to be page-homed, and we don't want the default mode
+ * of using the full set of kernel cpus for the striping.
+ */
+static __initdata struct cpumask kdata_mask;
+static __initdata int kdata_arg_seen;
+
+int __write_once kdata_huge; /* if no homecaching, small pages */
+
+
+/* Combine a generic pgprot_t with cache home to get a cache-aware pgprot. */
+static pgprot_t __init construct_pgprot(pgprot_t prot, int home)
+{
+ prot = pte_set_home(prot, home);
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (home == PAGE_HOME_IMMUTABLE) {
+ if (ktext_hash)
+ prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_HASH_L3);
+ else
+ prot = hv_pte_set_mode(prot, HV_PTE_MODE_CACHE_NO_L3);
+ }
+#endif
+ return prot;
+}
+
+/*
+ * For a given kernel data VA, how should it be cached?
+ * We return the complete pgprot_t with caching bits set.
+ */
+static pgprot_t __init init_pgprot(ulong address)
+{
+ int cpu;
+ unsigned long page;
+ enum { CODE_DELTA = MEM_SV_INTRPT - PAGE_OFFSET };
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ /* For kdata=huge, everything is just hash-for-home. */
+ if (kdata_huge)
+ return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
+#endif
+
+ /* We map the aliased pages of permanent text inaccessible. */
+ if (address < (ulong) _sinittext - CODE_DELTA)
+ return PAGE_NONE;
+
+ /*
+ * We map read-only data non-coherent for performance. We could
+ * use neighborhood caching on TILE64, but it's not clear it's a win.
+ */
+ if ((address >= (ulong) __start_rodata &&
+ address < (ulong) __end_rodata) ||
+ address == (ulong) empty_zero_page) {
+ return construct_pgprot(PAGE_KERNEL_RO, PAGE_HOME_IMMUTABLE);
+ }
+
+ /* As a performance optimization, keep the boot init stack here. */
+ if (address >= (ulong)&init_thread_union &&
+ address < (ulong)&init_thread_union + THREAD_SIZE)
+ return construct_pgprot(PAGE_KERNEL, smp_processor_id());
+
+#ifndef __tilegx__
+#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ /* Force the atomic_locks[] array page to be hash-for-home. */
+ if (address == (ulong) atomic_locks)
+ return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
+#endif
+#endif
+
+ /*
+ * Everything else that isn't data or bss is heap, so mark it
+ * with the initial heap home (hash-for-home, or this cpu). This
+ * includes any addresses after the loaded image and any address before
+ * _einitdata, since we already captured the case of text before
+ * _sinittext, and __pa(einittext) is approximately __pa(sinitdata).
+ *
+ * All the LOWMEM pages that we mark this way will get their
+ * struct page homecache properly marked later, in set_page_homes().
+ * The HIGHMEM pages we leave with a default zero for their
+ * homes, but with a zero free_time we don't have to actually
+ * do a flush action the first time we use them, either.
+ */
+ if (address >= (ulong) _end || address < (ulong) _einitdata)
+ return construct_pgprot(PAGE_KERNEL, initial_heap_home());
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ /* Use hash-for-home if requested for data/bss. */
+ if (kdata_hash)
+ return construct_pgprot(PAGE_KERNEL, PAGE_HOME_HASH);
+#endif
+
+ /*
+ * Make the w1data homed like heap to start with, to avoid
+ * making it part of the page-striped data area when we're just
+ * going to convert it to read-only soon anyway.
+ */
+ if (address >= (ulong)__w1data_begin && address < (ulong)__w1data_end)
+ return construct_pgprot(PAGE_KERNEL, initial_heap_home());
+
+ /*
+ * Otherwise we just hand out consecutive cpus. To avoid
+ * requiring this function to hold state, we just walk forward from
+ * _sdata by PAGE_SIZE, skipping the readonly and init data, to reach
+ * the requested address, while walking cpu home around kdata_mask.
+ * This is typically no more than a dozen or so iterations.
+ */
+ page = (((ulong)__w1data_end) + PAGE_SIZE - 1) & PAGE_MASK;
+ BUG_ON(address < page || address >= (ulong)_end);
+ cpu = cpumask_first(&kdata_mask);
+ for (; page < address; page += PAGE_SIZE) {
+ if (page >= (ulong)&init_thread_union &&
+ page < (ulong)&init_thread_union + THREAD_SIZE)
+ continue;
+ if (page == (ulong)empty_zero_page)
+ continue;
+#ifndef __tilegx__
+#if !ATOMIC_LOCKS_FOUND_VIA_TABLE()
+ if (page == (ulong)atomic_locks)
+ continue;
+#endif
+#endif
+ cpu = cpumask_next(cpu, &kdata_mask);
+ if (cpu == NR_CPUS)
+ cpu = cpumask_first(&kdata_mask);
+ }
+ return construct_pgprot(PAGE_KERNEL, cpu);
+}
+
+/*
+ * This function sets up how we cache the kernel text. If we have
+ * hash-for-home support, normally that is used instead (see the
+ * kcache_hash boot flag for more information). But if we end up
+ * using a page-based caching technique, this option sets up the
+ * details of that. In addition, the "ktext=nocache" option may
+ * always be used to disable local caching of text pages, if desired.
+ */
+
+static int __initdata ktext_arg_seen;
+static int __initdata ktext_small;
+static int __initdata ktext_local;
+static int __initdata ktext_all;
+static int __initdata ktext_nondataplane;
+static int __initdata ktext_nocache;
+static struct cpumask __initdata ktext_mask;
+
+static int __init setup_ktext(char *str)
+{
+ if (str == NULL)
+ return -EINVAL;
+
+ /* If you have a leading "nocache", turn off ktext caching */
+ if (strncmp(str, "nocache", 7) == 0) {
+ ktext_nocache = 1;
+ pr_info("ktext: disabling local caching of kernel text\n");
+ str += 7;
+ if (*str == ',')
+ ++str;
+ if (*str == '\0')
+ return 0;
+ }
+
+ ktext_arg_seen = 1;
+
+ /* Default setting on Tile64: use a huge page */
+ if (strcmp(str, "huge") == 0)
+ pr_info("ktext: using one huge locally cached page\n");
+
+ /* Pay TLB cost but get no cache benefit: cache small pages locally */
+ else if (strcmp(str, "local") == 0) {
+ ktext_small = 1;
+ ktext_local = 1;
+ pr_info("ktext: using small pages with local caching\n");
+ }
+
+ /* Neighborhood cache ktext pages on all cpus. */
+ else if (strcmp(str, "all") == 0) {
+ ktext_small = 1;
+ ktext_all = 1;
+ pr_info("ktext: using maximal caching neighborhood\n");
+ }
+
+
+ /* Neighborhood ktext pages on specified mask */
+ else if (cpulist_parse(str, &ktext_mask) == 0) {
+ char buf[NR_CPUS * 5];
+ cpulist_scnprintf(buf, sizeof(buf), &ktext_mask);
+ if (cpumask_weight(&ktext_mask) > 1) {
+ ktext_small = 1;
+ pr_info("ktext: using caching neighborhood %s "
+ "with small pages\n", buf);
+ } else {
+ pr_info("ktext: caching on cpu %s with one huge page\n",
+ buf);
+ }
+ }
+
+ else if (*str)
+ return -EINVAL;
+
+ return 0;
+}
+
+early_param("ktext", setup_ktext);
+
+
+static inline pgprot_t ktext_set_nocache(pgprot_t prot)
+{
+ if (!ktext_nocache)
+ prot = hv_pte_set_nc(prot);
+#if CHIP_HAS_NC_AND_NOALLOC_BITS()
+ else
+ prot = hv_pte_set_no_alloc_l2(prot);
+#endif
+ return prot;
+}
+
+#ifndef __tilegx__
+static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va)
+{
+ return pmd_offset(pud_offset(&pgtables[pgd_index(va)], va), va);
+}
+#else
+static pmd_t *__init get_pmd(pgd_t pgtables[], unsigned long va)
+{
+ pud_t *pud = pud_offset(&pgtables[pgd_index(va)], va);
+ if (pud_none(*pud))
+ assign_pmd(pud, alloc_pmd());
+ return pmd_offset(pud, va);
+}
+#endif
+
+/* Temporary page table we use for staging. */
+static pgd_t pgtables[PTRS_PER_PGD]
+ __attribute__((section(".init.page")));
+
+/*
+ * This maps the physical memory to kernel virtual address space, a total
+ * of max_low_pfn pages, by creating page tables starting from address
+ * PAGE_OFFSET.
+ *
+ * This routine transitions us from using a set of compiled-in large
+ * pages to using some more precise caching, including removing access
+ * to code pages mapped at PAGE_OFFSET (executed only at MEM_SV_START)
+ * marking read-only data as locally cacheable, striping the remaining
+ * .data and .bss across all the available tiles, and removing access
+ * to pages above the top of RAM (thus ensuring a page fault from a bad
+ * virtual address rather than a hypervisor shoot down for accessing
+ * memory outside the assigned limits).
+ */
+static void __init kernel_physical_mapping_init(pgd_t *pgd_base)
+{
+ unsigned long address, pfn;
+ pmd_t *pmd;
+ pte_t *pte;
+ int pte_ofs;
+ const struct cpumask *my_cpu_mask = cpumask_of(smp_processor_id());
+ struct cpumask kstripe_mask;
+ int rc, i;
+
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (ktext_arg_seen && ktext_hash) {
+ pr_warning("warning: \"ktext\" boot argument ignored"
+ " if \"kcache_hash\" sets up text hash-for-home\n");
+ ktext_small = 0;
+ }
+
+ if (kdata_arg_seen && kdata_hash) {
+ pr_warning("warning: \"kdata\" boot argument ignored"
+ " if \"kcache_hash\" sets up data hash-for-home\n");
+ }
+
+ if (kdata_huge && !hash_default) {
+ pr_warning("warning: disabling \"kdata=huge\"; requires"
+ " kcache_hash=all or =allbutstack\n");
+ kdata_huge = 0;
+ }
+#endif
+
+ /*
+ * Set up a mask for cpus to use for kernel striping.
+ * This is normally all cpus, but minus dataplane cpus if any.
+ * If the dataplane covers the whole chip, we stripe over
+ * the whole chip too.
+ */
+ cpumask_copy(&kstripe_mask, cpu_possible_mask);
+ if (!kdata_arg_seen)
+ kdata_mask = kstripe_mask;
+
+ /* Allocate and fill in L2 page tables */
+ for (i = 0; i < MAX_NUMNODES; ++i) {
+#ifdef CONFIG_HIGHMEM
+ unsigned long end_pfn = node_lowmem_end_pfn[i];
+#else
+ unsigned long end_pfn = node_end_pfn[i];
+#endif
+ unsigned long end_huge_pfn = 0;
+
+ /* Pre-shatter the last huge page to allow per-cpu pages. */
+ if (kdata_huge)
+ end_huge_pfn = end_pfn - (HPAGE_SIZE >> PAGE_SHIFT);
+
+ pfn = node_start_pfn[i];
+
+ /* Allocate enough memory to hold L2 page tables for node. */
+ init_prealloc_ptes(i, end_pfn - pfn);
+
+ address = (unsigned long) pfn_to_kaddr(pfn);
+ while (pfn < end_pfn) {
+ BUG_ON(address & (HPAGE_SIZE-1));
+ pmd = get_pmd(pgtables, address);
+ pte = get_prealloc_pte(pfn);
+ if (pfn < end_huge_pfn) {
+ pgprot_t prot = init_pgprot(address);
+ *(pte_t *)pmd = pte_mkhuge(pfn_pte(pfn, prot));
+ for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE;
+ pfn++, pte_ofs++, address += PAGE_SIZE)
+ pte[pte_ofs] = pfn_pte(pfn, prot);
+ } else {
+ if (kdata_huge)
+ printk(KERN_DEBUG "pre-shattered huge"
+ " page at %#lx\n", address);
+ for (pte_ofs = 0; pte_ofs < PTRS_PER_PTE;
+ pfn++, pte_ofs++, address += PAGE_SIZE) {
+ pgprot_t prot = init_pgprot(address);
+ pte[pte_ofs] = pfn_pte(pfn, prot);
+ }
+ assign_pte(pmd, pte);
+ }
+ }
+ }
+
+ /*
+ * Set or check ktext_map now that we have cpu_possible_mask
+ * and kstripe_mask to work with.
+ */
+ if (ktext_all)
+ cpumask_copy(&ktext_mask, cpu_possible_mask);
+ else if (ktext_nondataplane)
+ ktext_mask = kstripe_mask;
+ else if (!cpumask_empty(&ktext_mask)) {
+ /* Sanity-check any mask that was requested */
+ struct cpumask bad;
+ cpumask_andnot(&bad, &ktext_mask, cpu_possible_mask);
+ cpumask_and(&ktext_mask, &ktext_mask, cpu_possible_mask);
+ if (!cpumask_empty(&bad)) {
+ char buf[NR_CPUS * 5];
+ cpulist_scnprintf(buf, sizeof(buf), &bad);
+ pr_info("ktext: not using unavailable cpus %s\n", buf);
+ }
+ if (cpumask_empty(&ktext_mask)) {
+ pr_warning("ktext: no valid cpus; caching on %d.\n",
+ smp_processor_id());
+ cpumask_copy(&ktext_mask,
+ cpumask_of(smp_processor_id()));
+ }
+ }
+
+ address = MEM_SV_INTRPT;
+ pmd = get_pmd(pgtables, address);
+ if (ktext_small) {
+ /* Allocate an L2 PTE for the kernel text */
+ int cpu = 0;
+ pgprot_t prot = construct_pgprot(PAGE_KERNEL_EXEC,
+ PAGE_HOME_IMMUTABLE);
+
+ if (ktext_local) {
+ if (ktext_nocache)
+ prot = hv_pte_set_mode(prot,
+ HV_PTE_MODE_UNCACHED);
+ else
+ prot = hv_pte_set_mode(prot,
+ HV_PTE_MODE_CACHE_NO_L3);
+ } else {
+ prot = hv_pte_set_mode(prot,
+ HV_PTE_MODE_CACHE_TILE_L3);
+ cpu = cpumask_first(&ktext_mask);
+
+ prot = ktext_set_nocache(prot);
+ }
+
+ BUG_ON(address != (unsigned long)_stext);
+ pfn = 0; /* code starts at PA 0 */
+ pte = alloc_pte();
+ for (pte_ofs = 0; address < (unsigned long)_einittext;
+ pfn++, pte_ofs++, address += PAGE_SIZE) {
+ if (!ktext_local) {
+ prot = set_remote_cache_cpu(prot, cpu);
+ cpu = cpumask_next(cpu, &ktext_mask);
+ if (cpu == NR_CPUS)
+ cpu = cpumask_first(&ktext_mask);
+ }
+ pte[pte_ofs] = pfn_pte(pfn, prot);
+ }
+ assign_pte(pmd, pte);
+ } else {
+ pte_t pteval = pfn_pte(0, PAGE_KERNEL_EXEC);
+ pteval = pte_mkhuge(pteval);
+#if CHIP_HAS_CBOX_HOME_MAP()
+ if (ktext_hash) {
+ pteval = hv_pte_set_mode(pteval,
+ HV_PTE_MODE_CACHE_HASH_L3);
+ pteval = ktext_set_nocache(pteval);
+ } else
+#endif /* CHIP_HAS_CBOX_HOME_MAP() */
+ if (cpumask_weight(&ktext_mask) == 1) {
+ pteval = set_remote_cache_cpu(pteval,
+ cpumask_first(&ktext_mask));
+ pteval = hv_pte_set_mode(pteval,
+ HV_PTE_MODE_CACHE_TILE_L3);
+ pteval = ktext_set_nocache(pteval);
+ } else if (ktext_nocache)
+ pteval = hv_pte_set_mode(pteval,
+ HV_PTE_MODE_UNCACHED);
+ else
+ pteval = hv_pte_set_mode(pteval,
+ HV_PTE_MODE_CACHE_NO_L3);
+ *(pte_t *)pmd = pteval;
+ }
+
+ /* Set swapper_pgprot here so it is flushed to memory right away. */
+ swapper_pgprot = init_pgprot((unsigned long)swapper_pg_dir);
+
+ /*
+ * Since we may be changing the caching of the stack and page
+ * table itself, we invoke an assembly helper to do the
+ * following steps:
+ *
+ * - flush the cache so we start with an empty slate
+ * - install pgtables[] as the real page table
+ * - flush the TLB so the new page table takes effect
+ */
+ rc = flush_and_install_context(__pa(pgtables),
+ init_pgprot((unsigned long)pgtables),
+ __get_cpu_var(current_asid),
+ cpumask_bits(my_cpu_mask));
+ BUG_ON(rc != 0);
+
+ /* Copy the page table back to the normal swapper_pg_dir. */
+ memcpy(pgd_base, pgtables, sizeof(pgtables));
+ __install_page_table(pgd_base, __get_cpu_var(current_asid),
+ swapper_pgprot);
+}
+
+/*
+ * devmem_is_allowed() checks to see if /dev/mem access to a certain address
+ * is valid. The argument is a physical page number.
+ *
+ * On Tile, the only valid things for which we can just hand out unchecked
+ * PTEs are the kernel code and data. Anything else might change its
+ * homing with time, and we wouldn't know to adjust the /dev/mem PTEs.
+ * Note that init_thread_union is released to heap soon after boot,
+ * so we include it in the init data.
+ *
+ * For TILE-Gx, we might want to consider allowing access to PA
+ * regions corresponding to PCI space, etc.
+ */
+int devmem_is_allowed(unsigned long pagenr)
+{
+ return pagenr < kaddr_to_pfn(_end) &&
+ !(pagenr >= kaddr_to_pfn(&init_thread_union) ||
+ pagenr < kaddr_to_pfn(_einitdata)) &&
+ !(pagenr >= kaddr_to_pfn(_sinittext) ||
+ pagenr <= kaddr_to_pfn(_einittext-1));
+}
+
+#ifdef CONFIG_HIGHMEM
+static void __init permanent_kmaps_init(pgd_t *pgd_base)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ unsigned long vaddr;
+
+ vaddr = PKMAP_BASE;
+ page_table_range_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
+
+ pgd = swapper_pg_dir + pgd_index(vaddr);
+ pud = pud_offset(pgd, vaddr);
+ pmd = pmd_offset(pud, vaddr);
+ pte = pte_offset_kernel(pmd, vaddr);
+ pkmap_page_table = pte;
+}
+#endif /* CONFIG_HIGHMEM */
+
+
+static void __init init_free_pfn_range(unsigned long start, unsigned long end)
+{
+ unsigned long pfn;
+ struct page *page = pfn_to_page(start);
+
+ for (pfn = start; pfn < end; ) {
+ /* Optimize by freeing pages in large batches */
+ int order = __ffs(pfn);
+ int count, i;
+ struct page *p;
+
+ if (order >= MAX_ORDER)
+ order = MAX_ORDER-1;
+ count = 1 << order;
+ while (pfn + count > end) {
+ count >>= 1;
+ --order;
+ }
+ for (p = page, i = 0; i < count; ++i, ++p) {
+ __ClearPageReserved(p);
+ /*
+ * Hacky direct set to avoid unnecessary
+ * lock take/release for EVERY page here.
+ */
+ p->_count.counter = 0;
+ p->_mapcount.counter = -1;
+ }
+ init_page_count(page);
+ __free_pages(page, order);
+ totalram_pages += count;
+
+ page += count;
+ pfn += count;
+ }
+}
+
+static void __init set_non_bootmem_pages_init(void)
+{
+ struct zone *z;
+ for_each_zone(z) {
+ unsigned long start, end;
+ int nid = z->zone_pgdat->node_id;
+ int idx = zone_idx(z);
+
+ start = z->zone_start_pfn;
+ if (start == 0)
+ continue; /* bootmem */
+ end = start + z->spanned_pages;
+ if (idx == ZONE_NORMAL) {
+ BUG_ON(start != node_start_pfn[nid]);
+ start = node_free_pfn[nid];
+ }
+#ifdef CONFIG_HIGHMEM
+ if (idx == ZONE_HIGHMEM)
+ totalhigh_pages += z->spanned_pages;
+#endif
+ if (kdata_huge) {
+ unsigned long percpu_pfn = node_percpu_pfn[nid];
+ if (start < percpu_pfn && end > percpu_pfn)
+ end = percpu_pfn;
+ }
+#ifdef CONFIG_PCI
+ if (start <= pci_reserve_start_pfn &&
+ end > pci_reserve_start_pfn) {
+ if (end > pci_reserve_end_pfn)
+ init_free_pfn_range(pci_reserve_end_pfn, end);
+ end = pci_reserve_start_pfn;
+ }
+#endif
+ init_free_pfn_range(start, end);
+ }
+}
+
+/*
+ * paging_init() sets up the page tables - note that all of lowmem is
+ * already mapped by head.S.
+ */
+void __init paging_init(void)
+{
+#ifdef CONFIG_HIGHMEM
+ unsigned long vaddr, end;
+#endif
+#ifdef __tilegx__
+ pud_t *pud;
+#endif
+ pgd_t *pgd_base = swapper_pg_dir;
+
+ kernel_physical_mapping_init(pgd_base);
+
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Fixed mappings, only the page table structure has to be
+ * created - mappings will be set by set_fixmap():
+ */
+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
+ end = (FIXADDR_TOP + PMD_SIZE - 1) & PMD_MASK;
+ page_table_range_init(vaddr, end, pgd_base);
+ permanent_kmaps_init(pgd_base);
+#endif
+
+#ifdef __tilegx__
+ /*
+ * Since GX allocates just one pmd_t array worth of vmalloc space,
+ * we go ahead and allocate it statically here, then share it
+ * globally. As a result we don't have to worry about any task
+ * changing init_mm once we get up and running, and there's no
+ * need for e.g. vmalloc_sync_all().
+ */
+ BUILD_BUG_ON(pgd_index(VMALLOC_START) != pgd_index(VMALLOC_END));
+ pud = pud_offset(pgd_base + pgd_index(VMALLOC_START), VMALLOC_START);
+ assign_pmd(pud, alloc_pmd());
+#endif
+}
+
+
+/*
+ * Walk the kernel page tables and derive the page_home() from
+ * the PTEs, so that set_pte() can properly validate the caching
+ * of all PTEs it sees.
+ */
+void __init set_page_homes(void)
+{
+}
+
+static void __init set_max_mapnr_init(void)
+{
+#ifdef CONFIG_FLATMEM
+ max_mapnr = max_low_pfn;
+#endif
+}
+
+void __init mem_init(void)
+{
+ int codesize, datasize, initsize;
+ int i;
+#ifndef __tilegx__
+ void *last;
+#endif
+
+#ifdef CONFIG_FLATMEM
+ if (!mem_map)
+ BUG();
+#endif
+
+#ifdef CONFIG_HIGHMEM
+ /* check that fixmap and pkmap do not overlap */
+ if (PKMAP_ADDR(LAST_PKMAP-1) >= FIXADDR_START) {
+ pr_err("fixmap and kmap areas overlap"
+ " - this will crash\n");
+ pr_err("pkstart: %lxh pkend: %lxh fixstart %lxh\n",
+ PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP-1),
+ FIXADDR_START);
+ BUG();
+ }
+#endif
+
+ set_max_mapnr_init();
+
+ /* this will put all bootmem onto the freelists */
+ totalram_pages += free_all_bootmem();
+
+ /* count all remaining LOWMEM and give all HIGHMEM to page allocator */
+ set_non_bootmem_pages_init();
+
+ codesize = (unsigned long)&_etext - (unsigned long)&_text;
+ datasize = (unsigned long)&_end - (unsigned long)&_sdata;
+ initsize = (unsigned long)&_einittext - (unsigned long)&_sinittext;
+ initsize += (unsigned long)&_einitdata - (unsigned long)&_sinitdata;
+
+ pr_info("Memory: %luk/%luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ num_physpages << (PAGE_SHIFT-10),
+ codesize >> 10,
+ datasize >> 10,
+ initsize >> 10,
+ (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
+ );
+
+ /*
+ * In debug mode, dump some interesting memory mappings.
+ */
+#ifdef CONFIG_HIGHMEM
+ printk(KERN_DEBUG " KMAP %#lx - %#lx\n",
+ FIXADDR_START, FIXADDR_TOP + PAGE_SIZE - 1);
+ printk(KERN_DEBUG " PKMAP %#lx - %#lx\n",
+ PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP) - 1);
+#endif
+#ifdef CONFIG_HUGEVMAP
+ printk(KERN_DEBUG " HUGEMAP %#lx - %#lx\n",
+ HUGE_VMAP_BASE, HUGE_VMAP_END - 1);
+#endif
+ printk(KERN_DEBUG " VMALLOC %#lx - %#lx\n",
+ _VMALLOC_START, _VMALLOC_END - 1);
+#ifdef __tilegx__
+ for (i = MAX_NUMNODES-1; i >= 0; --i) {
+ struct pglist_data *node = &node_data[i];
+ if (node->node_present_pages) {
+ unsigned long start = (unsigned long)
+ pfn_to_kaddr(node->node_start_pfn);
+ unsigned long end = start +
+ (node->node_present_pages << PAGE_SHIFT);
+ printk(KERN_DEBUG " MEM%d %#lx - %#lx\n",
+ i, start, end - 1);
+ }
+ }
+#else
+ last = high_memory;
+ for (i = MAX_NUMNODES-1; i >= 0; --i) {
+ if ((unsigned long)vbase_map[i] != -1UL) {
+ printk(KERN_DEBUG " LOWMEM%d %#lx - %#lx\n",
+ i, (unsigned long) (vbase_map[i]),
+ (unsigned long) (last-1));
+ last = vbase_map[i];
+ }
+ }
+#endif
+
+#ifndef __tilegx__
+ /*
+ * Convert from using one lock for all atomic operations to
+ * one per cpu.
+ */
+ __init_atomic_per_cpu();
+#endif
+}
+
+/*
+ * this is for the non-NUMA, single node SMP system case.
+ * Specifically, in the case of x86, we will always add
+ * memory to the highmem for now.
+ */
+#ifndef CONFIG_NEED_MULTIPLE_NODES
+int arch_add_memory(u64 start, u64 size)
+{
+ struct pglist_data *pgdata = &contig_page_data;
+ struct zone *zone = pgdata->node_zones + MAX_NR_ZONES-1;
+ unsigned long start_pfn = start >> PAGE_SHIFT;
+ unsigned long nr_pages = size >> PAGE_SHIFT;
+
+ return __add_pages(zone, start_pfn, nr_pages);
+}
+
+int remove_memory(u64 start, u64 size)
+{
+ return -EINVAL;
+}
+#endif
+
+struct kmem_cache *pgd_cache;
+
+void __init pgtable_cache_init(void)
+{
+ pgd_cache = kmem_cache_create("pgd",
+ PTRS_PER_PGD*sizeof(pgd_t),
+ PTRS_PER_PGD*sizeof(pgd_t),
+ 0,
+ NULL);
+ if (!pgd_cache)
+ panic("pgtable_cache_init(): Cannot create pgd cache");
+}
+
+#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
+/*
+ * The __w1data area holds data that is only written during initialization,
+ * and is read-only and thus freely cacheable thereafter. Fix the page
+ * table entries that cover that region accordingly.
+ */
+static void mark_w1data_ro(void)
+{
+ /* Loop over page table entries */
+ unsigned long addr = (unsigned long)__w1data_begin;
+ BUG_ON((addr & (PAGE_SIZE-1)) != 0);
+ for (; addr <= (unsigned long)__w1data_end - 1; addr += PAGE_SIZE) {
+ unsigned long pfn = kaddr_to_pfn((void *)addr);
+ pte_t *ptep = virt_to_pte(NULL, addr);
+ BUG_ON(pte_huge(*ptep)); /* not relevant for kdata_huge */
+ set_pte_at(&init_mm, addr, ptep, pfn_pte(pfn, PAGE_KERNEL_RO));
+ }
+}
+#endif
+
+#ifdef CONFIG_DEBUG_PAGEALLOC
+static long __write_once initfree;
+#else
+static long __write_once initfree = 1;
+#endif
+
+/* Select whether to free (1) or mark unusable (0) the __init pages. */
+static int __init set_initfree(char *str)
+{
+ strict_strtol(str, 0, &initfree);
+ pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't");
+ return 1;
+}
+__setup("initfree=", set_initfree);
+
+static void free_init_pages(char *what, unsigned long begin, unsigned long end)
+{
+ unsigned long addr = (unsigned long) begin;
+
+ if (kdata_huge && !initfree) {
+ pr_warning("Warning: ignoring initfree=0:"
+ " incompatible with kdata=huge\n");
+ initfree = 1;
+ }
+ end = (end + PAGE_SIZE - 1) & PAGE_MASK;
+ local_flush_tlb_pages(NULL, begin, PAGE_SIZE, end - begin);
+ for (addr = begin; addr < end; addr += PAGE_SIZE) {
+ /*
+ * Note we just reset the home here directly in the
+ * page table. We know this is safe because our caller
+ * just flushed the caches on all the other cpus,
+ * and they won't be touching any of these pages.
+ */
+ int pfn = kaddr_to_pfn((void *)addr);
+ struct page *page = pfn_to_page(pfn);
+ pte_t *ptep = virt_to_pte(NULL, addr);
+ if (!initfree) {
+ /*
+ * If debugging page accesses then do not free
+ * this memory but mark them not present - any
+ * buggy init-section access will create a
+ * kernel page fault:
+ */
+ pte_clear(&init_mm, addr, ptep);
+ continue;
+ }
+ __ClearPageReserved(page);
+ init_page_count(page);
+ if (pte_huge(*ptep))
+ BUG_ON(!kdata_huge);
+ else
+ set_pte_at(&init_mm, addr, ptep,
+ pfn_pte(pfn, PAGE_KERNEL));
+ memset((void *)addr, POISON_FREE_INITMEM, PAGE_SIZE);
+ free_page(addr);
+ totalram_pages++;
+ }
+ pr_info("Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
+}
+
+void free_initmem(void)
+{
+ const unsigned long text_delta = MEM_SV_INTRPT - PAGE_OFFSET;
+
+ /*
+ * Evict the dirty initdata on the boot cpu, evict the w1data
+ * wherever it's homed, and evict all the init code everywhere.
+ * We are guaranteed that no one will touch the init pages any
+ * more, and although other cpus may be touching the w1data,
+ * we only actually change the caching on tile64, which won't
+ * be keeping local copies in the other tiles' caches anyway.
+ */
+ homecache_evict(&cpu_cacheable_map);
+
+ /* Free the data pages that we won't use again after init. */
+ free_init_pages("unused kernel data",
+ (unsigned long)_sinitdata,
+ (unsigned long)_einitdata);
+
+ /*
+ * Free the pages mapped from 0xc0000000 that correspond to code
+ * pages from 0xfd000000 that we won't use again after init.
+ */
+ free_init_pages("unused kernel text",
+ (unsigned long)_sinittext - text_delta,
+ (unsigned long)_einittext - text_delta);
+
+#if !CHIP_HAS_COHERENT_LOCAL_CACHE()
+ /*
+ * Upgrade the .w1data section to globally cached.
+ * We don't do this on tilepro, since the cache architecture
+ * pretty much makes it irrelevant, and in any case we end
+ * up having racing issues with other tiles that may touch
+ * the data after we flush the cache but before we update
+ * the PTEs and flush the TLBs, causing sharer shootdowns
+ * later. Even though this is to clean data, it seems like
+ * an unnecessary complication.
+ */
+ mark_w1data_ro();
+#endif
+
+ /* Do a global TLB flush so everyone sees the changes. */
+ flush_tlb_all();
+}
diff --git a/arch/tile/mm/migrate.h b/arch/tile/mm/migrate.h
new file mode 100644
index 000000000000..cd45a0837fa6
--- /dev/null
+++ b/arch/tile/mm/migrate.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Structure definitions for migration, exposed here for use by
+ * arch/tile/kernel/asm-offsets.c.
+ */
+
+#ifndef MM_MIGRATE_H
+#define MM_MIGRATE_H
+
+#include <linux/cpumask.h>
+#include <hv/hypervisor.h>
+
+/*
+ * This function is used as a helper when setting up the initial
+ * page table (swapper_pg_dir).
+ */
+extern int flush_and_install_context(HV_PhysAddr page_table, HV_PTE access,
+ HV_ASID asid,
+ const unsigned long *cpumask);
+
+/*
+ * This function supports migration as a "helper" as follows:
+ *
+ * - Set the stack PTE itself to "migrating".
+ * - Do a global TLB flush for (va,length) and the specified ASIDs.
+ * - Do a cache-evict on all necessary cpus.
+ * - Write the new stack PTE.
+ *
+ * Note that any non-NULL pointers must not point to the page that
+ * is handled by the stack_pte itself.
+ */
+extern int homecache_migrate_stack_and_flush(pte_t stack_pte, unsigned long va,
+ size_t length, pte_t *stack_ptep,
+ const struct cpumask *cache_cpumask,
+ const struct cpumask *tlb_cpumask,
+ HV_Remote_ASID *asids,
+ int asidcount);
+
+#endif /* MM_MIGRATE_H */
diff --git a/arch/tile/mm/migrate_32.S b/arch/tile/mm/migrate_32.S
new file mode 100644
index 000000000000..f738765cd1e6
--- /dev/null
+++ b/arch/tile/mm/migrate_32.S
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * This routine is a helper for migrating the home of a set of pages to
+ * a new cpu. See the documentation in homecache.c for more information.
+ */
+
+#include <linux/linkage.h>
+#include <linux/threads.h>
+#include <asm/page.h>
+#include <asm/types.h>
+#include <asm/asm-offsets.h>
+#include <hv/hypervisor.h>
+
+ .text
+
+/*
+ * First, some definitions that apply to all the code in the file.
+ */
+
+/* Locals (caller-save) */
+#define r_tmp r10
+#define r_save_sp r11
+
+/* What we save where in the stack frame; must include all callee-saves. */
+#define FRAME_SP 4
+#define FRAME_R30 8
+#define FRAME_R31 12
+#define FRAME_R32 16
+#define FRAME_R33 20
+#define FRAME_R34 24
+#define FRAME_R35 28
+#define FRAME_SIZE 32
+
+
+
+
+/*
+ * On entry:
+ *
+ * r0 low word of the new context PA to install (moved to r_context_lo)
+ * r1 high word of the new context PA to install (moved to r_context_hi)
+ * r2 low word of PTE to use for context access (moved to r_access_lo)
+ * r3 high word of PTE to use for context access (moved to r_access_lo)
+ * r4 ASID to use for new context (moved to r_asid)
+ * r5 pointer to cpumask with just this cpu set in it (r_my_cpumask)
+ */
+
+/* Arguments (caller-save) */
+#define r_context_lo_in r0
+#define r_context_hi_in r1
+#define r_access_lo_in r2
+#define r_access_hi_in r3
+#define r_asid_in r4
+#define r_my_cpumask r5
+
+/* Locals (callee-save); must not be more than FRAME_xxx above. */
+#define r_save_ics r30
+#define r_context_lo r31
+#define r_context_hi r32
+#define r_access_lo r33
+#define r_access_hi r34
+#define r_asid r35
+
+STD_ENTRY(flush_and_install_context)
+ /*
+ * Create a stack frame; we can't touch it once we flush the
+ * cache until we install the new page table and flush the TLB.
+ */
+ {
+ move r_save_sp, sp
+ sw sp, lr
+ addi sp, sp, -FRAME_SIZE
+ }
+ addi r_tmp, sp, FRAME_SP
+ {
+ sw r_tmp, r_save_sp
+ addi r_tmp, sp, FRAME_R30
+ }
+ {
+ sw r_tmp, r30
+ addi r_tmp, sp, FRAME_R31
+ }
+ {
+ sw r_tmp, r31
+ addi r_tmp, sp, FRAME_R32
+ }
+ {
+ sw r_tmp, r32
+ addi r_tmp, sp, FRAME_R33
+ }
+ {
+ sw r_tmp, r33
+ addi r_tmp, sp, FRAME_R34
+ }
+ {
+ sw r_tmp, r34
+ addi r_tmp, sp, FRAME_R35
+ }
+ sw r_tmp, r35
+
+ /* Move some arguments to callee-save registers. */
+ {
+ move r_context_lo, r_context_lo_in
+ move r_context_hi, r_context_hi_in
+ }
+ {
+ move r_access_lo, r_access_lo_in
+ move r_access_hi, r_access_hi_in
+ }
+ move r_asid, r_asid_in
+
+ /* Disable interrupts, since we can't use our stack. */
+ {
+ mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
+ movei r_tmp, 1
+ }
+ mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
+
+ /* First, flush our L2 cache. */
+ {
+ move r0, zero /* cache_pa */
+ move r1, zero
+ }
+ {
+ auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */
+ move r3, r_my_cpumask /* cache_cpumask */
+ }
+ {
+ move r4, zero /* tlb_va */
+ move r5, zero /* tlb_length */
+ }
+ {
+ move r6, zero /* tlb_pgsize */
+ move r7, zero /* tlb_cpumask */
+ }
+ {
+ move r8, zero /* asids */
+ move r9, zero /* asidcount */
+ }
+ jal hv_flush_remote
+ bnz r0, .Ldone
+
+ /* Now install the new page table. */
+ {
+ move r0, r_context_lo
+ move r1, r_context_hi
+ }
+ {
+ move r2, r_access_lo
+ move r3, r_access_hi
+ }
+ {
+ move r4, r_asid
+ movei r5, HV_CTX_DIRECTIO
+ }
+ jal hv_install_context
+ bnz r0, .Ldone
+
+ /* Finally, flush the TLB. */
+ {
+ movei r0, 0 /* preserve_global */
+ jal hv_flush_all
+ }
+
+.Ldone:
+ /* Reset interrupts back how they were before. */
+ mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
+
+ /* Restore the callee-saved registers and return. */
+ addli lr, sp, FRAME_SIZE
+ {
+ lw lr, lr
+ addli r_tmp, sp, FRAME_R30
+ }
+ {
+ lw r30, r_tmp
+ addli r_tmp, sp, FRAME_R31
+ }
+ {
+ lw r31, r_tmp
+ addli r_tmp, sp, FRAME_R32
+ }
+ {
+ lw r32, r_tmp
+ addli r_tmp, sp, FRAME_R33
+ }
+ {
+ lw r33, r_tmp
+ addli r_tmp, sp, FRAME_R34
+ }
+ {
+ lw r34, r_tmp
+ addli r_tmp, sp, FRAME_R35
+ }
+ {
+ lw r35, r_tmp
+ addi sp, sp, FRAME_SIZE
+ }
+ jrp lr
+ STD_ENDPROC(flush_and_install_context)
diff --git a/arch/tile/mm/mmap.c b/arch/tile/mm/mmap.c
new file mode 100644
index 000000000000..f96f4cec602a
--- /dev/null
+++ b/arch/tile/mm/mmap.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Taken from the i386 architecture and simplified.
+ */
+
+#include <linux/mm.h>
+#include <linux/random.h>
+#include <linux/limits.h>
+#include <linux/sched.h>
+#include <linux/mman.h>
+#include <linux/compat.h>
+
+/*
+ * Top of mmap area (just below the process stack).
+ *
+ * Leave an at least ~128 MB hole.
+ */
+#define MIN_GAP (128*1024*1024)
+#define MAX_GAP (TASK_SIZE/6*5)
+
+static inline unsigned long mmap_base(struct mm_struct *mm)
+{
+ unsigned long gap = rlimit(RLIMIT_STACK);
+ unsigned long random_factor = 0;
+
+ if (current->flags & PF_RANDOMIZE)
+ random_factor = get_random_int() % (1024*1024);
+
+ if (gap < MIN_GAP)
+ gap = MIN_GAP;
+ else if (gap > MAX_GAP)
+ gap = MAX_GAP;
+
+ return PAGE_ALIGN(TASK_SIZE - gap - random_factor);
+}
+
+/*
+ * This function, called very early during the creation of a new
+ * process VM image, sets up which VM layout function to use:
+ */
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+#if !defined(__tilegx__)
+ int is_32bit = 1;
+#elif defined(CONFIG_COMPAT)
+ int is_32bit = is_compat_task();
+#else
+ int is_32bit = 0;
+#endif
+
+ /*
+ * Use standard layout if the expected stack growth is unlimited
+ * or we are running native 64 bits.
+ */
+ if (!is_32bit || rlimit(RLIMIT_STACK) == RLIM_INFINITY) {
+ mm->mmap_base = TASK_UNMAPPED_BASE;
+ mm->get_unmapped_area = arch_get_unmapped_area;
+ mm->unmap_area = arch_unmap_area;
+ } else {
+ mm->mmap_base = mmap_base(mm);
+ mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+ mm->unmap_area = arch_unmap_area_topdown;
+ }
+}
diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c
new file mode 100644
index 000000000000..28c23140c947
--- /dev/null
+++ b/arch/tile/mm/pgtable.c
@@ -0,0 +1,530 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/smp.h>
+#include <linux/highmem.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/spinlock.h>
+#include <linux/cpumask.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/vmalloc.h>
+#include <linux/smp.h>
+
+#include <asm/system.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/fixmap.h>
+#include <asm/tlb.h>
+#include <asm/tlbflush.h>
+#include <asm/homecache.h>
+
+#define K(x) ((x) << (PAGE_SHIFT-10))
+
+/*
+ * The normal show_free_areas() is too verbose on Tile, with dozens
+ * of processors and often four NUMA zones each with high and lowmem.
+ */
+void show_mem(void)
+{
+ struct zone *zone;
+
+ pr_err("Active:%lu inactive:%lu dirty:%lu writeback:%lu unstable:%lu"
+ " free:%lu\n slab:%lu mapped:%lu pagetables:%lu bounce:%lu"
+ " pagecache:%lu swap:%lu\n",
+ (global_page_state(NR_ACTIVE_ANON) +
+ global_page_state(NR_ACTIVE_FILE)),
+ (global_page_state(NR_INACTIVE_ANON) +
+ global_page_state(NR_INACTIVE_FILE)),
+ global_page_state(NR_FILE_DIRTY),
+ global_page_state(NR_WRITEBACK),
+ global_page_state(NR_UNSTABLE_NFS),
+ global_page_state(NR_FREE_PAGES),
+ (global_page_state(NR_SLAB_RECLAIMABLE) +
+ global_page_state(NR_SLAB_UNRECLAIMABLE)),
+ global_page_state(NR_FILE_MAPPED),
+ global_page_state(NR_PAGETABLE),
+ global_page_state(NR_BOUNCE),
+ global_page_state(NR_FILE_PAGES),
+ nr_swap_pages);
+
+ for_each_zone(zone) {
+ unsigned long flags, order, total = 0, largest_order = -1;
+
+ if (!populated_zone(zone))
+ continue;
+
+ spin_lock_irqsave(&zone->lock, flags);
+ for (order = 0; order < MAX_ORDER; order++) {
+ int nr = zone->free_area[order].nr_free;
+ total += nr << order;
+ if (nr)
+ largest_order = order;
+ }
+ spin_unlock_irqrestore(&zone->lock, flags);
+ pr_err("Node %d %7s: %lukB (largest %luKb)\n",
+ zone_to_nid(zone), zone->name,
+ K(total), largest_order ? K(1UL) << largest_order : 0);
+ }
+}
+
+/*
+ * Associate a virtual page frame with a given physical page frame
+ * and protection flags for that frame.
+ */
+static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ pgd = swapper_pg_dir + pgd_index(vaddr);
+ if (pgd_none(*pgd)) {
+ BUG();
+ return;
+ }
+ pud = pud_offset(pgd, vaddr);
+ if (pud_none(*pud)) {
+ BUG();
+ return;
+ }
+ pmd = pmd_offset(pud, vaddr);
+ if (pmd_none(*pmd)) {
+ BUG();
+ return;
+ }
+ pte = pte_offset_kernel(pmd, vaddr);
+ /* <pfn,flags> stored as-is, to permit clearing entries */
+ set_pte(pte, pfn_pte(pfn, flags));
+
+ /*
+ * It's enough to flush this one mapping.
+ * This appears conservative since it is only called
+ * from __set_fixmap.
+ */
+ local_flush_tlb_page(NULL, vaddr, PAGE_SIZE);
+}
+
+void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+{
+ unsigned long address = __fix_to_virt(idx);
+
+ if (idx >= __end_of_fixed_addresses) {
+ BUG();
+ return;
+ }
+ set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
+}
+
+#if defined(CONFIG_HIGHPTE)
+pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type)
+{
+ pte_t *pte = kmap_atomic(pmd_page(*dir), type) +
+ (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK;
+ return &pte[pte_index(address)];
+}
+#endif
+
+/*
+ * List of all pgd's needed so it can invalidate entries in both cached
+ * and uncached pgd's. This is essentially codepath-based locking
+ * against pageattr.c; it is the unique case in which a valid change
+ * of kernel pagetables can't be lazily synchronized by vmalloc faults.
+ * vmalloc faults work because attached pagetables are never freed.
+ * The locking scheme was chosen on the basis of manfred's
+ * recommendations and having no core impact whatsoever.
+ * -- wli
+ */
+DEFINE_SPINLOCK(pgd_lock);
+LIST_HEAD(pgd_list);
+
+static inline void pgd_list_add(pgd_t *pgd)
+{
+ list_add(pgd_to_list(pgd), &pgd_list);
+}
+
+static inline void pgd_list_del(pgd_t *pgd)
+{
+ list_del(pgd_to_list(pgd));
+}
+
+#define KERNEL_PGD_INDEX_START pgd_index(PAGE_OFFSET)
+#define KERNEL_PGD_PTRS (PTRS_PER_PGD - KERNEL_PGD_INDEX_START)
+
+static void pgd_ctor(pgd_t *pgd)
+{
+ unsigned long flags;
+
+ memset(pgd, 0, KERNEL_PGD_INDEX_START*sizeof(pgd_t));
+ spin_lock_irqsave(&pgd_lock, flags);
+
+#ifndef __tilegx__
+ /*
+ * Check that the user interrupt vector has no L2.
+ * It never should for the swapper, and new page tables
+ * should always start with an empty user interrupt vector.
+ */
+ BUG_ON(((u64 *)swapper_pg_dir)[pgd_index(MEM_USER_INTRPT)] != 0);
+#endif
+
+ clone_pgd_range(pgd + KERNEL_PGD_INDEX_START,
+ swapper_pg_dir + KERNEL_PGD_INDEX_START,
+ KERNEL_PGD_PTRS);
+
+ pgd_list_add(pgd);
+ spin_unlock_irqrestore(&pgd_lock, flags);
+}
+
+static void pgd_dtor(pgd_t *pgd)
+{
+ unsigned long flags; /* can be called from interrupt context */
+
+ spin_lock_irqsave(&pgd_lock, flags);
+ pgd_list_del(pgd);
+ spin_unlock_irqrestore(&pgd_lock, flags);
+}
+
+pgd_t *pgd_alloc(struct mm_struct *mm)
+{
+ pgd_t *pgd = kmem_cache_alloc(pgd_cache, GFP_KERNEL);
+ if (pgd)
+ pgd_ctor(pgd);
+ return pgd;
+}
+
+void pgd_free(struct mm_struct *mm, pgd_t *pgd)
+{
+ pgd_dtor(pgd);
+ kmem_cache_free(pgd_cache, pgd);
+}
+
+
+#define L2_USER_PGTABLE_PAGES (1 << L2_USER_PGTABLE_ORDER)
+
+struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
+{
+ gfp_t flags = GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO|__GFP_COMP;
+ struct page *p;
+
+#ifdef CONFIG_HIGHPTE
+ flags |= __GFP_HIGHMEM;
+#endif
+
+ p = alloc_pages(flags, L2_USER_PGTABLE_ORDER);
+ if (p == NULL)
+ return NULL;
+
+ pgtable_page_ctor(p);
+ return p;
+}
+
+/*
+ * Free page immediately (used in __pte_alloc if we raced with another
+ * process). We have to correct whatever pte_alloc_one() did before
+ * returning the pages to the allocator.
+ */
+void pte_free(struct mm_struct *mm, struct page *p)
+{
+ pgtable_page_dtor(p);
+ __free_pages(p, L2_USER_PGTABLE_ORDER);
+}
+
+void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address)
+{
+ int i;
+
+ pgtable_page_dtor(pte);
+ tlb->need_flush = 1;
+ if (tlb_fast_mode(tlb)) {
+ struct page *pte_pages[L2_USER_PGTABLE_PAGES];
+ for (i = 0; i < L2_USER_PGTABLE_PAGES; ++i)
+ pte_pages[i] = pte + i;
+ free_pages_and_swap_cache(pte_pages, L2_USER_PGTABLE_PAGES);
+ return;
+ }
+ for (i = 0; i < L2_USER_PGTABLE_PAGES; ++i) {
+ tlb->pages[tlb->nr++] = pte + i;
+ if (tlb->nr >= FREE_PTE_NR)
+ tlb_flush_mmu(tlb, 0, 0);
+ }
+}
+
+#ifndef __tilegx__
+
+/*
+ * FIXME: needs to be atomic vs hypervisor writes. For now we make the
+ * window of vulnerability a bit smaller by doing an unlocked 8-bit update.
+ */
+int ptep_test_and_clear_young(struct vm_area_struct *vma,
+ unsigned long addr, pte_t *ptep)
+{
+#if HV_PTE_INDEX_ACCESSED < 8 || HV_PTE_INDEX_ACCESSED >= 16
+# error Code assumes HV_PTE "accessed" bit in second byte
+#endif
+ u8 *tmp = (u8 *)ptep;
+ u8 second_byte = tmp[1];
+ if (!(second_byte & (1 << (HV_PTE_INDEX_ACCESSED - 8))))
+ return 0;
+ tmp[1] = second_byte & ~(1 << (HV_PTE_INDEX_ACCESSED - 8));
+ return 1;
+}
+
+/*
+ * This implementation is atomic vs hypervisor writes, since the hypervisor
+ * always writes the low word (where "accessed" and "dirty" are) and this
+ * routine only writes the high word.
+ */
+void ptep_set_wrprotect(struct mm_struct *mm,
+ unsigned long addr, pte_t *ptep)
+{
+#if HV_PTE_INDEX_WRITABLE < 32
+# error Code assumes HV_PTE "writable" bit in high word
+#endif
+ u32 *tmp = (u32 *)ptep;
+ tmp[1] = tmp[1] & ~(1 << (HV_PTE_INDEX_WRITABLE - 32));
+}
+
+#endif
+
+pte_t *virt_to_pte(struct mm_struct* mm, unsigned long addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+
+ if (pgd_addr_invalid(addr))
+ return NULL;
+
+ pgd = mm ? pgd_offset(mm, addr) : swapper_pg_dir + pgd_index(addr);
+ pud = pud_offset(pgd, addr);
+ if (!pud_present(*pud))
+ return NULL;
+ pmd = pmd_offset(pud, addr);
+ if (pmd_huge_page(*pmd))
+ return (pte_t *)pmd;
+ if (!pmd_present(*pmd))
+ return NULL;
+ return pte_offset_kernel(pmd, addr);
+}
+
+pgprot_t set_remote_cache_cpu(pgprot_t prot, int cpu)
+{
+ unsigned int width = smp_width;
+ int x = cpu % width;
+ int y = cpu / width;
+ BUG_ON(y >= smp_height);
+ BUG_ON(hv_pte_get_mode(prot) != HV_PTE_MODE_CACHE_TILE_L3);
+ BUG_ON(cpu < 0 || cpu >= NR_CPUS);
+ BUG_ON(!cpu_is_valid_lotar(cpu));
+ return hv_pte_set_lotar(prot, HV_XY_TO_LOTAR(x, y));
+}
+
+int get_remote_cache_cpu(pgprot_t prot)
+{
+ HV_LOTAR lotar = hv_pte_get_lotar(prot);
+ int x = HV_LOTAR_X(lotar);
+ int y = HV_LOTAR_Y(lotar);
+ BUG_ON(hv_pte_get_mode(prot) != HV_PTE_MODE_CACHE_TILE_L3);
+ return x + y * smp_width;
+}
+
+void set_pte_order(pte_t *ptep, pte_t pte, int order)
+{
+ unsigned long pfn = pte_pfn(pte);
+ struct page *page = pfn_to_page(pfn);
+
+ /* Update the home of a PTE if necessary */
+ pte = pte_set_home(pte, page_home(page));
+
+#ifdef __tilegx__
+ *ptep = pte;
+#else
+ /*
+ * When setting a PTE, write the high bits first, then write
+ * the low bits. This sets the "present" bit only after the
+ * other bits are in place. If a particular PTE update
+ * involves transitioning from one valid PTE to another, it
+ * may be necessary to call set_pte_order() more than once,
+ * transitioning via a suitable intermediate state.
+ * Note that this sequence also means that if we are transitioning
+ * from any migrating PTE to a non-migrating one, we will not
+ * see a half-updated PTE with the migrating bit off.
+ */
+#if HV_PTE_INDEX_PRESENT >= 32 || HV_PTE_INDEX_MIGRATING >= 32
+# error Must write the present and migrating bits last
+#endif
+ ((u32 *)ptep)[1] = (u32)(pte_val(pte) >> 32);
+ barrier();
+ ((u32 *)ptep)[0] = (u32)(pte_val(pte));
+#endif
+}
+
+/* Can this mm load a PTE with cached_priority set? */
+static inline int mm_is_priority_cached(struct mm_struct *mm)
+{
+ return mm->context.priority_cached;
+}
+
+/*
+ * Add a priority mapping to an mm_context and
+ * notify the hypervisor if this is the first one.
+ */
+void start_mm_caching(struct mm_struct *mm)
+{
+ if (!mm_is_priority_cached(mm)) {
+ mm->context.priority_cached = -1U;
+ hv_set_caching(-1U);
+ }
+}
+
+/*
+ * Validate and return the priority_cached flag. We know if it's zero
+ * that we don't need to scan, since we immediately set it non-zero
+ * when we first consider a MAP_CACHE_PRIORITY mapping.
+ *
+ * We only _try_ to acquire the mmap_sem semaphore; if we can't acquire it,
+ * since we're in an interrupt context (servicing switch_mm) we don't
+ * worry about it and don't unset the "priority_cached" field.
+ * Presumably we'll come back later and have more luck and clear
+ * the value then; for now we'll just keep the cache marked for priority.
+ */
+static unsigned int update_priority_cached(struct mm_struct *mm)
+{
+ if (mm->context.priority_cached && down_write_trylock(&mm->mmap_sem)) {
+ struct vm_area_struct *vm;
+ for (vm = mm->mmap; vm; vm = vm->vm_next) {
+ if (hv_pte_get_cached_priority(vm->vm_page_prot))
+ break;
+ }
+ if (vm == NULL)
+ mm->context.priority_cached = 0;
+ up_write(&mm->mmap_sem);
+ }
+ return mm->context.priority_cached;
+}
+
+/* Set caching correctly for an mm that we are switching to. */
+void check_mm_caching(struct mm_struct *prev, struct mm_struct *next)
+{
+ if (!mm_is_priority_cached(next)) {
+ /*
+ * If the new mm doesn't use priority caching, just see if we
+ * need the hv_set_caching(), or can assume it's already zero.
+ */
+ if (mm_is_priority_cached(prev))
+ hv_set_caching(0);
+ } else {
+ hv_set_caching(update_priority_cached(next));
+ }
+}
+
+#if CHIP_HAS_MMIO()
+
+/* Map an arbitrary MMIO address, homed according to pgprot, into VA space. */
+void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
+ pgprot_t home)
+{
+ void *addr;
+ struct vm_struct *area;
+ unsigned long offset, last_addr;
+ pgprot_t pgprot;
+
+ /* Don't allow wraparound or zero size */
+ last_addr = phys_addr + size - 1;
+ if (!size || last_addr < phys_addr)
+ return NULL;
+
+ /* Create a read/write, MMIO VA mapping homed at the requested shim. */
+ pgprot = PAGE_KERNEL;
+ pgprot = hv_pte_set_mode(pgprot, HV_PTE_MODE_MMIO);
+ pgprot = hv_pte_set_lotar(pgprot, hv_pte_get_lotar(home));
+
+ /*
+ * Mappings have to be page-aligned
+ */
+ offset = phys_addr & ~PAGE_MASK;
+ phys_addr &= PAGE_MASK;
+ size = PAGE_ALIGN(last_addr+1) - phys_addr;
+
+ /*
+ * Ok, go for it..
+ */
+ area = get_vm_area(size, VM_IOREMAP /* | other flags? */);
+ if (!area)
+ return NULL;
+ area->phys_addr = phys_addr;
+ addr = area->addr;
+ if (ioremap_page_range((unsigned long)addr, (unsigned long)addr + size,
+ phys_addr, pgprot)) {
+ remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr));
+ return NULL;
+ }
+ return (__force void __iomem *) (offset + (char *)addr);
+}
+EXPORT_SYMBOL(ioremap_prot);
+
+/* Map a PCI MMIO bus address into VA space. */
+void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
+{
+ panic("ioremap for PCI MMIO is not supported");
+}
+EXPORT_SYMBOL(ioremap);
+
+/* Unmap an MMIO VA mapping. */
+void iounmap(volatile void __iomem *addr_in)
+{
+ volatile void __iomem *addr = (volatile void __iomem *)
+ (PAGE_MASK & (unsigned long __force)addr_in);
+#if 1
+ vunmap((void * __force)addr);
+#else
+ /* x86 uses this complicated flow instead of vunmap(). Is
+ * there any particular reason we should do the same? */
+ struct vm_struct *p, *o;
+
+ /* Use the vm area unlocked, assuming the caller
+ ensures there isn't another iounmap for the same address
+ in parallel. Reuse of the virtual address is prevented by
+ leaving it in the global lists until we're done with it.
+ cpa takes care of the direct mappings. */
+ read_lock(&vmlist_lock);
+ for (p = vmlist; p; p = p->next) {
+ if (p->addr == addr)
+ break;
+ }
+ read_unlock(&vmlist_lock);
+
+ if (!p) {
+ pr_err("iounmap: bad address %p\n", addr);
+ dump_stack();
+ return;
+ }
+
+ /* Finally remove it */
+ o = remove_vm_area((void *)addr);
+ BUG_ON(p != o || o == NULL);
+ kfree(p);
+#endif
+}
+EXPORT_SYMBOL(iounmap);
+
+#endif /* CHIP_HAS_MMIO() */
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
index cd40fddcf99d..c4617baaa4f2 100644
--- a/arch/um/include/shared/os.h
+++ b/arch/um/include/shared/os.h
@@ -161,6 +161,9 @@ extern int os_stat_filesystem(char *path, long *bsize_out,
long *spare_out);
extern int os_change_dir(char *dir);
extern int os_fchange_dir(int fd);
+extern unsigned os_major(unsigned long long dev);
+extern unsigned os_minor(unsigned long long dev);
+extern unsigned long long os_makedev(unsigned major, unsigned minor);
/* start_up.c */
extern void os_early_checks(void);
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 836fc9b94707..0ae0dfcfbffb 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -58,6 +58,9 @@ EXPORT_SYMBOL(os_accept_connection);
EXPORT_SYMBOL(os_rcv_fd);
EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(start_thread);
+EXPORT_SYMBOL(os_major);
+EXPORT_SYMBOL(os_minor);
+EXPORT_SYMBOL(os_makedev);
EXPORT_SYMBOL(add_sigio_fd);
EXPORT_SYMBOL(ignore_sigio_fd);
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index b5afcfd0f861..140e587bc0ad 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -561,3 +561,18 @@ int os_lock_file(int fd, int excl)
out:
return err;
}
+
+unsigned os_major(unsigned long long dev)
+{
+ return major(dev);
+}
+
+unsigned os_minor(unsigned long long dev)
+{
+ return minor(dev);
+}
+
+unsigned long long os_makedev(unsigned major, unsigned minor)
+{
+ return makedev(major, minor);
+}
diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 89b48a116a89..05f5ea8e83d2 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -103,6 +103,10 @@ EXPORT_SYMBOL_PROTO(getuid);
EXPORT_SYMBOL_PROTO(fsync);
EXPORT_SYMBOL_PROTO(fdatasync);
+EXPORT_SYMBOL_PROTO(lstat64);
+EXPORT_SYMBOL_PROTO(fstat64);
+EXPORT_SYMBOL_PROTO(mknod);
+
/* Export symbols used by GCC for the stack protector. */
extern void __stack_smash_handler(void *) __attribute__((weak));
EXPORT_SYMBOL(__stack_smash_handler);
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h
index cd2a31dc5fb8..49c7219826f9 100644
--- a/arch/x86/include/asm/pci_x86.h
+++ b/arch/x86/include/asm/pci_x86.h
@@ -30,6 +30,7 @@
#define PCI_HAS_IO_ECS 0x40000
#define PCI_NOASSIGN_ROMS 0x80000
#define PCI_ROOT_NO_CRS 0x100000
+#define PCI_NOASSIGN_BARS 0x200000
extern unsigned int pci_probe;
extern unsigned long pirq_table_addr;
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 215a27ae050d..a0772af64efb 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -125,6 +125,23 @@ void __init dmi_check_skip_isa_align(void)
static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev)
{
struct resource *rom_r = &dev->resource[PCI_ROM_RESOURCE];
+ struct resource *bar_r;
+ int bar;
+
+ if (pci_probe & PCI_NOASSIGN_BARS) {
+ /*
+ * If the BIOS did not assign the BAR, zero out the
+ * resource so the kernel doesn't attmept to assign
+ * it later on in pci_assign_unassigned_resources
+ */
+ for (bar = 0; bar <= PCI_STD_RESOURCE_END; bar++) {
+ bar_r = &dev->resource[bar];
+ if (bar_r->start == 0 && bar_r->end != 0) {
+ bar_r->flags = 0;
+ bar_r->end = 0;
+ }
+ }
+ }
if (pci_probe & PCI_NOASSIGN_ROMS) {
if (rom_r->parent)
@@ -509,6 +526,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "norom")) {
pci_probe |= PCI_NOASSIGN_ROMS;
return NULL;
+ } else if (!strcmp(str, "nobar")) {
+ pci_probe |= PCI_NOASSIGN_BARS;
+ return NULL;
} else if (!strcmp(str, "assign-busses")) {
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
return NULL;
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 8d460eaf524f..c89266be6048 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -36,7 +36,7 @@ int __init pci_legacy_init(void)
return 0;
}
-void pcibios_scan_specific_bus(int busn)
+void __devinit pcibios_scan_specific_bus(int busn)
{
int devfn;
long node;
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index ebe228d02b08..52e5dbbb1941 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -84,10 +84,10 @@ config XTENSA_VARIANT_S6000
endchoice
config XTENSA_UNALIGNED_USER
- bool "Unaligned memory access in use space"
+ bool "Unaligned memory access in user space"
help
- The Xtensa architecture currently does not handle unaligned
- memory accesses in hardware but through an exception handler.
+ Xtensa processors are often not configured to handle unaligned
+ memory accesses in hardware, but rather through an exception handler.
Per default, unaligned memory accesses are disabled in user space.
Say Y here to enable unaligned memory access in user space.
@@ -157,8 +157,15 @@ config XTENSA_PLATFORM_ISS
config XTENSA_PLATFORM_XT2000
bool "XT2000"
help
- XT2000 is the name of Tensilica's feature-rich emulation platform.
- This hardware is capable of running a full Linux distribution.
+ XT2000 is the name of Tensilica's older emulation platform.
+
+config XTENSA_PLATFORM_XTAVNET
+ bool "XTAVNET"
+ select XTENSA_CALIBRATE_CCOUNT
+ select ETHOC
+ help
+ Selects support for the Tensilica-configured Avnet emulation boards.
+ These include the LX60 (XT-AV60), LX200 (XT-AV200), and LX110 (XT-AV110).
config XTENSA_PLATFORM_S6105
bool "S6105"
diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile
index 4caffac3ca2e..34d8427622eb 100644
--- a/arch/xtensa/Makefile
+++ b/arch/xtensa/Makefile
@@ -24,6 +24,7 @@ export VARIANT
# Platform configuration
platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000
+platform-$(CONFIG_XTENSA_PLATFORM_XTAVNET) := xtavnet
platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss
platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105
@@ -35,6 +36,8 @@ KBUILD_CFLAGS += -ffreestanding
KBUILD_CFLAGS += -pipe -mlongcalls
+KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,)
+
vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y))
plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y))
@@ -59,7 +62,9 @@ ifneq ($(VARIANT),)
ifneq ($(COMPILE_ARCH), xtensa)
ifndef CROSS_COMPILE
- CROSS_COMPILE = xtensa_$(VARIANT)-
+ CROSS_COMPILE := $(call cc-cross-prefix, xtensa_$(VARIANT)- \
+ xtensa-linux-uclibc- xtensa_$(VARIANT)-linux-uclibc- \
+ xtensa-linux-gnu- xtensa_$(VARIANT)-linux-gnu-)
endif
endif
endif
diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile
index 40aa55b485be..8657c62fc78b 100644
--- a/arch/xtensa/boot/Makefile
+++ b/arch/xtensa/boot/Makefile
@@ -23,6 +23,7 @@ subdir-y := lib
bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf
bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf
+bootdir-$(CONFIG_XTENSA_PLATFORM_XTAVNET) += boot-redboot boot-elf
zImage zImage.initrd Image Image.initrd: $(bootdir-y)
diff --git a/arch/xtensa/configs/iss_defconfig b/arch/xtensa/configs/iss_defconfig
index f19854035e61..61bac9d62255 100644
--- a/arch/xtensa/configs/iss_defconfig
+++ b/arch/xtensa/configs/iss_defconfig
@@ -77,6 +77,7 @@ CONFIG_XTENSA_ISS_NETWORK=y
#
# Bus options
#
+CONFIG_PCI=n
#
# PCCARD (PCMCIA/CardBus) support
diff --git a/arch/xtensa/include/asm/cacheflush.h b/arch/xtensa/include/asm/cacheflush.h
index a508f2f73bd7..376cd9d5f455 100644
--- a/arch/xtensa/include/asm/cacheflush.h
+++ b/arch/xtensa/include/asm/cacheflush.h
@@ -115,6 +115,7 @@ extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned lon
#define flush_cache_vmap(start,end) do { } while (0)
#define flush_cache_vunmap(start,end) do { } while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
#define flush_dcache_page(page) do { } while (0)
#define flush_cache_page(vma,addr,pfn) do { } while (0)
diff --git a/arch/xtensa/include/asm/coprocessor.h b/arch/xtensa/include/asm/coprocessor.h
index 65a285d8d3fb..04bc285df1a7 100644
--- a/arch/xtensa/include/asm/coprocessor.h
+++ b/arch/xtensa/include/asm/coprocessor.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/coprocessor.h
+ * arch/xtensa/include/asm/coprocessor.h
*
* 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 - 2007 Tensilica Inc.
+ * Copyright (C) 2003-2010 Tensilica Inc.
*/
@@ -14,9 +14,10 @@
#include <linux/stringify.h>
#include <variant/tie.h>
+#include <variant/core.h>
#include <asm/types.h>
-#ifdef __ASSEMBLY__
+#if defined(__ASSEMBLY__) && !defined(LINKER_SCRIPT)
# include <variant/tie-asm.h>
.macro xchal_sa_start a b
@@ -69,7 +70,7 @@
-#endif /* __ASSEMBLY__ */
+#endif /* __ASSEMBLY__ && !LINKER_SCRIPT */
/*
* XTENSA_HAVE_COPROCESSOR(x) returns 1 if coprocessor x is configured.
diff --git a/arch/xtensa/include/asm/elf.h b/arch/xtensa/include/asm/elf.h
index 5eb6d695e987..6e65eadaae14 100644
--- a/arch/xtensa/include/asm/elf.h
+++ b/arch/xtensa/include/asm/elf.h
@@ -14,6 +14,7 @@
#define _XTENSA_ELF_H
#include <asm/ptrace.h>
+#include <asm/coprocessor.h>
/* Xtensa processor ELF architecture-magic number */
diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h
index d04cd3a625fa..145db5cc6191 100644
--- a/arch/xtensa/include/asm/io.h
+++ b/arch/xtensa/include/asm/io.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/io.h
+ * arch/xtensa/include/asm/io.h
*
* 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) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_IO_H
@@ -63,40 +63,33 @@ static inline void * phys_to_virt(unsigned long address)
#define bus_to_virt(x) phys_to_virt(x)
/*
- * Return the virtual (cached) address for the specified bus memory.
+ * Return the virtual (uncached) address for the specified bus memory
+ * (which is, for now, simply a physical address).
* Note that we currently don't support any address outside the KIO segment.
+ * See also arch/mips/include/asm/io.h for nice comments.
*/
-static inline void *ioremap(unsigned long offset, unsigned long size)
+static inline void __iomem *__ioremap(unsigned long offset, unsigned long size)
{
#ifdef CONFIG_MMU
if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
- return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_BYPASS_VADDR);
+ && offset <= XCHAL_KIO_PADDR + XCHAL_KIO_SIZE - 1)
+ return (void __iomem *)(offset - XCHAL_KIO_PADDR + XCHAL_KIO_BYPASS_VADDR);
else
BUG();
#else
- return (void *)offset;
+ return (void __iomem *)offset;
#endif
}
-static inline void *ioremap_nocache(unsigned long offset, unsigned long size)
-{
-#ifdef CONFIG_MMU
- if (offset >= XCHAL_KIO_PADDR
- && offset < XCHAL_KIO_PADDR + XCHAL_KIO_SIZE)
- return (void*)(offset-XCHAL_KIO_PADDR+XCHAL_KIO_CACHED_VADDR);
- else
- BUG();
-#else
- return (void *)offset;
-#endif
-}
+#define ioremap(offset, size) __ioremap(offset, size)
+#define ioremap_nocache(offset, size) __ioremap(offset, size)
-static inline void iounmap(void *addr)
+static inline void iounmap(void __iomem *addr)
{
}
+
/*
* Generic I/O
*/
@@ -191,6 +184,13 @@ extern void outsl (unsigned long port, const void *src, unsigned long count);
#endif
+#ifndef CONFIG_GENERIC_IOMAP
+/* Partial Simple MMIO */
+#define ioread32(a) __raw_readl(a)
+#define iowrite32(v,a) __raw_writel((v),(a))
+#endif
+
+
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem access
*/
diff --git a/arch/xtensa/include/asm/irq.h b/arch/xtensa/include/asm/irq.h
index 4c0ccc9c4f4c..6af436f4429d 100644
--- a/arch/xtensa/include/asm/irq.h
+++ b/arch/xtensa/include/asm/irq.h
@@ -1,11 +1,11 @@
/*
- * include/asm-xtensa/irq.h
+ * arch/xtensa/include/asm/irq.h
*
* 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) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_IRQ_H
@@ -22,6 +22,9 @@ static inline void variant_irq_enable(unsigned int irq) { }
static inline void variant_irq_disable(unsigned int irq) { }
#endif
+/* This number is used when no interrupt has been assigned. */
+#define NO_IRQ (-1)
+
#ifndef VARIANT_NR_IRQS
# define VARIANT_NR_IRQS 0
#endif
diff --git a/arch/xtensa/include/asm/pgalloc.h b/arch/xtensa/include/asm/pgalloc.h
index 4f4a7987eded..40cf9bceda2c 100644
--- a/arch/xtensa/include/asm/pgalloc.h
+++ b/arch/xtensa/include/asm/pgalloc.h
@@ -14,6 +14,7 @@
#ifdef __KERNEL__
#include <linux/highmem.h>
+#include <linux/slab.h>
/*
* Allocating and freeing a pmd is trivial: the 1-entry pmd is
diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h
index 0ea4937c0b61..3acb26e8dead 100644
--- a/arch/xtensa/include/asm/processor.h
+++ b/arch/xtensa/include/asm/processor.h
@@ -12,7 +12,6 @@
#define _XTENSA_PROCESSOR_H
#include <variant/core.h>
-#include <asm/coprocessor.h>
#include <platform/hardware.h>
#include <linux/compiler.h>
diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h
index 3c549f798727..0d42c934b66f 100644
--- a/arch/xtensa/include/asm/ptrace.h
+++ b/arch/xtensa/include/asm/ptrace.h
@@ -77,6 +77,8 @@
#ifndef __ASSEMBLY__
+#include <asm/coprocessor.h>
+
/*
* This struct defines the way the registers are stored on the
* kernel stack during a system call or other kernel entry.
diff --git a/arch/xtensa/include/asm/serial.h b/arch/xtensa/include/asm/serial.h
index a8a2493260f6..c55a0e2b47ca 100644
--- a/arch/xtensa/include/asm/serial.h
+++ b/arch/xtensa/include/asm/serial.h
@@ -1,5 +1,5 @@
/*
- * include/asm-xtensa/serial.h
+ * arch/xtensa/include/asm/serial.h
*
* Configuration details for 8250, 16450, 16550, etc. serial ports
*
@@ -7,12 +7,20 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2001 - 2005 Tensilica Inc.
+ * Copyright (C) 2001-2010 Tensilica Inc.
*/
#ifndef _XTENSA_SERIAL_H
#define _XTENSA_SERIAL_H
+#include <asm/irq.h>
#include <platform/serial.h>
+/* The 8250 driver treats IRQ 0 as absent. For the Xtensa architecture,
+ interrupt 0 is valid, must compare against NO_IRQ instead. */
+#ifdef is_real_interrupt
+#undef is_real_interrupt
+#define is_real_interrupt(irq) ((irq) != NO_IRQ)
+#endif
+
#endif /* _XTENSA_SERIAL_H */
diff --git a/arch/xtensa/kernel/Makefile b/arch/xtensa/kernel/Makefile
index 6f56d95f2c1e..e426a4ec7f22 100644
--- a/arch/xtensa/kernel/Makefile
+++ b/arch/xtensa/kernel/Makefile
@@ -23,12 +23,12 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o
#
# Replicate rules in scripts/Makefile.build
-sed-y = -e 's/(\(\.[a-z]*it\|\.ref\|\)\.text)/(\1.literal \1.text)/g' \
- -e 's/(\(\.text\.[a-z]*\))/(\1.literal \1)/g'
+sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \
+ -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g'
quiet_cmd__cpp_lds_S = LDS $@
- cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \
- | sed $(sed-y) >$@
+ cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ \
+ -DLINKER_SCRIPT $< | sed $(sed-y) >$@
$(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE
$(call if_changed_dep,_cpp_lds_S)
diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c
index 070ff8af3a21..7dc3f9157185 100644
--- a/arch/xtensa/kernel/asm-offsets.c
+++ b/arch/xtensa/kernel/asm-offsets.c
@@ -13,6 +13,7 @@
*/
#include <asm/processor.h>
+#include <asm/coprocessor.h>
#include <linux/types.h>
#include <linux/stddef.h>
diff --git a/arch/xtensa/kernel/entry.S b/arch/xtensa/kernel/entry.S
index 77fc9f6dc016..5fd01f6aaf37 100644
--- a/arch/xtensa/kernel/entry.S
+++ b/arch/xtensa/kernel/entry.S
@@ -16,6 +16,7 @@
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/processor.h>
+#include <asm/coprocessor.h>
#include <asm/thread_info.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
diff --git a/arch/xtensa/kernel/head.S b/arch/xtensa/kernel/head.S
index d215adcfd4ea..3ef91a73652d 100644
--- a/arch/xtensa/kernel/head.S
+++ b/arch/xtensa/kernel/head.S
@@ -184,8 +184,8 @@ _startup:
* Now clear the BSS segment.
*/
- movi a2, _bss_start # start of BSS
- movi a3, _bss_end # end of BSS
+ movi a2, __bss_start # start of BSS
+ movi a3, __bss_stop # end of BSS
__loopt a2, a3, a4, 2
s32i a0, a2, 0
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c
index 19df764f6399..88ba96e2df25 100644
--- a/arch/xtensa/kernel/time.c
+++ b/arch/xtensa/kernel/time.c
@@ -31,7 +31,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */
unsigned long nsec_per_ccount; /* nsec per ccount increment */
#endif
-static cycle_t ccount_read(void)
+static cycle_t ccount_read(struct clocksource *cs)
{
return (cycle_t)get_ccount();
}
diff --git a/arch/xtensa/platforms/iss/network.c b/arch/xtensa/platforms/iss/network.c
index 87e218f98ef4..f717e20d961b 100644
--- a/arch/xtensa/platforms/iss/network.c
+++ b/arch/xtensa/platforms/iss/network.c
@@ -623,6 +623,19 @@ static struct platform_driver iss_net_driver = {
static int driver_registered;
+static const struct net_device_ops iss_netdev_ops = {
+ .ndo_open = iss_net_open,
+ .ndo_stop = iss_net_close,
+ .ndo_get_stats = iss_net_get_stats,
+ .ndo_start_xmit = iss_net_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_change_mtu = iss_net_change_mtu,
+ .ndo_set_mac_address = iss_net_set_mac,
+ //.ndo_do_ioctl = iss_net_ioctl,
+ .ndo_tx_timeout = iss_net_tx_timeout,
+ .ndo_set_multicast_list = iss_net_set_multicast_list,
+};
+
static int iss_net_configure(int index, char *init)
{
struct net_device *dev;
@@ -686,15 +699,8 @@ static int iss_net_configure(int index, char *init)
*/
snprintf(dev->name, sizeof dev->name, "eth%d", index);
+ dev->netdev_ops = &iss_netdev_ops;
dev->mtu = lp->mtu;
- dev->open = iss_net_open;
- dev->hard_start_xmit = iss_net_start_xmit;
- dev->stop = iss_net_close;
- dev->get_stats = iss_net_get_stats;
- dev->set_multicast_list = iss_net_set_multicast_list;
- dev->tx_timeout = iss_net_tx_timeout;
- dev->set_mac_address = iss_net_set_mac;
- dev->change_mtu = iss_net_change_mtu;
dev->watchdog_timeo = (HZ >> 1);
dev->irq = -1;
diff --git a/arch/xtensa/platforms/xtavnet/Makefile b/arch/xtensa/platforms/xtavnet/Makefile
new file mode 100644
index 000000000000..06b120b40015
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/Makefile
@@ -0,0 +1,10 @@
+# Makefile for the Tensilica Avnet-based Emulation Boards
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are in the main makefile...
+
+obj-y = setup.o lcd.o
+
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/hardware.h b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h
new file mode 100644
index 000000000000..5301be745113
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/hardware.h
@@ -0,0 +1,85 @@
+/*
+ * arch/xtensa/platforms/xtavnet/include/platform/hardware.h
+ *
+ * This file contains the hardware configuration of Tensilica Avnet boards
+ * (XT-AV60, XT-AV110, XT-AV200, derived from Avnet LX60, LX110, LX200
+ * boards respectively).
+ *
+ * Copyright (C) 2006-2010 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __XTAVNET_HARDWARE_H
+#define __XTAVNET_HARDWARE_H
+
+#include <variant/core.h>
+
+/* Memory configuration. */
+
+#define PLATFORM_DEFAULT_MEM_START 0x00000000
+#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000
+
+/* Interrupt configuration. */
+
+#define PLATFORM_NR_IRQS 2
+
+/*
+ * Default assignment of XTAVnet devices to external interrupts.
+ *
+ * CONFIG_ARCH_HAS_SMP means the hardware supports SMP, ie. is Xtensa MX.
+ *
+ * Systems with SMP support (MX) have an External Interrupt Distributor
+ * between external interrupts and the core's interrupts. The first three
+ * core interrupts are used for IPI (interprocessor interrupts), so
+ * external (board device) interrupts end up shifted up by 3.
+ */
+
+/* UART interrupt: */
+#ifdef CONFIG_ARCH_HAS_SMP
+#define UART_INTNUM XCHAL_EXTINT3_NUM
+#else
+#define UART_INTNUM XCHAL_EXTINT0_NUM
+#endif
+
+/* Ethernet interrupt: */
+#ifdef CONFIG_ARCH_HAS_SMP
+#define OETH_IRQ XCHAL_EXTINT4_NUM
+#else
+#define OETH_IRQ XCHAL_EXTINT1_NUM
+#endif
+
+/*
+ * Device addresses and parameters.
+ */
+
+/* UART */
+#define UART_PADDR 0xFD050020
+
+/* LCD instruction and data virt. addresses. */
+#define LCD_INSTR_ADDR (char*)(0xFD040000)
+#define LCD_DATA_ADDR (char*)(0xFD040004)
+
+/* Misc. */
+#define XTAVNET_FPGAREGS_VADDR 0xFD020000
+/* Clock frequency in Hz (read-only): */
+#define XTAVNET_CLKFRQ_VADDR (XTAVNET_FPGAREGS_VADDR + 0x04)
+/* Setting of 8 DIP switches: */
+#define DIP_SWITCHES_VADDR (XTAVNET_FPGAREGS_VADDR + 0x0C)
+/* Software reset (write 0xdead): */
+#define XTAVNET_SWRST_VADDR (XTAVNET_FPGAREGS_VADDR + 0x10)
+
+/* OpenCores Ethernet controller: */
+#define OETH_REGS_PADDR IOADDR(0xD030000) /* regs + RX/TX descriptors */
+#define OETH_REGS_VADDR 0xFD030000
+#define OETH_REGS_SIZE 0x1000
+#define OETH_SRAMBUFF_PADDR 0xFD800000
+#define OETH_SRAMBUFF_SIZE (5*0x600 + 5*0x600) /* 5*rx buffs + 5*tx buffs */
+/*#define OETH_SRAMBUFF_SIZE 0x3C00*/ /* probably 0x4000 ? */
+/* The MAC address for these boards is 00:50:c2:13:6f:xx.
+ The last byte (here as zero) is read from the DIP switches on the board. */
+#define OETH_MACADDR 0x00, 0x50, 0xc2, 0x13, 0x6f, 0
+
+#endif /* __XTAVNET_HARDWARE_H */
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/lcd.h b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h
new file mode 100644
index 000000000000..67de96acb2f9
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/lcd.h
@@ -0,0 +1,22 @@
+/*
+ * arch/xtensa/platforms/xtavnet/include/platform/lcd.h
+ *
+ * Copyright (C) 2001-2006 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#ifndef __XTAVNET_LCD_H
+#define __XTAVNET_LCD_H
+
+/* Display string STR at position POS on the LCD. */
+void lcd_disp_at_pos(char *str, unsigned char pos);
+
+/* Shift the contents of the LCD display left or right. */
+void lcd_shiftleft(void);
+void lcd_shiftright(void);
+
+#endif
+
diff --git a/arch/xtensa/platforms/xtavnet/include/platform/serial.h b/arch/xtensa/platforms/xtavnet/include/platform/serial.h
new file mode 100644
index 000000000000..a0cb0caff152
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/include/platform/serial.h
@@ -0,0 +1 @@
+#include <asm-generic/serial.h>
diff --git a/arch/xtensa/platforms/xtavnet/lcd.c b/arch/xtensa/platforms/xtavnet/lcd.c
new file mode 100644
index 000000000000..283986f158ad
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/lcd.c
@@ -0,0 +1,79 @@
+/*
+ * Driver for the LCD display on the Tensilica LX60 Board.
+ * This code has no effect on the LX200 board. (LX110: TBD)
+ *
+ * Copyright (C) 2001-2006 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ *
+ * FIXME: this code is from the examples from the LX60 user guide.
+ *
+ * The lcd_pause function does busy waiting, which is probably not
+ * great. Maybe the code could be changed to use kernel timers, or
+ * change the hardware to not need to wait.
+ */
+
+#include <linux/init.h>
+
+#include <platform/hardware.h>
+#include <asm/processor.h>
+#include <platform/lcd.h>
+#include <linux/delay.h>
+
+#define LCD_PAUSE_ITERATIONS 4000
+#define LCD_CLEAR 0x1
+#define LCD_DISPLAY_ON 0xc
+
+/* 8bit and 2 lines display */
+#define LCD_DISPLAY_MODE8BIT 0x38
+#define LCD_DISPLAY_POS 0x80
+#define LCD_SHIFT_LEFT 0x18
+#define LCD_SHIFT_RIGHT 0x1c
+
+static int __init lcd_init(void)
+{
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ mdelay(5);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ udelay(200);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT;
+ udelay(50);
+ *LCD_INSTR_ADDR = LCD_DISPLAY_ON;
+ udelay(50);
+ *LCD_INSTR_ADDR = LCD_CLEAR;
+ mdelay(10);
+ lcd_disp_at_pos("XTENSA LINUX", 0);
+
+ return 0;
+}
+
+void lcd_disp_at_pos (char *str, unsigned char pos)
+{
+ *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos;
+ udelay(100);
+ while (*str != 0){
+ *LCD_DATA_ADDR = *str;
+ udelay(200);
+ str++;
+ }
+}
+
+void lcd_shiftleft(void)
+{
+ *LCD_INSTR_ADDR = LCD_SHIFT_LEFT;
+ udelay(50);
+}
+
+void lcd_shiftright(void)
+{
+ *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT;
+ udelay(50);
+}
+
+arch_initcall(lcd_init);
+
diff --git a/arch/xtensa/platforms/xtavnet/setup.c b/arch/xtensa/platforms/xtavnet/setup.c
new file mode 100644
index 000000000000..256fcb2b2af4
--- /dev/null
+++ b/arch/xtensa/platforms/xtavnet/setup.c
@@ -0,0 +1,269 @@
+/*
+ * arch/xtensa/platform-xtavnet/setup.c
+ *
+ * Setup/initialization for Tensilica Avnet boards (XT-AV60, XT-AV110, XT-AV200,
+ * derived from Avnet LX60, LX110, LX200 boards respectively).
+ * For details, see "Tensilica Avnet LX### (XT-AV###) Board User's Guide"
+ * (where ### is 60, 110, or 200).
+ *
+ * Authors: Chris Zankel <chris@zankel.net>
+ * Joe Taylor <joe@tensilica.com>
+ * Pete Delaney <piet@tensilica.com>
+ * Marc Gauthier <marc@tensilica.com> <marc@alumni.uwaterloo.ca>
+ *
+ * Copyright 2001-2010 Tensilica Inc.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License, version 2. See the file "COPYING" in the main directory of this
+ * archive for more details.
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/reboot.h>
+#include <linux/kdev_t.h>
+#include <linux/types.h>
+#include <linux/major.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/stringify.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <asm/timex.h>
+
+#include <linux/etherdevice.h>
+#include <net/ethoc.h>
+
+#include <asm/processor.h>
+#include <asm/platform.h>
+#include <asm/bootparam.h>
+#include <platform/lcd.h>
+#include <platform/hardware.h>
+#include <variant/core.h>
+
+/* For doing extra init. beyond what the ethoc driver does. */
+struct oeth_regs {
+ unsigned moder; /* Mode Register */
+ unsigned int_src; /* Interrupt Source Register */
+ unsigned int_mask; /* Interrupt Mask Register */
+ unsigned ipgt; /* Back to Bak Inter Packet Gap Register */
+ unsigned ipgr1; /* Non Back to Back Inter Packet Gap Register 1 */
+ unsigned ipgr2; /* Non Back to Back Inter Packet Gap Register 2 */
+ unsigned packet_len; /* Packet Length Register (min. and max.) */
+ unsigned collconf; /* Collision and Retry Configuration Register */
+ unsigned tx_bd_num; /* Transmit Buffer Descriptor Number Register */
+ unsigned ctrlmoder; /* Control Module Mode Register */
+ unsigned miimoder; /* MII Mode Register */
+ unsigned miicommand; /* MII Command Register */
+ unsigned miiaddress; /* MII Address Register */
+ unsigned miitx_data; /* MII Transmit Data Register */
+ unsigned miirx_data; /* MII Receive Data Register */
+ unsigned miistatus; /* MII Status Register */
+ unsigned mac_addr0; /* MAC Individual Address Register 0 */
+ unsigned mac_addr1; /* MAC Individual Address Register 1 */
+ unsigned hash_addr0; /* Hash Register 0 */
+ unsigned hash_addr1; /* Hash Register 1 */
+};
+/* MODER Register */
+#define OETH_MODER_RST 0x00000800 /* Reset MAC */
+/* MII Mode Register */
+#define OETH_MIIMODER_CLKDIV 0x000000FF /* Clock Divider */
+
+
+
+void platform_halt(void)
+{
+ /* Just display HALT on LCD display, and loop. */
+ lcd_disp_at_pos(" HALT ", 0);
+ local_irq_disable();
+ while (1);
+}
+
+void platform_power_off(void)
+{
+ /* No software-controlled power-off, just display POWEROFF and loop. */
+ lcd_disp_at_pos ("POWEROFF", 0);
+ local_irq_disable();
+ while (1);
+}
+
+void platform_restart(void)
+{
+ /* Software-initiated board reset. */
+ *(volatile unsigned *)XTAVNET_SWRST_VADDR = 0xdead;
+}
+
+void platform_heartbeat(void)
+{
+ /* Executes every timer tick. */
+}
+
+
+/*
+ * Called from time_init(). "Calibrating" is a misnomer, here we just read
+ * the clock rate from the board specific FPGA registers.
+ */
+void platform_calibrate_ccount(void)
+{
+ long clk_freq = *(long *)XTAVNET_CLKFRQ_VADDR;
+
+ ccount_per_jiffy = clk_freq / HZ;
+ nsec_per_ccount = 1000000000UL / clk_freq;
+}
+
+
+/*----------------------------------------------------------------------------
+ * Ethernet -- OpenCores Ethernet MAC (ethoc driver)
+ */
+
+static struct resource ethoc_res[] = {
+ [0] = { /* register space */
+ .start = OETH_REGS_PADDR,
+ .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = { /* buffer space */
+ .start = OETH_SRAMBUFF_PADDR,
+ .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ number */
+ .start = OETH_IRQ,
+ .end = OETH_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ethoc_platform_data ethoc_pdata = {
+ .hwaddr = { OETH_MACADDR }, /* last byte written in setup below */
+ .phy_id = -1,
+};
+
+static struct platform_device ethoc_device = {
+ .name = "ethoc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ethoc_res),
+ .resource = ethoc_res,
+ .dev = {
+ .platform_data = &ethoc_pdata,
+ },
+};
+
+
+/*----------------------------------------------------------------------------
+ * UART
+ */
+
+static struct resource serial_resource = {
+ .start = UART_PADDR,
+ .end = UART_PADDR + 0x1f,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct plat_serial8250_port serial_platform_data[] = {
+ [0] = {
+ .mapbase = UART_PADDR,
+ .irq = UART_INTNUM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ .uartclk = 0, /* set in xtavnet_init() */
+ },
+ { },
+};
+
+static struct platform_device xtavnet_uart = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = serial_platform_data,
+ },
+ .num_resources = 1,
+ .resource = &serial_resource,
+};
+
+
+/*----------------------------------------------------------------------------
+ */
+
+/* platform devices */
+static struct platform_device *platform_devices[] = {
+ &ethoc_device,
+ &xtavnet_uart,
+};
+
+
+
+/* very early init */
+void __init platform_setup(char **cmdline)
+{
+ if (cmdline) {
+ if (cmdline[0])
+ printk("XTAVnet: platform_setup(cmdline[0]:'%s')\n", cmdline[0]);
+ else
+ printk("XTAVnet: platform_setup(cmdline[0]:<null>)\n");
+ }
+}
+
+/* early initialization, before secondary cpu's have been brought up */
+
+void platform_init(bp_tag_t *bootparams)
+{
+ printk("\n");
+ if( bootparams )
+ printk("XTAVnet: platform_init(bootparams:0x%x)\n", (unsigned)bootparams);
+}
+
+static int xtavnet_init(void)
+{
+ volatile struct oeth_regs *regs = (volatile struct oeth_regs*)OETH_REGS_VADDR;
+
+ /*
+ * Do some of the initialization missing in the ETHOC driver.
+ * (Perhaps not all necessary, but was in a previously used driver.)
+ */
+
+ /* Reset the controller. */
+ regs->moder = OETH_MODER_RST; /* Reset ON */
+ regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
+
+ regs->packet_len = (64 << 16) | 1536;
+ regs->ipgr1 = 0x0000000c;
+ regs->ipgr2 = 0x00000012;
+ regs->collconf = 0x000f003f;
+ regs->ctrlmoder = 0;
+ regs->miimoder = (OETH_MIIMODER_CLKDIV & 0x2);
+
+ /*
+ * Setup dynamic info in platform device init structures.
+ */
+
+ /* Ethernet MAC address. */
+ ethoc_pdata.hwaddr[5] = *(u32*)DIP_SWITCHES_VADDR;
+
+ /* Clock rate varies among FPGA bitstreams; board specific FPGA register
+ * reports the actual clock rate. */
+ serial_platform_data[0].uartclk = *(long *)XTAVNET_CLKFRQ_VADDR;
+
+
+ /* register platform devices */
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user
+ knows whether they set it correctly on the DIP switches. */
+ printk("XTAVnet: Ethernet MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
+ ethoc_pdata.hwaddr[0], ethoc_pdata.hwaddr[1], ethoc_pdata.hwaddr[2],
+ ethoc_pdata.hwaddr[3], ethoc_pdata.hwaddr[4], ethoc_pdata.hwaddr[5]);
+
+ return 0;
+}
+
+
+/*
+ * Register to be done during do_initcalls().
+ */
+arch_initcall(xtavnet_init);
+
+
diff --git a/crypto/ablkcipher.c b/crypto/ablkcipher.c
index 98a66103f4f2..a854df2a5a4b 100644
--- a/crypto/ablkcipher.c
+++ b/crypto/ablkcipher.c
@@ -165,7 +165,7 @@ static inline int ablkcipher_next_slow(struct ablkcipher_request *req,
p = kmalloc(n, GFP_ATOMIC);
if (!p)
- ablkcipher_walk_done(req, walk, -ENOMEM);
+ return ablkcipher_walk_done(req, walk, -ENOMEM);
base = p + 1;
diff --git a/drivers/Makefile b/drivers/Makefile
index 91874e048552..b713e75cee71 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_EISA) += eisa/
obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
+obj-$(CONFIG_DMA_ENGINE) += dma/
obj-$(CONFIG_MMC) += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-$(CONFIG_NEW_LEDS) += leds/
@@ -102,7 +103,6 @@ obj-$(CONFIG_CRYPTO) += crypto/
obj-$(CONFIG_SUPERH) += sh/
obj-$(CONFIG_ARCH_SHMOBILE) += sh/
obj-$(CONFIG_GENERIC_TIME) += clocksource/
-obj-$(CONFIG_DMA_ENGINE) += dma/
obj-$(CONFIG_DCA) += dca/
obj-$(CONFIG_HID) += hid/
obj-$(CONFIG_PPC_PS3) += ps3/
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 4eac59393edc..1f67057af2a5 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -33,6 +33,7 @@
#include <linux/pm_runtime.h>
#include <linux/pci.h>
#include <linux/pci-acpi.h>
+#include <linux/pci-aspm.h>
#include <linux/acpi.h>
#include <linux/slab.h>
#include <acpi/acpi_bus.h>
@@ -543,6 +544,14 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
if (flags != base_flags)
acpi_pci_osc_support(root, flags);
+ status = acpi_pci_osc_control_set(root->device->handle,
+ OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+
+ if (ACPI_FAILURE(status)) {
+ printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
+ pcie_no_aspm();
+ }
+
pci_acpi_add_bus_pm_notifier(device, root->bus);
if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true);
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 88d6eac69754..273cee1cc77b 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_RIO) += rio/ generic_serial.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o
obj-$(CONFIG_HVC_ISERIES) += hvc_iseries.o
obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o
+obj-$(CONFIG_HVC_TILE) += hvc_tile.o
obj-$(CONFIG_HVC_BEAT) += hvc_beat.o
obj-$(CONFIG_HVC_DRIVER) += hvc_console.o
obj-$(CONFIG_HVC_IRQ) += hvc_irq.o
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 35cca4c7fb18..fa27d1676ee5 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -194,7 +194,7 @@ static int __init hvc_console_setup(struct console *co, char *options)
return 0;
}
-static struct console hvc_con_driver = {
+static struct console hvc_console = {
.name = "hvc",
.write = hvc_console_print,
.device = hvc_console_device,
@@ -220,7 +220,7 @@ static struct console hvc_con_driver = {
*/
static int __init hvc_console_init(void)
{
- register_console(&hvc_con_driver);
+ register_console(&hvc_console);
return 0;
}
console_initcall(hvc_console_init);
@@ -276,8 +276,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
* now (setup won't fail at this point). It's ok to just
* call register again if previously .setup failed.
*/
- if (index == hvc_con_driver.index)
- register_console(&hvc_con_driver);
+ if (index == hvc_console.index)
+ register_console(&hvc_console);
return 0;
}
@@ -641,7 +641,7 @@ int hvc_poll(struct hvc_struct *hp)
}
for (i = 0; i < n; ++i) {
#ifdef CONFIG_MAGIC_SYSRQ
- if (hp->index == hvc_con_driver.index) {
+ if (hp->index == hvc_console.index) {
/* Handle the SysRq Hack */
/* XXX should support a sequence */
if (buf[i] == '\x0f') { /* ^O */
@@ -909,7 +909,7 @@ static void __exit hvc_exit(void)
tty_unregister_driver(hvc_driver);
/* return tty_struct instances allocated in hvc_init(). */
put_tty_driver(hvc_driver);
- unregister_console(&hvc_con_driver);
+ unregister_console(&hvc_console);
}
}
module_exit(hvc_exit);
diff --git a/drivers/char/hvc_tile.c b/drivers/char/hvc_tile.c
new file mode 100644
index 000000000000..c4efb55cbc03
--- /dev/null
+++ b/drivers/char/hvc_tile.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ *
+ * Tilera TILE Processor hypervisor console
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+
+#include <hv/hypervisor.h>
+
+#include "hvc_console.h"
+
+static int hvc_tile_put_chars(uint32_t vt, const char *buf, int count)
+{
+ return hv_console_write((HV_VirtAddr)buf, count);
+}
+
+static int hvc_tile_get_chars(uint32_t vt, char *buf, int count)
+{
+ int i, c;
+
+ for (i = 0; i < count; ++i) {
+ c = hv_console_read_if_ready();
+ if (c < 0)
+ break;
+ buf[i] = c;
+ }
+
+ return i;
+}
+
+static const struct hv_ops hvc_tile_get_put_ops = {
+ .get_chars = hvc_tile_get_chars,
+ .put_chars = hvc_tile_put_chars,
+};
+
+static int __init hvc_tile_console_init(void)
+{
+ extern void disable_early_printk(void);
+ hvc_instantiate(0, 0, &hvc_tile_get_put_ops);
+ add_preferred_console("hvc", 0, NULL);
+ disable_early_printk();
+ return 0;
+}
+console_initcall(hvc_tile_console_init);
+
+static int __init hvc_tile_init(void)
+{
+ hvc_alloc(0, 0, &hvc_tile_get_put_ops, 128);
+ return 0;
+}
+device_initcall(hvc_tile_init);
diff --git a/drivers/char/hvsi.c b/drivers/char/hvsi.c
index d4b14ff1c4c1..1f4b6de65a2d 100644
--- a/drivers/char/hvsi.c
+++ b/drivers/char/hvsi.c
@@ -1255,7 +1255,7 @@ static int __init hvsi_console_setup(struct console *console, char *options)
return 0;
}
-static struct console hvsi_con_driver = {
+static struct console hvsi_console = {
.name = "hvsi",
.write = hvsi_console_print,
.device = hvsi_console_device,
@@ -1308,7 +1308,7 @@ static int __init hvsi_console_init(void)
}
if (hvsi_count)
- register_console(&hvsi_con_driver);
+ register_console(&hvsi_console);
return 0;
}
console_initcall(hvsi_console_init);
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 9e01e96fee94..8344375dc015 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -128,7 +128,7 @@ config TXX9_DMAC
config SH_DMAE
tristate "Renesas SuperH DMAC support"
- depends on SUPERH && SH_DMA
+ depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE)
depends on !SH_DMA_API
select DMA_ENGINE
help
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index a2a519fd2a24..fb64cf36ba61 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -816,7 +816,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
return ret;
}
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
static irqreturn_t sh_dmae_err(int irq, void *data)
{
struct sh_dmae_device *shdev = (struct sh_dmae_device *)data;
@@ -1057,7 +1057,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
/* Default transfer size of 32 bytes requires 32-byte alignment */
shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
if (!chanirq_res)
@@ -1082,7 +1082,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
#else
chanirq_res = errirq_res;
-#endif /* CONFIG_CPU_SH4 */
+#endif /* CONFIG_CPU_SH4 || CONFIG_ARCH_SHMOBILE */
if (chanirq_res->start == chanirq_res->end &&
!platform_get_resource(pdev, IORESOURCE_IRQ, 1)) {
@@ -1129,7 +1129,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
chan_probe_err:
sh_dmae_chan_remove(shdev);
eirqres:
-#if defined(CONFIG_CPU_SH4)
+#if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
free_irq(errirq, shdev);
eirq_err:
#endif
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 434099369058..f54050c2e38d 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -148,6 +148,12 @@ config HID_EGALAX
---help---
Support for the eGalax dual-touch panel.
+config HID_ELECOM
+ tristate "ELECOM"
+ depends on BT_HIDP
+ ---help---
+ Support for the ELECOM BM084 (bluetooth mouse).
+
config HID_EZKEY
tristate "Ezkey" if EMBEDDED
depends on USB_HID
@@ -417,10 +423,11 @@ config SMARTJOYPLUS_FF
enable force feedback support for it.
config HID_TOPSEED
- tristate "TopSeed Cyberlink remote control support"
+ tristate "TopSeed Cyberlink, BTC Emprex, Conceptronic remote control support"
depends on USB_HID
---help---
- Say Y if you have a TopSeed Cyberlink or BTC Emprex remote control.
+ Say Y if you have a TopSeed Cyberlink or BTC Emprex or Conceptronic
+ CLLRCMCE remote control.
config HID_THRUSTMASTER
tristate "ThrustMaster devices support"
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 987fa0627367..2ec042f57138 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o
obj-$(CONFIG_HID_EGALAX) += hid-egalax.o
+obj-$(CONFIG_HID_ELECOM) += hid-elecom.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 866e54ec5fb2..7c052bb78f21 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1294,6 +1294,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1375,6 +1376,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653) },
{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
new file mode 100644
index 000000000000..7a40878f46b4
--- /dev/null
+++ b/drivers/hid/hid-elecom.c
@@ -0,0 +1,57 @@
+/*
+ * HID driver for Elecom BM084 (bluetooth mouse).
+ * Removes a non-existing horizontal wheel from
+ * the HID descriptor.
+ * (This module is based on "hid-ortek".)
+ *
+ * Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+static void elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int rsize)
+{
+ if (rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
+ dev_info(&hdev->dev, "Fixing up Elecom BM084 "
+ "report descriptor.\n");
+ rdesc[47] = 0x00;
+ }
+}
+
+static const struct hid_device_id elecom_devices[] = {
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)},
+ { }
+};
+MODULE_DEVICE_TABLE(hid, elecom_devices);
+
+static struct hid_driver elecom_driver = {
+ .name = "elecom",
+ .id_table = elecom_devices,
+ .report_fixup = elecom_report_fixup
+};
+
+static int __init elecom_init(void)
+{
+ return hid_register_driver(&elecom_driver);
+}
+
+static void __exit elecom_exit(void)
+{
+ hid_unregister_driver(&elecom_driver);
+}
+
+module_init(elecom_init);
+module_exit(elecom_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 31601eef25dd..f09ff6db3952 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -34,7 +34,7 @@
#define USB_DEVICE_ID_ACECAD_FLAIR 0x0004
#define USB_DEVICE_ID_ACECAD_302 0x0008
-#define USB_VENDOR_ID_ADS_TECH 0x06e1
+#define USB_VENDOR_ID_ADS_TECH 0x06e1
#define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X 0xa155
#define USB_VENDOR_ID_AFATECH 0x15a4
@@ -81,12 +81,12 @@
#define USB_DEVICE_ID_APPLE_WELLSPRING_ANSI 0x0223
#define USB_DEVICE_ID_APPLE_WELLSPRING_ISO 0x0224
#define USB_DEVICE_ID_APPLE_WELLSPRING_JIS 0x0225
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
-#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
-#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI 0x0229
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO 0x022a
+#define USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS 0x022b
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI 0x022c
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO 0x022d
+#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS 0x022e
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI 0x0230
#define USB_DEVICE_ID_APPLE_WELLSPRING2_ISO 0x0231
#define USB_DEVICE_ID_APPLE_WELLSPRING2_JIS 0x0232
@@ -118,8 +118,8 @@
#define USB_VENDOR_ID_AVERMEDIA 0x07ca
#define USB_DEVICE_ID_AVER_FM_MR800 0xb800
-#define USB_VENDOR_ID_BELKIN 0x050d
-#define USB_DEVICE_ID_FLIP_KVM 0x3201
+#define USB_VENDOR_ID_BELKIN 0x050d
+#define USB_DEVICE_ID_FLIP_KVM 0x3201
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
@@ -128,7 +128,7 @@
#define USB_DEVICE_ID_BTC_EMPREX_REMOTE 0x5578
#define USB_VENDOR_ID_CANDO 0x2087
-#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
+#define USB_DEVICE_ID_CANDO_MULTI_TOUCH 0x0a01
#define USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6 0x0b03
#define USB_VENDOR_ID_CH 0x068e
@@ -175,7 +175,7 @@
#define USB_DEVICE_ID_DEALEXTREAME_RADIO_SI4701 0x819a
#define USB_VENDOR_ID_DELORME 0x1163
-#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
+#define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100
#define USB_DEVICE_ID_DELORME_EM_LT20 0x0200
#define USB_VENDOR_ID_DMI 0x0c0b
@@ -187,19 +187,22 @@
#define USB_DEVICE_ID_EGALAX_TOUCHCONTROLLER 0x0001
#define USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH 0x480d
+#define USB_VENDOR_ID_ELECOM 0x056e
+#define USB_DEVICE_ID_ELECOM_BM084 0x0061
+
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
#define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f
#define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100
-#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
-#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
-
#define USB_VENDOR_ID_ETT 0x0664
#define USB_DEVICE_ID_TC5UH 0x0309
-#define USB_VENDOR_ID_EZKEY 0x0518
+#define USB_VENDOR_ID_ETURBOTOUCH 0x22b9
+#define USB_DEVICE_ID_ETURBOTOUCH 0x0006
+
+#define USB_VENDOR_ID_EZKEY 0x0518
#define USB_DEVICE_ID_BTC_8193 0x0002
#define USB_VENDOR_ID_GAMERON 0x0810
@@ -282,8 +285,8 @@
#define USB_VENDOR_ID_GYRATION 0x0c16
#define USB_DEVICE_ID_GYRATION_REMOTE 0x0002
-#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
-#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
+#define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
+#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
#define USB_VENDOR_ID_HAPP 0x078b
#define USB_DEVICE_ID_UGCI_DRIVING 0x0010
@@ -296,9 +299,16 @@
#define USB_VENDOR_ID_KBGEAR 0x084e
#define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001
+#define USB_VENDOR_ID_KENSINGTON 0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
+
#define USB_VENDOR_ID_KWORLD 0x1b80
#define USB_DEVICE_ID_KWORLD_RADIO_FM700 0xd700
+#define USB_VENDOR_ID_KYE 0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
+#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
+
#define USB_VENDOR_ID_LABTEC 0x1020
#define USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD 0x0006
@@ -318,9 +328,6 @@
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
-#define USB_VENDOR_ID_KENSINGTON 0x047d
-#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
-
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -376,23 +383,23 @@
#define USB_VENDOR_ID_MONTEREY 0x0566
#define USB_DEVICE_ID_GENIUS_KB29E 0x3004
+#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
+#define USB_DEVICE_ID_N_S_HARMONY 0xc359
+
+#define USB_VENDOR_ID_NATSU 0x08b7
+#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
+
#define USB_VENDOR_ID_NCR 0x0404
#define USB_DEVICE_ID_NCR_FIRST 0x0300
#define USB_DEVICE_ID_NCR_LAST 0x03ff
-#define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400
-#define USB_DEVICE_ID_N_S_HARMONY 0xc359
-
-#define USB_VENDOR_ID_NATSU 0x08b7
-#define USB_DEVICE_ID_NATSU_GAMEPAD 0x0001
-
#define USB_VENDOR_ID_NEC 0x073e
#define USB_DEVICE_ID_NEC_USB_GAME_PAD 0x0301
#define USB_VENDOR_ID_NEXTWINDOW 0x1926
#define USB_DEVICE_ID_NEXTWINDOW_TOUCHSCREEN 0x0003
-#define USB_VENDOR_ID_NTRIG 0x1b96
+#define USB_VENDOR_ID_NTRIG 0x1b96
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN 0x0001
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_1 0x0003
#define USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_2 0x0004
@@ -427,7 +434,7 @@
#define USB_VENDOR_ID_PETALYNX 0x18b1
#define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE 0x0037
-#define USB_VENDOR_ID_PHILIPS 0x0471
+#define USB_VENDOR_ID_PHILIPS 0x0471
#define USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE 0x0617
#define USB_VENDOR_ID_PLAYDOTCOM 0x0b43
@@ -439,16 +446,16 @@
#define USB_VENDOR_ID_PRODIGE 0x05af
#define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062
+#define USB_VENDOR_ID_QUANTA 0x0408
+#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
+#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
+
#define USB_VENDOR_ID_ROCCAT 0x1e7d
#define USB_DEVICE_ID_ROCCAT_KONE 0x2ced
#define USB_VENDOR_ID_SAITEK 0x06a3
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
-#define USB_VENDOR_ID_QUANTA 0x0408
-#define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH 0x3000
-#define USB_DEVICE_ID_PIXART_IMAGING_INC_OPTICAL_TOUCH_SCREEN 0x3001
-
#define USB_VENDOR_ID_SAMSUNG 0x0419
#define USB_DEVICE_ID_SAMSUNG_IR_REMOTE 0x0001
#define USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE 0x0600
@@ -472,6 +479,9 @@
#define USB_VENDOR_ID_THRUSTMASTER 0x044f
+#define USB_VENDOR_ID_TOPSEED2 0x1784
+#define USB_DEVICE_ID_TOPSEED2_RF_COMBO 0x0004
+
#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
@@ -481,11 +491,14 @@
#define USB_VENDOR_ID_TOPSEED 0x0766
#define USB_DEVICE_ID_TOPSEED_CYBERLINK 0x0204
+#define USB_VENDOR_ID_TOUCHPACK 0x1bfd
+#define USB_DEVICE_ID_TOUCHPACK_RTS 0x1688
+
#define USB_VENDOR_ID_TURBOX 0x062a
#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
-#define USB_VENDOR_ID_TWINHAN 0x6253
-#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
+#define USB_VENDOR_ID_TWINHAN 0x6253
+#define USB_DEVICE_ID_TWINHAN_IR_REMOTE 0x0100
#define USB_VENDOR_ID_UCLOGIC 0x5543
#define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209 0x0042
@@ -522,9 +535,5 @@
#define USB_VENDOR_ID_ZYDACRON 0x13EC
#define USB_DEVICE_ID_ZYDACRON_REMOTE_CONTROL 0x0006
-#define USB_VENDOR_ID_KYE 0x0458
-#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
-#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
-
#endif
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
index 7a0d2e4661a1..6b10e5afe770 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -301,6 +301,9 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
case HID_UP_DIGITIZER:
switch (usage->hid & 0xff) {
+ case 0x00: /* Undefined */
+ goto ignore;
+
case 0x30: /* TipPressure */
if (!test_bit(BTN_TOUCH, input->keybit)) {
device->quirks |= HID_QUIRK_NOTOUCH;
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index f10d56a15f21..319b0e57ee41 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -30,6 +30,21 @@ static bool emulate_scroll_wheel = true;
module_param(emulate_scroll_wheel, bool, 0644);
MODULE_PARM_DESC(emulate_scroll_wheel, "Emulate a scroll wheel");
+static unsigned int scroll_speed = 32;
+static int param_set_scroll_speed(const char *val, struct kernel_param *kp) {
+ unsigned long speed;
+ if (!val || strict_strtoul(val, 0, &speed) || speed > 63)
+ return -EINVAL;
+ scroll_speed = speed;
+ return 0;
+}
+module_param_call(scroll_speed, param_set_scroll_speed, param_get_uint, &scroll_speed, 0644);
+MODULE_PARM_DESC(scroll_speed, "Scroll speed, value from 0 (slow) to 63 (fast)");
+
+static bool scroll_acceleration = false;
+module_param(scroll_acceleration, bool, 0644);
+MODULE_PARM_DESC(scroll_acceleration, "Accelerate sequential scroll events");
+
static bool report_touches = true;
module_param(report_touches, bool, 0644);
MODULE_PARM_DESC(report_touches, "Emit touch records (otherwise, only use them for emulation)");
@@ -50,6 +65,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie
#define TOUCH_STATE_START 0x30
#define TOUCH_STATE_DRAG 0x40
+#define SCROLL_ACCEL_DEFAULT 7
+
/**
* struct magicmouse_sc - Tracks Magic Mouse-specific data.
* @input: Input device through which we report events.
@@ -78,8 +95,10 @@ struct magicmouse_sc {
struct {
short x;
short y;
+ short scroll_x;
short scroll_y;
u8 size;
+ u8 down;
} touches[16];
int tracking_ids[16];
};
@@ -141,7 +160,7 @@ static void magicmouse_emit_buttons(struct magicmouse_sc *msc, int state)
input_report_key(msc->input, BTN_RIGHT, state & 2);
if (state != last_state)
- msc->scroll_accel = 0;
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
}
static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tdata)
@@ -152,6 +171,7 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
int id = (misc >> 6) & 15;
int x = x_y << 12 >> 20;
int y = -(x_y >> 20);
+ int down = (tdata[7] & TOUCH_STATE_MASK) != TOUCH_STATE_NONE;
/* Store tracking ID and other fields. */
msc->tracking_ids[raw_id] = id;
@@ -160,42 +180,54 @@ static void magicmouse_emit_touch(struct magicmouse_sc *msc, int raw_id, u8 *tda
msc->touches[id].size = misc & 63;
/* If requested, emulate a scroll wheel by detecting small
- * vertical touch motions along the middle of the mouse.
+ * vertical touch motions.
*/
- if (emulate_scroll_wheel &&
- middle_button_start < x && x < middle_button_stop) {
- static const int accel_profile[] = {
- 256, 228, 192, 160, 128, 96, 64, 32,
- };
+ if (emulate_scroll_wheel) {
unsigned long now = jiffies;
- int step = msc->touches[id].scroll_y - y;
-
- /* Reset acceleration after half a second. */
- if (time_after(now, msc->scroll_jiffies + HZ / 2))
- msc->scroll_accel = 0;
+ int step_x = msc->touches[id].scroll_x - x;
+ int step_y = msc->touches[id].scroll_y - y;
/* Calculate and apply the scroll motion. */
switch (tdata[7] & TOUCH_STATE_MASK) {
case TOUCH_STATE_START:
+ msc->touches[id].scroll_x = x;
msc->touches[id].scroll_y = y;
- msc->scroll_accel = min_t(int, msc->scroll_accel + 1,
- ARRAY_SIZE(accel_profile) - 1);
+
+ /* Reset acceleration after half a second. */
+ if (scroll_acceleration && time_before(now,
+ msc->scroll_jiffies + HZ / 2))
+ msc->scroll_accel = max_t(int,
+ msc->scroll_accel - 1, 1);
+ else
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
+
break;
case TOUCH_STATE_DRAG:
- step = step / accel_profile[msc->scroll_accel];
- if (step != 0) {
- msc->touches[id].scroll_y = y;
+ step_x /= (64 - (int)scroll_speed) * msc->scroll_accel;
+ if (step_x != 0) {
+ msc->touches[id].scroll_x -= step_x *
+ (64 - scroll_speed) * msc->scroll_accel;
msc->scroll_jiffies = now;
- input_report_rel(input, REL_WHEEL, step);
+ input_report_rel(input, REL_HWHEEL, -step_x);
+ }
+
+ step_y /= (64 - (int)scroll_speed) * msc->scroll_accel;
+ if (step_y != 0) {
+ msc->touches[id].scroll_y -= step_y *
+ (64 - scroll_speed) * msc->scroll_accel;
+ msc->scroll_jiffies = now;
+ input_report_rel(input, REL_WHEEL, step_y);
}
break;
}
}
/* Generate the input events for this touch. */
- if (report_touches) {
+ if (report_touches && down) {
int orientation = (misc >> 10) - 32;
+ msc->touches[id].down = 1;
+
input_report_abs(input, ABS_MT_TRACKING_ID, id);
input_report_abs(input, ABS_MT_TOUCH_MAJOR, tdata[3]);
input_report_abs(input, ABS_MT_TOUCH_MINOR, tdata[4]);
@@ -215,7 +247,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
{
struct magicmouse_sc *msc = hid_get_drvdata(hdev);
struct input_dev *input = msc->input;
- int x, y, ts, ii, clicks;
+ int x, y, ts, ii, clicks, last_up;
switch (data[0]) {
case 0x10:
@@ -235,12 +267,26 @@ static int magicmouse_raw_event(struct hid_device *hdev,
msc->ntouches = (size - 6) / 8;
for (ii = 0; ii < msc->ntouches; ii++)
magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
+
+ if (report_touches) {
+ last_up = 1;
+ for (ii = 0; ii < ARRAY_SIZE(msc->touches); ii++) {
+ if (msc->touches[ii].down) {
+ last_up = 0;
+ msc->touches[ii].down = 0;
+ }
+ }
+ if (last_up) {
+ input_mt_sync(input);
+ }
+ }
+
/* When emulating three-button mode, it is important
* to have the current touch information before
* generating a click event.
*/
- x = (signed char)data[1];
- y = (signed char)data[2];
+ x = (int)(((data[3] & 0x0c) << 28) | (data[1] << 22)) >> 22;
+ y = (int)(((data[3] & 0x30) << 26) | (data[2] << 22)) >> 22;
clicks = data[3];
break;
case 0x20: /* Theoretically battery status (0-100), but I have
@@ -301,8 +347,10 @@ static void magicmouse_setup_input(struct input_dev *input, struct hid_device *h
__set_bit(EV_REL, input->evbit);
__set_bit(REL_X, input->relbit);
__set_bit(REL_Y, input->relbit);
- if (emulate_scroll_wheel)
+ if (emulate_scroll_wheel) {
__set_bit(REL_WHEEL, input->relbit);
+ __set_bit(REL_HWHEEL, input->relbit);
+ }
if (report_touches) {
__set_bit(EV_ABS, input->evbit);
@@ -345,6 +393,8 @@ static int magicmouse_probe(struct hid_device *hdev,
return -ENOMEM;
}
+ msc->scroll_accel = SCROLL_ACCEL_DEFAULT;
+
msc->quirks = id->driver_data;
hid_set_drvdata(hdev, msc);
diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c
index 7aabf65c48ef..346f0e34987e 100644
--- a/drivers/hid/hid-picolcd.c
+++ b/drivers/hid/hid-picolcd.c
@@ -127,6 +127,26 @@ static const struct fb_var_screeninfo picolcdfb_var = {
.height = 26,
.bits_per_pixel = 1,
.grayscale = 1,
+ .red = {
+ .offset = 0,
+ .length = 1,
+ .msb_right = 0,
+ },
+ .green = {
+ .offset = 0,
+ .length = 1,
+ .msb_right = 0,
+ },
+ .blue = {
+ .offset = 0,
+ .length = 1,
+ .msb_right = 0,
+ },
+ .transp = {
+ .offset = 0,
+ .length = 0,
+ .msb_right = 0,
+ },
};
#endif /* CONFIG_HID_PICOLCD_FB */
@@ -188,6 +208,7 @@ struct picolcd_data {
/* Framebuffer stuff */
u8 fb_update_rate;
u8 fb_bpp;
+ u8 fb_force;
u8 *fb_vbitmap; /* local copy of what was sent to PicoLCD */
u8 *fb_bitmap; /* framebuffer */
struct fb_info *fb_info;
@@ -346,7 +367,7 @@ static int picolcd_fb_update_tile(u8 *vbitmap, const u8 *bitmap, int bpp,
const u8 *bdata = bitmap + tile * 256 + chip * 8 + b * 32;
for (i = 0; i < 64; i++) {
tdata[i] <<= 1;
- tdata[i] |= (bdata[i/8] >> (7 - i % 8)) & 0x01;
+ tdata[i] |= (bdata[i/8] >> (i % 8)) & 0x01;
}
}
} else if (bpp == 8) {
@@ -399,13 +420,10 @@ static int picolcd_fb_reset(struct picolcd_data *data, int clear)
if (data->fb_bitmap) {
if (clear) {
- memset(data->fb_vbitmap, 0xff, PICOLCDFB_SIZE);
+ memset(data->fb_vbitmap, 0, PICOLCDFB_SIZE);
memset(data->fb_bitmap, 0, PICOLCDFB_SIZE*data->fb_bpp);
- } else {
- /* invert 1 byte in each tile to force resend */
- for (i = 0; i < PICOLCDFB_SIZE; i += 64)
- data->fb_vbitmap[i] = ~data->fb_vbitmap[i];
}
+ data->fb_force = 1;
}
/* schedule first output of framebuffer */
@@ -421,6 +439,9 @@ static void picolcd_fb_update(struct picolcd_data *data)
int chip, tile, n;
unsigned long flags;
+ if (!data)
+ return;
+
spin_lock_irqsave(&data->lock, flags);
if (!(data->status & PICOLCD_READY_FB)) {
spin_unlock_irqrestore(&data->lock, flags);
@@ -440,14 +461,18 @@ static void picolcd_fb_update(struct picolcd_data *data)
for (chip = 0; chip < 4; chip++)
for (tile = 0; tile < 8; tile++)
if (picolcd_fb_update_tile(data->fb_vbitmap,
- data->fb_bitmap, data->fb_bpp, chip, tile)) {
+ data->fb_bitmap, data->fb_bpp, chip, tile) ||
+ data->fb_force) {
n += 2;
+ if (!data->fb_info->par)
+ return; /* device lost! */
if (n >= HID_OUTPUT_FIFO_SIZE / 2) {
usbhid_wait_io(data->hdev);
n = 0;
}
picolcd_fb_send_tile(data->hdev, chip, tile);
}
+ data->fb_force = false;
if (n)
usbhid_wait_io(data->hdev);
}
@@ -511,11 +536,23 @@ static int picolcd_fb_blank(int blank, struct fb_info *info)
static void picolcd_fb_destroy(struct fb_info *info)
{
struct picolcd_data *data = info->par;
+ u32 *ref_cnt = info->pseudo_palette;
+ int may_release;
+
info->par = NULL;
if (data)
data->fb_info = NULL;
fb_deferred_io_cleanup(info);
- framebuffer_release(info);
+
+ ref_cnt--;
+ mutex_lock(&info->lock);
+ (*ref_cnt)--;
+ may_release = !ref_cnt;
+ mutex_unlock(&info->lock);
+ if (may_release) {
+ framebuffer_release(info);
+ vfree((u8 *)info->fix.smem_start);
+ }
}
static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
@@ -526,29 +563,37 @@ static int picolcd_fb_check_var(struct fb_var_screeninfo *var, struct fb_info *i
/* only allow 1/8 bit depth (8-bit is grayscale) */
*var = picolcdfb_var;
var->activate = activate;
- if (bpp >= 8)
+ if (bpp >= 8) {
var->bits_per_pixel = 8;
- else
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ } else {
var->bits_per_pixel = 1;
+ var->red.length = 1;
+ var->green.length = 1;
+ var->blue.length = 1;
+ }
return 0;
}
static int picolcd_set_par(struct fb_info *info)
{
struct picolcd_data *data = info->par;
- u8 *o_fb, *n_fb;
+ u8 *tmp_fb, *o_fb;
+ if (!data)
+ return -ENODEV;
if (info->var.bits_per_pixel == data->fb_bpp)
return 0;
/* switch between 1/8 bit depths */
if (info->var.bits_per_pixel != 1 && info->var.bits_per_pixel != 8)
return -EINVAL;
- o_fb = data->fb_bitmap;
- n_fb = vmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel);
- if (!n_fb)
+ o_fb = data->fb_bitmap;
+ tmp_fb = kmalloc(PICOLCDFB_SIZE*info->var.bits_per_pixel, GFP_KERNEL);
+ if (!tmp_fb)
return -ENOMEM;
- fb_deferred_io_cleanup(info);
/* translate FB content to new bits-per-pixel */
if (info->var.bits_per_pixel == 1) {
int i, b;
@@ -558,24 +603,87 @@ static int picolcd_set_par(struct fb_info *info)
p <<= 1;
p |= o_fb[i*8+b] ? 0x01 : 0x00;
}
+ tmp_fb[i] = p;
}
+ memcpy(o_fb, tmp_fb, PICOLCDFB_SIZE);
info->fix.visual = FB_VISUAL_MONO01;
info->fix.line_length = PICOLCDFB_WIDTH / 8;
} else {
int i;
+ memcpy(tmp_fb, o_fb, PICOLCDFB_SIZE);
for (i = 0; i < PICOLCDFB_SIZE * 8; i++)
- n_fb[i] = o_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
- info->fix.visual = FB_VISUAL_TRUECOLOR;
+ o_fb[i] = tmp_fb[i/8] & (0x01 << (7 - i % 8)) ? 0xff : 0x00;
+ info->fix.visual = FB_VISUAL_DIRECTCOLOR;
info->fix.line_length = PICOLCDFB_WIDTH;
}
- data->fb_bitmap = n_fb;
+ kfree(tmp_fb);
data->fb_bpp = info->var.bits_per_pixel;
- info->screen_base = (char __force __iomem *)n_fb;
- info->fix.smem_start = (unsigned long)n_fb;
- info->fix.smem_len = PICOLCDFB_SIZE*data->fb_bpp;
- fb_deferred_io_init(info);
- vfree(o_fb);
+ return 0;
+}
+
+/* Do refcounting on our FB and cleanup per worker if FB is
+ * closed after unplug of our device
+ * (fb_release holds info->lock and still touches info after
+ * we return so we can't release it immediately.
+ */
+struct picolcd_fb_cleanup_item {
+ struct fb_info *info;
+ struct picolcd_fb_cleanup_item *next;
+};
+static struct picolcd_fb_cleanup_item *fb_pending;
+DEFINE_SPINLOCK(fb_pending_lock);
+
+static void picolcd_fb_do_cleanup(struct work_struct *data)
+{
+ struct picolcd_fb_cleanup_item *item;
+ unsigned long flags;
+
+ do {
+ spin_lock_irqsave(&fb_pending_lock, flags);
+ item = fb_pending;
+ fb_pending = item ? item->next : NULL;
+ spin_unlock_irqrestore(&fb_pending_lock, flags);
+
+ if (item) {
+ u8 *fb = (u8 *)item->info->fix.smem_start;
+ /* make sure we do not race against fb core when
+ * releasing */
+ mutex_lock(&item->info->lock);
+ mutex_unlock(&item->info->lock);
+ framebuffer_release(item->info);
+ vfree(fb);
+ }
+ } while (item);
+}
+
+DECLARE_WORK(picolcd_fb_cleanup, picolcd_fb_do_cleanup);
+
+static int picolcd_fb_open(struct fb_info *info, int u)
+{
+ u32 *ref_cnt = info->pseudo_palette;
+ ref_cnt--;
+
+ (*ref_cnt)++;
+ return 0;
+}
+
+static int picolcd_fb_release(struct fb_info *info, int u)
+{
+ u32 *ref_cnt = info->pseudo_palette;
+ ref_cnt--;
+
+ (*ref_cnt)++;
+ if (!*ref_cnt) {
+ unsigned long flags;
+ struct picolcd_fb_cleanup_item *item = (struct picolcd_fb_cleanup_item *)ref_cnt;
+ item--;
+ spin_lock_irqsave(&fb_pending_lock, flags);
+ item->next = fb_pending;
+ fb_pending = item;
+ spin_unlock_irqrestore(&fb_pending_lock, flags);
+ schedule_work(&picolcd_fb_cleanup);
+ }
return 0;
}
@@ -583,6 +691,8 @@ static int picolcd_set_par(struct fb_info *info)
static struct fb_ops picolcdfb_ops = {
.owner = THIS_MODULE,
.fb_destroy = picolcd_fb_destroy,
+ .fb_open = picolcd_fb_open,
+ .fb_release = picolcd_fb_release,
.fb_read = fb_sys_read,
.fb_write = picolcd_fb_write,
.fb_blank = picolcd_fb_blank,
@@ -660,11 +770,12 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
{
struct device *dev = &data->hdev->dev;
struct fb_info *info = NULL;
- int error = -ENOMEM;
+ int i, error = -ENOMEM;
u8 *fb_vbitmap = NULL;
u8 *fb_bitmap = NULL;
+ u32 *palette;
- fb_bitmap = vmalloc(PICOLCDFB_SIZE*picolcdfb_var.bits_per_pixel);
+ fb_bitmap = vmalloc(PICOLCDFB_SIZE*8);
if (fb_bitmap == NULL) {
dev_err(dev, "can't get a free page for framebuffer\n");
goto err_nomem;
@@ -678,18 +789,29 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
data->fb_update_rate = PICOLCDFB_UPDATE_RATE_DEFAULT;
data->fb_defio = picolcd_fb_defio;
- info = framebuffer_alloc(0, dev);
+ /* The extra memory is:
+ * - struct picolcd_fb_cleanup_item
+ * - u32 for ref_count
+ * - 256*u32 for pseudo_palette
+ */
+ info = framebuffer_alloc(257 * sizeof(u32) + sizeof(struct picolcd_fb_cleanup_item), dev);
if (info == NULL) {
dev_err(dev, "failed to allocate a framebuffer\n");
goto err_nomem;
}
+ palette = info->par + sizeof(struct picolcd_fb_cleanup_item);
+ *palette = 1;
+ palette++;
+ for (i = 0; i < 256; i++)
+ palette[i] = i > 0 && i < 16 ? 0xff : 0;
+ info->pseudo_palette = palette;
info->fbdefio = &data->fb_defio;
info->screen_base = (char __force __iomem *)fb_bitmap;
info->fbops = &picolcdfb_ops;
info->var = picolcdfb_var;
info->fix = picolcdfb_fix;
- info->fix.smem_len = PICOLCDFB_SIZE;
+ info->fix.smem_len = PICOLCDFB_SIZE*8;
info->fix.smem_start = (unsigned long)fb_bitmap;
info->par = data;
info->flags = FBINFO_FLAG_DEFAULT;
@@ -707,18 +829,20 @@ static int picolcd_init_framebuffer(struct picolcd_data *data)
dev_err(dev, "failed to create sysfs attributes\n");
goto err_cleanup;
}
+ fb_deferred_io_init(info);
data->fb_info = info;
error = register_framebuffer(info);
if (error) {
dev_err(dev, "failed to register framebuffer\n");
goto err_sysfs;
}
- fb_deferred_io_init(info);
/* schedule first output of framebuffer */
+ data->fb_force = 1;
schedule_delayed_work(&info->deferred_work, 0);
return 0;
err_sysfs:
+ fb_deferred_io_cleanup(info);
device_remove_file(dev, &dev_attr_fb_update_rate);
err_cleanup:
data->fb_vbitmap = NULL;
@@ -737,19 +861,17 @@ static void picolcd_exit_framebuffer(struct picolcd_data *data)
{
struct fb_info *info = data->fb_info;
u8 *fb_vbitmap = data->fb_vbitmap;
- u8 *fb_bitmap = data->fb_bitmap;
if (!info)
return;
+ info->par = NULL;
+ device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
+ unregister_framebuffer(info);
data->fb_vbitmap = NULL;
data->fb_bitmap = NULL;
data->fb_bpp = 0;
data->fb_info = NULL;
- device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
- fb_deferred_io_cleanup(info);
- unregister_framebuffer(info);
- vfree(fb_bitmap);
kfree(fb_vbitmap);
}
@@ -2566,6 +2688,13 @@ static void picolcd_remove(struct hid_device *hdev)
spin_lock_irqsave(&data->lock, flags);
data->status |= PICOLCD_FAILED;
spin_unlock_irqrestore(&data->lock, flags);
+#ifdef CONFIG_HID_PICOLCD_FB
+ /* short-circuit FB as early as possible in order to
+ * avoid long delays if we host console.
+ */
+ if (data->fb_info)
+ data->fb_info->par = NULL;
+#endif
picolcd_exit_devfs(data);
device_remove_file(&hdev->dev, &dev_attr_operation_mode);
@@ -2623,6 +2752,10 @@ static int __init picolcd_init(void)
static void __exit picolcd_exit(void)
{
hid_unregister_driver(&picolcd_driver);
+#ifdef CONFIG_HID_PICOLCD_FB
+ flush_scheduled_work();
+ WARN_ON(fb_pending);
+#endif
}
module_init(picolcd_init);
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
index 17f2dc04f883..f77695762cb5 100644
--- a/drivers/hid/hid-roccat-kone.c
+++ b/drivers/hid/hid-roccat-kone.c
@@ -22,11 +22,6 @@
* Is it possible to remove and reinstall the urb in raw-event- or any
* other handler, or to defer this action to be executed somewhere else?
*
- * TODO implement notification mechanism for overlong macro execution
- * If user wants to execute an overlong macro only the names of macroset
- * and macro are given. Should userland tap hidraw or is there an
- * additional streaming mechanism?
- *
* TODO is it possible to overwrite group for sysfs attributes via udev?
*/
@@ -277,7 +272,7 @@ static ssize_t kone_sysfs_read_settings(struct file *fp, struct kobject *kobj,
count = sizeof(struct kone_settings) - off;
mutex_lock(&kone->kone_lock);
- memcpy(buf, &kone->settings + off, count);
+ memcpy(buf, ((char const *)&kone->settings) + off, count);
mutex_unlock(&kone->kone_lock);
return count;
@@ -337,7 +332,7 @@ static ssize_t kone_sysfs_read_profilex(struct kobject *kobj,
count = sizeof(struct kone_profile) - off;
mutex_lock(&kone->kone_lock);
- memcpy(buf, &kone->profiles[number - 1], sizeof(struct kone_profile));
+ memcpy(buf, ((char const *)&kone->profiles[number - 1]) + off, count);
mutex_unlock(&kone->kone_lock);
return count;
@@ -623,18 +618,6 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev,
}
/*
- * This file is used by userland software to find devices that are handled by
- * this driver. This provides a consistent way for actual and older kernels
- * where this driver replaced usbhid instead of generic-usb.
- * Driver capabilities are determined by version number.
- */
-static ssize_t kone_sysfs_show_driver_version(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, ROCCAT_KONE_DRIVER_VERSION "\n");
-}
-
-/*
* Read actual dpi settings.
* Returns raw value for further processing. Refer to enum kone_polling_rates to
* get real value.
@@ -671,9 +654,6 @@ static DEVICE_ATTR(startup_profile, 0660,
kone_sysfs_show_startup_profile,
kone_sysfs_set_startup_profile);
-static DEVICE_ATTR(kone_driver_version, 0440,
- kone_sysfs_show_driver_version, NULL);
-
static struct attribute *kone_attributes[] = {
&dev_attr_actual_dpi.attr,
&dev_attr_actual_profile.attr,
@@ -681,7 +661,6 @@ static struct attribute *kone_attributes[] = {
&dev_attr_firmware_version.attr,
&dev_attr_tcu.attr,
&dev_attr_startup_profile.attr,
- &dev_attr_kone_driver_version.attr,
NULL
};
diff --git a/drivers/hid/hid-roccat-kone.h b/drivers/hid/hid-roccat-kone.h
index 003e6f81c195..130d6566ea82 100644
--- a/drivers/hid/hid-roccat-kone.h
+++ b/drivers/hid/hid-roccat-kone.h
@@ -14,8 +14,6 @@
#include <linux/types.h>
-#define ROCCAT_KONE_DRIVER_VERSION "v0.3.1"
-
#pragma pack(push)
#pragma pack(1)
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c
index e05d48edb66f..f6e80c7ca61e 100644
--- a/drivers/hid/hid-roccat.c
+++ b/drivers/hid/hid-roccat.c
@@ -168,7 +168,7 @@ static int roccat_open(struct inode *inode, struct file *file)
printk(KERN_EMERG "roccat device with minor %d doesn't exist\n",
minor);
error = -ENODEV;
- goto exit_unlock;
+ goto exit_err;
}
if (!device->open++) {
@@ -178,7 +178,7 @@ static int roccat_open(struct inode *inode, struct file *file)
PM_HINT_FULLON);
if (error < 0) {
--device->open;
- goto exit_unlock;
+ goto exit_err;
}
}
error = device->hid->ll_driver->open(device->hid);
@@ -187,7 +187,7 @@ static int roccat_open(struct inode *inode, struct file *file)
device->hid->ll_driver->power(device->hid,
PM_HINT_NORMAL);
--device->open;
- goto exit_unlock;
+ goto exit_err;
}
}
@@ -202,6 +202,9 @@ exit_unlock:
mutex_unlock(&device->readers_lock);
mutex_unlock(&devices_lock);
return error;
+exit_err:
+ kfree(reader);
+ goto exit_unlock;
}
static int roccat_release(struct inode *inode, struct file *file)
diff --git a/drivers/hid/hid-roccat.h b/drivers/hid/hid-roccat.h
index d8aae0c1fa7e..09e864e9f79d 100644
--- a/drivers/hid/hid-roccat.h
+++ b/drivers/hid/hid-roccat.h
@@ -15,7 +15,7 @@
#include <linux/hid.h>
#include <linux/types.h>
-#if defined(CONFIG_HID_ROCCAT) || defined (CONFIG_HID_ROCCAT_MODULE)
+#if defined(CONFIG_HID_ROCCAT) || defined(CONFIG_HID_ROCCAT_MODULE)
int roccat_connect(struct hid_device *hid);
void roccat_disconnect(int minor);
int roccat_report_event(int minor, u8 const *data, int len);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index 2eebdcc57bcf..5771f851f856 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -6,6 +6,9 @@
*
* Modified to also support BTC "Emprex 3009URF III Vista MCE Remote" by
* Wayne Thomas 2010.
+ *
+ * Modified to support Conceptronic CLLRCMCE by
+ * Kees Bakker 2010.
*/
/*
@@ -34,6 +37,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
case 0x00d: ts_map_key_clear(KEY_MEDIA); break;
case 0x024: ts_map_key_clear(KEY_MENU); break;
case 0x025: ts_map_key_clear(KEY_TV); break;
+ case 0x027: ts_map_key_clear(KEY_MODE); break;
case 0x031: ts_map_key_clear(KEY_AUDIO); break;
case 0x032: ts_map_key_clear(KEY_TEXT); break;
case 0x033: ts_map_key_clear(KEY_CHANNEL); break;
@@ -60,6 +64,7 @@ static int ts_input_mapping(struct hid_device *hdev, struct hid_input *hi,
static const struct hid_device_id ts_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
{ }
};
MODULE_DEVICE_TABLE(hid, ts_devices);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 3ccd47850677..7df1310a28d1 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -46,7 +46,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
{
struct hidraw_list *list = file->private_data;
int ret = 0, len;
- char *report;
DECLARE_WAITQUEUE(wait, current);
mutex_lock(&list->read_mutex);
@@ -84,7 +83,6 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
if (ret)
goto out;
- report = list->buffer[list->tail].value;
len = list->buffer[list->tail].len > count ?
count : list->buffer[list->tail].len;
@@ -103,14 +101,14 @@ out:
}
/* the first byte is expected to be a report number */
-static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+/* This function is to be called with the minors_lock mutex held */
+static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
{
unsigned int minor = iminor(file->f_path.dentry->d_inode);
struct hid_device *dev;
__u8 *buf;
int ret = 0;
- mutex_lock(&minors_lock);
dev = hidraw_table[minor]->hid;
if (!dev->hid_output_raw_report) {
@@ -143,14 +141,92 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t
goto out_free;
}
- ret = dev->hid_output_raw_report(dev, buf, count, HID_OUTPUT_REPORT);
+ ret = dev->hid_output_raw_report(dev, buf, count, report_type);
out_free:
kfree(buf);
out:
+ return ret;
+}
+
+/* the first byte is expected to be a report number */
+static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
+{
+ ssize_t ret;
+ mutex_lock(&minors_lock);
+ ret = hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
mutex_unlock(&minors_lock);
return ret;
}
+
+/* This function performs a Get_Report transfer over the control endpoint
+ per section 7.2.1 of the HID specification, version 1.1. The first byte
+ of buffer is the report number to request, or 0x0 if the defice does not
+ use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
+ or HID_INPUT_REPORT. This function is to be called with the minors_lock
+ mutex held. */
+static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
+{
+ unsigned int minor = iminor(file->f_path.dentry->d_inode);
+ struct hid_device *dev;
+ __u8 *buf;
+ int ret = 0, len;
+ unsigned char report_number;
+
+ dev = hidraw_table[minor]->hid;
+
+ if (!dev->hid_get_raw_report) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ if (count > HID_MAX_BUFFER_SIZE) {
+ printk(KERN_WARNING "hidraw: pid %d passed too large report\n",
+ task_pid_nr(current));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (count < 2) {
+ printk(KERN_WARNING "hidraw: pid %d passed too short report\n",
+ task_pid_nr(current));
+ ret = -EINVAL;
+ goto out;
+ }
+
+ buf = kmalloc(count * sizeof(__u8), GFP_KERNEL);
+ if (!buf) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* Read the first byte from the user. This is the report number,
+ which is passed to dev->hid_get_raw_report(). */
+ if (copy_from_user(&report_number, buffer, 1)) {
+ ret = -EFAULT;
+ goto out_free;
+ }
+
+ ret = dev->hid_get_raw_report(dev, report_number, buf, count, report_type);
+
+ if (ret < 0)
+ goto out_free;
+
+ len = (ret < count) ? ret : count;
+
+ if (copy_to_user(buffer, buf, len)) {
+ ret = -EFAULT;
+ goto out_free;
+ }
+
+ ret = len;
+
+out_free:
+ kfree(buf);
+out:
+ return ret;
+}
+
static unsigned int hidraw_poll(struct file *file, poll_table *wait)
{
struct hidraw_list *list = file->private_data;
@@ -283,7 +359,24 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
default:
{
struct hid_device *hid = dev->hid;
- if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) {
+ if (_IOC_TYPE(cmd) != 'H') {
+ ret = -EINVAL;
+ break;
+ }
+
+ if (_IOC_NR(cmd) == _IOC_NR(HIDIOCSFEATURE(0))) {
+ int len = _IOC_SIZE(cmd);
+ ret = hidraw_send_report(file, user_arg, len, HID_FEATURE_REPORT);
+ break;
+ }
+ if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGFEATURE(0))) {
+ int len = _IOC_SIZE(cmd);
+ ret = hidraw_get_report(file, user_arg, len, HID_FEATURE_REPORT);
+ break;
+ }
+
+ /* Begin Read-only ioctls. */
+ if (_IOC_DIR(cmd) != _IOC_READ) {
ret = -EINVAL;
break;
}
@@ -315,7 +408,7 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
-EFAULT : len;
break;
}
- }
+ }
ret = -ENOTTY;
}
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index b729c0286679..16976877855d 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -798,6 +798,33 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid)
return 0;
}
+static int usbhid_get_raw_report(struct hid_device *hid,
+ unsigned char report_number, __u8 *buf, size_t count,
+ unsigned char report_type)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ struct usb_device *dev = hid_to_usb_dev(hid);
+ struct usb_interface *intf = usbhid->intf;
+ struct usb_host_interface *interface = intf->cur_altsetting;
+ int ret;
+
+ /* Byte 0 is the report number. Report data starts at byte 1.*/
+ buf[0] = report_number;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ HID_REQ_GET_REPORT,
+ USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ ((report_type + 1) << 8) | report_number,
+ interface->desc.bInterfaceNumber, buf + 1, count - 1,
+ USB_CTRL_SET_TIMEOUT);
+
+ /* count also the report id */
+ if (ret > 0)
+ ret++;
+
+ return ret;
+}
+
static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t count,
unsigned char report_type)
{
@@ -807,7 +834,7 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
struct usb_host_interface *interface = intf->cur_altsetting;
int ret;
- if (usbhid->urbout) {
+ if (usbhid->urbout && report_type != HID_FEATURE_REPORT) {
int actual_length;
int skipped_report_id = 0;
if (buf[0] == 0x0) {
@@ -1149,6 +1176,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
usb_set_intfdata(intf, hid);
hid->ll_driver = &usb_hid_driver;
+ hid->hid_get_raw_report = usbhid_get_raw_report;
hid->hid_output_raw_report = usbhid_output_raw_report;
hid->ff_init = hid_pidff_init;
#ifdef CONFIG_USB_HIDDEV
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index c24d2fa3e3b6..254a003af048 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -67,7 +67,7 @@ struct hiddev_list {
struct mutex thread_lock;
};
-static struct hiddev *hiddev_table[HIDDEV_MINORS];
+static struct usb_driver hiddev_driver;
/*
* Find a report, given the report's type and ID. The ID can be specified
@@ -265,22 +265,19 @@ static int hiddev_release(struct inode * inode, struct file * file)
static int hiddev_open(struct inode *inode, struct file *file)
{
struct hiddev_list *list;
- int res, i;
-
- /* See comment in hiddev_connect() for BKL explanation */
- lock_kernel();
- i = iminor(inode) - HIDDEV_MINOR_BASE;
+ struct usb_interface *intf;
+ struct hiddev *hiddev;
+ int res;
- if (i >= HIDDEV_MINORS || i < 0 || !hiddev_table[i])
+ intf = usb_find_interface(&hiddev_driver, iminor(inode));
+ if (!intf)
return -ENODEV;
+ hiddev = usb_get_intfdata(intf);
if (!(list = kzalloc(sizeof(struct hiddev_list), GFP_KERNEL)))
return -ENOMEM;
mutex_init(&list->thread_lock);
-
- list->hiddev = hiddev_table[i];
-
-
+ list->hiddev = hiddev;
file->private_data = list;
/*
@@ -289,7 +286,7 @@ static int hiddev_open(struct inode *inode, struct file *file)
*/
if (list->hiddev->exist) {
if (!list->hiddev->open++) {
- res = usbhid_open(hiddev_table[i]->hid);
+ res = usbhid_open(hiddev->hid);
if (res < 0) {
res = -EIO;
goto bail;
@@ -301,12 +298,12 @@ static int hiddev_open(struct inode *inode, struct file *file)
}
spin_lock_irq(&list->hiddev->list_lock);
- list_add_tail(&list->node, &hiddev_table[i]->list);
+ list_add_tail(&list->node, &hiddev->list);
spin_unlock_irq(&list->hiddev->list_lock);
if (!list->hiddev->open++)
if (list->hiddev->exist) {
- struct hid_device *hid = hiddev_table[i]->hid;
+ struct hid_device *hid = hiddev->hid;
res = usbhid_get_power(hid);
if (res < 0) {
res = -EIO;
@@ -314,13 +311,10 @@ static int hiddev_open(struct inode *inode, struct file *file)
}
usbhid_open(hid);
}
-
- unlock_kernel();
return 0;
bail:
file->private_data = NULL;
kfree(list);
- unlock_kernel();
return res;
}
@@ -894,37 +888,14 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hid->hiddev = hiddev;
hiddev->hid = hid;
hiddev->exist = 1;
-
- /*
- * BKL here is used to avoid race after usb_register_dev().
- * Once the device node has been created, open() could happen on it.
- * The code below will then fail, as hiddev_table hasn't been
- * updated.
- *
- * The obvious fix -- introducing mutex to guard hiddev_table[]
- * doesn't work, as usb_open() and usb_register_dev() both take
- * minor_rwsem, thus we'll have ABBA deadlock.
- *
- * Before BKL pushdown, usb_open() had been acquiring it in right
- * order, so _open() was safe to use it to protect from this race.
- * Now the order is different, but AB-BA deadlock still doesn't occur
- * as BKL is dropped on schedule() (i.e. while sleeping on
- * minor_rwsem). Fugly.
- */
- lock_kernel();
+ usb_set_intfdata(usbhid->intf, usbhid);
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
hid->hiddev = NULL;
- unlock_kernel();
kfree(hiddev);
return -1;
- } else {
- hid->minor = usbhid->intf->minor;
- hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
}
- unlock_kernel();
-
return 0;
}
@@ -942,7 +913,6 @@ void hiddev_disconnect(struct hid_device *hid)
hiddev->exist = 0;
mutex_unlock(&hiddev->existancelock);
- hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
usb_deregister_dev(usbhid->intf, &hiddev_class);
if (hiddev->open) {
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index e19cf8eb6ccf..2608e38470bf 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -761,6 +761,16 @@ config SENSORS_EMC1403
Threshold values can be configured using sysfs.
Data from the different diodes are accessible via sysfs.
+config SENSORS_EMC2103
+ tristate "SMSC EMC2103"
+ depends on I2C
+ help
+ If you say yes here you get support for the temperature
+ and fan sensors of the SMSC EMC2103 chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called emc2103.
+
config SENSORS_SMSC47M1
tristate "SMSC LPC47M10x and compatibles"
help
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2138ceb1a713..b8e7e6587202 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DME1737) += dme1737.o
obj-$(CONFIG_SENSORS_DS1621) += ds1621.o
obj-$(CONFIG_SENSORS_EMC1403) += emc1403.o
+obj-$(CONFIG_SENSORS_EMC2103) += emc2103.o
obj-$(CONFIG_SENSORS_F71805F) += f71805f.o
obj-$(CONFIG_SENSORS_F71882FG) += f71882fg.o
obj-$(CONFIG_SENSORS_F75375S) += f75375s.o
diff --git a/drivers/hwmon/asc7621.c b/drivers/hwmon/asc7621.c
index 3b973f30b1f6..89b4f3babe87 100644
--- a/drivers/hwmon/asc7621.c
+++ b/drivers/hwmon/asc7621.c
@@ -1150,9 +1150,6 @@ static int asc7621_detect(struct i2c_client *client,
{
struct i2c_adapter *adapter = client->adapter;
int company, verstep, chip_index;
- struct device *dev;
-
- dev = &client->dev;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
@@ -1169,13 +1166,11 @@ static int asc7621_detect(struct i2c_client *client,
if (company == asc7621_chips[chip_index].company_id &&
verstep == asc7621_chips[chip_index].verstep_id) {
- strlcpy(client->name, asc7621_chips[chip_index].name,
- I2C_NAME_SIZE);
strlcpy(info->type, asc7621_chips[chip_index].name,
I2C_NAME_SIZE);
- dev_info(&adapter->dev, "Matched %s\n",
- asc7621_chips[chip_index].name);
+ dev_info(&adapter->dev, "Matched %s at 0x%02x\n",
+ asc7621_chips[chip_index].name, client->addr);
return 0;
}
}
diff --git a/drivers/hwmon/emc1403.c b/drivers/hwmon/emc1403.c
index 0e4b5642638d..5b58b20dead1 100644
--- a/drivers/hwmon/emc1403.c
+++ b/drivers/hwmon/emc1403.c
@@ -89,6 +89,35 @@ static ssize_t store_temp(struct device *dev,
return count;
}
+static ssize_t store_bit(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct thermal_data *data = i2c_get_clientdata(client);
+ struct sensor_device_attribute_2 *sda = to_sensor_dev_attr_2(attr);
+ unsigned long val;
+ int retval;
+
+ if (strict_strtoul(buf, 10, &val))
+ return -EINVAL;
+
+ mutex_lock(&data->mutex);
+ retval = i2c_smbus_read_byte_data(client, sda->nr);
+ if (retval < 0)
+ goto fail;
+
+ retval &= ~sda->index;
+ if (val)
+ retval |= sda->index;
+
+ retval = i2c_smbus_write_byte_data(client, sda->index, retval);
+ if (retval == 0)
+ retval = count;
+fail:
+ mutex_unlock(&data->mutex);
+ return retval;
+}
+
static ssize_t show_hyst(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -200,6 +229,9 @@ static SENSOR_DEVICE_ATTR_2(temp3_crit_alarm, S_IRUGO,
static SENSOR_DEVICE_ATTR(temp3_crit_hyst, S_IRUGO | S_IWUSR,
show_hyst, store_hyst, 0x1A);
+static SENSOR_DEVICE_ATTR_2(power_state, S_IRUGO | S_IWUSR,
+ show_bit, store_bit, 0x03, 0x40);
+
static struct attribute *mid_att_thermal[] = {
&sensor_dev_attr_temp1_min.dev_attr.attr,
&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -225,6 +257,7 @@ static struct attribute *mid_att_thermal[] = {
&sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_crit_alarm.dev_attr.attr,
&sensor_dev_attr_temp3_crit_hyst.dev_attr.attr,
+ &sensor_dev_attr_power_state.dev_attr.attr,
NULL
};
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
new file mode 100644
index 000000000000..af914ad93ece
--- /dev/null
+++ b/drivers/hwmon/emc2103.c
@@ -0,0 +1,740 @@
+/*
+ emc2103.c - Support for SMSC EMC2103
+ Copyright (c) 2010 SMSC
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = { 0x2E, I2C_CLIENT_END };
+
+static const u8 REG_TEMP[4] = { 0x00, 0x02, 0x04, 0x06 };
+static const u8 REG_TEMP_MIN[4] = { 0x3c, 0x38, 0x39, 0x3a };
+static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 };
+
+#define REG_CONF1 0x20
+#define REG_TEMP_MAX_ALARM 0x24
+#define REG_TEMP_MIN_ALARM 0x25
+#define REG_FAN_CONF1 0x42
+#define REG_FAN_TARGET_LO 0x4c
+#define REG_FAN_TARGET_HI 0x4d
+#define REG_FAN_TACH_HI 0x4e
+#define REG_FAN_TACH_LO 0x4f
+#define REG_PRODUCT_ID 0xfd
+#define REG_MFG_ID 0xfe
+
+/* equation 4 from datasheet: rpm = (3932160 * multipler) / count */
+#define FAN_RPM_FACTOR 3932160
+
+/* 2103-2 and 2103-4's 3rd temperature sensor can be connected to two diodes
+ * in anti-parallel mode, and in this configuration both can be read
+ * independently (so we have 4 temperature inputs). The device can't
+ * detect if it's connected in this mode, so we have to manually enable
+ * 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_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode");
+
+struct temperature {
+ s8 degrees;
+ u8 fraction; /* 0-7 multiples of 0.125 */
+};
+
+struct emc2103_data {
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ bool valid; /* registers are valid */
+ bool fan_rpm_control;
+ int temp_count; /* num of temp sensors */
+ unsigned long last_updated; /* in jiffies */
+ struct temperature temp[4]; /* internal + 3 external */
+ s8 temp_min[4]; /* no fractional part */
+ s8 temp_max[4]; /* no fractional part */
+ u8 temp_min_alarm;
+ u8 temp_max_alarm;
+ u8 fan_multiplier;
+ u16 fan_tach;
+ u16 fan_target;
+};
+
+static int read_u8_from_i2c(struct i2c_client *client, u8 i2c_reg, u8 *output)
+{
+ int status = i2c_smbus_read_byte_data(client, i2c_reg);
+ if (status < 0) {
+ dev_warn(&client->dev, "reg 0x%02x, err %d\n",
+ i2c_reg, status);
+ } else {
+ *output = status;
+ }
+ return status;
+}
+
+static void read_temp_from_i2c(struct i2c_client *client, u8 i2c_reg,
+ struct temperature *temp)
+{
+ u8 degrees, fractional;
+
+ if (read_u8_from_i2c(client, i2c_reg, &degrees) < 0)
+ return;
+
+ if (read_u8_from_i2c(client, i2c_reg + 1, &fractional) < 0)
+ return;
+
+ temp->degrees = degrees;
+ temp->fraction = (fractional & 0xe0) >> 5;
+}
+
+static void read_fan_from_i2c(struct i2c_client *client, u16 *output,
+ u8 hi_addr, u8 lo_addr)
+{
+ u8 high_byte, lo_byte;
+
+ if (read_u8_from_i2c(client, hi_addr, &high_byte) < 0)
+ return;
+
+ if (read_u8_from_i2c(client, lo_addr, &lo_byte) < 0)
+ return;
+
+ *output = ((u16)high_byte << 5) | (lo_byte >> 3);
+}
+
+static void write_fan_target_to_i2c(struct i2c_client *client, u16 new_target)
+{
+ u8 high_byte = (new_target & 0x1fe0) >> 5;
+ u8 low_byte = (new_target & 0x001f) << 3;
+ i2c_smbus_write_byte_data(client, REG_FAN_TARGET_LO, low_byte);
+ i2c_smbus_write_byte_data(client, REG_FAN_TARGET_HI, high_byte);
+}
+
+static void read_fan_config_from_i2c(struct i2c_client *client)
+
+{
+ struct emc2103_data *data = i2c_get_clientdata(client);
+ u8 conf1;
+
+ if (read_u8_from_i2c(client, REG_FAN_CONF1, &conf1) < 0)
+ return;
+
+ data->fan_multiplier = 1 << ((conf1 & 0x60) >> 5);
+ data->fan_rpm_control = (conf1 & 0x80) != 0;
+}
+
+static struct emc2103_data *emc2103_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct emc2103_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+
+ for (i = 0; i < data->temp_count; i++) {
+ read_temp_from_i2c(client, REG_TEMP[i], &data->temp[i]);
+ read_u8_from_i2c(client, REG_TEMP_MIN[i],
+ &data->temp_min[i]);
+ read_u8_from_i2c(client, REG_TEMP_MAX[i],
+ &data->temp_max[i]);
+ }
+
+ read_u8_from_i2c(client, REG_TEMP_MIN_ALARM,
+ &data->temp_min_alarm);
+ read_u8_from_i2c(client, REG_TEMP_MAX_ALARM,
+ &data->temp_max_alarm);
+
+ read_fan_from_i2c(client, &data->fan_tach,
+ REG_FAN_TACH_HI, REG_FAN_TACH_LO);
+ read_fan_from_i2c(client, &data->fan_target,
+ REG_FAN_TARGET_HI, REG_FAN_TARGET_LO);
+ read_fan_config_from_i2c(client);
+
+ data->last_updated = jiffies;
+ data->valid = true;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static ssize_t
+show_temp(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int millidegrees = data->temp[nr].degrees * 1000
+ + data->temp[nr].fraction * 125;
+ return sprintf(buf, "%d\n", millidegrees);
+}
+
+static ssize_t
+show_temp_min(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int millidegrees = data->temp_min[nr] * 1000;
+ return sprintf(buf, "%d\n", millidegrees);
+}
+
+static ssize_t
+show_temp_max(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int millidegrees = data->temp_max[nr] * 1000;
+ return sprintf(buf, "%d\n", millidegrees);
+}
+
+static ssize_t
+show_temp_fault(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ bool fault = (data->temp[nr].degrees == -128);
+ return sprintf(buf, "%d\n", fault ? 1 : 0);
+}
+
+static ssize_t
+show_temp_min_alarm(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ bool alarm = data->temp_min_alarm & (1 << nr);
+ return sprintf(buf, "%d\n", alarm ? 1 : 0);
+}
+
+static ssize_t
+show_temp_max_alarm(struct device *dev, struct device_attribute *da, char *buf)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct emc2103_data *data = emc2103_update_device(dev);
+ bool alarm = data->temp_max_alarm & (1 << nr);
+ return sprintf(buf, "%d\n", alarm ? 1 : 0);
+}
+
+static ssize_t set_temp_min(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct emc2103_data *data = i2c_get_clientdata(client);
+ long val;
+
+ int result = strict_strtol(buf, 10, &val);
+ if (result < 0)
+ return -EINVAL;
+
+ val = DIV_ROUND_CLOSEST(val, 1000);
+ if ((val < -63) || (val > 127))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->temp_min[nr] = val;
+ i2c_smbus_write_byte_data(client, REG_TEMP_MIN[nr], val);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ int nr = to_sensor_dev_attr(da)->index;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct emc2103_data *data = i2c_get_clientdata(client);
+ long val;
+
+ int result = strict_strtol(buf, 10, &val);
+ if (result < 0)
+ return -EINVAL;
+
+ val = DIV_ROUND_CLOSEST(val, 1000);
+ if ((val < -63) || (val > 127))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ data->temp_max[nr] = val;
+ i2c_smbus_write_byte_data(client, REG_TEMP_MAX[nr], val);
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static ssize_t
+show_fan(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int rpm = 0;
+ if (data->fan_tach != 0)
+ rpm = (FAN_RPM_FACTOR * data->fan_multiplier) / data->fan_tach;
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t
+show_fan_div(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int fan_div = 8 / data->fan_multiplier;
+ return sprintf(buf, "%d\n", fan_div);
+}
+
+/* Note: we also update the fan target here, because its value is
+ determined in part by the fan clock divider. This follows the principle
+ of least surprise; the user doesn't expect the fan target to change just
+ because the divider changed. */
+static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ int new_range_bits, old_div = 8 / data->fan_multiplier;
+ long new_div;
+
+ int status = strict_strtol(buf, 10, &new_div);
+ if (status < 0)
+ return -EINVAL;
+
+ if (new_div == old_div) /* No change */
+ return count;
+
+ switch (new_div) {
+ case 1:
+ new_range_bits = 3;
+ break;
+ case 2:
+ new_range_bits = 2;
+ break;
+ case 4:
+ new_range_bits = 1;
+ break;
+ case 8:
+ new_range_bits = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ status = i2c_smbus_read_byte_data(client, REG_FAN_CONF1);
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg 0x%02x, err %d\n",
+ REG_FAN_CONF1, status);
+ mutex_unlock(&data->update_lock);
+ return -EIO;
+ }
+ status &= 0x9F;
+ status |= (new_range_bits << 5);
+ i2c_smbus_write_byte_data(client, REG_FAN_CONF1, status);
+
+ data->fan_multiplier = 8 / new_div;
+
+ /* update fan target if high byte is not disabled */
+ if ((data->fan_target & 0x1fe0) != 0x1fe0) {
+ u16 new_target = (data->fan_target * old_div) / new_div;
+ data->fan_target = min(new_target, (u16)0x1fff);
+ write_fan_target_to_i2c(client, data->fan_target);
+ }
+
+ /* invalidate data to force re-read from hardware */
+ data->valid = false;
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_fan_target(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ int rpm = 0;
+
+ /* high byte of 0xff indicates disabled so return 0 */
+ if ((data->fan_target != 0) && ((data->fan_target & 0x1fe0) != 0x1fe0))
+ rpm = (FAN_RPM_FACTOR * data->fan_multiplier)
+ / data->fan_target;
+
+ return sprintf(buf, "%d\n", rpm);
+}
+
+static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ struct i2c_client *client = to_i2c_client(dev);
+ long rpm_target;
+
+ int result = strict_strtol(buf, 10, &rpm_target);
+ if (result < 0)
+ return -EINVAL;
+
+ /* Datasheet states 16384 as maximum RPM target (table 3.2) */
+ if ((rpm_target < 0) || (rpm_target > 16384))
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+
+ if (rpm_target == 0)
+ data->fan_target = 0x1fff;
+ else
+ data->fan_target = SENSORS_LIMIT(
+ (FAN_RPM_FACTOR * data->fan_multiplier) / rpm_target,
+ 0, 0x1fff);
+
+ write_fan_target_to_i2c(client, data->fan_target);
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static ssize_t
+show_fan_fault(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ bool fault = ((data->fan_tach & 0x1fe0) == 0x1fe0);
+ return sprintf(buf, "%d\n", fault ? 1 : 0);
+}
+
+static ssize_t
+show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf)
+{
+ struct emc2103_data *data = emc2103_update_device(dev);
+ return sprintf(buf, "%d\n", data->fan_rpm_control ? 3 : 0);
+}
+
+static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct emc2103_data *data = i2c_get_clientdata(client);
+ long new_value;
+ u8 conf_reg;
+
+ int result = strict_strtol(buf, 10, &new_value);
+ if (result < 0)
+ return -EINVAL;
+
+ mutex_lock(&data->update_lock);
+ switch (new_value) {
+ case 0:
+ data->fan_rpm_control = false;
+ break;
+ case 3:
+ data->fan_rpm_control = true;
+ break;
+ default:
+ mutex_unlock(&data->update_lock);
+ return -EINVAL;
+ }
+
+ read_u8_from_i2c(client, REG_FAN_CONF1, &conf_reg);
+
+ if (data->fan_rpm_control)
+ conf_reg |= 0x80;
+ else
+ conf_reg &= ~0x80;
+
+ i2c_smbus_write_byte_data(client, REG_FAN_CONF1, conf_reg);
+
+ mutex_unlock(&data->update_lock);
+ return count;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, show_temp_min,
+ set_temp_min, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp_max,
+ set_temp_max, 0);
+static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, show_temp_fault, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_temp_min_alarm,
+ NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_temp_max_alarm,
+ NULL, 0);
+
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, show_temp_min,
+ set_temp_min, 1);
+static SENSOR_DEVICE_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
+ set_temp_max, 1);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_temp_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_temp_min_alarm,
+ NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_temp_max_alarm,
+ NULL, 1);
+
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_min, S_IRUGO | S_IWUSR, show_temp_min,
+ set_temp_min, 2);
+static SENSOR_DEVICE_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
+ set_temp_max, 2);
+static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_temp_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_min_alarm, S_IRUGO, show_temp_min_alarm,
+ NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_max_alarm, S_IRUGO, show_temp_max_alarm,
+ NULL, 2);
+
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_min, S_IRUGO | S_IWUSR, show_temp_min,
+ set_temp_min, 3);
+static SENSOR_DEVICE_ATTR(temp4_max, S_IRUGO | S_IWUSR, show_temp_max,
+ set_temp_max, 3);
+static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_temp_fault, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_min_alarm, S_IRUGO, show_temp_min_alarm,
+ NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_max_alarm, S_IRUGO, show_temp_max_alarm,
+ NULL, 3);
+
+static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
+static DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR, show_fan_div, set_fan_div);
+static DEVICE_ATTR(fan1_target, S_IRUGO | S_IWUSR, show_fan_target,
+ set_fan_target);
+static DEVICE_ATTR(fan1_fault, S_IRUGO, show_fan_fault, NULL);
+
+static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable,
+ set_pwm_enable);
+
+/* sensors present on all models */
+static struct attribute *emc2103_attributes[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ &sensor_dev_attr_temp1_min.dev_attr.attr,
+ &sensor_dev_attr_temp1_max.dev_attr.attr,
+ &sensor_dev_attr_temp1_fault.dev_attr.attr,
+ &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_input.dev_attr.attr,
+ &sensor_dev_attr_temp2_min.dev_attr.attr,
+ &sensor_dev_attr_temp2_max.dev_attr.attr,
+ &sensor_dev_attr_temp2_fault.dev_attr.attr,
+ &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+ &dev_attr_fan1_input.attr,
+ &dev_attr_fan1_div.attr,
+ &dev_attr_fan1_target.attr,
+ &dev_attr_fan1_fault.attr,
+ &dev_attr_pwm1_enable.attr,
+ NULL
+};
+
+/* extra temperature sensors only present on 2103-2 and 2103-4 */
+static struct attribute *emc2103_attributes_temp3[] = {
+ &sensor_dev_attr_temp3_input.dev_attr.attr,
+ &sensor_dev_attr_temp3_min.dev_attr.attr,
+ &sensor_dev_attr_temp3_max.dev_attr.attr,
+ &sensor_dev_attr_temp3_fault.dev_attr.attr,
+ &sensor_dev_attr_temp3_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp3_max_alarm.dev_attr.attr,
+ NULL
+};
+
+/* extra temperature sensors only present on 2103-2 and 2103-4 in APD mode */
+static struct attribute *emc2103_attributes_temp4[] = {
+ &sensor_dev_attr_temp4_input.dev_attr.attr,
+ &sensor_dev_attr_temp4_min.dev_attr.attr,
+ &sensor_dev_attr_temp4_max.dev_attr.attr,
+ &sensor_dev_attr_temp4_fault.dev_attr.attr,
+ &sensor_dev_attr_temp4_min_alarm.dev_attr.attr,
+ &sensor_dev_attr_temp4_max_alarm.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group emc2103_group = {
+ .attrs = emc2103_attributes,
+};
+
+static const struct attribute_group emc2103_temp3_group = {
+ .attrs = emc2103_attributes_temp3,
+};
+
+static const struct attribute_group emc2103_temp4_group = {
+ .attrs = emc2103_attributes_temp4,
+};
+
+static int
+emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct emc2103_data *data;
+ int status;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct emc2103_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ /* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */
+ status = i2c_smbus_read_byte_data(client, REG_PRODUCT_ID);
+ if (status == 0x24) {
+ /* 2103-1 only has 1 external diode */
+ data->temp_count = 2;
+ } else {
+ /* 2103-2 and 2103-4 have 3 or 4 external diodes */
+ status = i2c_smbus_read_byte_data(client, REG_CONF1);
+ if (status < 0) {
+ dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1,
+ status);
+ goto exit_free;
+ }
+
+ /* detect current state of hardware */
+ data->temp_count = (status & 0x01) ? 4 : 3;
+
+ /* force APD state if module parameter is set */
+ if (apd == 0) {
+ /* force APD mode off */
+ data->temp_count = 3;
+ status &= ~(0x01);
+ i2c_smbus_write_byte_data(client, REG_CONF1, status);
+ } else if (apd == 1) {
+ /* force APD mode on */
+ data->temp_count = 4;
+ status |= 0x01;
+ i2c_smbus_write_byte_data(client, REG_CONF1, status);
+ }
+ }
+
+ /* Register sysfs hooks */
+ status = sysfs_create_group(&client->dev.kobj, &emc2103_group);
+ if (status)
+ goto exit_free;
+
+ if (data->temp_count >= 3) {
+ status = sysfs_create_group(&client->dev.kobj,
+ &emc2103_temp3_group);
+ if (status)
+ goto exit_remove;
+ }
+
+ if (data->temp_count == 4) {
+ status = sysfs_create_group(&client->dev.kobj,
+ &emc2103_temp4_group);
+ if (status)
+ goto exit_remove_temp3;
+ }
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ status = PTR_ERR(data->hwmon_dev);
+ goto exit_remove_temp4;
+ }
+
+ dev_info(&client->dev, "%s: sensor '%s'\n",
+ dev_name(data->hwmon_dev), client->name);
+
+ return 0;
+
+exit_remove_temp4:
+ if (data->temp_count == 4)
+ sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
+exit_remove_temp3:
+ if (data->temp_count >= 3)
+ sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
+exit_remove:
+ sysfs_remove_group(&client->dev.kobj, &emc2103_group);
+exit_free:
+ kfree(data);
+ return status;
+}
+
+static int emc2103_remove(struct i2c_client *client)
+{
+ struct emc2103_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+
+ if (data->temp_count == 4)
+ sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
+
+ if (data->temp_count >= 3)
+ sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
+
+ sysfs_remove_group(&client->dev.kobj, &emc2103_group);
+
+ kfree(data);
+ return 0;
+}
+
+static const struct i2c_device_id emc2103_ids[] = {
+ { "emc2103", 0, },
+ { /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, emc2103_ids);
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int
+emc2103_detect(struct i2c_client *new_client, struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = new_client->adapter;
+ int manufacturer, product;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ manufacturer = i2c_smbus_read_byte_data(new_client, REG_MFG_ID);
+ if (manufacturer != 0x5D)
+ return -ENODEV;
+
+ product = i2c_smbus_read_byte_data(new_client, REG_PRODUCT_ID);
+ if ((product != 0x24) && (product != 0x26))
+ return -ENODEV;
+
+ strlcpy(info->type, "emc2103", I2C_NAME_SIZE);
+
+ return 0;
+}
+
+static struct i2c_driver emc2103_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "emc2103",
+ },
+ .probe = emc2103_probe,
+ .remove = emc2103_remove,
+ .id_table = emc2103_ids,
+ .detect = emc2103_detect,
+ .address_list = normal_i2c,
+};
+
+static int __init sensors_emc2103_init(void)
+{
+ return i2c_add_driver(&emc2103_driver);
+}
+
+static void __exit sensors_emc2103_exit(void)
+{
+ i2c_del_driver(&emc2103_driver);
+}
+
+MODULE_AUTHOR("Steve Glendinning <steve.glendinning@smsc.com>");
+MODULE_DESCRIPTION("SMSC EMC2103 hwmon driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_emc2103_init);
+module_exit(sensors_emc2103_exit);
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 25763d2223b6..f7701295937d 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -259,6 +259,7 @@ struct it87_sio_data {
u8 revision;
u8 vid_value;
u8 beep_pin;
+ u8 internal; /* Internal sensors can be labeled */
/* Features skipped based on config or DMI */
u8 skip_vid;
u8 skip_fan;
@@ -1194,6 +1195,22 @@ static ssize_t show_vid_reg(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);
+static ssize_t show_label(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ static const char *labels[] = {
+ "+5V",
+ "5VSB",
+ "Vbat",
+ };
+ int nr = to_sensor_dev_attr(attr)->index;
+
+ return sprintf(buf, "%s\n", labels[nr]);
+}
+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_label, NULL, 2);
+
static ssize_t show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@@ -1434,6 +1451,17 @@ static const struct attribute_group it87_group_vid = {
.attrs = it87_attributes_vid,
};
+static struct attribute *it87_attributes_label[] = {
+ &sensor_dev_attr_in3_label.dev_attr.attr,
+ &sensor_dev_attr_in7_label.dev_attr.attr,
+ &sensor_dev_attr_in8_label.dev_attr.attr,
+ NULL
+};
+
+static const struct attribute_group it87_group_label = {
+ .attrs = it87_attributes_vid,
+};
+
/* SuperIO detection - will change isa_address if a chip is found */
static int __init it87_find(unsigned short *address,
struct it87_sio_data *sio_data)
@@ -1487,6 +1515,9 @@ static int __init it87_find(unsigned short *address,
pr_info("it87: Found IT%04xF chip at 0x%x, revision %d\n",
chip_type, *address, sio_data->revision);
+ /* in8 (Vbat) is always internal */
+ sio_data->internal = (1 << 2);
+
/* Read GPIO config and VID value from LDN 7 (GPIO) */
if (sio_data->type == it87) {
/* The IT8705F doesn't have VID pins at all */
@@ -1540,9 +1571,9 @@ static int __init it87_find(unsigned short *address,
pr_notice("it87: Routing internal VCCH to in7\n");
}
if (reg & (1 << 0))
- pr_info("it87: in3 is VCC (+5V)\n");
+ sio_data->internal |= (1 << 0);
if (reg & (1 << 1))
- pr_info("it87: in7 is VCCH (+5V Stand-By)\n");
+ sio_data->internal |= (1 << 1);
sio_data->beep_pin = superio_inb(IT87_SIO_BEEP_PIN_REG) & 0x3f;
}
@@ -1600,6 +1631,7 @@ static void it87_remove_files(struct device *dev)
}
if (!sio_data->skip_vid)
sysfs_remove_group(&dev->kobj, &it87_group_vid);
+ sysfs_remove_group(&dev->kobj, &it87_group_label);
}
static int __devinit it87_probe(struct platform_device *pdev)
@@ -1725,6 +1757,16 @@ static int __devinit it87_probe(struct platform_device *pdev)
goto ERROR4;
}
+ /* Export labels for internal sensors */
+ for (i = 0; i < 3; i++) {
+ if (!(sio_data->internal & (1 << i)))
+ continue;
+ err = sysfs_create_file(&dev->kobj,
+ it87_attributes_label[i]);
+ if (err)
+ goto ERROR4;
+ }
+
data->hwmon_dev = hwmon_device_register(dev);
if (IS_ERR(data->hwmon_dev)) {
err = PTR_ERR(data->hwmon_dev);
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c
index 393f354f92a4..ab5b87a81677 100644
--- a/drivers/hwmon/lm75.c
+++ b/drivers/hwmon/lm75.c
@@ -280,10 +280,49 @@ static int lm75_detect(struct i2c_client *new_client,
return 0;
}
+#ifdef CONFIG_PM
+static int lm75_suspend(struct device *dev)
+{
+ int status;
+ struct i2c_client *client = to_i2c_client(dev);
+ status = lm75_read_value(client, LM75_REG_CONF);
+ if (status < 0) {
+ dev_dbg(&client->dev, "Can't read config? %d\n", status);
+ return status;
+ }
+ status = status | LM75_SHUTDOWN;
+ lm75_write_value(client, LM75_REG_CONF, status);
+ return 0;
+}
+
+static int lm75_resume(struct device *dev)
+{
+ int status;
+ struct i2c_client *client = to_i2c_client(dev);
+ status = lm75_read_value(client, LM75_REG_CONF);
+ if (status < 0) {
+ dev_dbg(&client->dev, "Can't read config? %d\n", status);
+ return status;
+ }
+ status = status & ~LM75_SHUTDOWN;
+ lm75_write_value(client, LM75_REG_CONF, status);
+ return 0;
+}
+
+static const struct dev_pm_ops lm75_dev_pm_ops = {
+ .suspend = lm75_suspend,
+ .resume = lm75_resume,
+};
+#define LM75_DEV_PM_OPS (&lm75_dev_pm_ops)
+#else
+#define LM75_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
static struct i2c_driver lm75_driver = {
.class = I2C_CLASS_HWMON,
.driver = {
.name = "lm75",
+ .pm = LM75_DEV_PM_OPS,
},
.probe = lm75_probe,
.remove = lm75_remove,
diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h
index 7c93454bb4e3..e547a3eb4de3 100644
--- a/drivers/hwmon/lm75.h
+++ b/drivers/hwmon/lm75.h
@@ -30,6 +30,7 @@
/* straight from the datasheet */
#define LM75_TEMP_MIN (-55000)
#define LM75_TEMP_MAX 125000
+#define LM75_SHUTDOWN 0x01
/* TEMP: 0.001C/bit (-55C to +125C)
REG: (0.5C/bit, two's complement) << 7 */
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c
index 21d201befc2c..659308329308 100644
--- a/drivers/hwmon/ltc4245.c
+++ b/drivers/hwmon/ltc4245.c
@@ -21,6 +21,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
+#include <linux/i2c/ltc4245.h>
/* Here are names of the chip's registers (a.k.a. commands) */
enum ltc4245_cmd {
@@ -60,8 +61,72 @@ struct ltc4245_data {
/* Voltage registers */
u8 vregs[0x0d];
+
+ /* GPIO ADC registers */
+ bool use_extra_gpios;
+ int gpios[3];
};
+/*
+ * Update the readings from the GPIO pins. If the driver has been configured to
+ * sample all GPIO's as analog voltages, a round-robin sampling method is used.
+ * Otherwise, only the configured GPIO pin is sampled.
+ *
+ * LOCKING: must hold data->update_lock
+ */
+static void ltc4245_update_gpios(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ltc4245_data *data = i2c_get_clientdata(client);
+ u8 gpio_curr, gpio_next, gpio_reg;
+ int i;
+
+ /* no extra gpio support, we're basically done */
+ if (!data->use_extra_gpios) {
+ data->gpios[0] = data->vregs[LTC4245_GPIOADC - 0x10];
+ return;
+ }
+
+ /*
+ * If the last reading was too long ago, then we mark all old GPIO
+ * readings as stale by setting them to -EAGAIN
+ */
+ if (time_after(jiffies, data->last_updated + 5 * HZ)) {
+ dev_dbg(&client->dev, "Marking GPIOs invalid\n");
+ for (i = 0; i < ARRAY_SIZE(data->gpios); i++)
+ data->gpios[i] = -EAGAIN;
+ }
+
+ /*
+ * Get the current GPIO pin
+ *
+ * The datasheet calls these GPIO[1-3], but we'll calculate the zero
+ * based array index instead, and call them GPIO[0-2]. This is much
+ * easier to think about.
+ */
+ gpio_curr = (data->cregs[LTC4245_GPIO] & 0xc0) >> 6;
+ if (gpio_curr > 0)
+ gpio_curr -= 1;
+
+ /* Read the GPIO voltage from the GPIOADC register */
+ data->gpios[gpio_curr] = data->vregs[LTC4245_GPIOADC - 0x10];
+
+ /* Find the next GPIO pin to read */
+ gpio_next = (gpio_curr + 1) % ARRAY_SIZE(data->gpios);
+
+ /*
+ * Calculate the correct setting for the GPIO register so it will
+ * sample the next GPIO pin
+ */
+ gpio_reg = (data->cregs[LTC4245_GPIO] & 0x3f) | ((gpio_next + 1) << 6);
+
+ /* Update the GPIO register */
+ i2c_smbus_write_byte_data(client, LTC4245_GPIO, gpio_reg);
+
+ /* Update saved data */
+ data->cregs[LTC4245_GPIO] = gpio_reg;
+}
+
static struct ltc4245_data *ltc4245_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -93,6 +158,9 @@ static struct ltc4245_data *ltc4245_update_device(struct device *dev)
data->vregs[i] = val;
}
+ /* Update GPIO readings */
+ ltc4245_update_gpios(dev);
+
data->last_updated = jiffies;
data->valid = 1;
}
@@ -233,6 +301,22 @@ static ssize_t ltc4245_show_alarm(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
}
+static ssize_t ltc4245_show_gpio(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ struct ltc4245_data *data = ltc4245_update_device(dev);
+ int val = data->gpios[attr->index];
+
+ /* handle stale GPIO's */
+ if (val < 0)
+ return val;
+
+ /* Convert to millivolts and print */
+ return snprintf(buf, PAGE_SIZE, "%u\n", val * 10);
+}
+
/* These macros are used below in constructing device attribute objects
* for use with sysfs_create_group() to make a sysfs device file
* for each register.
@@ -254,6 +338,10 @@ static ssize_t ltc4245_show_alarm(struct device *dev,
static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
ltc4245_show_alarm, NULL, (mask), reg)
+#define LTC4245_GPIO_VOLTAGE(name, gpio_num) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4245_show_gpio, NULL, gpio_num)
+
/* Construct a sensor_device_attribute structure for each register */
/* Input voltages */
@@ -293,7 +381,9 @@ LTC4245_ALARM(in7_min_alarm, (1 << 2), LTC4245_FAULT2);
LTC4245_ALARM(in8_min_alarm, (1 << 3), LTC4245_FAULT2);
/* GPIO voltages */
-LTC4245_VOLTAGE(in9_input, LTC4245_GPIOADC);
+LTC4245_GPIO_VOLTAGE(in9_input, 0);
+LTC4245_GPIO_VOLTAGE(in10_input, 1);
+LTC4245_GPIO_VOLTAGE(in11_input, 2);
/* Power Consumption (virtual) */
LTC4245_POWER(power1_input, LTC4245_12VSENSE);
@@ -304,7 +394,7 @@ LTC4245_POWER(power4_input, LTC4245_VEESENSE);
/* Finally, construct an array of pointers to members of the above objects,
* as required for sysfs_create_group()
*/
-static struct attribute *ltc4245_attributes[] = {
+static struct attribute *ltc4245_std_attributes[] = {
&sensor_dev_attr_in1_input.dev_attr.attr,
&sensor_dev_attr_in2_input.dev_attr.attr,
&sensor_dev_attr_in3_input.dev_attr.attr,
@@ -345,10 +435,77 @@ static struct attribute *ltc4245_attributes[] = {
NULL,
};
-static const struct attribute_group ltc4245_group = {
- .attrs = ltc4245_attributes,
+static struct attribute *ltc4245_gpio_attributes[] = {
+ &sensor_dev_attr_in10_input.dev_attr.attr,
+ &sensor_dev_attr_in11_input.dev_attr.attr,
+ NULL,
+};
+
+static const struct attribute_group ltc4245_std_group = {
+ .attrs = ltc4245_std_attributes,
+};
+
+static const struct attribute_group ltc4245_gpio_group = {
+ .attrs = ltc4245_gpio_attributes,
};
+static int ltc4245_sysfs_create_groups(struct i2c_client *client)
+{
+ struct ltc4245_data *data = i2c_get_clientdata(client);
+ struct device *dev = &client->dev;
+ int ret;
+
+ /* register the standard sysfs attributes */
+ ret = sysfs_create_group(&dev->kobj, &ltc4245_std_group);
+ if (ret) {
+ dev_err(dev, "unable to register standard attributes\n");
+ return ret;
+ }
+
+ /* if we're using the extra gpio support, register it's attributes */
+ if (data->use_extra_gpios) {
+ ret = sysfs_create_group(&dev->kobj, &ltc4245_gpio_group);
+ if (ret) {
+ dev_err(dev, "unable to register gpio attributes\n");
+ sysfs_remove_group(&dev->kobj, &ltc4245_std_group);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void ltc4245_sysfs_remove_groups(struct i2c_client *client)
+{
+ struct ltc4245_data *data = i2c_get_clientdata(client);
+ struct device *dev = &client->dev;
+
+ if (data->use_extra_gpios)
+ sysfs_remove_group(&dev->kobj, &ltc4245_gpio_group);
+
+ sysfs_remove_group(&dev->kobj, &ltc4245_std_group);
+}
+
+static bool ltc4245_use_extra_gpios(struct i2c_client *client)
+{
+ struct ltc4245_platform_data *pdata = dev_get_platdata(&client->dev);
+#ifdef CONFIG_OF
+ struct device_node *np = client->dev.of_node;
+#endif
+
+ /* prefer platform data */
+ if (pdata)
+ return pdata->use_extra_gpios;
+
+#ifdef CONFIG_OF
+ /* fallback on OF */
+ if (of_find_property(np, "ltc4245,use-extra-gpios", NULL))
+ return true;
+#endif
+
+ return false;
+}
+
static int ltc4245_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
@@ -367,15 +524,16 @@ static int ltc4245_probe(struct i2c_client *client,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
+ data->use_extra_gpios = ltc4245_use_extra_gpios(client);
/* Initialize the LTC4245 chip */
i2c_smbus_write_byte_data(client, LTC4245_FAULT1, 0x00);
i2c_smbus_write_byte_data(client, LTC4245_FAULT2, 0x00);
/* Register sysfs hooks */
- ret = sysfs_create_group(&client->dev.kobj, &ltc4245_group);
+ ret = ltc4245_sysfs_create_groups(client);
if (ret)
- goto out_sysfs_create_group;
+ goto out_sysfs_create_groups;
data->hwmon_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->hwmon_dev)) {
@@ -386,8 +544,8 @@ static int ltc4245_probe(struct i2c_client *client,
return 0;
out_hwmon_device_register:
- sysfs_remove_group(&client->dev.kobj, &ltc4245_group);
-out_sysfs_create_group:
+ ltc4245_sysfs_remove_groups(client);
+out_sysfs_create_groups:
kfree(data);
out_kzalloc:
return ret;
@@ -398,8 +556,7 @@ static int ltc4245_remove(struct i2c_client *client)
struct ltc4245_data *data = i2c_get_clientdata(client);
hwmon_device_unregister(data->hwmon_dev);
- sysfs_remove_group(&client->dev.kobj, &ltc4245_group);
-
+ ltc4245_sysfs_remove_groups(client);
kfree(data);
return 0;
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index 4a64b85d4ec9..20d63f7872aa 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -1610,11 +1610,8 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
static int __init pc87360_device_add(unsigned short address)
{
- struct resource res = {
- .name = "pc87360",
- .flags = IORESOURCE_IO,
- };
- int err, i;
+ struct resource res[3];
+ int err, i, res_count;
pdev = platform_device_alloc("pc87360", address);
if (!pdev) {
@@ -1623,22 +1620,27 @@ static int __init pc87360_device_add(unsigned short address)
goto exit;
}
+ memset(res, 0, 3 * sizeof(struct resource));
for (i = 0; i < 3; i++) {
if (!extra_isa[i])
continue;
- res.start = extra_isa[i];
- res.end = extra_isa[i] + PC87360_EXTENT - 1;
+ res[res_count].start = extra_isa[i];
+ res[res_count].end = extra_isa[i] + PC87360_EXTENT - 1;
+ res[res_count].name = "pc87360",
+ res[res_count].flags = IORESOURCE_IO,
- err = acpi_check_resource_conflict(&res);
+ err = acpi_check_resource_conflict(&res[res_count]);
if (err)
goto exit_device_put;
- err = platform_device_add_resources(pdev, &res, 1);
- if (err) {
- printk(KERN_ERR "pc87360: Device resource[%d] "
- "addition failed (%d)\n", i, err);
- goto exit_device_put;
- }
+ res_count++;
+ }
+
+ err = platform_device_add_resources(pdev, res, res_count);
+ if (err) {
+ printk(KERN_ERR "pc87360: Device resources addition failed "
+ "(%d)\n", err);
+ goto exit_device_put;
}
err = platform_device_add(pdev);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 0dcaba9b7189..e96e69dd36fb 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -39,6 +39,7 @@
w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
w83627dhg-p 9 5 4 3 0xb070 0xc1 0x5ca3
w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
+ w83667hg-b 9 5 3 3 0xb350 0xc1 0x5ca3
*/
#include <linux/module.h>
@@ -55,7 +56,7 @@
#include <linux/io.h>
#include "lm75.h"
-enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
+enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg, w83667hg_b };
/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
static const char * w83627ehf_device_names[] = {
@@ -63,6 +64,7 @@ static const char * w83627ehf_device_names[] = {
"w83627dhg",
"w83627dhg",
"w83667hg",
+ "w83667hg",
};
static unsigned short force_id;
@@ -91,6 +93,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
#define SIO_W83627DHG_ID 0xa020
#define SIO_W83627DHG_P_ID 0xb070
#define SIO_W83667HG_ID 0xa510
+#define SIO_W83667HG_B_ID 0xb350
#define SIO_ID_MASK 0xFFF0
static inline void
@@ -201,8 +204,14 @@ static const u8 W83627EHF_REG_TOLERANCE[] = { 0x07, 0x07, 0x14, 0x62 };
static const u8 W83627EHF_REG_FAN_START_OUTPUT[] = { 0x0a, 0x0b, 0x16, 0x65 };
static const u8 W83627EHF_REG_FAN_STOP_OUTPUT[] = { 0x08, 0x09, 0x15, 0x64 };
static const u8 W83627EHF_REG_FAN_STOP_TIME[] = { 0x0c, 0x0d, 0x17, 0x66 };
-static const u8 W83627EHF_REG_FAN_MAX_OUTPUT[] = { 0xff, 0x67, 0xff, 0x69 };
-static const u8 W83627EHF_REG_FAN_STEP_OUTPUT[] = { 0xff, 0x68, 0xff, 0x6a };
+
+static const u8 W83627EHF_REG_FAN_MAX_OUTPUT_COMMON[]
+ = { 0xff, 0x67, 0xff, 0x69 };
+static const u8 W83627EHF_REG_FAN_STEP_OUTPUT_COMMON[]
+ = { 0xff, 0x68, 0xff, 0x6a };
+
+static const u8 W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B[] = { 0x67, 0x69, 0x6b };
+static const u8 W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B[] = { 0x68, 0x6a, 0x6c };
/*
* Conversions
@@ -277,6 +286,11 @@ struct w83627ehf_data {
struct device *hwmon_dev;
struct mutex lock;
+ const u8 *REG_FAN_START_OUTPUT;
+ const u8 *REG_FAN_STOP_OUTPUT;
+ const u8 *REG_FAN_MAX_OUTPUT;
+ const u8 *REG_FAN_STEP_OUTPUT;
+
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@@ -524,7 +538,10 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
}
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < data->pwm_num; i++) {
+ if (!(data->has_fan & (1 << i)))
+ continue;
+
/* pwmcfg, tolerance mapped for i=0, i=1 to same reg */
if (i != 1) {
pwmcfg = w83627ehf_read_value(data,
@@ -546,6 +563,17 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
W83627EHF_REG_FAN_STOP_OUTPUT[i]);
data->fan_stop_time[i] = w83627ehf_read_value(data,
W83627EHF_REG_FAN_STOP_TIME[i]);
+
+ if (data->REG_FAN_MAX_OUTPUT[i] != 0xff)
+ data->fan_max_output[i] =
+ w83627ehf_read_value(data,
+ data->REG_FAN_MAX_OUTPUT[i]);
+
+ if (data->REG_FAN_STEP_OUTPUT[i] != 0xff)
+ data->fan_step_output[i] =
+ w83627ehf_read_value(data,
+ data->REG_FAN_STEP_OUTPUT[i]);
+
data->target_temp[i] =
w83627ehf_read_value(data,
W83627EHF_REG_TARGET[i]) &
@@ -1126,7 +1154,7 @@ store_##reg(struct device *dev, struct device_attribute *attr, \
u32 val = SENSORS_LIMIT(simple_strtoul(buf, NULL, 10), 1, 255); \
mutex_lock(&data->update_lock); \
data->reg[nr] = val; \
- w83627ehf_write_value(data, W83627EHF_REG_##REG[nr], val); \
+ w83627ehf_write_value(data, data->REG_##REG[nr], val); \
mutex_unlock(&data->update_lock); \
return count; \
}
@@ -1206,12 +1234,26 @@ static struct sensor_device_attribute sda_sf3_arrays[] = {
store_fan_stop_output, 1),
SENSOR_ATTR(pwm3_stop_output, S_IWUSR | S_IRUGO, show_fan_stop_output,
store_fan_stop_output, 2),
+};
- /* pwm1 and pwm3 don't support max and step settings */
+
+/*
+ * pwm1 and pwm3 don't support max and step settings on all chips.
+ * Need to check support while generating/removing attribute files.
+ */
+static struct sensor_device_attribute sda_sf3_max_step_arrays[] = {
+ SENSOR_ATTR(pwm1_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
+ store_fan_max_output, 0),
+ SENSOR_ATTR(pwm1_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
+ store_fan_step_output, 0),
SENSOR_ATTR(pwm2_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
store_fan_max_output, 1),
SENSOR_ATTR(pwm2_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
store_fan_step_output, 1),
+ SENSOR_ATTR(pwm3_max_output, S_IWUSR | S_IRUGO, show_fan_max_output,
+ store_fan_max_output, 2),
+ SENSOR_ATTR(pwm3_step_output, S_IWUSR | S_IRUGO, show_fan_step_output,
+ store_fan_step_output, 2),
};
static ssize_t
@@ -1235,6 +1277,12 @@ static void w83627ehf_device_remove_files(struct device *dev)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++)
device_remove_file(dev, &sda_sf3_arrays[i].dev_attr);
+ for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) {
+ struct sensor_device_attribute *attr =
+ &sda_sf3_max_step_arrays[i];
+ if (data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff)
+ device_remove_file(dev, &attr->dev_attr);
+ }
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
for (i = 0; i < data->in_num; i++) {
@@ -1343,22 +1391,37 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
/* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
/* 667HG has 3 pwms */
- data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
+ data->pwm_num = (sio_data->kind == w83667hg
+ || sio_data->kind == w83667hg_b) ? 3 : 4;
/* Check temp3 configuration bit for 667HG */
- if (sio_data->kind == w83667hg) {
+ if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
data->temp3_disable = w83627ehf_read_value(data,
W83627EHF_REG_TEMP_CONFIG[1]) & 0x01;
data->in6_skip = !data->temp3_disable;
}
+ data->REG_FAN_START_OUTPUT = W83627EHF_REG_FAN_START_OUTPUT;
+ data->REG_FAN_STOP_OUTPUT = W83627EHF_REG_FAN_STOP_OUTPUT;
+ if (sio_data->kind == w83667hg_b) {
+ data->REG_FAN_MAX_OUTPUT =
+ W83627EHF_REG_FAN_MAX_OUTPUT_W83667_B;
+ data->REG_FAN_STEP_OUTPUT =
+ W83627EHF_REG_FAN_STEP_OUTPUT_W83667_B;
+ } else {
+ data->REG_FAN_MAX_OUTPUT =
+ W83627EHF_REG_FAN_MAX_OUTPUT_COMMON;
+ data->REG_FAN_STEP_OUTPUT =
+ W83627EHF_REG_FAN_STEP_OUTPUT_COMMON;
+ }
+
/* Initialize the chip */
w83627ehf_init_device(data);
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
/* Read VID value */
- if (sio_data->kind == w83667hg) {
+ if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
/* W83667HG has different pins for VID input and output, so
we can get the VID input values directly at logical device D
0xe3. */
@@ -1409,7 +1472,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
}
/* fan4 and fan5 share some pins with the GPIO and serial flash */
- if (sio_data->kind == w83667hg) {
+ if (sio_data->kind == w83667hg || sio_data->kind == w83667hg_b) {
fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
} else {
@@ -1440,6 +1503,15 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
&sda_sf3_arrays[i].dev_attr)))
goto exit_remove;
+ for (i = 0; i < ARRAY_SIZE(sda_sf3_max_step_arrays); i++) {
+ struct sensor_device_attribute *attr =
+ &sda_sf3_max_step_arrays[i];
+ if (data->REG_FAN_STEP_OUTPUT[attr->index] != 0xff) {
+ err = device_create_file(dev, &attr->dev_attr);
+ if (err)
+ goto exit_remove;
+ }
+ }
/* if fan4 is enabled create the sf3 files for it */
if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
@@ -1556,6 +1628,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
static const char __initdata sio_name_W83627DHG_P[] = "W83627DHG-P";
static const char __initdata sio_name_W83667HG[] = "W83667HG";
+ static const char __initdata sio_name_W83667HG_B[] = "W83667HG-B";
u16 val;
const char *sio_name;
@@ -1588,6 +1661,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
sio_data->kind = w83667hg;
sio_name = sio_name_W83667HG;
break;
+ case SIO_W83667HG_B_ID:
+ sio_data->kind = w83667hg_b;
+ sio_name = sio_name_W83667HG_B;
+ break;
default:
if (val != 0xffff)
pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index bceafbfa7268..29e01f6238a7 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -549,7 +549,7 @@ config I2C_SH7760
config I2C_SH_MOBILE
tristate "SuperH Mobile I2C Controller"
- depends on SUPERH
+ depends on SUPERH || ARCH_SHMOBILE
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Renesas SH-Mobile processor.
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index ffb405d7c6f2..598c49acaeb5 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data {
struct i2c_adapter adap;
struct clk *clk;
+ u_int8_t icic;
u_int8_t iccl;
u_int8_t icch;
+ u_int8_t flags;
spinlock_t lock;
wait_queue_head_t wait;
@@ -129,15 +131,17 @@ struct sh_mobile_i2c_data {
int sr;
};
+#define IIC_FLAG_HAS_ICIC67 (1 << 0)
+
#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
/* Register offsets */
-#define ICDR(pd) (pd->reg + 0x00)
-#define ICCR(pd) (pd->reg + 0x04)
-#define ICSR(pd) (pd->reg + 0x08)
-#define ICIC(pd) (pd->reg + 0x0c)
-#define ICCL(pd) (pd->reg + 0x10)
-#define ICCH(pd) (pd->reg + 0x14)
+#define ICDR 0x00
+#define ICCR 0x04
+#define ICSR 0x08
+#define ICIC 0x0c
+#define ICCL 0x10
+#define ICCH 0x14
/* Register bits */
#define ICCR_ICE 0x80
@@ -155,11 +159,32 @@ struct sh_mobile_i2c_data {
#define ICSR_WAIT 0x02
#define ICSR_DTE 0x01
+#define ICIC_ICCLB8 0x80
+#define ICIC_ICCHB8 0x40
#define ICIC_ALE 0x08
#define ICIC_TACKE 0x04
#define ICIC_WAITE 0x02
#define ICIC_DTEE 0x01
+static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
+{
+ if (offs == ICIC)
+ data |= pd->icic;
+
+ iowrite8(data, pd->reg + offs);
+}
+
+static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
+{
+ return ioread8(pd->reg + offs);
+}
+
+static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
+ unsigned char set, unsigned char clr)
+{
+ iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
+}
+
static void activate_ch(struct sh_mobile_i2c_data *pd)
{
unsigned long i2c_clk;
@@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else
pd->iccl = (u_int8_t)(num/denom);
+ /* one more bit of ICCL in ICIC */
+ if (pd->flags & IIC_FLAG_HAS_ICIC67) {
+ if ((num/denom) > 0xff)
+ pd->icic |= ICIC_ICCLB8;
+ else
+ pd->icic &= ~ICIC_ICCLB8;
+ }
+
/* Calculate the value for icch. From the data sheet:
icch = (p clock / transfer rate) * (H / (L + H)) */
num = i2c_clk * 4;
@@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else
pd->icch = (u_int8_t)(num/denom);
+ /* one more bit of ICCH in ICIC */
+ if (pd->flags & IIC_FLAG_HAS_ICIC67) {
+ if ((num/denom) > 0xff)
+ pd->icic |= ICIC_ICCHB8;
+ else
+ pd->icic &= ~ICIC_ICCHB8;
+ }
+
/* Enable channel and configure rx ack */
- iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+ iic_set_clr(pd, ICCR, ICCR_ICE, 0);
/* Mask all interrupts */
- iowrite8(0, ICIC(pd));
+ iic_wr(pd, ICIC, 0);
/* Set the clock */
- iowrite8(pd->iccl, ICCL(pd));
- iowrite8(pd->icch, ICCH(pd));
+ iic_wr(pd, ICCL, pd->iccl);
+ iic_wr(pd, ICCH, pd->icch);
}
static void deactivate_ch(struct sh_mobile_i2c_data *pd)
{
/* Clear/disable interrupts */
- iowrite8(0, ICSR(pd));
- iowrite8(0, ICIC(pd));
+ iic_wr(pd, ICSR, 0);
+ iic_wr(pd, ICIC, 0);
/* Disable channel */
- iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+ iic_set_clr(pd, ICCR, 0, ICCR_ICE);
/* Disable clock and mark device as idle */
clk_disable(pd->clk);
@@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
switch (op) {
case OP_START: /* issue start and trigger DTE interrupt */
- iowrite8(0x94, ICCR(pd));
+ iic_wr(pd, ICCR, 0x94);
break;
case OP_TX_FIRST: /* disable DTE interrupt and write data */
- iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd));
- iowrite8(data, ICDR(pd));
+ iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
+ iic_wr(pd, ICDR, data);
break;
case OP_TX: /* write data */
- iowrite8(data, ICDR(pd));
+ iic_wr(pd, ICDR, data);
break;
case OP_TX_STOP: /* write data and issue a stop afterwards */
- iowrite8(data, ICDR(pd));
- iowrite8(0x90, ICCR(pd));
+ iic_wr(pd, ICDR, data);
+ iic_wr(pd, ICCR, 0x90);
break;
case OP_TX_TO_RX: /* select read mode */
- iowrite8(0x81, ICCR(pd));
+ iic_wr(pd, ICCR, 0x81);
break;
case OP_RX: /* just read data */
- ret = ioread8(ICDR(pd));
+ ret = iic_rd(pd, ICDR);
break;
case OP_RX_STOP: /* enable DTE interrupt, issue stop */
- iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
- ICIC(pd));
- iowrite8(0xc0, ICCR(pd));
+ iic_wr(pd, ICIC,
+ ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
+ iic_wr(pd, ICCR, 0xc0);
break;
case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
- iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
- ICIC(pd));
- ret = ioread8(ICDR(pd));
- iowrite8(0xc0, ICCR(pd));
+ iic_wr(pd, ICIC,
+ ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
+ ret = iic_rd(pd, ICDR);
+ iic_wr(pd, ICCR, 0xc0);
break;
}
@@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
unsigned char sr;
int wakeup;
- sr = ioread8(ICSR(pd));
+ sr = iic_rd(pd, ICSR);
pd->sr |= sr; /* remember state */
dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
@@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
if (sr & (ICSR_AL | ICSR_TACK)) {
/* don't interrupt transaction - continue to issue stop */
- iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd));
+ iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK));
wakeup = 0;
} else if (pd->msg->flags & I2C_M_RD)
wakeup = sh_mobile_i2c_isr_rx(pd);
@@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
wakeup = sh_mobile_i2c_isr_tx(pd);
if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
- iowrite8(sr & ~ICSR_WAIT, ICSR(pd));
+ iic_wr(pd, ICSR, sr & ~ICSR_WAIT);
if (wakeup) {
pd->sr |= SW_DONE;
@@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
}
/* Initialize channel registers */
- iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
+ iic_set_clr(pd, ICCR, 0, ICCR_ICE);
/* Enable channel and configure rx ack */
- iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
+ iic_set_clr(pd, ICCR, ICCR_ICE, 0);
/* Set the clock */
- iowrite8(pd->iccl, ICCL(pd));
- iowrite8(pd->icch, ICCH(pd));
+ iic_wr(pd, ICCL, pd->iccl);
+ iic_wr(pd, ICCH, pd->icch);
pd->msg = usr_msg;
pd->pos = -1;
pd->sr = 0;
/* Enable all interrupts to begin with */
- iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd));
+ iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
return 0;
}
@@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
retry_count = 1000;
again:
- val = ioread8(ICSR(pd));
+ val = iic_rd(pd, ICSR);
dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
@@ -576,6 +617,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
goto err_irq;
}
+ /* The IIC blocks on SH-Mobile ARM processors
+ * come with two new bits in ICIC.
+ */
+ if (size > 0x17)
+ pd->flags |= IIC_FLAG_HAS_ICIC67;
+
/* Enable Runtime PM for this device.
*
* Also tell the Runtime PM core to ignore children
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 0815e10da7c6..6a9d9bb47073 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -424,6 +424,35 @@ static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
}
/**
+ * i2c_lock_adapter - Get exclusive access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+void i2c_lock_adapter(struct i2c_adapter *adapter)
+{
+ rt_mutex_lock(&adapter->bus_lock);
+}
+EXPORT_SYMBOL_GPL(i2c_lock_adapter);
+
+/**
+ * i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+static int i2c_trylock_adapter(struct i2c_adapter *adapter)
+{
+ return rt_mutex_trylock(&adapter->bus_lock);
+}
+
+/**
+ * i2c_unlock_adapter - Release exclusive access to an I2C bus segment
+ * @adapter: Target I2C bus segment
+ */
+void i2c_unlock_adapter(struct i2c_adapter *adapter)
+{
+ rt_mutex_unlock(&adapter->bus_lock);
+}
+EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
+
+/**
* i2c_new_device - instantiate an i2c device
* @adap: the adapter managing the device
* @info: describes one I2C device; bus_num is ignored
@@ -754,7 +783,7 @@ static int __process_new_adapter(struct device_driver *d, void *data)
static int i2c_register_adapter(struct i2c_adapter *adap)
{
- int res = 0, dummy;
+ int res = 0;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p))) {
@@ -792,8 +821,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
/* Notify drivers */
mutex_lock(&core_lock);
- dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
- __process_new_adapter);
+ bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
mutex_unlock(&core_lock);
return 0;
@@ -1229,12 +1257,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
#endif
if (in_atomic() || irqs_disabled()) {
- ret = rt_mutex_trylock(&adap->bus_lock);
+ ret = i2c_trylock_adapter(adap);
if (!ret)
/* I2C activity is ongoing. */
return -EAGAIN;
} else {
- rt_mutex_lock(&adap->bus_lock);
+ i2c_lock_adapter(adap);
}
/* Retry automatically on arbitration loss */
@@ -1246,7 +1274,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
if (time_after(jiffies, orig_jiffies + adap->timeout))
break;
}
- rt_mutex_unlock(&adap->bus_lock);
+ i2c_unlock_adapter(adap);
return ret;
} else {
@@ -1341,13 +1369,17 @@ static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
I2C_SMBUS_BYTE_DATA, &dummy);
else
#endif
- if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50
- || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
- err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
- I2C_SMBUS_BYTE, &dummy);
- else
+ if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50)
+ && i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
I2C_SMBUS_QUICK, NULL);
+ else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE))
+ err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
+ I2C_SMBUS_BYTE, &dummy);
+ else {
+ dev_warn(&adap->dev, "No suitable probing method supported\n");
+ err = -EOPNOTSUPP;
+ }
return err >= 0;
}
@@ -1428,16 +1460,6 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
if (!(adapter->class & driver->class))
goto exit_free;
- /* Stop here if the bus doesn't support probing */
- if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)) {
- if (address_list[0] == I2C_CLIENT_END)
- goto exit_free;
-
- dev_warn(&adapter->dev, "Probing not supported\n");
- err = -EOPNOTSUPP;
- goto exit_free;
- }
-
for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
"addr 0x%02x\n", adap_id, address_list[i]);
@@ -1452,18 +1474,23 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
return err;
}
+int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr)
+{
+ return i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
+ I2C_SMBUS_QUICK, NULL) >= 0;
+}
+EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read);
+
struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
- unsigned short const *addr_list)
+ unsigned short const *addr_list,
+ int (*probe)(struct i2c_adapter *, unsigned short addr))
{
int i;
- /* Stop here if the bus doesn't support probing */
- if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
- dev_err(&adap->dev, "Probing not supported\n");
- return NULL;
- }
+ if (!probe)
+ probe = i2c_default_probe;
for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
/* Check address validity */
@@ -1481,7 +1508,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
}
/* Test address responsiveness */
- if (i2c_default_probe(adap, addr_list[i]))
+ if (probe(adap, addr_list[i]))
break;
}
@@ -1993,7 +2020,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adapter->algo->smbus_xfer) {
- rt_mutex_lock(&adapter->bus_lock);
+ i2c_lock_adapter(adapter);
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
@@ -2007,7 +2034,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
orig_jiffies + adapter->timeout))
break;
}
- rt_mutex_unlock(&adapter->bus_lock);
+ i2c_unlock_adapter(adapter);
} else
res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
command, protocol, data);
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index e0694e4d86c7..0b0427f7d348 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -167,13 +167,9 @@ static ssize_t i2cdev_write(struct file *file, const char __user *buf,
if (count > 8192)
count = 8192;
- tmp = kmalloc(count, GFP_KERNEL);
- if (tmp == NULL)
- return -ENOMEM;
- if (copy_from_user(tmp, buf, count)) {
- kfree(tmp);
- return -EFAULT;
- }
+ tmp = memdup_user(buf, count);
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
@@ -219,9 +215,7 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
return -EINVAL;
- rdwr_pa = (struct i2c_msg *)
- kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
- GFP_KERNEL);
+ rdwr_pa = kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);
if (!rdwr_pa)
return -ENOMEM;
@@ -247,15 +241,9 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
break;
}
data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
- rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
- if (rdwr_pa[i].buf == NULL) {
- res = -ENOMEM;
- break;
- }
- if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
- rdwr_pa[i].len)) {
- ++i; /* Needs to be kfreed too */
- res = -EFAULT;
+ rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
+ if (IS_ERR(rdwr_pa[i].buf)) {
+ res = PTR_ERR(rdwr_pa[i].buf);
break;
}
}
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 67fb73559fd5..34b9872f35d1 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -480,13 +480,9 @@ int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
u16 nsect = 0;
char __user *buf = (char __user *)arg;
- req_task = kzalloc(tasksize, GFP_KERNEL);
- if (req_task == NULL)
- return -ENOMEM;
- if (copy_from_user(req_task, buf, tasksize)) {
- kfree(req_task);
- return -EFAULT;
- }
+ req_task = memdup_user(buf, tasksize);
+ if (IS_ERR(req_task))
+ return PTR_ERR(req_task);
taskout = req_task->out_size;
taskin = req_task->in_size;
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index 1d80f1fdbc97..7002765b593c 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -64,7 +64,7 @@ static void tx4938ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
pair = ide_get_pair_dev(drive);
if (pair)
- safe = min(safe, pair->pio_mode - XFER_PIO_0);
+ safe = min_t(u8, safe, pair->pio_mode - XFER_PIO_0);
tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, safe);
}
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 3c7367751873..bed3e39aac96 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -114,7 +114,7 @@ static void tx4939ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
pair = ide_get_pair_dev(drive);
if (pair)
- safe = min(safe, pair->pio_mode - XFER_PIO_0);
+ safe = min_t(u8, safe, pair->pio_mode - XFER_PIO_0);
/*
* Update Command Transfer Mode for master/slave and Data
* Transfer Mode for this drive.
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 2ee6c7a68bdc..b8a567328e9a 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -515,6 +515,8 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
struct input_absinfo abs;
struct ff_effect effect;
int __user *ip = (int __user *)p;
+ struct keycode_table_entry kt, *kt_p = p;
+ char scancode[16];
unsigned int i, t, u, v;
int error;
@@ -569,6 +571,43 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
return input_set_keycode(dev, t, v);
+ case EVIOCGKEYCODEBIG:
+ if (copy_from_user(&kt, kt_p, sizeof(kt)))
+ return -EFAULT;
+
+ if (kt.len > sizeof(scancode))
+ return -EINVAL;
+
+ kt.scancode = scancode;
+
+ error = input_get_keycode_big(dev, &kt);
+ if (error)
+ return error;
+
+ if (copy_to_user(kt_p, &kt, sizeof(kt)))
+ return -EFAULT;
+
+ /* FIXME: probably need some compat32 code */
+ if (copy_to_user(kt_p->scancode, kt.scancode, kt.len))
+ return -EFAULT;
+
+ return 0;
+
+ case EVIOCSKEYCODEBIG:
+ if (copy_from_user(&kt, kt_p, sizeof(kt)))
+ return -EFAULT;
+
+ if (kt.len > sizeof(scancode))
+ return -EINVAL;
+
+ kt.scancode = scancode;
+
+ /* FIXME: probably need some compat32 code */
+ if (copy_from_user(kt.scancode, kt_p->scancode, kt.len))
+ return -EFAULT;
+
+ return input_set_keycode_big(dev, &kt);
+
case EVIOCRMFF:
return input_ff_erase(dev, (int)(unsigned long) p, file);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 9c79bd56b51a..43aeb71e472c 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -568,6 +568,11 @@ static void input_disconnect_device(struct input_dev *dev)
spin_unlock_irq(&dev->event_lock);
}
+/*
+ * Those routines handle the default case where no [gs]etkeycode() is
+ * defined. In this case, an array indexed by the scancode is used.
+ */
+
static int input_fetch_keycode(struct input_dev *dev, int scancode)
{
switch (dev->keycodesize) {
@@ -582,27 +587,74 @@ static int input_fetch_keycode(struct input_dev *dev, int scancode)
}
}
-static int input_default_getkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int *keycode)
+/*
+ * Supports only 8, 16 and 32 bit scancodes. It wouldn't be that
+ * hard to write some machine-endian logic to support 24 bit scancodes,
+ * but it seemed overkill. It should also be noticed that, since there
+ * are, in general, less than 256 scancodes sparsed into the scancode
+ * space, even with 16 bits, the codespace is sparsed, with leads into
+ * memory and code ineficiency, when retrieving the entire scancode
+ * space.
+ * So, it is highly recommended to implement getkeycodebig/setkeycodebig
+ * instead of using a normal table approach, when more than 8 bits is
+ * needed for the scancode.
+ */
+static int input_fetch_scancode(struct keycode_table_entry *kt_entry,
+ u32 *scancode)
{
+ switch (kt_entry->len) {
+ case 1:
+ *scancode = *((u8 *)kt_entry->scancode);
+ break;
+ case 2:
+ *scancode = *((u16 *)kt_entry->scancode);
+ break;
+ case 4:
+ *scancode = *((u32 *)kt_entry->scancode);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+
+static int input_default_getkeycode_from_index(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry)
+{
+ u32 scancode = kt_entry->index;
+
if (!dev->keycodesize)
return -EINVAL;
if (scancode >= dev->keycodemax)
return -EINVAL;
- *keycode = input_fetch_keycode(dev, scancode);
+ kt_entry->keycode = input_fetch_keycode(dev, scancode);
+ memcpy(kt_entry->scancode, &scancode, 4);
return 0;
}
+static int input_default_getkeycode_from_scancode(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry)
+{
+ if (input_fetch_scancode(kt_entry, &kt_entry->index))
+ return -EINVAL;
+
+ return input_default_getkeycode_from_index(dev, kt_entry);
+}
+
+
static int input_default_setkeycode(struct input_dev *dev,
- unsigned int scancode,
- unsigned int keycode)
+ struct keycode_table_entry *kt_entry)
{
- int old_keycode;
+ u32 old_keycode;
int i;
+ u32 scancode;
+
+ if (input_fetch_scancode(kt_entry, &scancode))
+ return -EINVAL;
if (scancode >= dev->keycodemax)
return -EINVAL;
@@ -610,32 +662,33 @@ static int input_default_setkeycode(struct input_dev *dev,
if (!dev->keycodesize)
return -EINVAL;
- if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
+ if (dev->keycodesize < sizeof(dev->keycode) &&
+ (kt_entry->keycode >> (dev->keycodesize * 8)))
return -EINVAL;
switch (dev->keycodesize) {
case 1: {
u8 *k = (u8 *)dev->keycode;
old_keycode = k[scancode];
- k[scancode] = keycode;
+ k[scancode] = kt_entry->keycode;
break;
}
case 2: {
u16 *k = (u16 *)dev->keycode;
old_keycode = k[scancode];
- k[scancode] = keycode;
+ k[scancode] = kt_entry->keycode;
break;
}
default: {
u32 *k = (u32 *)dev->keycode;
old_keycode = k[scancode];
- k[scancode] = keycode;
+ k[scancode] = kt_entry->keycode;
break;
}
}
__clear_bit(old_keycode, dev->keybit);
- __set_bit(keycode, dev->keybit);
+ __set_bit(kt_entry->keycode, dev->keybit);
for (i = 0; i < dev->keycodemax; i++) {
if (input_fetch_keycode(dev, i) == old_keycode) {
@@ -648,6 +701,110 @@ static int input_default_setkeycode(struct input_dev *dev,
}
/**
+ * input_get_keycode_big - retrieve keycode currently mapped to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone interested in retrieving current
+ * keymap. Presently evdev handlers use it.
+ */
+int input_get_keycode_big(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry)
+{
+ if (dev->getkeycode) {
+ u32 scancode = kt_entry->index;
+
+ /*
+ * Support for legacy drivers, that don't implement the new
+ * ioctls
+ */
+ memcpy(kt_entry->scancode, &scancode, 4);
+ return dev->getkeycode(dev, scancode,
+ &kt_entry->keycode);
+ } else
+ return dev->getkeycodebig_from_index(dev, kt_entry);
+}
+EXPORT_SYMBOL(input_get_keycode_big);
+
+/**
+ * input_set_keycode_big - attribute a keycode to a given scancode
+ * @dev: input device which keymap is being queried
+ * @kt_entry: keytable entry
+ *
+ * This function should be called by anyone needing to update current
+ * keymap. Presently keyboard and evdev handlers use it.
+ */
+int input_set_keycode_big(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry)
+{
+ unsigned long flags;
+ int old_keycode;
+ int retval = -EINVAL;
+ u32 uninitialized_var(scancode);
+
+ if (kt_entry->keycode < 0 || kt_entry->keycode > KEY_MAX)
+ return -EINVAL;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+
+ /*
+ * We need to know the old scancode, in order to generate a
+ * keyup effect, if the set operation happens successfully
+ */
+ if (dev->getkeycode) {
+ /*
+ * Support for legacy drivers, that don't implement the new
+ * ioctls
+ */
+ if (!dev->setkeycode)
+ goto out;
+
+ retval = input_fetch_scancode(kt_entry, &scancode);
+ if (retval)
+ goto out;
+
+ retval = dev->getkeycode(dev, scancode,
+ &old_keycode);
+ } else {
+ int new_keycode = kt_entry->keycode;
+
+ retval = dev->getkeycodebig_from_scancode(dev, kt_entry);
+ old_keycode = kt_entry->keycode;
+ kt_entry->keycode = new_keycode;
+ }
+
+ if (retval)
+ goto out;
+
+ if (dev->getkeycode)
+ retval = dev->setkeycode(dev, scancode,
+ kt_entry->keycode);
+ else
+ retval = dev->setkeycodebig(dev, kt_entry);
+ if (retval)
+ goto out;
+
+ /*
+ * Simulate keyup event if keycode is not present
+ * in the keymap anymore
+ */
+ if (test_bit(EV_KEY, dev->evbit) &&
+ !is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
+ __test_and_clear_bit(old_keycode, dev->key)) {
+
+ input_pass_event(dev, EV_KEY, old_keycode, 0);
+ if (dev->sync)
+ input_pass_event(dev, EV_SYN, SYN_REPORT, 1);
+ }
+
+ out:
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ return retval;
+}
+EXPORT_SYMBOL(input_set_keycode_big);
+
+/**
* input_get_keycode - retrieve keycode currently mapped to a given scancode
* @dev: input device which keymap is being queried
* @scancode: scancode (or its equivalent for device in question) for which
@@ -661,13 +818,35 @@ int input_get_keycode(struct input_dev *dev,
unsigned int scancode, unsigned int *keycode)
{
unsigned long flags;
- int retval;
- spin_lock_irqsave(&dev->event_lock, flags);
- retval = dev->getkeycode(dev, scancode, keycode);
- spin_unlock_irqrestore(&dev->event_lock, flags);
+ if (dev->getkeycode) {
+ /*
+ * Use the legacy calls
+ */
+ return dev->getkeycode(dev, scancode, keycode);
+ } else {
+ int retval;
+ struct keycode_table_entry kt_entry;
- return retval;
+ /*
+ * Userspace is using a legacy call with a driver ported
+ * to the new way. This is a bad idea with long sparsed
+ * tables, since lots of the retrieved values will be in
+ * blank. Also, it makes sense only if the table size is
+ * lower than 2^32.
+ */
+ memset(&kt_entry, 0, sizeof(kt_entry));
+ kt_entry.len = 4;
+ kt_entry.index = scancode;
+ kt_entry.scancode = (char *)&scancode;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ retval = dev->getkeycodebig_from_index(dev, &kt_entry);
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+
+ *keycode = kt_entry.keycode;
+ return retval;
+ }
}
EXPORT_SYMBOL(input_get_keycode);
@@ -692,13 +871,41 @@ int input_set_keycode(struct input_dev *dev,
spin_lock_irqsave(&dev->event_lock, flags);
- retval = dev->getkeycode(dev, scancode, &old_keycode);
- if (retval)
- goto out;
+ if (dev->getkeycode) {
+ /*
+ * Use the legacy calls
+ */
+ retval = dev->getkeycode(dev, scancode, &old_keycode);
+ if (retval)
+ goto out;
- retval = dev->setkeycode(dev, scancode, keycode);
- if (retval)
- goto out;
+ retval = dev->setkeycode(dev, scancode, keycode);
+ if (retval)
+ goto out;
+ } else {
+ struct keycode_table_entry kt_entry;
+
+ /*
+ * Userspace is using a legacy call with a driver ported
+ * to the new way. This is a bad idea with long sparsed
+ * tables, since lots of the retrieved values will be in
+ * blank. Also, it makes sense only if the table size is
+ * lower than 2^32.
+ */
+ memset(&kt_entry, 0, sizeof(kt_entry));
+ kt_entry.len = 4;
+ kt_entry.scancode = (char *)&scancode;
+
+ retval = dev->getkeycodebig_from_scancode(dev, &kt_entry);
+ if (retval)
+ goto out;
+
+ kt_entry.keycode = keycode;
+
+ retval = dev->setkeycodebig(dev, &kt_entry);
+ if (retval)
+ goto out;
+ }
/* Make sure KEY_RESERVED did not get enabled. */
__clear_bit(KEY_RESERVED, dev->keybit);
@@ -1636,11 +1843,17 @@ int input_register_device(struct input_dev *dev)
dev->rep[REP_PERIOD] = 33;
}
- if (!dev->getkeycode)
- dev->getkeycode = input_default_getkeycode;
+ if (!dev->getkeycode) {
+ if (!dev->getkeycodebig_from_index)
+ dev->getkeycodebig_from_index = input_default_getkeycode_from_index;
+ if (!dev->getkeycodebig_from_scancode)
+ dev->getkeycodebig_from_scancode = input_default_getkeycode_from_scancode;
+ }
- if (!dev->setkeycode)
- dev->setkeycode = input_default_setkeycode;
+ if (dev->setkeycode) {
+ if (!dev->setkeycodebig)
+ dev->setkeycodebig = input_default_setkeycode;
+ }
dev_set_name(&dev->dev, "input%ld",
(unsigned long) atomic_inc_return(&input_no) - 1);
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c
index 40cea334ad13..9ba9c4a17e15 100644
--- a/drivers/input/mouse/synaptics.c
+++ b/drivers/input/mouse/synaptics.c
@@ -206,6 +206,7 @@ static int synaptics_resolution(struct psmouse *psmouse)
unsigned char max[3];
if (SYN_ID_MAJOR(priv->identity) < 4)
+ return 0;
if (synaptics_send_cmd(psmouse, SYN_QUE_RESOLUTION, res) == 0) {
if (res[0] != 0 && (res[1] & 0x80) && res[2] != 0) {
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 847f4aad7ed5..5d48bb66aa73 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -27,6 +27,11 @@
#include <asm/irq.h>
#elif defined(CONFIG_SH_CAYMAN)
#include <asm/irq.h>
+#elif defined(CONFIG_PPC)
+extern int of_i8042_kbd_irq;
+extern int of_i8042_aux_irq;
+# define I8042_KBD_IRQ of_i8042_kbd_irq
+# define I8042_AUX_IRQ of_i8042_aux_irq
#else
# define I8042_KBD_IRQ 1
# define I8042_AUX_IRQ 12
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 5c9367acf0cf..7d1bfeb6a82c 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -322,10 +322,10 @@ do_attach( struct i2c_adapter *adapter )
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "therm_ds1775", I2C_NAME_SIZE);
- i2c_new_probed_device(adapter, &info, scan_ds1775);
+ i2c_new_probed_device(adapter, &info, scan_ds1775, NULL);
strlcpy(info.type, "therm_adm1030", I2C_NAME_SIZE);
- i2c_new_probed_device(adapter, &info, scan_adm1030);
+ i2c_new_probed_device(adapter, &info, scan_adm1030, NULL);
if( x.thermostat && x.fan ) {
x.running = 1;
diff --git a/drivers/media/IR/Kconfig b/drivers/media/IR/Kconfig
index d22a8ec523fc..e557ae0e60b8 100644
--- a/drivers/media/IR/Kconfig
+++ b/drivers/media/IR/Kconfig
@@ -8,6 +8,17 @@ config VIDEO_IR
depends on IR_CORE
default IR_CORE
+config LIRC
+ tristate
+ default y
+
+ ---help---
+ Enable this option to build the Linux Infrared Remote
+ Control (LIRC) core device interface driver. The LIRC
+ interface passes raw IR to and from userspace, where the
+ LIRC daemon handles protocol decoding for IR reception ann
+ encoding for IR transmitting (aka "blasting").
+
source "drivers/media/IR/keymaps/Kconfig"
config IR_NEC_DECODER
@@ -42,6 +53,7 @@ config IR_RC6_DECODER
config IR_JVC_DECODER
tristate "Enable IR raw decoder for the JVC protocol"
depends on IR_CORE
+ select BITREVERSE
default y
---help---
@@ -57,6 +69,16 @@ config IR_SONY_DECODER
Enable this option if you have an infrared remote control which
uses the Sony protocol, and you need software decoding support.
+config IR_LIRC_CODEC
+ tristate "Enable IR to LIRC bridge"
+ depends on IR_CORE
+ depends on LIRC
+ default y
+
+ ---help---
+ Enable this option to pass raw IR to and from userspace via
+ the LIRC interface.
+
config IR_IMON
tristate "SoundGraph iMON Receiver and Display"
depends on USB_ARCH_HAS_HCD
@@ -68,3 +90,15 @@ config IR_IMON
To compile this driver as a module, choose M here: the
module will be called imon.
+
+config IR_MCEUSB
+ tristate "Windows Media Center Ed. eHome Infrared Transceiver"
+ depends on USB_ARCH_HAS_HCD
+ depends on IR_CORE
+ select USB
+ ---help---
+ Say Y here if you want to use a Windows Media Center Edition
+ eHome Infrared Transceiver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mceusb.
diff --git a/drivers/media/IR/Makefile b/drivers/media/IR/Makefile
index b998fcced2e4..2ae4f3abfdbd 100644
--- a/drivers/media/IR/Makefile
+++ b/drivers/media/IR/Makefile
@@ -5,11 +5,14 @@ obj-y += keymaps/
obj-$(CONFIG_IR_CORE) += ir-core.o
obj-$(CONFIG_VIDEO_IR) += ir-common.o
+obj-$(CONFIG_LIRC) += lirc_dev.o
obj-$(CONFIG_IR_NEC_DECODER) += ir-nec-decoder.o
obj-$(CONFIG_IR_RC5_DECODER) += ir-rc5-decoder.o
obj-$(CONFIG_IR_RC6_DECODER) += ir-rc6-decoder.o
obj-$(CONFIG_IR_JVC_DECODER) += ir-jvc-decoder.o
obj-$(CONFIG_IR_SONY_DECODER) += ir-sony-decoder.o
+obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
# stand-alone IR receivers/transmitters
obj-$(CONFIG_IR_IMON) += imon.o
+obj-$(CONFIG_IR_MCEUSB) += mceusb.o
diff --git a/drivers/media/IR/imon.c b/drivers/media/IR/imon.c
index 4bbd45f4284c..0195dd5ac078 100644
--- a/drivers/media/IR/imon.c
+++ b/drivers/media/IR/imon.c
@@ -1943,7 +1943,7 @@ static struct imon_context *imon_init_intf0(struct usb_interface *intf)
return ictx;
urb_submit_failed:
- input_unregister_device(ictx->idev);
+ ir_input_unregister(ictx->idev);
input_free_device(ictx->idev);
idev_setup_failed:
find_endpoint_failed:
@@ -2067,6 +2067,7 @@ static void imon_get_ffdc_type(struct imon_context *ictx)
detected_display_type = IMON_DISPLAY_TYPE_VFD;
break;
/* iMON LCD, MCE IR */
+ case 0x9e:
case 0x9f:
dev_info(ictx->dev, "0xffdc iMON LCD, MCE IR");
detected_display_type = IMON_DISPLAY_TYPE_LCD;
@@ -2306,7 +2307,7 @@ static void __devexit imon_disconnect(struct usb_interface *interface)
if (ifnum == 0) {
ictx->dev_present_intf0 = false;
usb_kill_urb(ictx->rx_urb_intf0);
- input_unregister_device(ictx->idev);
+ ir_input_unregister(ictx->idev);
if (ictx->display_supported) {
if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
usb_deregister_dev(interface, &imon_lcd_class);
diff --git a/drivers/media/IR/ir-core-priv.h b/drivers/media/IR/ir-core-priv.h
index 9a5e65a471a5..babd52061bc3 100644
--- a/drivers/media/IR/ir-core-priv.h
+++ b/drivers/media/IR/ir-core-priv.h
@@ -22,17 +22,62 @@
struct ir_raw_handler {
struct list_head list;
+ u64 protocols; /* which are handled by this handler */
int (*decode)(struct input_dev *input_dev, struct ir_raw_event event);
+
+ /* These two should only be used by the lirc decoder */
int (*raw_register)(struct input_dev *input_dev);
int (*raw_unregister)(struct input_dev *input_dev);
};
struct ir_raw_event_ctrl {
+ struct list_head list; /* to keep track of raw clients */
struct work_struct rx_work; /* for the rx decoding workqueue */
struct kfifo kfifo; /* fifo for the pulse/space durations */
ktime_t last_event; /* when last event occurred */
enum raw_event_type last_type; /* last event type */
struct input_dev *input_dev; /* pointer to the parent input_dev */
+ u64 enabled_protocols; /* enabled raw protocol decoders */
+
+ /* raw decoder state follows */
+ struct ir_raw_event prev_ev;
+ struct nec_dec {
+ int state;
+ unsigned count;
+ u32 bits;
+ } nec;
+ struct rc5_dec {
+ int state;
+ u32 bits;
+ unsigned count;
+ unsigned wanted_bits;
+ } rc5;
+ struct rc6_dec {
+ int state;
+ u8 header;
+ u32 body;
+ bool toggle;
+ unsigned count;
+ unsigned wanted_bits;
+ } rc6;
+ struct sony_dec {
+ int state;
+ u32 bits;
+ unsigned count;
+ } sony;
+ struct jvc_dec {
+ int state;
+ u16 bits;
+ u16 old_bits;
+ unsigned count;
+ bool first;
+ bool toggle;
+ } jvc;
+ struct lirc_codec {
+ struct ir_input_dev *ir_dev;
+ struct lirc_driver *drv;
+ int lircdata;
+ } lirc;
};
/* macros for IR decoders */
@@ -74,6 +119,7 @@ void ir_unregister_class(struct input_dev *input_dev);
/*
* Routines from ir-raw-event.c to be used internally and by decoders
*/
+u64 ir_raw_get_allowed_protocols(void);
int ir_raw_event_register(struct input_dev *input_dev);
void ir_raw_event_unregister(struct input_dev *input_dev);
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler);
@@ -123,4 +169,12 @@ void ir_raw_init(void);
#define load_sony_decode() 0
#endif
+/* from ir-lirc-codec.c */
+#ifdef CONFIG_IR_LIRC_CODEC_MODULE
+#define load_lirc_codec() request_module("ir-lirc-codec")
+#else
+#define load_lirc_codec() 0
+#endif
+
+
#endif /* _IR_RAW_EVENT */
diff --git a/drivers/media/IR/ir-jvc-decoder.c b/drivers/media/IR/ir-jvc-decoder.c
index 0b804944cbb0..8894d8b36048 100644
--- a/drivers/media/IR/ir-jvc-decoder.c
+++ b/drivers/media/IR/ir-jvc-decoder.c
@@ -25,10 +25,6 @@
#define JVC_TRAILER_PULSE (1 * JVC_UNIT)
#define JVC_TRAILER_SPACE (35 * JVC_UNIT)
-/* Used to register jvc_decoder clients */
-static LIST_HEAD(decoder_list);
-DEFINE_SPINLOCK(decoder_lock);
-
enum jvc_state {
STATE_INACTIVE,
STATE_HEADER_SPACE,
@@ -38,87 +34,6 @@ enum jvc_state {
STATE_TRAILER_SPACE,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
- int enabled:1;
-
- /* State machine control */
- enum jvc_state state;
- u16 jvc_bits;
- u16 jvc_old_bits;
- unsigned count;
- bool first;
- bool toggle;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
-{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static ssize_t store_enabled(struct device *d,
- struct device_attribute *mattr,
- const char *buf,
- size_t len)
-{
- unsigned long value;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (strict_strtoul(buf, 10, &value) || value > 1)
- return -EINVAL;
-
- data->enabled = value;
-
- return len;
-}
-
-static ssize_t show_enabled(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (data->enabled)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
-
-static struct attribute *decoder_attributes[] = {
- &dev_attr_enabled.attr,
- NULL
-};
-
-static struct attribute_group decoder_attribute_group = {
- .name = "jvc_decoder",
- .attrs = decoder_attributes,
-};
-
/**
* ir_jvc_decode() - Decode one JVC pulse or space
* @input_dev: the struct input_dev descriptor of the device
@@ -128,14 +43,10 @@ static struct attribute_group decoder_attribute_group = {
*/
static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct jvc_dec *data = &ir_dev->raw->jvc;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
- if (!data->enabled)
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_JVC))
return 0;
if (IS_RESET(ev)) {
@@ -188,9 +99,9 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse)
break;
- data->jvc_bits <<= 1;
+ data->bits <<= 1;
if (eq_margin(ev.duration, JVC_BIT_1_SPACE, JVC_UNIT / 2)) {
- data->jvc_bits |= 1;
+ data->bits |= 1;
decrease_duration(&ev, JVC_BIT_1_SPACE);
} else if (eq_margin(ev.duration, JVC_BIT_0_SPACE, JVC_UNIT / 2))
decrease_duration(&ev, JVC_BIT_0_SPACE);
@@ -223,13 +134,13 @@ static int ir_jvc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (data->first) {
u32 scancode;
- scancode = (bitrev8((data->jvc_bits >> 8) & 0xff) << 8) |
- (bitrev8((data->jvc_bits >> 0) & 0xff) << 0);
+ scancode = (bitrev8((data->bits >> 8) & 0xff) << 8) |
+ (bitrev8((data->bits >> 0) & 0xff) << 0);
IR_dprintk(1, "JVC scancode 0x%04x\n", scancode);
ir_keydown(input_dev, scancode, data->toggle);
data->first = false;
- data->jvc_old_bits = data->jvc_bits;
- } else if (data->jvc_bits == data->jvc_old_bits) {
+ data->old_bits = data->bits;
+ } else if (data->bits == data->old_bits) {
IR_dprintk(1, "JVC repeat\n");
ir_repeat(input_dev);
} else {
@@ -249,54 +160,9 @@ out:
return -EINVAL;
}
-static int ir_jvc_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
- int rc;
-
- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- if (rc < 0)
- return rc;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- return -ENOMEM;
- }
-
- data->ir_dev = ir_dev;
- data->enabled = 1;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_jvc_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler jvc_handler = {
+ .protocols = IR_TYPE_JVC,
.decode = ir_jvc_decode,
- .raw_register = ir_jvc_register,
- .raw_unregister = ir_jvc_unregister,
};
static int __init ir_jvc_decode_init(void)
diff --git a/drivers/media/IR/ir-lirc-codec.c b/drivers/media/IR/ir-lirc-codec.c
new file mode 100644
index 000000000000..178bc5baab78
--- /dev/null
+++ b/drivers/media/IR/ir-lirc-codec.c
@@ -0,0 +1,283 @@
+/* ir-lirc-codec.c - ir-core to classic lirc interface bridge
+ *
+ * Copyright (C) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <media/lirc.h>
+#include <media/ir-core.h>
+#include "ir-core-priv.h"
+#include "lirc_dev.h"
+
+#define LIRCBUF_SIZE 256
+
+/**
+ * ir_lirc_decode() - Send raw IR data to lirc_dev to be relayed to the
+ * lircd userspace daemon for decoding.
+ * @input_dev: the struct input_dev descriptor of the device
+ * @duration: the struct ir_raw_event descriptor of the pulse/space
+ *
+ * This function returns -EINVAL if the lirc interfaces aren't wired up.
+ */
+static int ir_lirc_decode(struct input_dev *input_dev, struct ir_raw_event ev)
+{
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_LIRC))
+ return 0;
+
+ if (!ir_dev->raw->lirc.drv || !ir_dev->raw->lirc.drv->rbuf)
+ return -EINVAL;
+
+ IR_dprintk(2, "LIRC data transfer started (%uus %s)\n",
+ TO_US(ev.duration), TO_STR(ev.pulse));
+
+ ir_dev->raw->lirc.lircdata += ev.duration / 1000;
+ if (ev.pulse)
+ ir_dev->raw->lirc.lircdata |= PULSE_BIT;
+
+ lirc_buffer_write(ir_dev->raw->lirc.drv->rbuf,
+ (unsigned char *) &ir_dev->raw->lirc.lircdata);
+ wake_up(&ir_dev->raw->lirc.drv->rbuf->wait_poll);
+
+ ir_dev->raw->lirc.lircdata = 0;
+
+ return 0;
+}
+
+static ssize_t ir_lirc_transmit_ir(struct file *file, const char *buf,
+ size_t n, loff_t *ppos)
+{
+ struct lirc_codec *lirc;
+ struct ir_input_dev *ir_dev;
+ int *txbuf; /* buffer with values to transmit */
+ int ret = 0, count;
+
+ lirc = lirc_get_pdata(file);
+ if (!lirc)
+ return -EFAULT;
+
+ if (n % sizeof(int))
+ return -EINVAL;
+
+ count = n / sizeof(int);
+ if (count > LIRCBUF_SIZE || count % 2 == 0)
+ return -EINVAL;
+
+ txbuf = kzalloc(sizeof(int) * LIRCBUF_SIZE, GFP_KERNEL);
+ if (!txbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(txbuf, buf, n)) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ir_dev = lirc->ir_dev;
+ if (!ir_dev) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ if (ir_dev->props && ir_dev->props->tx_ir)
+ ret = ir_dev->props->tx_ir(ir_dev->props->priv, txbuf, (u32)n);
+
+out:
+ kfree(txbuf);
+ return ret;
+}
+
+static long ir_lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+{
+ struct lirc_codec *lirc;
+ struct ir_input_dev *ir_dev;
+ int ret = 0;
+ void *drv_data;
+ unsigned long val;
+
+ lirc = lirc_get_pdata(filep);
+ if (!lirc)
+ return -EFAULT;
+
+ ir_dev = lirc->ir_dev;
+ if (!ir_dev || !ir_dev->props || !ir_dev->props->priv)
+ return -EFAULT;
+
+ drv_data = ir_dev->props->priv;
+
+ switch (cmd) {
+ case LIRC_SET_TRANSMITTER_MASK:
+ ret = get_user(val, (unsigned long *)arg);
+ if (ret)
+ return ret;
+
+ if (ir_dev->props && ir_dev->props->s_tx_mask)
+ ret = ir_dev->props->s_tx_mask(drv_data, (u32)val);
+ else
+ return -EINVAL;
+ break;
+
+ case LIRC_SET_SEND_CARRIER:
+ ret = get_user(val, (unsigned long *)arg);
+ if (ret)
+ return ret;
+
+ if (ir_dev->props && ir_dev->props->s_tx_carrier)
+ ir_dev->props->s_tx_carrier(drv_data, (u32)val);
+ else
+ return -EINVAL;
+ break;
+
+ case LIRC_GET_SEND_MODE:
+ val = LIRC_CAN_SEND_PULSE & LIRC_CAN_SEND_MASK;
+ ret = put_user(val, (unsigned long *)arg);
+ break;
+
+ case LIRC_SET_SEND_MODE:
+ ret = get_user(val, (unsigned long *)arg);
+ if (ret)
+ return ret;
+
+ if (val != (LIRC_MODE_PULSE & LIRC_CAN_SEND_MASK))
+ return -EINVAL;
+ break;
+
+ default:
+ return lirc_dev_fop_ioctl(filep, cmd, arg);
+ }
+
+ return ret;
+}
+
+static int ir_lirc_open(void *data)
+{
+ return 0;
+}
+
+static void ir_lirc_close(void *data)
+{
+ return;
+}
+
+static struct file_operations lirc_fops = {
+ .owner = THIS_MODULE,
+ .write = ir_lirc_transmit_ir,
+ .unlocked_ioctl = ir_lirc_ioctl,
+ .read = lirc_dev_fop_read,
+ .poll = lirc_dev_fop_poll,
+ .open = lirc_dev_fop_open,
+ .release = lirc_dev_fop_close,
+};
+
+static int ir_lirc_register(struct input_dev *input_dev)
+{
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct lirc_driver *drv;
+ struct lirc_buffer *rbuf;
+ int rc = -ENOMEM;
+ unsigned long features;
+
+ drv = kzalloc(sizeof(struct lirc_driver), GFP_KERNEL);
+ if (!drv)
+ return rc;
+
+ rbuf = kzalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+ if (!drv)
+ goto rbuf_alloc_failed;
+
+ rc = lirc_buffer_init(rbuf, sizeof(int), LIRCBUF_SIZE);
+ if (rc)
+ goto rbuf_init_failed;
+
+ features = LIRC_CAN_REC_MODE2;
+ if (ir_dev->props->tx_ir) {
+ features |= LIRC_CAN_SEND_PULSE;
+ if (ir_dev->props->s_tx_mask)
+ features |= LIRC_CAN_SET_TRANSMITTER_MASK;
+ if (ir_dev->props->s_tx_carrier)
+ features |= LIRC_CAN_SET_SEND_CARRIER;
+ }
+
+ snprintf(drv->name, sizeof(drv->name), "ir-lirc-codec (%s)",
+ ir_dev->driver_name);
+ drv->minor = -1;
+ drv->features = features;
+ drv->data = &ir_dev->raw->lirc;
+ drv->rbuf = rbuf;
+ drv->set_use_inc = &ir_lirc_open;
+ drv->set_use_dec = &ir_lirc_close;
+ drv->code_length = sizeof(struct ir_raw_event) * 8;
+ drv->fops = &lirc_fops;
+ drv->dev = &ir_dev->dev;
+ drv->owner = THIS_MODULE;
+
+ drv->minor = lirc_register_driver(drv);
+ if (drv->minor < 0) {
+ rc = -ENODEV;
+ goto lirc_register_failed;
+ }
+
+ ir_dev->raw->lirc.drv = drv;
+ ir_dev->raw->lirc.ir_dev = ir_dev;
+ ir_dev->raw->lirc.lircdata = PULSE_MASK;
+
+ return 0;
+
+lirc_register_failed:
+rbuf_init_failed:
+ kfree(rbuf);
+rbuf_alloc_failed:
+ kfree(drv);
+
+ return rc;
+}
+
+static int ir_lirc_unregister(struct input_dev *input_dev)
+{
+ struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct lirc_codec *lirc = &ir_dev->raw->lirc;
+
+ lirc_unregister_driver(lirc->drv->minor);
+ lirc_buffer_free(lirc->drv->rbuf);
+ kfree(lirc->drv);
+
+ return 0;
+}
+
+static struct ir_raw_handler lirc_handler = {
+ .protocols = IR_TYPE_LIRC,
+ .decode = ir_lirc_decode,
+ .raw_register = ir_lirc_register,
+ .raw_unregister = ir_lirc_unregister,
+};
+
+static int __init ir_lirc_codec_init(void)
+{
+ ir_raw_handler_register(&lirc_handler);
+
+ printk(KERN_INFO "IR LIRC bridge handler initialized\n");
+ return 0;
+}
+
+static void __exit ir_lirc_codec_exit(void)
+{
+ ir_raw_handler_unregister(&lirc_handler);
+}
+
+module_init(ir_lirc_codec_init);
+module_exit(ir_lirc_codec_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
+MODULE_AUTHOR("Red Hat Inc. (http://www.redhat.com)");
+MODULE_DESCRIPTION("LIRC IR handler bridge");
diff --git a/drivers/media/IR/ir-nec-decoder.c b/drivers/media/IR/ir-nec-decoder.c
index ba79233112ef..52e0f378ae3d 100644
--- a/drivers/media/IR/ir-nec-decoder.c
+++ b/drivers/media/IR/ir-nec-decoder.c
@@ -27,10 +27,6 @@
#define NEC_TRAILER_PULSE (1 * NEC_UNIT)
#define NEC_TRAILER_SPACE (10 * NEC_UNIT) /* even longer in reality */
-/* Used to register nec_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
enum nec_state {
STATE_INACTIVE,
STATE_HEADER_SPACE,
@@ -40,84 +36,6 @@ enum nec_state {
STATE_TRAILER_SPACE,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
- int enabled:1;
-
- /* State machine control */
- enum nec_state state;
- u32 nec_bits;
- unsigned count;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
-{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static ssize_t store_enabled(struct device *d,
- struct device_attribute *mattr,
- const char *buf,
- size_t len)
-{
- unsigned long value;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (strict_strtoul(buf, 10, &value) || value > 1)
- return -EINVAL;
-
- data->enabled = value;
-
- return len;
-}
-
-static ssize_t show_enabled(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (data->enabled)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
-
-static struct attribute *decoder_attributes[] = {
- &dev_attr_enabled.attr,
- NULL
-};
-
-static struct attribute_group decoder_attribute_group = {
- .name = "nec_decoder",
- .attrs = decoder_attributes,
-};
-
/**
* ir_nec_decode() - Decode one NEC pulse or space
* @input_dev: the struct input_dev descriptor of the device
@@ -127,16 +45,12 @@ static struct attribute_group decoder_attribute_group = {
*/
static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct nec_dec *data = &ir_dev->raw->nec;
u32 scancode;
u8 address, not_address, command, not_command;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
- if (!data->enabled)
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_NEC))
return 0;
if (IS_RESET(ev)) {
@@ -191,9 +105,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (ev.pulse)
break;
- data->nec_bits <<= 1;
+ data->bits <<= 1;
if (eq_margin(ev.duration, NEC_BIT_1_SPACE, NEC_UNIT / 2))
- data->nec_bits |= 1;
+ data->bits |= 1;
else if (!eq_margin(ev.duration, NEC_BIT_0_SPACE, NEC_UNIT / 2))
break;
data->count++;
@@ -222,14 +136,14 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!geq_margin(ev.duration, NEC_TRAILER_SPACE, NEC_UNIT / 2))
break;
- address = bitrev8((data->nec_bits >> 24) & 0xff);
- not_address = bitrev8((data->nec_bits >> 16) & 0xff);
- command = bitrev8((data->nec_bits >> 8) & 0xff);
- not_command = bitrev8((data->nec_bits >> 0) & 0xff);
+ address = bitrev8((data->bits >> 24) & 0xff);
+ not_address = bitrev8((data->bits >> 16) & 0xff);
+ command = bitrev8((data->bits >> 8) & 0xff);
+ not_command = bitrev8((data->bits >> 0) & 0xff);
if ((command ^ not_command) != 0xff) {
IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
- data->nec_bits);
+ data->bits);
break;
}
@@ -256,54 +170,9 @@ static int ir_nec_decode(struct input_dev *input_dev, struct ir_raw_event ev)
return -EINVAL;
}
-static int ir_nec_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
- int rc;
-
- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- if (rc < 0)
- return rc;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- return -ENOMEM;
- }
-
- data->ir_dev = ir_dev;
- data->enabled = 1;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_nec_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler nec_handler = {
+ .protocols = IR_TYPE_NEC,
.decode = ir_nec_decode,
- .raw_register = ir_nec_register,
- .raw_unregister = ir_nec_unregister,
};
static int __init ir_nec_decode_init(void)
diff --git a/drivers/media/IR/ir-raw-event.c b/drivers/media/IR/ir-raw-event.c
index ea68a3f2effa..6f192ef31db1 100644
--- a/drivers/media/IR/ir-raw-event.c
+++ b/drivers/media/IR/ir-raw-event.c
@@ -20,35 +20,13 @@
/* Define the max number of pulse/space transitions to buffer */
#define MAX_IR_EVENT_SIZE 512
+/* Used to keep track of IR raw clients, protected by ir_raw_handler_lock */
+static LIST_HEAD(ir_raw_client_list);
+
/* Used to handle IR raw handler extensions */
-static LIST_HEAD(ir_raw_handler_list);
static DEFINE_SPINLOCK(ir_raw_handler_lock);
-
-/**
- * RUN_DECODER() - runs an operation on all IR decoders
- * @ops: IR raw handler operation to be called
- * @arg: arguments to be passed to the callback
- *
- * Calls ir_raw_handler::ops for all registered IR handlers. It prevents
- * new decode addition/removal while running, by locking ir_raw_handler_lock
- * mutex. If an error occurs, it stops the ops. Otherwise, it returns a sum
- * of the return codes.
- */
-#define RUN_DECODER(ops, ...) ({ \
- struct ir_raw_handler *_ir_raw_handler; \
- int _sumrc = 0, _rc; \
- spin_lock(&ir_raw_handler_lock); \
- list_for_each_entry(_ir_raw_handler, &ir_raw_handler_list, list) { \
- if (_ir_raw_handler->ops) { \
- _rc = _ir_raw_handler->ops(__VA_ARGS__); \
- if (_rc < 0) \
- break; \
- _sumrc += _rc; \
- } \
- } \
- spin_unlock(&ir_raw_handler_lock); \
- _sumrc; \
-})
+static LIST_HEAD(ir_raw_handler_list);
+static u64 available_protocols;
#ifdef MODULE
/* Used to load the decoders */
@@ -58,57 +36,17 @@ static struct work_struct wq_load;
static void ir_raw_event_work(struct work_struct *work)
{
struct ir_raw_event ev;
+ struct ir_raw_handler *handler;
struct ir_raw_event_ctrl *raw =
container_of(work, struct ir_raw_event_ctrl, rx_work);
- while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev))
- RUN_DECODER(decode, raw->input_dev, ev);
-}
-
-int ir_raw_event_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
- int rc;
-
- ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
- if (!ir->raw)
- return -ENOMEM;
-
- ir->raw->input_dev = input_dev;
- INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
-
- rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
- GFP_KERNEL);
- if (rc < 0) {
- kfree(ir->raw);
- ir->raw = NULL;
- return rc;
- }
-
- rc = RUN_DECODER(raw_register, input_dev);
- if (rc < 0) {
- kfifo_free(&ir->raw->kfifo);
- kfree(ir->raw);
- ir->raw = NULL;
- return rc;
+ while (kfifo_out(&raw->kfifo, &ev, sizeof(ev)) == sizeof(ev)) {
+ spin_lock(&ir_raw_handler_lock);
+ list_for_each_entry(handler, &ir_raw_handler_list, list)
+ handler->decode(raw->input_dev, ev);
+ spin_unlock(&ir_raw_handler_lock);
+ raw->prev_ev = ev;
}
-
- return rc;
-}
-
-void ir_raw_event_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir = input_get_drvdata(input_dev);
-
- if (!ir->raw)
- return;
-
- cancel_work_sync(&ir->raw->rx_work);
- RUN_DECODER(raw_unregister, input_dev);
-
- kfifo_free(&ir->raw->kfifo);
- kfree(ir->raw);
- ir->raw = NULL;
}
/**
@@ -204,23 +142,103 @@ void ir_raw_event_handle(struct input_dev *input_dev)
}
EXPORT_SYMBOL_GPL(ir_raw_event_handle);
+/* used internally by the sysfs interface */
+u64
+ir_raw_get_allowed_protocols()
+{
+ u64 protocols;
+ spin_lock(&ir_raw_handler_lock);
+ protocols = available_protocols;
+ spin_unlock(&ir_raw_handler_lock);
+ return protocols;
+}
+
+/*
+ * Used to (un)register raw event clients
+ */
+int ir_raw_event_register(struct input_dev *input_dev)
+{
+ struct ir_input_dev *ir = input_get_drvdata(input_dev);
+ int rc;
+ struct ir_raw_handler *handler;
+
+ ir->raw = kzalloc(sizeof(*ir->raw), GFP_KERNEL);
+ if (!ir->raw)
+ return -ENOMEM;
+
+ ir->raw->input_dev = input_dev;
+ INIT_WORK(&ir->raw->rx_work, ir_raw_event_work);
+ ir->raw->enabled_protocols = ~0;
+ rc = kfifo_alloc(&ir->raw->kfifo, sizeof(s64) * MAX_IR_EVENT_SIZE,
+ GFP_KERNEL);
+ if (rc < 0) {
+ kfree(ir->raw);
+ ir->raw = NULL;
+ return rc;
+ }
+
+ spin_lock(&ir_raw_handler_lock);
+ list_add_tail(&ir->raw->list, &ir_raw_client_list);
+ list_for_each_entry(handler, &ir_raw_handler_list, list)
+ if (handler->raw_register)
+ handler->raw_register(ir->raw->input_dev);
+ spin_unlock(&ir_raw_handler_lock);
+
+ return 0;
+}
+
+void ir_raw_event_unregister(struct input_dev *input_dev)
+{
+ struct ir_input_dev *ir = input_get_drvdata(input_dev);
+ struct ir_raw_handler *handler;
+
+ if (!ir->raw)
+ return;
+
+ cancel_work_sync(&ir->raw->rx_work);
+
+ spin_lock(&ir_raw_handler_lock);
+ list_del(&ir->raw->list);
+ list_for_each_entry(handler, &ir_raw_handler_list, list)
+ if (handler->raw_unregister)
+ handler->raw_unregister(ir->raw->input_dev);
+ spin_unlock(&ir_raw_handler_lock);
+
+ kfifo_free(&ir->raw->kfifo);
+ kfree(ir->raw);
+ ir->raw = NULL;
+}
+
/*
* Extension interface - used to register the IR decoders
*/
int ir_raw_handler_register(struct ir_raw_handler *ir_raw_handler)
{
+ struct ir_raw_event_ctrl *raw;
+
spin_lock(&ir_raw_handler_lock);
list_add_tail(&ir_raw_handler->list, &ir_raw_handler_list);
+ if (ir_raw_handler->raw_register)
+ list_for_each_entry(raw, &ir_raw_client_list, list)
+ ir_raw_handler->raw_register(raw->input_dev);
+ available_protocols |= ir_raw_handler->protocols;
spin_unlock(&ir_raw_handler_lock);
+
return 0;
}
EXPORT_SYMBOL(ir_raw_handler_register);
void ir_raw_handler_unregister(struct ir_raw_handler *ir_raw_handler)
{
+ struct ir_raw_event_ctrl *raw;
+
spin_lock(&ir_raw_handler_lock);
list_del(&ir_raw_handler->list);
+ if (ir_raw_handler->raw_unregister)
+ list_for_each_entry(raw, &ir_raw_client_list, list)
+ ir_raw_handler->raw_unregister(raw->input_dev);
+ available_protocols &= ~ir_raw_handler->protocols;
spin_unlock(&ir_raw_handler_lock);
}
EXPORT_SYMBOL(ir_raw_handler_unregister);
@@ -235,6 +253,7 @@ static void init_decoders(struct work_struct *work)
load_rc6_decode();
load_jvc_decode();
load_sony_decode();
+ load_lirc_codec();
/* If needed, we may later add some init code. In this case,
it is needed to change the CONFIG_MODULE test at ir-core.h
diff --git a/drivers/media/IR/ir-rc5-decoder.c b/drivers/media/IR/ir-rc5-decoder.c
index 23cdb1b1a3bc..df4770d978ad 100644
--- a/drivers/media/IR/ir-rc5-decoder.c
+++ b/drivers/media/IR/ir-rc5-decoder.c
@@ -30,10 +30,6 @@
#define RC5_BIT_END (1 * RC5_UNIT)
#define RC5X_SPACE (4 * RC5_UNIT)
-/* Used to register rc5_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
enum rc5_state {
STATE_INACTIVE,
STATE_BIT_START,
@@ -42,87 +38,6 @@ enum rc5_state {
STATE_FINISHED,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
- int enabled:1;
-
- /* State machine control */
- enum rc5_state state;
- u32 rc5_bits;
- struct ir_raw_event prev_ev;
- unsigned count;
- unsigned wanted_bits;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
-{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static ssize_t store_enabled(struct device *d,
- struct device_attribute *mattr,
- const char *buf,
- size_t len)
-{
- unsigned long value;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (strict_strtoul(buf, 10, &value) || value > 1)
- return -EINVAL;
-
- data->enabled = value;
-
- return len;
-}
-
-static ssize_t show_enabled(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (data->enabled)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
-
-static struct attribute *decoder_attributes[] = {
- &dev_attr_enabled.attr,
- NULL
-};
-
-static struct attribute_group decoder_attribute_group = {
- .name = "rc5_decoder",
- .attrs = decoder_attributes,
-};
-
/**
* ir_rc5_decode() - Decode one RC-5 pulse or space
* @input_dev: the struct input_dev descriptor of the device
@@ -132,17 +47,13 @@ static struct attribute_group decoder_attribute_group = {
*/
static int ir_rc5_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct rc5_dec *data = &ir_dev->raw->rc5;
u8 toggle;
u32 scancode;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
- if (!data->enabled)
- return 0;
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC5))
+ return 0;
if (IS_RESET(ev)) {
data->state = STATE_INACTIVE;
@@ -176,16 +87,15 @@ again:
if (!eq_margin(ev.duration, RC5_BIT_START, RC5_UNIT / 2))
break;
- data->rc5_bits <<= 1;
+ data->bits <<= 1;
if (!ev.pulse)
- data->rc5_bits |= 1;
+ data->bits |= 1;
data->count++;
- data->prev_ev = ev;
data->state = STATE_BIT_END;
return 0;
case STATE_BIT_END:
- if (!is_transition(&ev, &data->prev_ev))
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -217,11 +127,11 @@ again:
if (data->wanted_bits == RC5X_NBITS) {
/* RC5X */
u8 xdata, command, system;
- xdata = (data->rc5_bits & 0x0003F) >> 0;
- command = (data->rc5_bits & 0x00FC0) >> 6;
- system = (data->rc5_bits & 0x1F000) >> 12;
- toggle = (data->rc5_bits & 0x20000) ? 1 : 0;
- command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
+ xdata = (data->bits & 0x0003F) >> 0;
+ command = (data->bits & 0x00FC0) >> 6;
+ system = (data->bits & 0x1F000) >> 12;
+ toggle = (data->bits & 0x20000) ? 1 : 0;
+ command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 16 | command << 8 | xdata;
IR_dprintk(1, "RC5X scancode 0x%06x (toggle: %u)\n",
@@ -230,10 +140,10 @@ again:
} else {
/* RC5 */
u8 command, system;
- command = (data->rc5_bits & 0x0003F) >> 0;
- system = (data->rc5_bits & 0x007C0) >> 6;
- toggle = (data->rc5_bits & 0x00800) ? 1 : 0;
- command += (data->rc5_bits & 0x01000) ? 0 : 0x40;
+ command = (data->bits & 0x0003F) >> 0;
+ system = (data->bits & 0x007C0) >> 6;
+ toggle = (data->bits & 0x00800) ? 1 : 0;
+ command += (data->bits & 0x01000) ? 0 : 0x40;
scancode = system << 8 | command;
IR_dprintk(1, "RC5 scancode 0x%04x (toggle: %u)\n",
@@ -252,54 +162,9 @@ out:
return -EINVAL;
}
-static int ir_rc5_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
- int rc;
-
- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- if (rc < 0)
- return rc;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- return -ENOMEM;
- }
-
- data->ir_dev = ir_dev;
- data->enabled = 1;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_rc5_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler rc5_handler = {
+ .protocols = IR_TYPE_RC5,
.decode = ir_rc5_decode,
- .raw_register = ir_rc5_register,
- .raw_unregister = ir_rc5_unregister,
};
static int __init ir_rc5_decode_init(void)
diff --git a/drivers/media/IR/ir-rc6-decoder.c b/drivers/media/IR/ir-rc6-decoder.c
index 2bf479f4f1bc..f1624b8279bc 100644
--- a/drivers/media/IR/ir-rc6-decoder.c
+++ b/drivers/media/IR/ir-rc6-decoder.c
@@ -36,10 +36,6 @@
#define RC6_STARTBIT_MASK 0x08 /* for the header bits */
#define RC6_6A_MCE_TOGGLE_MASK 0x8000 /* for the body bits */
-/* Used to register rc6_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
enum rc6_mode {
RC6_MODE_0,
RC6_MODE_6A,
@@ -58,89 +54,8 @@ enum rc6_state {
STATE_FINISHED,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
- int enabled:1;
-
- /* State machine control */
- enum rc6_state state;
- u8 header;
- u32 body;
- struct ir_raw_event prev_ev;
- bool toggle;
- unsigned count;
- unsigned wanted_bits;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
-{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static ssize_t store_enabled(struct device *d,
- struct device_attribute *mattr,
- const char *buf,
- size_t len)
+static enum rc6_mode rc6_mode(struct rc6_dec *data)
{
- unsigned long value;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (strict_strtoul(buf, 10, &value) || value > 1)
- return -EINVAL;
-
- data->enabled = value;
-
- return len;
-}
-
-static ssize_t show_enabled(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (data->enabled)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
-
-static struct attribute *decoder_attributes[] = {
- &dev_attr_enabled.attr,
- NULL
-};
-
-static struct attribute_group decoder_attribute_group = {
- .name = "rc6_decoder",
- .attrs = decoder_attributes,
-};
-
-static enum rc6_mode rc6_mode(struct decoder_data *data) {
switch (data->header & RC6_MODE_MASK) {
case 0:
return RC6_MODE_0;
@@ -162,16 +77,12 @@ static enum rc6_mode rc6_mode(struct decoder_data *data) {
*/
static int ir_rc6_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct rc6_dec *data = &ir_dev->raw->rc6;
u32 scancode;
u8 toggle;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
- if (!data->enabled)
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_RC6))
return 0;
if (IS_RESET(ev)) {
@@ -223,12 +134,11 @@ again:
if (ev.pulse)
data->header |= 1;
data->count++;
- data->prev_ev = ev;
data->state = STATE_HEADER_BIT_END;
return 0;
case STATE_HEADER_BIT_END:
- if (!is_transition(&ev, &data->prev_ev))
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == RC6_HEADER_NBITS)
@@ -244,12 +154,11 @@ again:
break;
data->toggle = ev.pulse;
- data->prev_ev = ev;
data->state = STATE_TOGGLE_END;
return 0;
case STATE_TOGGLE_END:
- if (!is_transition(&ev, &data->prev_ev) ||
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev) ||
!geq_margin(ev.duration, RC6_TOGGLE_END, RC6_UNIT / 2))
break;
@@ -259,7 +168,6 @@ again:
}
data->state = STATE_BODY_BIT_START;
- data->prev_ev = ev;
decrease_duration(&ev, RC6_TOGGLE_END);
data->count = 0;
@@ -291,13 +199,11 @@ again:
if (ev.pulse)
data->body |= 1;
data->count++;
- data->prev_ev = ev;
-
data->state = STATE_BODY_BIT_END;
return 0;
case STATE_BODY_BIT_END:
- if (!is_transition(&ev, &data->prev_ev))
+ if (!is_transition(&ev, &ir_dev->raw->prev_ev))
break;
if (data->count == data->wanted_bits)
@@ -348,54 +254,9 @@ out:
return -EINVAL;
}
-static int ir_rc6_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
- int rc;
-
- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- if (rc < 0)
- return rc;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- return -ENOMEM;
- }
-
- data->ir_dev = ir_dev;
- data->enabled = 1;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_rc6_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler rc6_handler = {
+ .protocols = IR_TYPE_RC6,
.decode = ir_rc6_decode,
- .raw_register = ir_rc6_register,
- .raw_unregister = ir_rc6_unregister,
};
static int __init ir_rc6_decode_init(void)
diff --git a/drivers/media/IR/ir-sony-decoder.c b/drivers/media/IR/ir-sony-decoder.c
index 9f440c5c060d..b9074f07c7a0 100644
--- a/drivers/media/IR/ir-sony-decoder.c
+++ b/drivers/media/IR/ir-sony-decoder.c
@@ -23,10 +23,6 @@
#define SONY_BIT_SPACE (1 * SONY_UNIT)
#define SONY_TRAILER_SPACE (10 * SONY_UNIT) /* minimum */
-/* Used to register sony_decoder clients */
-static LIST_HEAD(decoder_list);
-static DEFINE_SPINLOCK(decoder_lock);
-
enum sony_state {
STATE_INACTIVE,
STATE_HEADER_SPACE,
@@ -35,84 +31,6 @@ enum sony_state {
STATE_FINISHED,
};
-struct decoder_data {
- struct list_head list;
- struct ir_input_dev *ir_dev;
- int enabled:1;
-
- /* State machine control */
- enum sony_state state;
- u32 sony_bits;
- unsigned count;
-};
-
-
-/**
- * get_decoder_data() - gets decoder data
- * @input_dev: input device
- *
- * Returns the struct decoder_data that corresponds to a device
- */
-static struct decoder_data *get_decoder_data(struct ir_input_dev *ir_dev)
-{
- struct decoder_data *data = NULL;
-
- spin_lock(&decoder_lock);
- list_for_each_entry(data, &decoder_list, list) {
- if (data->ir_dev == ir_dev)
- break;
- }
- spin_unlock(&decoder_lock);
- return data;
-}
-
-static ssize_t store_enabled(struct device *d,
- struct device_attribute *mattr,
- const char *buf,
- size_t len)
-{
- unsigned long value;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (strict_strtoul(buf, 10, &value) || value > 1)
- return -EINVAL;
-
- data->enabled = value;
-
- return len;
-}
-
-static ssize_t show_enabled(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- struct decoder_data *data = get_decoder_data(ir_dev);
-
- if (!data)
- return -EINVAL;
-
- if (data->enabled)
- return sprintf(buf, "1\n");
- else
- return sprintf(buf, "0\n");
-}
-
-static DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, show_enabled, store_enabled);
-
-static struct attribute *decoder_attributes[] = {
- &dev_attr_enabled.attr,
- NULL
-};
-
-static struct attribute_group decoder_attribute_group = {
- .name = "sony_decoder",
- .attrs = decoder_attributes,
-};
-
/**
* ir_sony_decode() - Decode one Sony pulse or space
* @input_dev: the struct input_dev descriptor of the device
@@ -122,16 +40,12 @@ static struct attribute_group decoder_attribute_group = {
*/
static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
{
- struct decoder_data *data;
struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
+ struct sony_dec *data = &ir_dev->raw->sony;
u32 scancode;
u8 device, subdevice, function;
- data = get_decoder_data(ir_dev);
- if (!data)
- return -EINVAL;
-
- if (!data->enabled)
+ if (!(ir_dev->raw->enabled_protocols & IR_TYPE_SONY))
return 0;
if (IS_RESET(ev)) {
@@ -172,9 +86,9 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
if (!ev.pulse)
break;
- data->sony_bits <<= 1;
+ data->bits <<= 1;
if (eq_margin(ev.duration, SONY_BIT_1_PULSE, SONY_UNIT / 2))
- data->sony_bits |= 1;
+ data->bits |= 1;
else if (!eq_margin(ev.duration, SONY_BIT_0_PULSE, SONY_UNIT / 2))
break;
@@ -208,19 +122,19 @@ static int ir_sony_decode(struct input_dev *input_dev, struct ir_raw_event ev)
switch (data->count) {
case 12:
- device = bitrev8((data->sony_bits << 3) & 0xF8);
+ device = bitrev8((data->bits << 3) & 0xF8);
subdevice = 0;
- function = bitrev8((data->sony_bits >> 4) & 0xFE);
+ function = bitrev8((data->bits >> 4) & 0xFE);
break;
case 15:
- device = bitrev8((data->sony_bits >> 0) & 0xFF);
+ device = bitrev8((data->bits >> 0) & 0xFF);
subdevice = 0;
- function = bitrev8((data->sony_bits >> 7) & 0xFD);
+ function = bitrev8((data->bits >> 7) & 0xFD);
break;
case 20:
- device = bitrev8((data->sony_bits >> 5) & 0xF8);
- subdevice = bitrev8((data->sony_bits >> 0) & 0xFF);
- function = bitrev8((data->sony_bits >> 12) & 0xFE);
+ device = bitrev8((data->bits >> 5) & 0xF8);
+ subdevice = bitrev8((data->bits >> 0) & 0xFF);
+ function = bitrev8((data->bits >> 12) & 0xFE);
break;
default:
IR_dprintk(1, "Sony invalid bitcount %u\n", data->count);
@@ -241,54 +155,9 @@ out:
return -EINVAL;
}
-static int ir_sony_register(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- struct decoder_data *data;
- int rc;
-
- rc = sysfs_create_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- if (rc < 0)
- return rc;
-
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data) {
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
- return -ENOMEM;
- }
-
- data->ir_dev = ir_dev;
- data->enabled = 1;
-
- spin_lock(&decoder_lock);
- list_add_tail(&data->list, &decoder_list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
-static int ir_sony_unregister(struct input_dev *input_dev)
-{
- struct ir_input_dev *ir_dev = input_get_drvdata(input_dev);
- static struct decoder_data *data;
-
- data = get_decoder_data(ir_dev);
- if (!data)
- return 0;
-
- sysfs_remove_group(&ir_dev->dev.kobj, &decoder_attribute_group);
-
- spin_lock(&decoder_lock);
- list_del(&data->list);
- spin_unlock(&decoder_lock);
-
- return 0;
-}
-
static struct ir_raw_handler sony_handler = {
+ .protocols = IR_TYPE_SONY,
.decode = ir_sony_decode,
- .raw_register = ir_sony_register,
- .raw_unregister = ir_sony_unregister,
};
static int __init ir_sony_decode_init(void)
diff --git a/drivers/media/IR/ir-sysfs.c b/drivers/media/IR/ir-sysfs.c
index 2098dd1488e0..a841e51cfb9a 100644
--- a/drivers/media/IR/ir-sysfs.c
+++ b/drivers/media/IR/ir-sysfs.c
@@ -34,122 +34,186 @@ static struct class ir_input_class = {
};
/**
- * show_protocol() - shows the current IR protocol
+ * show_protocols() - shows the current IR protocol(s)
* @d: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the output buffer
*
- * This routine is a callback routine for input read the IR protocol type.
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
- * It returns the protocol name, as understood by the driver.
+ * This routine is a callback routine for input read the IR protocol type(s).
+ * it is trigged by reading /sys/class/rc/rc?/protocols.
+ * It returns the protocol names of supported protocols.
+ * Enabled protocols are printed in brackets.
*/
-static ssize_t show_protocol(struct device *d,
- struct device_attribute *mattr, char *buf)
+static ssize_t show_protocols(struct device *d,
+ struct device_attribute *mattr, char *buf)
{
- char *s;
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- u64 ir_type = ir_dev->rc_tab.ir_type;
-
- IR_dprintk(1, "Current protocol is %lld\n", (long long)ir_type);
-
- /* FIXME: doesn't support multiple protocols at the same time */
- if (ir_type == IR_TYPE_UNKNOWN)
- s = "Unknown";
- else if (ir_type == IR_TYPE_RC5)
- s = "rc-5";
- else if (ir_type == IR_TYPE_NEC)
- s = "nec";
- else if (ir_type == IR_TYPE_RC6)
- s = "rc6";
- else if (ir_type == IR_TYPE_JVC)
- s = "jvc";
- else if (ir_type == IR_TYPE_SONY)
- s = "sony";
- else
- s = "other";
+ u64 allowed, enabled;
+ char *tmp = buf;
+
+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+ enabled = ir_dev->rc_tab.ir_type;
+ allowed = ir_dev->props->allowed_protos;
+ } else {
+ enabled = ir_dev->raw->enabled_protocols;
+ allowed = ir_raw_get_allowed_protocols();
+ }
- return sprintf(buf, "%s\n", s);
+ IR_dprintk(1, "allowed - 0x%llx, enabled - 0x%llx\n",
+ (long long)allowed,
+ (long long)enabled);
+
+ if (allowed & enabled & IR_TYPE_UNKNOWN)
+ tmp += sprintf(tmp, "[unknown] ");
+ else if (allowed & IR_TYPE_UNKNOWN)
+ tmp += sprintf(tmp, "unknown ");
+
+ if (allowed & enabled & IR_TYPE_RC5)
+ tmp += sprintf(tmp, "[rc5] ");
+ else if (allowed & IR_TYPE_RC5)
+ tmp += sprintf(tmp, "rc5 ");
+
+ if (allowed & enabled & IR_TYPE_NEC)
+ tmp += sprintf(tmp, "[nec] ");
+ else if (allowed & IR_TYPE_NEC)
+ tmp += sprintf(tmp, "nec ");
+
+ if (allowed & enabled & IR_TYPE_RC6)
+ tmp += sprintf(tmp, "[rc6] ");
+ else if (allowed & IR_TYPE_RC6)
+ tmp += sprintf(tmp, "rc6 ");
+
+ if (allowed & enabled & IR_TYPE_JVC)
+ tmp += sprintf(tmp, "[jvc] ");
+ else if (allowed & IR_TYPE_JVC)
+ tmp += sprintf(tmp, "jvc ");
+
+ if (allowed & enabled & IR_TYPE_SONY)
+ tmp += sprintf(tmp, "[sony] ");
+ else if (allowed & IR_TYPE_SONY)
+ tmp += sprintf(tmp, "sony ");
+
+ if (allowed & enabled & IR_TYPE_LIRC)
+ tmp += sprintf(tmp, "[lirc] ");
+ else if (allowed & IR_TYPE_LIRC)
+ tmp += sprintf(tmp, "lirc ");
+
+ if (tmp != buf)
+ tmp--;
+ *tmp = '\n';
+ return tmp + 1 - buf;
}
/**
- * store_protocol() - shows the current IR protocol
+ * store_protocols() - changes the current IR protocol(s)
* @d: the device descriptor
* @mattr: the device attribute struct (unused)
* @buf: a pointer to the input buffer
* @len: length of the input buffer
*
* This routine is a callback routine for changing the IR protocol type.
- * it is trigged by reading /sys/class/rc/rc?/current_protocol.
- * It changes the IR the protocol name, if the IR type is recognized
- * by the driver.
- * If an unknown protocol name is used, returns -EINVAL.
+ * It is trigged by writing to /sys/class/rc/rc?/protocols.
+ * Writing "+proto" will add a protocol to the list of enabled protocols.
+ * Writing "-proto" will remove a protocol from the list of enabled protocols.
+ * Writing "proto" will enable only "proto".
+ * Returns -EINVAL if an invalid protocol combination or unknown protocol name
+ * is used, otherwise @len.
*/
-static ssize_t store_protocol(struct device *d,
- struct device_attribute *mattr,
- const char *data,
- size_t len)
+static ssize_t store_protocols(struct device *d,
+ struct device_attribute *mattr,
+ const char *data,
+ size_t len)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(d);
- u64 ir_type = 0;
- int rc = -EINVAL;
+ bool enable, disable;
+ const char *tmp;
+ u64 type;
+ u64 mask;
+ int rc;
unsigned long flags;
- char *buf;
-
- while ((buf = strsep((char **) &data, " \n")) != NULL) {
- if (!strcasecmp(buf, "rc-5") || !strcasecmp(buf, "rc5"))
- ir_type |= IR_TYPE_RC5;
- if (!strcasecmp(buf, "nec"))
- ir_type |= IR_TYPE_NEC;
- if (!strcasecmp(buf, "jvc"))
- ir_type |= IR_TYPE_JVC;
- if (!strcasecmp(buf, "sony"))
- ir_type |= IR_TYPE_SONY;
+
+ tmp = skip_spaces(data);
+
+ if (*tmp == '+') {
+ enable = true;
+ disable = false;
+ tmp++;
+ } else if (*tmp == '-') {
+ enable = false;
+ disable = true;
+ tmp++;
+ } else {
+ enable = false;
+ disable = false;
}
- if (!ir_type) {
+ if (!strncasecmp(tmp, "unknown", 7)) {
+ tmp += 7;
+ mask = IR_TYPE_UNKNOWN;
+ } else if (!strncasecmp(tmp, "rc5", 3)) {
+ tmp += 3;
+ mask = IR_TYPE_RC5;
+ } else if (!strncasecmp(tmp, "nec", 3)) {
+ tmp += 3;
+ mask = IR_TYPE_NEC;
+ } else if (!strncasecmp(tmp, "rc6", 3)) {
+ tmp += 3;
+ mask = IR_TYPE_RC6;
+ } else if (!strncasecmp(tmp, "jvc", 3)) {
+ tmp += 3;
+ mask = IR_TYPE_JVC;
+ } else if (!strncasecmp(tmp, "sony", 4)) {
+ tmp += 4;
+ mask = IR_TYPE_SONY;
+ } else if (!strncasecmp(tmp, "lirc", 4)) {
+ tmp += 4;
+ mask = IR_TYPE_LIRC;
+ } else {
IR_dprintk(1, "Unknown protocol\n");
return -EINVAL;
}
- if (ir_dev->props && ir_dev->props->change_protocol)
- rc = ir_dev->props->change_protocol(ir_dev->props->priv,
- ir_type);
-
- if (rc < 0) {
- IR_dprintk(1, "Error setting protocol to %lld\n",
- (long long)ir_type);
+ tmp = skip_spaces(tmp);
+ if (*tmp != '\0') {
+ IR_dprintk(1, "Invalid trailing characters\n");
return -EINVAL;
}
- spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
- ir_dev->rc_tab.ir_type = ir_type;
- spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
+ type = ir_dev->rc_tab.ir_type;
+ else
+ type = ir_dev->raw->enabled_protocols;
- IR_dprintk(1, "Current protocol(s) is(are) %lld\n",
- (long long)ir_type);
+ if (enable)
+ type |= mask;
+ else if (disable)
+ type &= ~mask;
+ else
+ type = mask;
- return len;
-}
+ if (ir_dev->props && ir_dev->props->change_protocol) {
+ rc = ir_dev->props->change_protocol(ir_dev->props->priv,
+ type);
+ if (rc < 0) {
+ IR_dprintk(1, "Error setting protocols to 0x%llx\n",
+ (long long)type);
+ return -EINVAL;
+ }
+ }
-static ssize_t show_supported_protocols(struct device *d,
- struct device_attribute *mattr, char *buf)
-{
- char *orgbuf = buf;
- struct ir_input_dev *ir_dev = dev_get_drvdata(d);
+ if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE) {
+ spin_lock_irqsave(&ir_dev->rc_tab.lock, flags);
+ ir_dev->rc_tab.ir_type = type;
+ spin_unlock_irqrestore(&ir_dev->rc_tab.lock, flags);
+ } else {
+ ir_dev->raw->enabled_protocols = type;
+ }
- /* FIXME: doesn't support multiple protocols at the same time */
- if (ir_dev->props->allowed_protos == IR_TYPE_UNKNOWN)
- buf += sprintf(buf, "unknown ");
- if (ir_dev->props->allowed_protos & IR_TYPE_RC5)
- buf += sprintf(buf, "rc-5 ");
- if (ir_dev->props->allowed_protos & IR_TYPE_NEC)
- buf += sprintf(buf, "nec ");
- if (buf == orgbuf)
- buf += sprintf(buf, "other ");
- buf += sprintf(buf - 1, "\n");
+ IR_dprintk(1, "Current protocol(s): 0x%llx\n",
+ (long long)type);
- return buf - orgbuf;
+ return len;
}
#define ADD_HOTPLUG_VAR(fmt, val...) \
@@ -159,7 +223,7 @@ static ssize_t show_supported_protocols(struct device *d,
return err; \
} while (0)
-static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
+static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
{
struct ir_input_dev *ir_dev = dev_get_drvdata(device);
@@ -174,34 +238,26 @@ static int ir_dev_uevent(struct device *device, struct kobj_uevent_env *env)
/*
* Static device attribute struct with the sysfs attributes for IR's
*/
-static DEVICE_ATTR(protocol, S_IRUGO | S_IWUSR,
- show_protocol, store_protocol);
-
-static DEVICE_ATTR(supported_protocols, S_IRUGO | S_IWUSR,
- show_supported_protocols, NULL);
+static DEVICE_ATTR(protocols, S_IRUGO | S_IWUSR,
+ show_protocols, store_protocols);
-static struct attribute *ir_hw_dev_attrs[] = {
- &dev_attr_protocol.attr,
- &dev_attr_supported_protocols.attr,
+static struct attribute *rc_dev_attrs[] = {
+ &dev_attr_protocols.attr,
NULL,
};
-static struct attribute_group ir_hw_dev_attr_grp = {
- .attrs = ir_hw_dev_attrs,
+static struct attribute_group rc_dev_attr_grp = {
+ .attrs = rc_dev_attrs,
};
-static const struct attribute_group *ir_hw_dev_attr_groups[] = {
- &ir_hw_dev_attr_grp,
+static const struct attribute_group *rc_dev_attr_groups[] = {
+ &rc_dev_attr_grp,
NULL
};
static struct device_type rc_dev_type = {
- .groups = ir_hw_dev_attr_groups,
- .uevent = ir_dev_uevent,
-};
-
-static struct device_type ir_raw_dev_type = {
- .uevent = ir_dev_uevent,
+ .groups = rc_dev_attr_groups,
+ .uevent = rc_dev_uevent,
};
/**
@@ -221,12 +277,7 @@ int ir_register_class(struct input_dev *input_dev)
if (unlikely(devno < 0))
return devno;
- if (ir_dev->props) {
- if (ir_dev->props->driver_type == RC_DRIVER_SCANCODE)
- ir_dev->dev.type = &rc_dev_type;
- } else
- ir_dev->dev.type = &ir_raw_dev_type;
-
+ ir_dev->dev.type = &rc_dev_type;
ir_dev->dev.class = &ir_input_class;
ir_dev->dev.parent = input_dev->dev.parent;
dev_set_name(&ir_dev->dev, "rc%d", devno);
diff --git a/drivers/media/IR/keymaps/Makefile b/drivers/media/IR/keymaps/Makefile
index aea649fbcf5a..86d3d1f2eaa9 100644
--- a/drivers/media/IR/keymaps/Makefile
+++ b/drivers/media/IR/keymaps/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-kaiomy.o \
rc-kworld-315u.o \
rc-kworld-plus-tv-analog.o \
+ rc-lirc.o \
rc-manli.o \
rc-msi-tvanywhere.o \
rc-msi-tvanywhere-plus.o \
@@ -57,6 +58,7 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
rc-pv951.o \
rc-rc5-hauppauge-new.o \
rc-rc5-tv.o \
+ rc-rc6-mce.o \
rc-real-audio-220-32-keys.o \
rc-tbs-nec.o \
rc-terratec-cinergy-xs.o \
diff --git a/drivers/media/IR/keymaps/rc-lirc.c b/drivers/media/IR/keymaps/rc-lirc.c
new file mode 100644
index 000000000000..43fcf9035082
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-lirc.c
@@ -0,0 +1,41 @@
+/* rc-lirc.c - Empty dummy keytable, for use when its preferred to pass
+ * all raw IR data to the lirc userspace decoder.
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.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 <media/ir-core.h>
+
+static struct ir_scancode lirc[] = {
+ { },
+};
+
+static struct rc_keymap lirc_map = {
+ .map = {
+ .scan = lirc,
+ .size = ARRAY_SIZE(lirc),
+ .ir_type = IR_TYPE_LIRC,
+ .name = RC_MAP_LIRC,
+ }
+};
+
+static int __init init_rc_map_lirc(void)
+{
+ return ir_register_map(&lirc_map);
+}
+
+static void __exit exit_rc_map_lirc(void)
+{
+ ir_unregister_map(&lirc_map);
+}
+
+module_init(init_rc_map_lirc)
+module_exit(exit_rc_map_lirc)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c
new file mode 100644
index 000000000000..c6726a8039be
--- /dev/null
+++ b/drivers/media/IR/keymaps/rc-rc6-mce.c
@@ -0,0 +1,105 @@
+/* rc-rc6-mce.c - Keytable for Windows Media Center RC-6 remotes for use
+ * with the Media Center Edition eHome Infrared Transceiver.
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.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 <media/rc-map.h>
+
+static struct ir_scancode rc6_mce[] = {
+ { 0x800f0415, KEY_REWIND },
+ { 0x800f0414, KEY_FASTFORWARD },
+ { 0x800f041b, KEY_PREVIOUS },
+ { 0x800f041a, KEY_NEXT },
+
+ { 0x800f0416, KEY_PLAY },
+ { 0x800f0418, KEY_PAUSE },
+ { 0x800f0419, KEY_STOP },
+ { 0x800f0417, KEY_RECORD },
+
+ { 0x800f041e, KEY_UP },
+ { 0x800f041f, KEY_DOWN },
+ { 0x800f0420, KEY_LEFT },
+ { 0x800f0421, KEY_RIGHT },
+
+ { 0x800f040b, KEY_ENTER },
+ { 0x800f0422, KEY_OK },
+ { 0x800f0423, KEY_EXIT },
+ { 0x800f040a, KEY_DELETE },
+
+ { 0x800f040e, KEY_MUTE },
+ { 0x800f0410, KEY_VOLUMEUP },
+ { 0x800f0411, KEY_VOLUMEDOWN },
+ { 0x800f0412, KEY_CHANNELUP },
+ { 0x800f0413, KEY_CHANNELDOWN },
+
+ { 0x800f0401, KEY_NUMERIC_1 },
+ { 0x800f0402, KEY_NUMERIC_2 },
+ { 0x800f0403, KEY_NUMERIC_3 },
+ { 0x800f0404, KEY_NUMERIC_4 },
+ { 0x800f0405, KEY_NUMERIC_5 },
+ { 0x800f0406, KEY_NUMERIC_6 },
+ { 0x800f0407, KEY_NUMERIC_7 },
+ { 0x800f0408, KEY_NUMERIC_8 },
+ { 0x800f0409, KEY_NUMERIC_9 },
+ { 0x800f0400, KEY_NUMERIC_0 },
+
+ { 0x800f041d, KEY_NUMERIC_STAR },
+ { 0x800f041c, KEY_NUMERIC_POUND },
+
+ { 0x800f0446, KEY_TV },
+ { 0x800f0447, KEY_AUDIO }, /* My Music */
+ { 0x800f0448, KEY_PVR }, /* RecordedTV */
+ { 0x800f0449, KEY_CAMERA },
+ { 0x800f044a, KEY_VIDEO },
+ { 0x800f0424, KEY_DVD },
+ { 0x800f0425, KEY_TUNER }, /* LiveTV */
+ { 0x800f0450, KEY_RADIO },
+
+ { 0x800f044c, KEY_LANGUAGE },
+ { 0x800f0427, KEY_ZOOM }, /* Aspect */
+
+ { 0x800f045b, KEY_RED },
+ { 0x800f045c, KEY_GREEN },
+ { 0x800f045d, KEY_YELLOW },
+ { 0x800f045e, KEY_BLUE },
+
+ { 0x800f040f, KEY_INFO },
+ { 0x800f0426, KEY_EPG }, /* Guide */
+ { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */
+ { 0x800f044d, KEY_TITLE },
+
+ { 0x800f040c, KEY_POWER },
+ { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */
+
+};
+
+static struct rc_keymap rc6_mce_map = {
+ .map = {
+ .scan = rc6_mce,
+ .size = ARRAY_SIZE(rc6_mce),
+ .ir_type = IR_TYPE_RC6,
+ .name = RC_MAP_RC6_MCE,
+ }
+};
+
+static int __init init_rc_map_rc6_mce(void)
+{
+ return ir_register_map(&rc6_mce_map);
+}
+
+static void __exit exit_rc_map_rc6_mce(void)
+{
+ ir_unregister_map(&rc6_mce_map);
+}
+
+module_init(init_rc_map_rc6_mce)
+module_exit(exit_rc_map_rc6_mce)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c
new file mode 100644
index 000000000000..c11b8f706258
--- /dev/null
+++ b/drivers/media/IR/lirc_dev.c
@@ -0,0 +1,764 @@
+/*
+ * LIRC base driver
+ *
+ * by Artur Lipowski <alipowski@interia.pl>
+ *
+ * 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/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/completion.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/unistd.h>
+#include <linux/kthread.h>
+#include <linux/bitops.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+
+#include <media/lirc.h>
+#include "lirc_dev.h"
+
+static int debug;
+
+#define IRCTL_DEV_NAME "BaseRemoteCtl"
+#define NOPLUG -1
+#define LOGHEAD "lirc_dev (%s[%d]): "
+
+static dev_t lirc_base_dev;
+
+struct irctl {
+ struct lirc_driver d;
+ int attached;
+ int open;
+
+ struct mutex irctl_lock;
+ struct lirc_buffer *buf;
+ unsigned int chunk_size;
+
+ struct task_struct *task;
+ long jiffies_to_wait;
+
+ struct cdev cdev;
+};
+
+static DEFINE_MUTEX(lirc_dev_lock);
+
+static struct irctl *irctls[MAX_IRCTL_DEVICES];
+
+/* Only used for sysfs but defined to void otherwise */
+static struct class *lirc_class;
+
+/* helper function
+ * initializes the irctl structure
+ */
+static void init_irctl(struct irctl *ir)
+{
+ dev_dbg(ir->d.dev, LOGHEAD "initializing irctl\n",
+ ir->d.name, ir->d.minor);
+ mutex_init(&ir->irctl_lock);
+ ir->d.minor = NOPLUG;
+}
+
+static void cleanup(struct irctl *ir)
+{
+ dev_dbg(ir->d.dev, LOGHEAD "cleaning up\n", ir->d.name, ir->d.minor);
+
+ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
+
+ if (ir->buf != ir->d.rbuf) {
+ lirc_buffer_free(ir->buf);
+ kfree(ir->buf);
+ }
+ ir->buf = NULL;
+}
+
+/* helper function
+ * reads key codes from driver and puts them into buffer
+ * returns 0 on success
+ */
+static int add_to_buf(struct irctl *ir)
+{
+ if (ir->d.add_to_buf) {
+ int res = -ENODATA;
+ int got_data = 0;
+
+ /*
+ * service the device as long as it is returning
+ * data and we have space
+ */
+get_data:
+ res = ir->d.add_to_buf(ir->d.data, ir->buf);
+ if (res == 0) {
+ got_data++;
+ goto get_data;
+ }
+
+ if (res == -ENODEV)
+ kthread_stop(ir->task);
+
+ return got_data ? 0 : res;
+ }
+
+ return 0;
+}
+
+/* main function of the polling thread
+ */
+static int lirc_thread(void *irctl)
+{
+ struct irctl *ir = irctl;
+
+ dev_dbg(ir->d.dev, LOGHEAD "poll thread started\n",
+ ir->d.name, ir->d.minor);
+
+ do {
+ if (ir->open) {
+ if (ir->jiffies_to_wait) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(ir->jiffies_to_wait);
+ }
+ if (kthread_should_stop())
+ break;
+ if (!add_to_buf(ir))
+ wake_up_interruptible(&ir->buf->wait_poll);
+ } else {
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ } while (!kthread_should_stop());
+
+ dev_dbg(ir->d.dev, LOGHEAD "poll thread ended\n",
+ ir->d.name, ir->d.minor);
+
+ return 0;
+}
+
+
+static struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .read = lirc_dev_fop_read,
+ .write = lirc_dev_fop_write,
+ .poll = lirc_dev_fop_poll,
+ .unlocked_ioctl = lirc_dev_fop_ioctl,
+ .open = lirc_dev_fop_open,
+ .release = lirc_dev_fop_close,
+};
+
+static int lirc_cdev_add(struct irctl *ir)
+{
+ int retval;
+ struct lirc_driver *d = &ir->d;
+
+ if (d->fops) {
+ cdev_init(&ir->cdev, d->fops);
+ ir->cdev.owner = d->owner;
+ } else {
+ cdev_init(&ir->cdev, &fops);
+ ir->cdev.owner = THIS_MODULE;
+ }
+ kobject_set_name(&ir->cdev.kobj, "lirc%d", d->minor);
+
+ retval = cdev_add(&ir->cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
+ if (retval)
+ kobject_put(&ir->cdev.kobj);
+
+ return retval;
+}
+
+int lirc_register_driver(struct lirc_driver *d)
+{
+ struct irctl *ir;
+ int minor;
+ int bytes_in_key;
+ unsigned int chunk_size;
+ unsigned int buffer_size;
+ int err;
+
+ if (!d) {
+ printk(KERN_ERR "lirc_dev: lirc_register_driver: "
+ "driver pointer must be not NULL!\n");
+ err = -EBADRQC;
+ goto out;
+ }
+
+ if (MAX_IRCTL_DEVICES <= d->minor) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "\"minor\" must be between 0 and %d (%d)!\n",
+ MAX_IRCTL_DEVICES-1, d->minor);
+ err = -EBADRQC;
+ goto out;
+ }
+
+ if (1 > d->code_length || (BUFLEN * 8) < d->code_length) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "code length in bits for minor (%d) "
+ "must be less than %d!\n",
+ d->minor, BUFLEN * 8);
+ err = -EBADRQC;
+ goto out;
+ }
+
+ dev_dbg(d->dev, "lirc_dev: lirc_register_driver: sample_rate: %d\n",
+ d->sample_rate);
+ if (d->sample_rate) {
+ if (2 > d->sample_rate || HZ < d->sample_rate) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "sample_rate must be between 2 and %d!\n", HZ);
+ err = -EBADRQC;
+ goto out;
+ }
+ if (!d->add_to_buf) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "add_to_buf cannot be NULL when "
+ "sample_rate is set\n");
+ err = -EBADRQC;
+ goto out;
+ }
+ } else if (!(d->fops && d->fops->read) && !d->rbuf) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "fops->read and rbuf cannot all be NULL!\n");
+ err = -EBADRQC;
+ goto out;
+ } else if (!d->rbuf) {
+ if (!(d->fops && d->fops->read && d->fops->poll &&
+ d->fops->unlocked_ioctl)) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "neither read, poll nor unlocked_ioctl can be NULL!\n");
+ err = -EBADRQC;
+ goto out;
+ }
+ }
+
+ mutex_lock(&lirc_dev_lock);
+
+ minor = d->minor;
+
+ if (minor < 0) {
+ /* find first free slot for driver */
+ for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++)
+ if (!irctls[minor])
+ break;
+ if (MAX_IRCTL_DEVICES == minor) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "no free slots for drivers!\n");
+ err = -ENOMEM;
+ goto out_lock;
+ }
+ } else if (irctls[minor]) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "minor (%d) just registered!\n", minor);
+ err = -EBUSY;
+ goto out_lock;
+ }
+
+ ir = kzalloc(sizeof(struct irctl), GFP_KERNEL);
+ if (!ir) {
+ err = -ENOMEM;
+ goto out_lock;
+ }
+ init_irctl(ir);
+ irctls[minor] = ir;
+ d->minor = minor;
+
+ if (d->sample_rate) {
+ ir->jiffies_to_wait = HZ / d->sample_rate;
+ } else {
+ /* it means - wait for external event in task queue */
+ ir->jiffies_to_wait = 0;
+ }
+
+ /* some safety check 8-) */
+ d->name[sizeof(d->name)-1] = '\0';
+
+ bytes_in_key = BITS_TO_LONGS(d->code_length) +
+ (d->code_length % 8 ? 1 : 0);
+ buffer_size = d->buffer_size ? d->buffer_size : BUFLEN / bytes_in_key;
+ chunk_size = d->chunk_size ? d->chunk_size : bytes_in_key;
+
+ if (d->rbuf) {
+ ir->buf = d->rbuf;
+ } else {
+ ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
+ if (!ir->buf) {
+ err = -ENOMEM;
+ goto out_lock;
+ }
+ err = lirc_buffer_init(ir->buf, chunk_size, buffer_size);
+ if (err) {
+ kfree(ir->buf);
+ goto out_lock;
+ }
+ }
+ ir->chunk_size = ir->buf->chunk_size;
+
+ if (d->features == 0)
+ d->features = LIRC_CAN_REC_LIRCCODE;
+
+ ir->d = *d;
+ ir->d.minor = minor;
+
+ device_create(lirc_class, ir->d.dev,
+ MKDEV(MAJOR(lirc_base_dev), ir->d.minor), NULL,
+ "lirc%u", ir->d.minor);
+
+ if (d->sample_rate) {
+ /* try to fire up polling thread */
+ ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev");
+ if (IS_ERR(ir->task)) {
+ dev_err(d->dev, "lirc_dev: lirc_register_driver: "
+ "cannot run poll thread for minor = %d\n",
+ d->minor);
+ err = -ECHILD;
+ goto out_sysfs;
+ }
+ }
+
+ err = lirc_cdev_add(ir);
+ if (err)
+ goto out_sysfs;
+
+ ir->attached = 1;
+ mutex_unlock(&lirc_dev_lock);
+
+ dev_info(ir->d.dev, "lirc_dev: driver %s registered at minor = %d\n",
+ ir->d.name, ir->d.minor);
+ return minor;
+
+out_sysfs:
+ device_destroy(lirc_class, MKDEV(MAJOR(lirc_base_dev), ir->d.minor));
+out_lock:
+ mutex_unlock(&lirc_dev_lock);
+out:
+ return err;
+}
+EXPORT_SYMBOL(lirc_register_driver);
+
+int lirc_unregister_driver(int minor)
+{
+ struct irctl *ir;
+
+ if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
+ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
+ "\"minor (%d)\" must be between 0 and %d!\n",
+ minor, MAX_IRCTL_DEVICES-1);
+ return -EBADRQC;
+ }
+
+ ir = irctls[minor];
+
+ mutex_lock(&lirc_dev_lock);
+
+ if (ir->d.minor != minor) {
+ printk(KERN_ERR "lirc_dev: lirc_unregister_driver: "
+ "minor (%d) device not registered!", minor);
+ mutex_unlock(&lirc_dev_lock);
+ return -ENOENT;
+ }
+
+ /* end up polling thread */
+ if (ir->task)
+ kthread_stop(ir->task);
+
+ dev_dbg(ir->d.dev, "lirc_dev: driver %s unregistered from minor = %d\n",
+ ir->d.name, ir->d.minor);
+
+ ir->attached = 0;
+ if (ir->open) {
+ dev_dbg(ir->d.dev, LOGHEAD "releasing opened driver\n",
+ ir->d.name, ir->d.minor);
+ wake_up_interruptible(&ir->buf->wait_poll);
+ mutex_lock(&ir->irctl_lock);
+ ir->d.set_use_dec(ir->d.data);
+ module_put(ir->d.owner);
+ mutex_unlock(&ir->irctl_lock);
+ cdev_del(&ir->cdev);
+ } else {
+ cleanup(ir);
+ cdev_del(&ir->cdev);
+ kfree(ir);
+ irctls[minor] = NULL;
+ }
+
+ mutex_unlock(&lirc_dev_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(lirc_unregister_driver);
+
+int lirc_dev_fop_open(struct inode *inode, struct file *file)
+{
+ struct irctl *ir;
+ int retval = 0;
+
+ if (iminor(inode) >= MAX_IRCTL_DEVICES) {
+ printk(KERN_WARNING "lirc_dev [%d]: open result = -ENODEV\n",
+ iminor(inode));
+ return -ENODEV;
+ }
+
+ if (mutex_lock_interruptible(&lirc_dev_lock))
+ return -ERESTARTSYS;
+
+ ir = irctls[iminor(inode)];
+ if (!ir) {
+ retval = -ENODEV;
+ goto error;
+ }
+ file->private_data = ir;
+
+ dev_dbg(ir->d.dev, LOGHEAD "open called\n", ir->d.name, ir->d.minor);
+
+ if (ir->d.minor == NOPLUG) {
+ retval = -ENODEV;
+ goto error;
+ }
+
+ if (ir->open) {
+ retval = -EBUSY;
+ goto error;
+ }
+
+ if (try_module_get(ir->d.owner)) {
+ ++ir->open;
+ retval = ir->d.set_use_inc(ir->d.data);
+
+ if (retval) {
+ module_put(ir->d.owner);
+ --ir->open;
+ } else {
+ lirc_buffer_clear(ir->buf);
+ }
+ if (ir->task)
+ wake_up_process(ir->task);
+ }
+
+error:
+ if (ir)
+ dev_dbg(ir->d.dev, LOGHEAD "open result = %d\n",
+ ir->d.name, ir->d.minor, retval);
+
+ mutex_unlock(&lirc_dev_lock);
+
+ return retval;
+}
+EXPORT_SYMBOL(lirc_dev_fop_open);
+
+int lirc_dev_fop_close(struct inode *inode, struct file *file)
+{
+ struct irctl *ir = irctls[iminor(inode)];
+
+ dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
+
+ WARN_ON(mutex_lock_killable(&lirc_dev_lock));
+
+ --ir->open;
+ if (ir->attached) {
+ ir->d.set_use_dec(ir->d.data);
+ module_put(ir->d.owner);
+ } else {
+ cleanup(ir);
+ irctls[ir->d.minor] = NULL;
+ kfree(ir);
+ }
+
+ mutex_unlock(&lirc_dev_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(lirc_dev_fop_close);
+
+unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait)
+{
+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
+ unsigned int ret;
+
+ dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor);
+
+ if (!ir->attached) {
+ mutex_unlock(&ir->irctl_lock);
+ return POLLERR;
+ }
+
+ poll_wait(file, &ir->buf->wait_poll, wait);
+
+ if (ir->buf)
+ if (lirc_buffer_empty(ir->buf))
+ ret = 0;
+ else
+ ret = POLLIN | POLLRDNORM;
+ else
+ ret = POLLERR;
+
+ dev_dbg(ir->d.dev, LOGHEAD "poll result = %d\n",
+ ir->d.name, ir->d.minor, ret);
+
+ return ret;
+}
+EXPORT_SYMBOL(lirc_dev_fop_poll);
+
+long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ unsigned long mode;
+ int result = 0;
+ struct irctl *ir = file->private_data;
+
+ dev_dbg(ir->d.dev, LOGHEAD "ioctl called (0x%x)\n",
+ ir->d.name, ir->d.minor, cmd);
+
+ if (ir->d.minor == NOPLUG || !ir->attached) {
+ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = -ENODEV\n",
+ ir->d.name, ir->d.minor);
+ return -ENODEV;
+ }
+
+ mutex_lock(&ir->irctl_lock);
+
+ switch (cmd) {
+ case LIRC_GET_FEATURES:
+ result = put_user(ir->d.features, (unsigned long *)arg);
+ break;
+ case LIRC_GET_REC_MODE:
+ if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
+ result = -ENOSYS;
+ break;
+ }
+
+ result = put_user(LIRC_REC2MODE
+ (ir->d.features & LIRC_CAN_REC_MASK),
+ (unsigned long *)arg);
+ break;
+ case LIRC_SET_REC_MODE:
+ if (!(ir->d.features & LIRC_CAN_REC_MASK)) {
+ result = -ENOSYS;
+ break;
+ }
+
+ result = get_user(mode, (unsigned long *)arg);
+ if (!result && !(LIRC_MODE2REC(mode) & ir->d.features))
+ result = -EINVAL;
+ /*
+ * FIXME: We should actually set the mode somehow but
+ * for now, lirc_serial doesn't support mode changing either
+ */
+ break;
+ case LIRC_GET_LENGTH:
+ result = put_user(ir->d.code_length, (unsigned long *)arg);
+ break;
+ case LIRC_GET_MIN_TIMEOUT:
+ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
+ ir->d.min_timeout == 0) {
+ result = -ENOSYS;
+ break;
+ }
+
+ result = put_user(ir->d.min_timeout, (unsigned long *)arg);
+ break;
+ case LIRC_GET_MAX_TIMEOUT:
+ if (!(ir->d.features & LIRC_CAN_SET_REC_TIMEOUT) ||
+ ir->d.max_timeout == 0) {
+ result = -ENOSYS;
+ break;
+ }
+
+ result = put_user(ir->d.max_timeout, (unsigned long *)arg);
+ break;
+ default:
+ result = -EINVAL;
+ }
+
+ dev_dbg(ir->d.dev, LOGHEAD "ioctl result = %d\n",
+ ir->d.name, ir->d.minor, result);
+
+ mutex_unlock(&ir->irctl_lock);
+
+ return result;
+}
+EXPORT_SYMBOL(lirc_dev_fop_ioctl);
+
+ssize_t lirc_dev_fop_read(struct file *file,
+ char *buffer,
+ size_t length,
+ loff_t *ppos)
+{
+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
+ unsigned char buf[ir->chunk_size];
+ int ret = 0, written = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ dev_dbg(ir->d.dev, LOGHEAD "read called\n", ir->d.name, ir->d.minor);
+
+ if (mutex_lock_interruptible(&ir->irctl_lock))
+ return -ERESTARTSYS;
+ if (!ir->attached) {
+ mutex_unlock(&ir->irctl_lock);
+ return -ENODEV;
+ }
+
+ if (length % ir->chunk_size) {
+ dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n",
+ ir->d.name, ir->d.minor);
+ mutex_unlock(&ir->irctl_lock);
+ return -EINVAL;
+ }
+
+ /*
+ * we add ourselves to the task queue before buffer check
+ * to avoid losing scan code (in case when queue is awaken somewhere
+ * between while condition checking and scheduling)
+ */
+ add_wait_queue(&ir->buf->wait_poll, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ /*
+ * while we didn't provide 'length' bytes, device is opened in blocking
+ * mode and 'copy_to_user' is happy, wait for data.
+ */
+ while (written < length && ret == 0) {
+ if (lirc_buffer_empty(ir->buf)) {
+ /* According to the read(2) man page, 'written' can be
+ * returned as less than 'length', instead of blocking
+ * again, returning -EWOULDBLOCK, or returning
+ * -ERESTARTSYS */
+ if (written)
+ break;
+ if (file->f_flags & O_NONBLOCK) {
+ ret = -EWOULDBLOCK;
+ break;
+ }
+ if (signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ mutex_unlock(&ir->irctl_lock);
+ schedule();
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (mutex_lock_interruptible(&ir->irctl_lock)) {
+ ret = -ERESTARTSYS;
+ remove_wait_queue(&ir->buf->wait_poll, &wait);
+ set_current_state(TASK_RUNNING);
+ goto out_unlocked;
+ }
+
+ if (!ir->attached) {
+ ret = -ENODEV;
+ break;
+ }
+ } else {
+ lirc_buffer_read(ir->buf, buf);
+ ret = copy_to_user((void *)buffer+written, buf,
+ ir->buf->chunk_size);
+ written += ir->buf->chunk_size;
+ }
+ }
+
+ remove_wait_queue(&ir->buf->wait_poll, &wait);
+ set_current_state(TASK_RUNNING);
+ mutex_unlock(&ir->irctl_lock);
+
+out_unlocked:
+ dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n",
+ ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret);
+
+ return ret ? ret : written;
+}
+EXPORT_SYMBOL(lirc_dev_fop_read);
+
+void *lirc_get_pdata(struct file *file)
+{
+ void *data = NULL;
+
+ if (file && file->f_dentry && file->f_dentry->d_inode &&
+ file->f_dentry->d_inode->i_rdev) {
+ struct irctl *ir;
+ ir = irctls[iminor(file->f_dentry->d_inode)];
+ data = ir->d.data;
+ }
+
+ return data;
+}
+EXPORT_SYMBOL(lirc_get_pdata);
+
+
+ssize_t lirc_dev_fop_write(struct file *file, const char *buffer,
+ size_t length, loff_t *ppos)
+{
+ struct irctl *ir = irctls[iminor(file->f_dentry->d_inode)];
+
+ dev_dbg(ir->d.dev, LOGHEAD "write called\n", ir->d.name, ir->d.minor);
+
+ if (!ir->attached)
+ return -ENODEV;
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(lirc_dev_fop_write);
+
+
+static int __init lirc_dev_init(void)
+{
+ int retval;
+
+ lirc_class = class_create(THIS_MODULE, "lirc");
+ if (IS_ERR(lirc_class)) {
+ retval = PTR_ERR(lirc_class);
+ printk(KERN_ERR "lirc_dev: class_create failed\n");
+ goto error;
+ }
+
+ retval = alloc_chrdev_region(&lirc_base_dev, 0, MAX_IRCTL_DEVICES,
+ IRCTL_DEV_NAME);
+ if (retval) {
+ class_destroy(lirc_class);
+ printk(KERN_ERR "lirc_dev: alloc_chrdev_region failed\n");
+ goto error;
+ }
+
+
+ printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, "
+ "major %d \n", MAJOR(lirc_base_dev));
+
+error:
+ return retval;
+}
+
+
+
+static void __exit lirc_dev_exit(void)
+{
+ class_destroy(lirc_class);
+ unregister_chrdev_region(lirc_base_dev, MAX_IRCTL_DEVICES);
+ printk(KERN_INFO "lirc_dev: module unloaded\n");
+}
+
+module_init(lirc_dev_init);
+module_exit(lirc_dev_exit);
+
+MODULE_DESCRIPTION("LIRC base driver module");
+MODULE_AUTHOR("Artur Lipowski");
+MODULE_LICENSE("GPL");
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/drivers/media/IR/lirc_dev.h b/drivers/media/IR/lirc_dev.h
new file mode 100644
index 000000000000..b1f60663cb39
--- /dev/null
+++ b/drivers/media/IR/lirc_dev.h
@@ -0,0 +1,225 @@
+/*
+ * LIRC base driver
+ *
+ * by Artur Lipowski <alipowski@interia.pl>
+ * This code is licensed under GNU GPL
+ *
+ */
+
+#ifndef _LINUX_LIRC_DEV_H
+#define _LINUX_LIRC_DEV_H
+
+#define MAX_IRCTL_DEVICES 4
+#define BUFLEN 16
+
+#define mod(n, div) ((n) % (div))
+
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/ioctl.h>
+#include <linux/poll.h>
+#include <linux/kfifo.h>
+#include <media/lirc.h>
+
+struct lirc_buffer {
+ wait_queue_head_t wait_poll;
+ spinlock_t fifo_lock;
+ unsigned int chunk_size;
+ unsigned int size; /* in chunks */
+ /* Using chunks instead of bytes pretends to simplify boundary checking
+ * And should allow for some performance fine tunning later */
+ struct kfifo fifo;
+ u8 fifo_initialized;
+};
+
+static inline void lirc_buffer_clear(struct lirc_buffer *buf)
+{
+ unsigned long flags;
+
+ if (buf->fifo_initialized) {
+ spin_lock_irqsave(&buf->fifo_lock, flags);
+ kfifo_reset(&buf->fifo);
+ spin_unlock_irqrestore(&buf->fifo_lock, flags);
+ } else
+ WARN(1, "calling %s on an uninitialized lirc_buffer\n",
+ __func__);
+}
+
+static inline int lirc_buffer_init(struct lirc_buffer *buf,
+ unsigned int chunk_size,
+ unsigned int size)
+{
+ int ret;
+
+ init_waitqueue_head(&buf->wait_poll);
+ spin_lock_init(&buf->fifo_lock);
+ buf->chunk_size = chunk_size;
+ buf->size = size;
+ ret = kfifo_alloc(&buf->fifo, size * chunk_size, GFP_KERNEL);
+ if (ret == 0)
+ buf->fifo_initialized = 1;
+
+ return ret;
+}
+
+static inline void lirc_buffer_free(struct lirc_buffer *buf)
+{
+ if (buf->fifo_initialized) {
+ kfifo_free(&buf->fifo);
+ buf->fifo_initialized = 0;
+ } else
+ WARN(1, "calling %s on an uninitialized lirc_buffer\n",
+ __func__);
+}
+
+static inline int lirc_buffer_len(struct lirc_buffer *buf)
+{
+ int len;
+ unsigned long flags;
+
+ spin_lock_irqsave(&buf->fifo_lock, flags);
+ len = kfifo_len(&buf->fifo);
+ spin_unlock_irqrestore(&buf->fifo_lock, flags);
+
+ return len;
+}
+
+static inline int lirc_buffer_full(struct lirc_buffer *buf)
+{
+ return lirc_buffer_len(buf) == buf->size * buf->chunk_size;
+}
+
+static inline int lirc_buffer_empty(struct lirc_buffer *buf)
+{
+ return !lirc_buffer_len(buf);
+}
+
+static inline int lirc_buffer_available(struct lirc_buffer *buf)
+{
+ return buf->size - (lirc_buffer_len(buf) / buf->chunk_size);
+}
+
+static inline unsigned int lirc_buffer_read(struct lirc_buffer *buf,
+ unsigned char *dest)
+{
+ unsigned int ret = 0;
+
+ if (lirc_buffer_len(buf) >= buf->chunk_size)
+ ret = kfifo_out_locked(&buf->fifo, dest, buf->chunk_size,
+ &buf->fifo_lock);
+ return ret;
+
+}
+
+static inline unsigned int lirc_buffer_write(struct lirc_buffer *buf,
+ unsigned char *orig)
+{
+ unsigned int ret;
+
+ ret = kfifo_in_locked(&buf->fifo, orig, buf->chunk_size,
+ &buf->fifo_lock);
+
+ return ret;
+}
+
+struct lirc_driver {
+ char name[40];
+ int minor;
+ unsigned long code_length;
+ unsigned int buffer_size; /* in chunks holding one code each */
+ int sample_rate;
+ unsigned long features;
+
+ unsigned int chunk_size;
+
+ void *data;
+ int min_timeout;
+ int max_timeout;
+ int (*add_to_buf) (void *data, struct lirc_buffer *buf);
+ struct lirc_buffer *rbuf;
+ int (*set_use_inc) (void *data);
+ void (*set_use_dec) (void *data);
+ struct file_operations *fops;
+ struct device *dev;
+ struct module *owner;
+};
+
+/* name:
+ * this string will be used for logs
+ *
+ * minor:
+ * indicates minor device (/dev/lirc) number for registered driver
+ * if caller fills it with negative value, then the first free minor
+ * number will be used (if available)
+ *
+ * code_length:
+ * length of the remote control key code expressed in bits
+ *
+ * sample_rate:
+ *
+ * data:
+ * it may point to any driver data and this pointer will be passed to
+ * all callback functions
+ *
+ * add_to_buf:
+ * add_to_buf will be called after specified period of the time or
+ * triggered by the external event, this behavior depends on value of
+ * the sample_rate this function will be called in user context. This
+ * routine should return 0 if data was added to the buffer and
+ * -ENODATA if none was available. This should add some number of bits
+ * evenly divisible by code_length to the buffer
+ *
+ * rbuf:
+ * if not NULL, it will be used as a read buffer, you will have to
+ * write to the buffer by other means, like irq's (see also
+ * lirc_serial.c).
+ *
+ * set_use_inc:
+ * set_use_inc will be called after device is opened
+ *
+ * set_use_dec:
+ * set_use_dec will be called after device is closed
+ *
+ * fops:
+ * file_operations for drivers which don't fit the current driver model.
+ *
+ * Some ioctl's can be directly handled by lirc_dev if the driver's
+ * ioctl function is NULL or if it returns -ENOIOCTLCMD (see also
+ * lirc_serial.c).
+ *
+ * owner:
+ * the module owning this struct
+ *
+ */
+
+
+/* following functions can be called ONLY from user context
+ *
+ * returns negative value on error or minor number
+ * of the registered device if success
+ * contents of the structure pointed by p is copied
+ */
+extern int lirc_register_driver(struct lirc_driver *d);
+
+/* returns negative value on error or 0 if success
+*/
+extern int lirc_unregister_driver(int minor);
+
+/* Returns the private data stored in the lirc_driver
+ * associated with the given device file pointer.
+ */
+void *lirc_get_pdata(struct file *file);
+
+/* default file operations
+ * used by drivers if they override only some operations
+ */
+int lirc_dev_fop_open(struct inode *inode, struct file *file);
+int lirc_dev_fop_close(struct inode *inode, struct file *file);
+unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait);
+long lirc_dev_fop_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+ssize_t lirc_dev_fop_read(struct file *file, char *buffer, size_t length,
+ loff_t *ppos);
+ssize_t lirc_dev_fop_write(struct file *file, const char *buffer, size_t length,
+ loff_t *ppos);
+
+#endif
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c
new file mode 100644
index 000000000000..78bf7f77a1a0
--- /dev/null
+++ b/drivers/media/IR/mceusb.c
@@ -0,0 +1,1143 @@
+/*
+ * Driver for USB Windows Media Center Ed. eHome Infrared Transceivers
+ *
+ * Copyright (c) 2010 by Jarod Wilson <jarod@redhat.com>
+ *
+ * Based on the original lirc_mceusb and lirc_mceusb2 drivers, by Dan
+ * Conti, Martin Blatter and Daniel Melander, the latter of which was
+ * in turn also based on the lirc_atiusb driver by Paul Miller. The
+ * two mce drivers were merged into one by Jarod Wilson, with transmit
+ * support for the 1st-gen device added primarily by Patrick Calhoun,
+ * with a bit of tweaks by Jarod. Debugging improvements and proper
+ * support for what appears to be 3rd-gen hardware added by Jarod.
+ * Initial port from lirc driver to ir-core drivery by Jarod, based
+ * partially on a port to an earlier proposed IR infrastructure by
+ * Jon Smirl, which included enhancements and simplifications to the
+ * incoming IR buffer parsing routines.
+ *
+ *
+ * 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/device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/input.h>
+#include <media/ir-core.h>
+#include <media/ir-common.h>
+
+#define DRIVER_VERSION "1.91"
+#define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
+#define DRIVER_DESC "Windows Media Center Ed. eHome Infrared Transceiver " \
+ "device driver"
+#define DRIVER_NAME "mceusb"
+
+#define USB_BUFLEN 32 /* USB reception buffer length */
+#define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */
+#define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */
+
+/* MCE constants */
+#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */
+#define MCE_TIME_UNIT 50 /* Approx 50us resolution */
+#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */
+#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */
+#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */
+#define MCE_CONTROL_HEADER 0x9F /* MCE status header */
+#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */
+#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */
+#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */
+#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */
+#define MCE_PULSE_MASK 0x7F /* Pulse mask */
+#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */
+#define MCE_PACKET_LENGTH_MASK 0x1F /* Packet length mask */
+
+
+/* module parameters */
+#ifdef CONFIG_USB_DEBUG
+static int debug = 1;
+#else
+static int debug;
+#endif
+
+/* general constants */
+#define SEND_FLAG_IN_PROGRESS 1
+#define SEND_FLAG_COMPLETE 2
+#define RECV_FLAG_IN_PROGRESS 3
+#define RECV_FLAG_COMPLETE 4
+
+#define MCEUSB_RX 1
+#define MCEUSB_TX 2
+
+#define VENDOR_PHILIPS 0x0471
+#define VENDOR_SMK 0x0609
+#define VENDOR_TATUNG 0x1460
+#define VENDOR_GATEWAY 0x107b
+#define VENDOR_SHUTTLE 0x1308
+#define VENDOR_SHUTTLE2 0x051c
+#define VENDOR_MITSUMI 0x03ee
+#define VENDOR_TOPSEED 0x1784
+#define VENDOR_RICAVISION 0x179d
+#define VENDOR_ITRON 0x195d
+#define VENDOR_FIC 0x1509
+#define VENDOR_LG 0x043e
+#define VENDOR_MICROSOFT 0x045e
+#define VENDOR_FORMOSA 0x147a
+#define VENDOR_FINTEK 0x1934
+#define VENDOR_PINNACLE 0x2304
+#define VENDOR_ECS 0x1019
+#define VENDOR_WISTRON 0x0fb8
+#define VENDOR_COMPRO 0x185b
+#define VENDOR_NORTHSTAR 0x04eb
+#define VENDOR_REALTEK 0x0bda
+#define VENDOR_TIVO 0x105a
+
+static struct usb_device_id mceusb_dev_table[] = {
+ /* Original Microsoft MCE IR Transceiver (often HP-branded) */
+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
+ /* Philips Infrared Transceiver - Sahara branded */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x0608) },
+ /* Philips Infrared Transceiver - HP branded */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
+ /* Philips SRM5100 */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x060d) },
+ /* Philips Infrared Transceiver - Omaura */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x060f) },
+ /* Philips Infrared Transceiver - Spinel plus */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x0613) },
+ /* Philips eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_PHILIPS, 0x0815) },
+ /* Realtek MCE IR Receiver */
+ { USB_DEVICE(VENDOR_REALTEK, 0x0161) },
+ /* SMK/Toshiba G83C0004D410 */
+ { USB_DEVICE(VENDOR_SMK, 0x031d) },
+ /* SMK eHome Infrared Transceiver (Sony VAIO) */
+ { USB_DEVICE(VENDOR_SMK, 0x0322) },
+ /* bundled with Hauppauge PVR-150 */
+ { USB_DEVICE(VENDOR_SMK, 0x0334) },
+ /* SMK eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_SMK, 0x0338) },
+ /* Tatung eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TATUNG, 0x9150) },
+ /* Shuttle eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) },
+ /* Shuttle eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) },
+ /* Gateway eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_GATEWAY, 0x3009) },
+ /* Mitsumi */
+ { USB_DEVICE(VENDOR_MITSUMI, 0x2501) },
+ /* Topseed eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
+ /* Topseed HP eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
+ /* Topseed eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
+ /* Topseed eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
+ /* Topseed eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
+ /* Topseed eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
+ /* Ricavision internal Infrared Transceiver */
+ { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
+ /* Itron ione Libra Q-11 */
+ { USB_DEVICE(VENDOR_ITRON, 0x7002) },
+ /* FIC eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_FIC, 0x9242) },
+ /* LG eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_LG, 0x9803) },
+ /* Microsoft MCE Infrared Transceiver */
+ { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) },
+ /* Formosa eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe015) },
+ /* Formosa21 / eHome Infrared Receiver */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
+ /* Formosa aim / Trust MCE Infrared Receiver */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
+ /* Formosa Industrial Computing / Beanbag Emulation Device */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
+ /* Formosa21 / eHome Infrared Receiver */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03a) },
+ /* Formosa Industrial Computing AIM IR605/A */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) },
+ /* Formosa Industrial Computing */
+ { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) },
+ /* Fintek eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_FINTEK, 0x0602) },
+ /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */
+ { USB_DEVICE(VENDOR_FINTEK, 0x0702) },
+ /* Pinnacle Remote Kit */
+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
+ /* Elitegroup Computer Systems IR */
+ { USB_DEVICE(VENDOR_ECS, 0x0f38) },
+ /* Wistron Corp. eHome Infrared Receiver */
+ { USB_DEVICE(VENDOR_WISTRON, 0x0002) },
+ /* Compro K100 */
+ { USB_DEVICE(VENDOR_COMPRO, 0x3020) },
+ /* Compro K100 v2 */
+ { USB_DEVICE(VENDOR_COMPRO, 0x3082) },
+ /* Northstar Systems, Inc. eHome Infrared Transceiver */
+ { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
+ /* TiVo PC IR Receiver */
+ { USB_DEVICE(VENDOR_TIVO, 0x2000) },
+ /* Terminating entry */
+ { }
+};
+
+static struct usb_device_id gen3_list[] = {
+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
+ {}
+};
+
+static struct usb_device_id microsoft_gen1_list[] = {
+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
+ {}
+};
+
+static struct usb_device_id std_tx_mask_list[] = {
+ { USB_DEVICE(VENDOR_MICROSOFT, 0x006d) },
+ { USB_DEVICE(VENDOR_PHILIPS, 0x060c) },
+ { USB_DEVICE(VENDOR_SMK, 0x031d) },
+ { USB_DEVICE(VENDOR_SMK, 0x0322) },
+ { USB_DEVICE(VENDOR_SMK, 0x0334) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0001) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0006) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
+ { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
+ { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
+ {}
+};
+
+/* data structure for each usb transceiver */
+struct mceusb_dev {
+ /* ir-core bits */
+ struct ir_input_dev *irdev;
+ struct ir_dev_props *props;
+ struct ir_raw_event rawir;
+
+ /* core device bits */
+ struct device *dev;
+ struct input_dev *idev;
+
+ /* usb */
+ struct usb_device *usbdev;
+ struct urb *urb_in;
+ struct usb_endpoint_descriptor *usb_ep_in;
+ struct usb_endpoint_descriptor *usb_ep_out;
+
+ /* buffers and dma */
+ unsigned char *buf_in;
+ unsigned int len_in;
+ u8 cmd; /* MCE command type */
+ u8 rem; /* Remaining IR data bytes in packet */
+ dma_addr_t dma_in;
+ dma_addr_t dma_out;
+
+ struct {
+ u32 connected:1;
+ u32 tx_mask_inverted:1;
+ u32 microsoft_gen1:1;
+ u32 reserved:29;
+ } flags;
+
+ /* transmit support */
+ int send_flags;
+ u32 carrier;
+ unsigned char tx_mask;
+
+ char name[128];
+ char phys[64];
+};
+
+/*
+ * MCE Device Command Strings
+ * Device command responses vary from device to device...
+ * - DEVICE_RESET resets the hardware to its default state
+ * - GET_REVISION fetches the hardware/software revision, common
+ * replies are ff 0b 45 ff 1b 08 and ff 0b 50 ff 1b 42
+ * - GET_CARRIER_FREQ gets the carrier mode and frequency of the
+ * device, with replies in the form of 9f 06 MM FF, where MM is 0-3,
+ * meaning clk of 10000000, 2500000, 625000 or 156250, and FF is
+ * ((clk / frequency) - 1)
+ * - GET_RX_TIMEOUT fetches the receiver timeout in units of 50us,
+ * response in the form of 9f 0c msb lsb
+ * - GET_TX_BITMASK fetches the transmitter bitmask, replies in
+ * the form of 9f 08 bm, where bm is the bitmask
+ * - GET_RX_SENSOR fetches the RX sensor setting -- long-range
+ * general use one or short-range learning one, in the form of
+ * 9f 14 ss, where ss is either 01 for long-range or 02 for short
+ * - SET_CARRIER_FREQ sets a new carrier mode and frequency
+ * - SET_TX_BITMASK sets the transmitter bitmask
+ * - SET_RX_TIMEOUT sets the receiver timeout
+ * - SET_RX_SENSOR sets which receiver sensor to use
+ */
+static char DEVICE_RESET[] = {0x00, 0xff, 0xaa};
+static char GET_REVISION[] = {0xff, 0x0b};
+static char GET_UNKNOWN[] = {0xff, 0x18};
+static char GET_UNKNOWN2[] = {0x9f, 0x05};
+static char GET_CARRIER_FREQ[] = {0x9f, 0x07};
+static char GET_RX_TIMEOUT[] = {0x9f, 0x0d};
+static char GET_TX_BITMASK[] = {0x9f, 0x13};
+static char GET_RX_SENSOR[] = {0x9f, 0x15};
+/* sub in desired values in lower byte or bytes for full command */
+/* FIXME: make use of these for transmit.
+static char SET_CARRIER_FREQ[] = {0x9f, 0x06, 0x00, 0x00};
+static char SET_TX_BITMASK[] = {0x9f, 0x08, 0x00};
+static char SET_RX_TIMEOUT[] = {0x9f, 0x0c, 0x00, 0x00};
+static char SET_RX_SENSOR[] = {0x9f, 0x14, 0x00};
+*/
+
+static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
+ int len, bool out)
+{
+ char codes[USB_BUFLEN * 3 + 1];
+ char inout[9];
+ int i;
+ u8 cmd, subcmd, data1, data2;
+ struct device *dev = ir->dev;
+ int idx = 0;
+
+ /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
+ if (ir->flags.microsoft_gen1 && !out)
+ idx = 2;
+
+ if (len <= idx)
+ return;
+
+ for (i = 0; i < len && i < USB_BUFLEN; i++)
+ snprintf(codes + i * 3, 4, "%02x ", buf[i] & 0xFF);
+
+ dev_info(dev, "%sx data: %s (length=%d)\n",
+ (out ? "t" : "r"), codes, len);
+
+ if (out)
+ strcpy(inout, "Request\0");
+ else
+ strcpy(inout, "Got\0");
+
+ cmd = buf[idx] & 0xff;
+ subcmd = buf[idx + 1] & 0xff;
+ data1 = buf[idx + 2] & 0xff;
+ data2 = buf[idx + 3] & 0xff;
+
+ switch (cmd) {
+ case 0x00:
+ if (subcmd == 0xff && data1 == 0xaa)
+ dev_info(dev, "Device reset requested\n");
+ else
+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+ cmd, subcmd);
+ break;
+ case 0xff:
+ switch (subcmd) {
+ case 0x0b:
+ if (len == 2)
+ dev_info(dev, "Get hw/sw rev?\n");
+ else
+ dev_info(dev, "hw/sw rev 0x%02x 0x%02x "
+ "0x%02x 0x%02x\n", data1, data2,
+ buf[idx + 4], buf[idx + 5]);
+ break;
+ case 0xaa:
+ dev_info(dev, "Device reset requested\n");
+ break;
+ case 0xfe:
+ dev_info(dev, "Previous command not supported\n");
+ break;
+ case 0x18:
+ case 0x1b:
+ default:
+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+ cmd, subcmd);
+ break;
+ }
+ break;
+ case 0x9f:
+ switch (subcmd) {
+ case 0x03:
+ dev_info(dev, "Ping\n");
+ break;
+ case 0x04:
+ dev_info(dev, "Resp to 9f 05 of 0x%02x 0x%02x\n",
+ data1, data2);
+ break;
+ case 0x06:
+ dev_info(dev, "%s carrier mode and freq of "
+ "0x%02x 0x%02x\n", inout, data1, data2);
+ break;
+ case 0x07:
+ dev_info(dev, "Get carrier mode and freq\n");
+ break;
+ case 0x08:
+ dev_info(dev, "%s transmit blaster mask of 0x%02x\n",
+ inout, data1);
+ break;
+ case 0x0c:
+ /* value is in units of 50us, so x*50/100 or x/2 ms */
+ dev_info(dev, "%s receive timeout of %d ms\n",
+ inout, ((data1 << 8) | data2) / 2);
+ break;
+ case 0x0d:
+ dev_info(dev, "Get receive timeout\n");
+ break;
+ case 0x13:
+ dev_info(dev, "Get transmit blaster mask\n");
+ break;
+ case 0x14:
+ dev_info(dev, "%s %s-range receive sensor in use\n",
+ inout, data1 == 0x02 ? "short" : "long");
+ break;
+ case 0x15:
+ if (len == 2)
+ dev_info(dev, "Get receive sensor\n");
+ else
+ dev_info(dev, "Received pulse count is %d\n",
+ ((data1 << 8) | data2));
+ break;
+ case 0xfe:
+ dev_info(dev, "Error! Hardware is likely wedged...\n");
+ break;
+ case 0x05:
+ case 0x09:
+ case 0x0f:
+ default:
+ dev_info(dev, "Unknown command 0x%02x 0x%02x\n",
+ cmd, subcmd);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void usb_async_callback(struct urb *urb, struct pt_regs *regs)
+{
+ struct mceusb_dev *ir;
+ int len;
+
+ if (!urb)
+ return;
+
+ ir = urb->context;
+ if (ir) {
+ len = urb->actual_length;
+
+ dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
+ urb->status, len);
+
+ if (debug)
+ mceusb_dev_printdata(ir, urb->transfer_buffer,
+ len, true);
+ }
+
+}
+
+/* request incoming or send outgoing usb packet - used to initialize remote */
+static void mce_request_packet(struct mceusb_dev *ir,
+ struct usb_endpoint_descriptor *ep,
+ unsigned char *data, int size, int urb_type)
+{
+ int res;
+ struct urb *async_urb;
+ struct device *dev = ir->dev;
+ unsigned char *async_buf;
+
+ if (urb_type == MCEUSB_TX) {
+ async_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (unlikely(!async_urb)) {
+ dev_err(dev, "Error, couldn't allocate urb!\n");
+ return;
+ }
+
+ async_buf = kzalloc(size, GFP_KERNEL);
+ if (!async_buf) {
+ dev_err(dev, "Error, couldn't allocate buf!\n");
+ usb_free_urb(async_urb);
+ return;
+ }
+
+ /* outbound data */
+ usb_fill_int_urb(async_urb, ir->usbdev,
+ usb_sndintpipe(ir->usbdev, ep->bEndpointAddress),
+ async_buf, size, (usb_complete_t) usb_async_callback,
+ ir, ep->bInterval);
+ memcpy(async_buf, data, size);
+
+ } else if (urb_type == MCEUSB_RX) {
+ /* standard request */
+ async_urb = ir->urb_in;
+ ir->send_flags = RECV_FLAG_IN_PROGRESS;
+
+ } else {
+ dev_err(dev, "Error! Unknown urb type %d\n", urb_type);
+ return;
+ }
+
+ dev_dbg(dev, "receive request called (size=%#x)\n", size);
+
+ async_urb->transfer_buffer_length = size;
+ async_urb->dev = ir->usbdev;
+
+ res = usb_submit_urb(async_urb, GFP_ATOMIC);
+ if (res) {
+ dev_dbg(dev, "receive request FAILED! (res=%d)\n", res);
+ return;
+ }
+ dev_dbg(dev, "receive request complete (res=%d)\n", res);
+}
+
+static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
+{
+ mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX);
+}
+
+static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
+{
+ mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX);
+}
+
+/* Send data out the IR blaster port(s) */
+static int mceusb_tx_ir(void *priv, int *txbuf, u32 n)
+{
+ struct mceusb_dev *ir = priv;
+ int i, ret = 0;
+ int count, cmdcount = 0;
+ unsigned char *cmdbuf; /* MCE command buffer */
+ long signal_duration = 0; /* Singnal length in us */
+ struct timeval start_time, end_time;
+
+ do_gettimeofday(&start_time);
+
+ count = n / sizeof(int);
+
+ cmdbuf = kzalloc(sizeof(int) * MCE_CMDBUF_SIZE, GFP_KERNEL);
+ if (!cmdbuf)
+ return -ENOMEM;
+
+ /* MCE tx init header */
+ cmdbuf[cmdcount++] = MCE_CONTROL_HEADER;
+ cmdbuf[cmdcount++] = 0x08;
+ cmdbuf[cmdcount++] = ir->tx_mask;
+
+ /* Generate mce packet data */
+ for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) {
+ signal_duration += txbuf[i];
+ txbuf[i] = txbuf[i] / MCE_TIME_UNIT;
+
+ do { /* loop to support long pulses/spaces > 127*50us=6.35ms */
+
+ /* Insert mce packet header every 4th entry */
+ if ((cmdcount < MCE_CMDBUF_SIZE) &&
+ (cmdcount - MCE_TX_HEADER_LENGTH) %
+ MCE_CODE_LENGTH == 0)
+ cmdbuf[cmdcount++] = MCE_PACKET_HEADER;
+
+ /* Insert mce packet data */
+ if (cmdcount < MCE_CMDBUF_SIZE)
+ cmdbuf[cmdcount++] =
+ (txbuf[i] < MCE_PULSE_BIT ?
+ txbuf[i] : MCE_MAX_PULSE_LENGTH) |
+ (i & 1 ? 0x00 : MCE_PULSE_BIT);
+ else {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ } while ((txbuf[i] > MCE_MAX_PULSE_LENGTH) &&
+ (txbuf[i] -= MCE_MAX_PULSE_LENGTH));
+ }
+
+ /* Fix packet length in last header */
+ cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] =
+ 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1;
+
+ /* Check if we have room for the empty packet at the end */
+ if (cmdcount >= MCE_CMDBUF_SIZE) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* All mce commands end with an empty packet (0x80) */
+ cmdbuf[cmdcount++] = 0x80;
+
+ /* Transmit the command to the mce device */
+ mce_async_out(ir, cmdbuf, cmdcount);
+
+ /*
+ * The lircd gap calculation expects the write function to
+ * wait the time it takes for the ircommand to be sent before
+ * it returns.
+ */
+ do_gettimeofday(&end_time);
+ signal_duration -= (end_time.tv_usec - start_time.tv_usec) +
+ (end_time.tv_sec - start_time.tv_sec) * 1000000;
+
+ /* delay with the closest number of ticks */
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(usecs_to_jiffies(signal_duration));
+
+out:
+ kfree(cmdbuf);
+ return ret ? ret : n;
+}
+
+/* Sets active IR outputs -- mce devices typically (all?) have two */
+static int mceusb_set_tx_mask(void *priv, u32 mask)
+{
+ struct mceusb_dev *ir = priv;
+
+ if (ir->flags.tx_mask_inverted)
+ ir->tx_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1;
+ else
+ ir->tx_mask = mask;
+
+ return 0;
+}
+
+/* Sets the send carrier frequency and mode */
+static int mceusb_set_tx_carrier(void *priv, u32 carrier)
+{
+ struct mceusb_dev *ir = priv;
+ int clk = 10000000;
+ int prescaler = 0, divisor = 0;
+ unsigned char cmdbuf[4] = { 0x9f, 0x06, 0x00, 0x00 };
+
+ /* Carrier has changed */
+ if (ir->carrier != carrier) {
+
+ if (carrier == 0) {
+ ir->carrier = carrier;
+ cmdbuf[2] = 0x01;
+ cmdbuf[3] = 0x80;
+ dev_dbg(ir->dev, "%s: disabling carrier "
+ "modulation\n", __func__);
+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+ return carrier;
+ }
+
+ for (prescaler = 0; prescaler < 4; ++prescaler) {
+ divisor = (clk >> (2 * prescaler)) / carrier;
+ if (divisor <= 0xFF) {
+ ir->carrier = carrier;
+ cmdbuf[2] = prescaler;
+ cmdbuf[3] = divisor;
+ dev_dbg(ir->dev, "%s: requesting %u HZ "
+ "carrier\n", __func__, carrier);
+
+ /* Transmit new carrier to mce device */
+ mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
+ return carrier;
+ }
+ }
+
+ return -EINVAL;
+
+ }
+
+ return carrier;
+}
+
+static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len)
+{
+ struct ir_raw_event rawir = { .pulse = false, .duration = 0 };
+ int i, start_index = 0;
+ u8 hdr = MCE_CONTROL_HEADER;
+
+ /* skip meaningless 0xb1 0x60 header bytes on orig receiver */
+ if (ir->flags.microsoft_gen1)
+ start_index = 2;
+
+ for (i = start_index; i < buf_len;) {
+ if (ir->rem == 0) {
+ /* decode mce packets of the form (84),AA,BB,CC,DD */
+ /* IR data packets can span USB messages - rem */
+ hdr = ir->buf_in[i];
+ ir->rem = (hdr & MCE_PACKET_LENGTH_MASK);
+ ir->cmd = (hdr & ~MCE_PACKET_LENGTH_MASK);
+ dev_dbg(ir->dev, "New data. rem: 0x%02x, cmd: 0x%02x\n",
+ ir->rem, ir->cmd);
+ i++;
+ }
+
+ /* don't process MCE commands */
+ if (hdr == MCE_CONTROL_HEADER || hdr == 0xff) {
+ ir->rem = 0;
+ return;
+ }
+
+ for (; (ir->rem > 0) && (i < buf_len); i++) {
+ ir->rem--;
+
+ rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0);
+ rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
+ * MCE_TIME_UNIT * 1000;
+
+ if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) {
+ if (ir->rawir.pulse == rawir.pulse)
+ ir->rawir.duration += rawir.duration;
+ else {
+ ir->rawir.duration = rawir.duration;
+ ir->rawir.pulse = rawir.pulse;
+ }
+ continue;
+ }
+ rawir.duration += ir->rawir.duration;
+ ir->rawir.duration = 0;
+ ir->rawir.pulse = rawir.pulse;
+
+ dev_dbg(ir->dev, "Storing %s with duration %d\n",
+ rawir.pulse ? "pulse" : "space",
+ rawir.duration);
+
+ ir_raw_event_store(ir->idev, &rawir);
+ }
+
+ if (ir->buf_in[i] == 0x80 || ir->buf_in[i] == 0x9f)
+ ir->rem = 0;
+
+ dev_dbg(ir->dev, "calling ir_raw_event_handle\n");
+ ir_raw_event_handle(ir->idev);
+ }
+}
+
+static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs)
+{
+ struct mceusb_dev *ir;
+ int buf_len;
+
+ if (!urb)
+ return;
+
+ ir = urb->context;
+ if (!ir) {
+ usb_unlink_urb(urb);
+ return;
+ }
+
+ buf_len = urb->actual_length;
+
+ if (debug)
+ mceusb_dev_printdata(ir, urb->transfer_buffer, buf_len, false);
+
+ if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
+ ir->send_flags = SEND_FLAG_COMPLETE;
+ dev_dbg(&ir->irdev->dev, "setup answer received %d bytes\n",
+ buf_len);
+ }
+
+ switch (urb->status) {
+ /* success */
+ case 0:
+ mceusb_process_ir_data(ir, buf_len);
+ break;
+
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ usb_unlink_urb(urb);
+ return;
+
+ case -EPIPE:
+ default:
+ break;
+ }
+
+ usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static void mceusb_gen1_init(struct mceusb_dev *ir)
+{
+ int ret;
+ int maxp = ir->len_in;
+ struct device *dev = ir->dev;
+ char *data;
+
+ data = kzalloc(USB_CTRL_MSG_SZ, GFP_KERNEL);
+ if (!data) {
+ dev_err(dev, "%s: memory allocation failed!\n", __func__);
+ return;
+ }
+
+ /*
+ * This is a strange one. Windows issues a set address to the device
+ * on the receive control pipe and expect a certain value pair back
+ */
+ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
+ USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
+ data, USB_CTRL_MSG_SZ, HZ * 3);
+ dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
+ dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
+ __func__, data[0], data[1]);
+
+ /* set feature: bit rate 38400 bps */
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
+ USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
+ 0xc04e, 0x0000, NULL, 0, HZ * 3);
+
+ dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
+
+ /* bRequest 4: set char length to 8 bits */
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
+ 4, USB_TYPE_VENDOR,
+ 0x0808, 0x0000, NULL, 0, HZ * 3);
+ dev_dbg(dev, "%s - retB = %d\n", __func__, ret);
+
+ /* bRequest 2: set handshaking to use DTR/DSR */
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
+ 2, USB_TYPE_VENDOR,
+ 0x0000, 0x0100, NULL, 0, HZ * 3);
+ dev_dbg(dev, "%s - retC = %d\n", __func__, ret);
+
+ /* device reset */
+ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* get hw/sw revision? */
+ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
+ mce_sync_in(ir, NULL, maxp);
+
+ kfree(data);
+};
+
+static void mceusb_gen2_init(struct mceusb_dev *ir)
+{
+ int maxp = ir->len_in;
+
+ /* device reset */
+ mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* get hw/sw revision? */
+ mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* unknown what the next two actually return... */
+ mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
+ mce_sync_in(ir, NULL, maxp);
+ mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
+ mce_sync_in(ir, NULL, maxp);
+}
+
+static void mceusb_get_parameters(struct mceusb_dev *ir)
+{
+ int maxp = ir->len_in;
+
+ /* get the carrier and frequency */
+ mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* get the transmitter bitmask */
+ mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* get receiver timeout value */
+ mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
+ mce_sync_in(ir, NULL, maxp);
+
+ /* get receiver sensor setting */
+ mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
+ mce_sync_in(ir, NULL, maxp);
+}
+
+static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir)
+{
+ struct input_dev *idev;
+ struct ir_dev_props *props;
+ struct ir_input_dev *irdev;
+ struct device *dev = ir->dev;
+ int ret = -ENODEV;
+
+ idev = input_allocate_device();
+ if (!idev) {
+ dev_err(dev, "remote input dev allocation failed\n");
+ goto idev_alloc_failed;
+ }
+
+ ret = -ENOMEM;
+ props = kzalloc(sizeof(struct ir_dev_props), GFP_KERNEL);
+ if (!props) {
+ dev_err(dev, "remote ir dev props allocation failed\n");
+ goto props_alloc_failed;
+ }
+
+ irdev = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL);
+ if (!irdev) {
+ dev_err(dev, "remote ir input dev allocation failed\n");
+ goto ir_dev_alloc_failed;
+ }
+
+ snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome "
+ "Infrared Remote Transceiver (%04x:%04x)",
+ le16_to_cpu(ir->usbdev->descriptor.idVendor),
+ le16_to_cpu(ir->usbdev->descriptor.idProduct));
+
+ idev->name = ir->name;
+ usb_make_path(ir->usbdev, ir->phys, sizeof(ir->phys));
+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
+ idev->phys = ir->phys;
+
+ props->priv = ir;
+ props->driver_type = RC_DRIVER_IR_RAW;
+ props->allowed_protos = IR_TYPE_ALL;
+ props->s_tx_mask = mceusb_set_tx_mask;
+ props->s_tx_carrier = mceusb_set_tx_carrier;
+ props->tx_ir = mceusb_tx_ir;
+
+ ir->props = props;
+ ir->irdev = irdev;
+
+ input_set_drvdata(idev, irdev);
+
+ ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME);
+ if (ret < 0) {
+ dev_err(dev, "remote input device register failed\n");
+ goto irdev_failed;
+ }
+
+ return idev;
+
+irdev_failed:
+ kfree(irdev);
+ir_dev_alloc_failed:
+ kfree(props);
+props_alloc_failed:
+ input_free_device(idev);
+idev_alloc_failed:
+ return NULL;
+}
+
+static int __devinit mceusb_dev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct usb_host_interface *idesc;
+ struct usb_endpoint_descriptor *ep = NULL;
+ struct usb_endpoint_descriptor *ep_in = NULL;
+ struct usb_endpoint_descriptor *ep_out = NULL;
+ struct usb_host_config *config;
+ struct mceusb_dev *ir = NULL;
+ int pipe, maxp, i;
+ char buf[63], name[128] = "";
+ bool is_gen3;
+ bool is_microsoft_gen1;
+ bool tx_mask_inverted;
+
+ dev_dbg(&intf->dev, ": %s called\n", __func__);
+
+ config = dev->actconfig;
+ idesc = intf->cur_altsetting;
+
+ is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
+ is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
+ tx_mask_inverted = usb_match_id(intf, std_tx_mask_list) ? 0 : 1;
+
+ /* step through the endpoints to find first bulk in and out endpoint */
+ for (i = 0; i < idesc->desc.bNumEndpoints; ++i) {
+ ep = &idesc->endpoint[i].desc;
+
+ if ((ep_in == NULL)
+ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ == USB_DIR_IN)
+ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_BULK)
+ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT))) {
+
+ ep_in = ep;
+ ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
+ ep_in->bInterval = 1;
+ dev_dbg(&intf->dev, ": acceptable inbound endpoint "
+ "found\n");
+ }
+
+ if ((ep_out == NULL)
+ && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ == USB_DIR_OUT)
+ && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_BULK)
+ || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_INT))) {
+
+ ep_out = ep;
+ ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
+ ep_out->bInterval = 1;
+ dev_dbg(&intf->dev, ": acceptable outbound endpoint "
+ "found\n");
+ }
+ }
+ if (ep_in == NULL) {
+ dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n");
+ return -ENODEV;
+ }
+
+ pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress);
+ maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe));
+
+ ir = kzalloc(sizeof(struct mceusb_dev), GFP_KERNEL);
+ if (!ir)
+ goto mem_alloc_fail;
+
+ ir->buf_in = usb_alloc_coherent(dev, maxp, GFP_ATOMIC, &ir->dma_in);
+ if (!ir->buf_in)
+ goto buf_in_alloc_fail;
+
+ ir->urb_in = usb_alloc_urb(0, GFP_KERNEL);
+ if (!ir->urb_in)
+ goto urb_in_alloc_fail;
+
+ ir->usbdev = dev;
+ ir->dev = &intf->dev;
+ ir->len_in = maxp;
+ ir->flags.microsoft_gen1 = is_microsoft_gen1;
+ ir->flags.tx_mask_inverted = tx_mask_inverted;
+
+ /* Saving usb interface data for use by the transmitter routine */
+ ir->usb_ep_in = ep_in;
+ ir->usb_ep_out = ep_out;
+
+ if (dev->descriptor.iManufacturer
+ && usb_string(dev, dev->descriptor.iManufacturer,
+ buf, sizeof(buf)) > 0)
+ strlcpy(name, buf, sizeof(name));
+ if (dev->descriptor.iProduct
+ && usb_string(dev, dev->descriptor.iProduct,
+ buf, sizeof(buf)) > 0)
+ snprintf(name + strlen(name), sizeof(name) - strlen(name),
+ " %s", buf);
+
+ ir->idev = mceusb_init_input_dev(ir);
+ if (!ir->idev)
+ goto input_dev_fail;
+
+ /* flush buffers on the device */
+ mce_sync_in(ir, NULL, maxp);
+ mce_sync_in(ir, NULL, maxp);
+
+ /* wire up inbound data handler */
+ usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
+ maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval);
+ ir->urb_in->transfer_dma = ir->dma_in;
+ ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+ /* initialize device */
+ if (ir->flags.microsoft_gen1)
+ mceusb_gen1_init(ir);
+ else if (!is_gen3)
+ mceusb_gen2_init(ir);
+
+ mceusb_get_parameters(ir);
+
+ mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK);
+
+ usb_set_intfdata(intf, ir);
+
+ dev_info(&intf->dev, "Registered %s on usb%d:%d\n", name,
+ dev->bus->busnum, dev->devnum);
+
+ return 0;
+
+ /* Error-handling path */
+input_dev_fail:
+ usb_free_urb(ir->urb_in);
+urb_in_alloc_fail:
+ usb_free_coherent(dev, maxp, ir->buf_in, ir->dma_in);
+buf_in_alloc_fail:
+ kfree(ir);
+mem_alloc_fail:
+ dev_err(&intf->dev, "%s: device setup failed!\n", __func__);
+
+ return -ENOMEM;
+}
+
+
+static void __devexit mceusb_dev_disconnect(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ struct mceusb_dev *ir = usb_get_intfdata(intf);
+
+ usb_set_intfdata(intf, NULL);
+
+ if (!ir)
+ return;
+
+ ir->usbdev = NULL;
+ ir_input_unregister(ir->idev);
+ usb_kill_urb(ir->urb_in);
+ usb_free_urb(ir->urb_in);
+ usb_free_coherent(dev, ir->len_in, ir->buf_in, ir->dma_in);
+
+ kfree(ir);
+}
+
+static int mceusb_dev_suspend(struct usb_interface *intf, pm_message_t message)
+{
+ struct mceusb_dev *ir = usb_get_intfdata(intf);
+ dev_info(ir->dev, "suspend\n");
+ usb_kill_urb(ir->urb_in);
+ return 0;
+}
+
+static int mceusb_dev_resume(struct usb_interface *intf)
+{
+ struct mceusb_dev *ir = usb_get_intfdata(intf);
+ dev_info(ir->dev, "resume\n");
+ if (usb_submit_urb(ir->urb_in, GFP_ATOMIC))
+ return -EIO;
+ return 0;
+}
+
+static struct usb_driver mceusb_dev_driver = {
+ .name = DRIVER_NAME,
+ .probe = mceusb_dev_probe,
+ .disconnect = mceusb_dev_disconnect,
+ .suspend = mceusb_dev_suspend,
+ .resume = mceusb_dev_resume,
+ .reset_resume = mceusb_dev_resume,
+ .id_table = mceusb_dev_table
+};
+
+static int __init mceusb_dev_init(void)
+{
+ int ret;
+
+ ret = usb_register(&mceusb_dev_driver);
+ if (ret < 0)
+ printk(KERN_ERR DRIVER_NAME
+ ": usb register failed, result = %d\n", ret);
+
+ return ret;
+}
+
+static void __exit mceusb_dev_exit(void)
+{
+ usb_deregister(&mceusb_dev_driver);
+}
+
+module_init(mceusb_dev_init);
+module_exit(mceusb_dev_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, mceusb_dev_table);
+
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 7364b9642d00..4da2a54cb8bd 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -57,7 +57,7 @@ void saa7146_dma_free(struct saa7146_dev *dev,struct videobuf_queue *q,
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index b2e15456d5f3..7955e49a3440 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -1249,7 +1249,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
struct tda18271_config *cfg)
{
struct tda18271_priv *priv = NULL;
- int instance;
+ int instance, ret;
mutex_lock(&tda18271_list_mutex);
@@ -1268,10 +1268,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
priv->cal_initialized = false;
mutex_init(&priv->lock);
- if (tda_fail(tda18271_get_id(fe)))
+ ret = tda18271_get_id(fe);
+ if (tda_fail(ret))
goto fail;
- if (tda_fail(tda18271_assign_map_layout(fe)))
+ ret = tda18271_assign_map_layout(fe);
+ if (tda_fail(ret))
goto fail;
mutex_lock(&priv->lock);
diff --git a/drivers/media/common/tuners/tuner-simple.c b/drivers/media/common/tuners/tuner-simple.c
index 8cf2ab609d5e..f8ee29e6059c 100644
--- a/drivers/media/common/tuners/tuner-simple.c
+++ b/drivers/media/common/tuners/tuner-simple.c
@@ -546,14 +546,11 @@ static int simple_set_tv_freq(struct dvb_frontend *fe,
struct tuner_simple_priv *priv = fe->tuner_priv;
u8 config, cb;
u16 div;
- struct tunertype *tun;
u8 buffer[4];
int rc, IFPCoff, i;
enum param_type desired_type;
struct tuner_params *t_params;
- tun = priv->tun;
-
/* IFPCoff = Video Intermediate Frequency - Vif:
940 =16*58.75 NTSC/J (Japan)
732 =16*45.75 M/N STD
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 432003dded7c..d2b2c12a5561 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -217,6 +217,7 @@ static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
return XC_RESULT_SUCCESS;
}
+#if 0
/* This routine is never used because the only time we read data from the
i2c bus is when we read registers, and we want that to be an atomic i2c
transaction in case we are on a multi-master bus */
@@ -231,6 +232,27 @@ static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
}
return 0;
}
+#endif
+
+static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
+{
+ u8 buf[2] = { reg >> 8, reg & 0xff };
+ u8 bval[2] = { 0, 0 };
+ struct i2c_msg msg[2] = {
+ { .addr = priv->i2c_props.addr,
+ .flags = 0, .buf = &buf[0], .len = 2 },
+ { .addr = priv->i2c_props.addr,
+ .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
+ };
+
+ if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
+ printk(KERN_WARNING "xc5000: I2C read failed\n");
+ return -EREMOTEIO;
+ }
+
+ *val = (bval[0] << 8) | bval[1];
+ return XC_RESULT_SUCCESS;
+}
static void xc_wait(int wait_ms)
{
@@ -275,20 +297,14 @@ static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
if (result == XC_RESULT_SUCCESS) {
/* wait for busy flag to clear */
while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
- buf[0] = 0;
- buf[1] = XREG_BUSY;
-
- result = xc_send_i2c_data(priv, buf, 2);
+ result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf);
if (result == XC_RESULT_SUCCESS) {
- result = xc_read_i2c_data(priv, buf, 2);
- if (result == XC_RESULT_SUCCESS) {
- if ((buf[0] == 0) && (buf[1] == 0)) {
- /* busy flag cleared */
+ if ((buf[0] == 0) && (buf[1] == 0)) {
+ /* busy flag cleared */
break;
- } else {
- xc_wait(5); /* wait 5 ms */
- WatchDogTimer--;
- }
+ } else {
+ xc_wait(5); /* wait 5 ms */
+ WatchDogTimer--;
}
}
}
@@ -526,25 +542,6 @@ static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
return found;
}
-static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
-{
- u8 buf[2] = { reg >> 8, reg & 0xff };
- u8 bval[2] = { 0, 0 };
- struct i2c_msg msg[2] = {
- { .addr = priv->i2c_props.addr,
- .flags = 0, .buf = &buf[0], .len = 2 },
- { .addr = priv->i2c_props.addr,
- .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
- };
-
- if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
- printk(KERN_WARNING "xc5000: I2C read failed\n");
- return -EREMOTEIO;
- }
-
- *val = (bval[0] << 8) | bval[1];
- return XC_RESULT_SUCCESS;
-}
static int xc5000_fwupload(struct dvb_frontend *fe)
{
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index ef259a0718ac..cb97e6b85432 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1318,8 +1318,11 @@ static ssize_t dvb_ca_en50221_io_write(struct file *file,
fragbuf[0] = connection_id;
fragbuf[1] = ((fragpos + fraglen) < count) ? 0x80 : 0x00;
- if ((status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen)) != 0)
+ status = copy_from_user(fragbuf + 2, buf + fragpos, fraglen);
+ if (status) {
+ status = -EFAULT;
goto exit;
+ }
timeout = jiffies + HZ / 2;
written = 0;
@@ -1494,8 +1497,11 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf,
hdr[0] = slot;
hdr[1] = connection_id;
- if ((status = copy_to_user(buf, hdr, 2)) != 0)
+ status = copy_to_user(buf, hdr, 2);
+ if (status) {
+ status = -EFAULT;
goto exit;
+ }
status = pktlen;
exit:
diff --git a/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c
index 977ddba3e235..4a88a3e4db2b 100644
--- a/drivers/media/dvb/dvb-core/dvb_demux.c
+++ b/drivers/media/dvb/dvb-core/dvb_demux.c
@@ -1130,13 +1130,9 @@ static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t
if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
return -EINVAL;
- p = kmalloc(count, GFP_USER);
- if (!p)
- return -ENOMEM;
- if (copy_from_user(p, buf, count)) {
- kfree(p);
- return -EFAULT;
- }
+ p = memdup_user(buf, count);
+ if (IS_ERR(p))
+ return PTR_ERR(p);
if (mutex_lock_interruptible(&dvbdemux->mutex)) {
kfree(p);
return -ERESTARTSYS;
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 44ae89ecef94..4d45b7d6b3fb 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -465,7 +465,7 @@ static void dvb_frontend_swzigzag(struct dvb_frontend *fe)
if ((fepriv->state & FESTATE_SEARCHING_FAST) || (fepriv->state & FESTATE_RETUNE)) {
fepriv->delay = fepriv->min_delay;
- /* peform a tune */
+ /* perform a tune */
retval = dvb_frontend_swzigzag_autotune(fe,
fepriv->check_wrapped);
if (retval < 0) {
@@ -791,7 +791,7 @@ static int dvb_frontend_start(struct dvb_frontend *fe)
return 0;
}
-static void dvb_frontend_get_frequeny_limits(struct dvb_frontend *fe,
+static void dvb_frontend_get_frequency_limits(struct dvb_frontend *fe,
u32 *freq_min, u32 *freq_max)
{
*freq_min = max(fe->ops.info.frequency_min, fe->ops.tuner_ops.info.frequency_min);
@@ -815,7 +815,7 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
u32 freq_max;
/* range check: frequency */
- dvb_frontend_get_frequeny_limits(fe, &freq_min, &freq_max);
+ dvb_frontend_get_frequency_limits(fe, &freq_min, &freq_max);
if ((freq_min && parms->frequency < freq_min) ||
(freq_max && parms->frequency > freq_max)) {
printk(KERN_WARNING "DVB: adapter %i frontend %i frequency %u out of range (%u..%u)\n",
@@ -1627,7 +1627,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
case FE_GET_INFO: {
struct dvb_frontend_info* info = parg;
memcpy(info, &fe->ops.info, sizeof(struct dvb_frontend_info));
- dvb_frontend_get_frequeny_limits(fe, &info->frequency_min, &info->frequency_max);
+ dvb_frontend_get_frequency_limits(fe, &info->frequency_min, &info->frequency_max);
/* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't
* do it, it is done for it. */
@@ -1726,7 +1726,7 @@ static int dvb_frontend_ioctl_legacy(struct file *file,
* (stv0299 for instance) take longer than 8msec to
* respond to a set_voltage command. Those switches
* need custom routines to switch properly. For all
- * other frontends, the following shoule work ok.
+ * other frontends, the following should work ok.
* Dish network legacy switches (as used by Dish500)
* are controlled by sending 9-bit command words
* spaced 8msec apart.
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index faca1ad88a67..aa5c7d5eef69 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -463,6 +463,11 @@ static int anysee_probe(struct usb_interface *intf,
if (intf->num_altsetting < 1)
return -ENODEV;
+ /*
+ * Anysee is always warm (its USB-bridge, Cypress FX2, uploads
+ * firmware from eeprom). If dvb_usb_device_init() succeeds that
+ * means d is a valid pointer.
+ */
ret = dvb_usb_device_init(intf, &anysee_properties, THIS_MODULE, &d,
adapter_nr);
if (ret)
@@ -479,10 +484,7 @@ static int anysee_probe(struct usb_interface *intf,
if (ret)
return ret;
- if (d)
- ret = anysee_init(d);
-
- return ret;
+ return anysee_init(d);
}
static struct usb_device_id anysee_table[] = {
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 4f961d2d1817..7deade7d1d23 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -53,7 +53,7 @@ static int dib0700_ctrl_wr(struct dvb_usb_device *d, u8 *tx, u8 txlen)
int status;
deb_data(">>> ");
- debug_dump(tx,txlen,deb_data);
+ debug_dump(tx, txlen, deb_data);
status = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0),
tx[0], USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0, tx, txlen,
@@ -98,7 +98,7 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen
deb_info("ep 0 read error (status = %d)\n",status);
deb_data("<<< ");
- debug_dump(rx,rxlen,deb_data);
+ debug_dump(rx, rxlen, deb_data);
return status; /* length in case of success */
}
@@ -106,28 +106,29 @@ int dib0700_ctrl_rd(struct dvb_usb_device *d, u8 *tx, u8 txlen, u8 *rx, u8 rxlen
int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
{
u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) };
- return dib0700_ctrl_wr(d,buf,3);
+ return dib0700_ctrl_wr(d, buf, sizeof(buf));
}
static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
{
- struct dib0700_state *st = d->priv;
- u8 b[3];
- int ret;
-
- if (st->fw_version >= 0x10201) {
- b[0] = REQUEST_SET_USB_XFER_LEN;
- b[1] = (nb_ts_packets >> 8)&0xff;
- b[2] = nb_ts_packets & 0xff;
-
- deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
-
- ret = dib0700_ctrl_wr(d, b, 3);
- } else {
- deb_info("this firmware does not allow to change the USB xfer len\n");
- ret = -EIO;
- }
- return ret;
+ struct dib0700_state *st = d->priv;
+ u8 b[3];
+ int ret;
+
+ if (st->fw_version >= 0x10201) {
+ b[0] = REQUEST_SET_USB_XFER_LEN;
+ b[1] = (nb_ts_packets >> 8) & 0xff;
+ b[2] = nb_ts_packets & 0xff;
+
+ deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
+
+ ret = dib0700_ctrl_wr(d, b, sizeof(b));
+ } else {
+ deb_info("this firmware does not allow to change the USB xfer len\n");
+ ret = -EIO;
+ }
+
+ return ret;
}
/*
@@ -178,7 +179,8 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
value = ((en_start << 7) | (en_stop << 6) |
(msg[i].len & 0x3F)) << 8 | i2c_dest;
/* I2C ctrl + FE bus; */
- index = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
+ index = ((gen_mode << 6) & 0xC0) |
+ ((bus_mode << 4) & 0x30);
result = usb_control_msg(d->udev,
usb_rcvctrlpipe(d->udev, 0),
@@ -198,11 +200,12 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
- buf[1] = (msg[i].addr << 1);
+ buf[1] = msg[i].addr << 1;
buf[2] = (en_start << 7) | (en_stop << 6) |
(msg[i].len & 0x3F);
/* I2C ctrl + FE bus; */
- buf[3] = ((gen_mode<<6)&0xC0) | ((bus_mode<<4)&0x30);
+ buf[3] = ((gen_mode << 6) & 0xC0) |
+ ((bus_mode << 4) & 0x30);
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);
@@ -240,7 +243,7 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
for (i = 0; i < num; i++) {
/* fill in the address */
- buf[1] = (msg[i].addr << 1);
+ buf[1] = msg[i].addr << 1;
/* fill the buffer */
memcpy(&buf[2], msg[i].buf, msg[i].len);
@@ -368,7 +371,8 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
u8 buf[260];
while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
- deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",hx.addr, hx.len, hx.chk);
+ deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
+ hx.addr, hx.len, hx.chk);
buf[0] = hx.len;
buf[1] = (hx.addr >> 8) & 0xff;
@@ -408,16 +412,16 @@ int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw
REQUEST_GET_VERSION,
USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
b, sizeof(b), USB_CTRL_GET_TIMEOUT);
- fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
+ fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
/* set the buffer size - DVB-USB is allocating URB buffers
* only after the firwmare download was successful */
for (i = 0; i < dib0700_device_count; i++) {
for (adap_num = 0; adap_num < dib0700_devices[i].num_adapters;
adap_num++) {
- if (fw_version >= 0x10201)
+ if (fw_version >= 0x10201) {
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = 188*nb_packet_buffer_size;
- else {
+ } else {
/* for fw version older than 1.20.1,
* the buffersize has to be n times 512 */
dib0700_devices[i].adapter[adap_num].stream.u.bulk.buffersize = ((188*nb_packet_buffer_size+188/2)/512)*512;
@@ -453,7 +457,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
if (st->disable_streaming_master_mode == 1)
b[2] = 0x00;
else
- b[2] = (0x01 << 4); /* Master mode */
+ b[2] = 0x01 << 4; /* Master mode */
b[3] = 0x00;
@@ -466,7 +470,7 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
b[2] |= st->channel_state;
- deb_info("data for streaming: %x %x\n",b[1],b[2]);
+ deb_info("data for streaming: %x %x\n", b[1], b[2]);
return dib0700_ctrl_wr(adap->dev, b, 4);
}
@@ -631,7 +635,7 @@ resubmit:
int dib0700_rc_setup(struct dvb_usb_device *d)
{
struct dib0700_state *st = d->priv;
- u8 rc_setup[3] = {REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0};
+ u8 rc_setup[3] = { REQUEST_SET_RC, dvb_usb_dib0700_ir_proto, 0 };
struct urb *purb;
int ret;
int i;
@@ -640,10 +644,10 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
return 0;
/* Set the IR mode */
- i = dib0700_ctrl_wr(d, rc_setup, 3);
- if (i<0) {
+ i = dib0700_ctrl_wr(d, rc_setup, sizeof(rc_setup));
+ if (i < 0) {
err("ir protocol setup failed");
- return -1;
+ return i;
}
if (st->fw_version < 0x10200)
@@ -653,14 +657,14 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
purb = usb_alloc_urb(0, GFP_KERNEL);
if (purb == NULL) {
err("rc usb alloc urb failed\n");
- return -1;
+ return -ENOMEM;
}
purb->transfer_buffer = kzalloc(RC_MSG_SIZE_V1_20, GFP_KERNEL);
if (purb->transfer_buffer == NULL) {
err("rc kzalloc failed\n");
usb_free_urb(purb);
- return -1;
+ return -ENOMEM;
}
purb->status = -EINPROGRESS;
@@ -669,12 +673,10 @@ int dib0700_rc_setup(struct dvb_usb_device *d)
dib0700_rc_urb_completion, d);
ret = usb_submit_urb(purb, GFP_ATOMIC);
- if (ret != 0) {
+ if (ret)
err("rc submit urb failed\n");
- return -1;
- }
- return 0;
+ return ret;
}
static int dib0700_probe(struct usb_interface *intf,
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
index 5d91f70d2d2d..2e3ea0fa28e0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c
@@ -15,7 +15,7 @@
/* debug */
int dvb_usb_debug;
-module_param_named(debug,dvb_usb_debug, int, 0644);
+module_param_named(debug, dvb_usb_debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,pll=4,ts=8,err=16,rc=32,fw=64,mem=128,uxfer=256 (or-able))." DVB_USB_DEBUG_STATUS);
int dvb_usb_disable_rc_polling;
@@ -29,7 +29,7 @@ MODULE_PARM_DESC(force_pid_filter_usage, "force all dvb-usb-devices to use a PID
static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
{
struct dvb_usb_adapter *adap;
- int ret,n;
+ int ret, n;
for (n = 0; n < d->props.num_adapters; n++) {
adap = &d->adapter[n];
@@ -38,7 +38,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
memcpy(&adap->props, &d->props.adapter[n], sizeof(struct dvb_usb_adapter_properties));
-/* speed - when running at FULL speed we need a HW PID filter */
+ /* speed - when running at FULL speed we need a HW PID filter */
if (d->udev->speed == USB_SPEED_FULL && !(adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER)) {
err("This USB2.0 device cannot be run on a USB1.1 port. (it lacks a hardware PID filter)");
return -ENODEV;
@@ -46,7 +46,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
if ((d->udev->speed == USB_SPEED_FULL && adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER) ||
(adap->props.caps & DVB_USB_ADAP_NEED_PID_FILTERING)) {
- info("will use the device's hardware PID filter (table count: %d).",adap->props.pid_filter_count);
+ info("will use the device's hardware PID filter (table count: %d).", adap->props.pid_filter_count);
adap->pid_filtering = 1;
adap->max_feed_count = adap->props.pid_filter_count;
} else {
@@ -64,9 +64,9 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
}
if (adap->props.size_of_priv > 0) {
- adap->priv = kzalloc(adap->props.size_of_priv,GFP_KERNEL);
+ adap->priv = kzalloc(adap->props.size_of_priv, GFP_KERNEL);
if (adap->priv == NULL) {
- err("no memory for priv for adapter %d.",n);
+ err("no memory for priv for adapter %d.", n);
return -ENOMEM;
}
}
@@ -86,8 +86,8 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
* sometimes a timeout occures, this helps
*/
if (d->props.generic_bulk_ctrl_endpoint != 0) {
- usb_clear_halt(d->udev,usb_sndbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
- usb_clear_halt(d->udev,usb_rcvbulkpipe(d->udev,d->props.generic_bulk_ctrl_endpoint));
+ usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
+ usb_clear_halt(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint));
}
return 0;
@@ -96,6 +96,7 @@ static int dvb_usb_adapter_init(struct dvb_usb_device *d, short *adapter_nrs)
static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
{
int n;
+
for (n = 0; n < d->num_adapters_initialized; n++) {
dvb_usb_adapter_frontend_exit(&d->adapter[n]);
dvb_usb_adapter_dvb_exit(&d->adapter[n]);
@@ -111,11 +112,11 @@ static int dvb_usb_adapter_exit(struct dvb_usb_device *d)
/* general initialization functions */
static int dvb_usb_exit(struct dvb_usb_device *d)
{
- deb_info("state before exiting everything: %x\n",d->state);
+ deb_info("state before exiting everything: %x\n", d->state);
dvb_usb_remote_exit(d);
dvb_usb_adapter_exit(d);
dvb_usb_i2c_exit(d);
- deb_info("state should be zero now: %x\n",d->state);
+ deb_info("state should be zero now: %x\n", d->state);
d->state = DVB_USB_STATE_INIT;
kfree(d->priv);
kfree(d);
@@ -132,14 +133,14 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
d->state = DVB_USB_STATE_INIT;
if (d->props.size_of_priv > 0) {
- d->priv = kzalloc(d->props.size_of_priv,GFP_KERNEL);
+ d->priv = kzalloc(d->props.size_of_priv, GFP_KERNEL);
if (d->priv == NULL) {
err("no memory for priv in 'struct dvb_usb_device'");
return -ENOMEM;
}
}
-/* check the capabilities and set appropriate variables */
+ /* check the capabilities and set appropriate variables */
dvb_usb_device_power_ctrl(d, 1);
if ((ret = dvb_usb_i2c_init(d)) ||
@@ -157,16 +158,17 @@ static int dvb_usb_init(struct dvb_usb_device *d, short *adapter_nums)
}
/* determine the name and the state of the just found USB device */
-static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device *udev,struct dvb_usb_device_properties *props, int *cold)
+static struct dvb_usb_device_description *dvb_usb_find_device(struct usb_device *udev, struct dvb_usb_device_properties *props, int *cold)
{
- int i,j;
+ int i, j;
struct dvb_usb_device_description *desc = NULL;
+
*cold = -1;
for (i = 0; i < props->num_device_descs; i++) {
for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].cold_ids[j] != NULL; j++) {
- deb_info("check for cold %x %x\n",props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
+ deb_info("check for cold %x %x\n", props->devices[i].cold_ids[j]->idVendor, props->devices[i].cold_ids[j]->idProduct);
if (props->devices[i].cold_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
props->devices[i].cold_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
*cold = 1;
@@ -179,7 +181,7 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
break;
for (j = 0; j < DVB_USB_ID_MAX_NUM && props->devices[i].warm_ids[j] != NULL; j++) {
- deb_info("check for warm %x %x\n",props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
+ deb_info("check for warm %x %x\n", props->devices[i].warm_ids[j]->idVendor, props->devices[i].warm_ids[j]->idProduct);
if (props->devices[i].warm_ids[j]->idVendor == le16_to_cpu(udev->descriptor.idVendor) &&
props->devices[i].warm_ids[j]->idProduct == le16_to_cpu(udev->descriptor.idProduct)) {
*cold = 0;
@@ -190,7 +192,7 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device
}
if (desc != NULL && props->identify_state != NULL)
- props->identify_state(udev,props,&desc,cold);
+ props->identify_state(udev, props, &desc, cold);
return desc;
}
@@ -202,7 +204,7 @@ int dvb_usb_device_power_ctrl(struct dvb_usb_device *d, int onoff)
else
d->powered--;
- if (d->powered == 0 || (onoff && d->powered == 1)) { // when switching from 1 to 0 or from 0 to 1
+ if (d->powered == 0 || (onoff && d->powered == 1)) { /* when switching from 1 to 0 or from 0 to 1 */
deb_info("power control: %d\n", onoff);
if (d->props.power_ctrl)
return d->props.power_ctrl(d, onoff);
@@ -222,32 +224,32 @@ int dvb_usb_device_init(struct usb_interface *intf,
struct dvb_usb_device *d = NULL;
struct dvb_usb_device_description *desc = NULL;
- int ret = -ENOMEM,cold=0;
+ int ret = -ENOMEM, cold = 0;
if (du != NULL)
*du = NULL;
- if ((desc = dvb_usb_find_device(udev,props,&cold)) == NULL) {
+ if ((desc = dvb_usb_find_device(udev, props, &cold)) == NULL) {
deb_err("something went very wrong, device was not found in current device list - let's see what comes next.\n");
return -ENODEV;
}
if (cold) {
- info("found a '%s' in cold state, will try to load a firmware",desc->name);
- ret = dvb_usb_download_firmware(udev,props);
+ info("found a '%s' in cold state, will try to load a firmware", desc->name);
+ ret = dvb_usb_download_firmware(udev, props);
if (!props->no_reconnect || ret != 0)
return ret;
}
- info("found a '%s' in warm state.",desc->name);
- d = kzalloc(sizeof(struct dvb_usb_device),GFP_KERNEL);
+ info("found a '%s' in warm state.", desc->name);
+ d = kzalloc(sizeof(struct dvb_usb_device), GFP_KERNEL);
if (d == NULL) {
err("no memory for 'struct dvb_usb_device'");
return -ENOMEM;
}
d->udev = udev;
- memcpy(&d->props,props,sizeof(struct dvb_usb_device_properties));
+ memcpy(&d->props, props, sizeof(struct dvb_usb_device_properties));
d->desc = desc;
d->owner = owner;
@@ -259,9 +261,9 @@ int dvb_usb_device_init(struct usb_interface *intf,
ret = dvb_usb_init(d, adapter_nums);
if (ret == 0)
- info("%s successfully initialized and connected.",desc->name);
+ info("%s successfully initialized and connected.", desc->name);
else
- info("%s error while loading driver (%d)",desc->name,ret);
+ info("%s error while loading driver (%d)", desc->name, ret);
return ret;
}
EXPORT_SYMBOL(dvb_usb_device_init);
@@ -271,12 +273,12 @@ void dvb_usb_device_exit(struct usb_interface *intf)
struct dvb_usb_device *d = usb_get_intfdata(intf);
const char *name = "generic DVB-USB module";
- usb_set_intfdata(intf,NULL);
+ usb_set_intfdata(intf, NULL);
if (d != NULL && d->desc != NULL) {
name = d->desc->name;
dvb_usb_exit(d);
}
- info("%s successfully deinitialized and disconnected.",name);
+ info("%s successfully deinitialized and disconnected.", name);
}
EXPORT_SYMBOL(dvb_usb_device_exit);
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
index 7a7f1b2b681c..dbdb5347b2a8 100644
--- a/drivers/media/dvb/dvb-usb/gp8psk-fe.c
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -349,7 +349,7 @@ static struct dvb_frontend_ops gp8psk_fe_ops = {
* FE_CAN_QAM_16 is for compatibility
* (Myth incorrectly detects Turbo-QPSK as plain QAM-16)
*/
- FE_CAN_QPSK | FE_CAN_QAM_16
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_TURBO_FEC
},
.release = gp8psk_fe_release,
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index cd7f9b7cbffa..51d578a758a7 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -584,6 +584,7 @@ config DVB_LGS8GL5
config DVB_LGS8GXX
tristate "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator"
depends on DVB_CORE && I2C
+ select FW_LOADER
default m if DVB_FE_CUSTOMISE
help
A DMB-TH tuner module. Say Y when you want to support this frontend.
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index ad4c8cfd8090..e80c59796368 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -38,11 +38,10 @@
#define DRIVER_DESC "DiBcom 3000M-B DVB-T demodulator"
#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
-#endif
+
#define deb_info(args...) dprintk(0x01,args)
#define deb_i2c(args...) dprintk(0x02,args)
#define deb_srch(args...) dprintk(0x04,args)
@@ -51,12 +50,6 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-a
#define deb_setf(args...) dprintk(0x04,args)
#define deb_getf(args...) dprintk(0x08,args)
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
-#endif
-
static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
{
u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
index 1a12747fdc91..16c526591f36 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -37,12 +37,8 @@
/* debug */
-#ifdef CONFIG_DVB_DIBCOM_DEBUG
#define dprintk(level,args...) \
do { if ((debug & level)) { printk(args); } } while (0)
-#else
-#define dprintk(args...) do { } while (0)
-#endif
/* mask for enabling a specific pid for the pid_filter */
#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
index d69c775f8645..3272881cb112 100644
--- a/drivers/media/dvb/frontends/lgdt3305.c
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -1,7 +1,9 @@
/*
- * Support for LGDT3305 - VSB/QAM
+ * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
*
- * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ * Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * LGDT3304 support by Jarod Wilson <jarod@redhat.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
@@ -65,6 +67,8 @@ struct lgdt3305_state {
/* ------------------------------------------------------------------------ */
+/* FIXME: verify & document the LGDT3304 registers */
+
#define LGDT3305_GEN_CTRL_1 0x0000
#define LGDT3305_GEN_CTRL_2 0x0001
#define LGDT3305_GEN_CTRL_3 0x0002
@@ -358,7 +362,12 @@ static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
case QAM_256:
agcdelay = 0x046b;
rfbw = 0x8889;
- ifbw = 0x8888;
+ /* FIXME: investigate optimal ifbw & rfbw values for the
+ * DT3304 and re-write this switch..case block */
+ if (state->cfg->demod_chip == LGDT3304)
+ ifbw = 0x6666;
+ else /* (state->cfg->demod_chip == LGDT3305) */
+ ifbw = 0x8888;
break;
default:
return -EINVAL;
@@ -410,8 +419,18 @@ static int lgdt3305_agc_setup(struct lgdt3305_state *state,
lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
/* control agc function */
- lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
- lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+ switch (state->cfg->demod_chip) {
+ case LGDT3304:
+ lgdt3305_write_reg(state, 0x0314, 0xe1 | lockdten << 1);
+ lgdt3305_set_reg_bit(state, 0x030e, 2, acqen);
+ break;
+ case LGDT3305:
+ lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+ break;
+ default:
+ return -EINVAL;
+ }
return lgdt3305_rfagc_loop(state, param);
}
@@ -577,61 +596,79 @@ static int lgdt3305_init(struct dvb_frontend *fe)
struct lgdt3305_state *state = fe->demodulator_priv;
int ret;
+ static struct lgdt3305_reg lgdt3304_init_data[] = {
+ { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, },
+ { .reg = 0x000d, .val = 0x02, },
+ { .reg = 0x000e, .val = 0x02, },
+ { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
+ { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
+ { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTRL_7, .val = 0xf9, },
+ { .reg = 0x0112, .val = 0x17, },
+ { .reg = 0x0113, .val = 0x15, },
+ { .reg = 0x0114, .val = 0x18, },
+ { .reg = 0x0115, .val = 0xff, },
+ { .reg = 0x0116, .val = 0x3c, },
+ { .reg = 0x0214, .val = 0x67, },
+ { .reg = 0x0424, .val = 0x8d, },
+ { .reg = 0x0427, .val = 0x12, },
+ { .reg = 0x0428, .val = 0x4f, },
+ { .reg = LGDT3305_IFBW_1, .val = 0x80, },
+ { .reg = LGDT3305_IFBW_2, .val = 0x00, },
+ { .reg = 0x030a, .val = 0x08, },
+ { .reg = 0x030b, .val = 0x9b, },
+ { .reg = 0x030d, .val = 0x00, },
+ { .reg = 0x030e, .val = 0x1c, },
+ { .reg = 0x0314, .val = 0xe1, },
+ { .reg = 0x000d, .val = 0x82, },
+ { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
+ { .reg = LGDT3305_TP_CTRL_1, .val = 0x5b, },
+ };
+
static struct lgdt3305_reg lgdt3305_init_data[] = {
- { .reg = LGDT3305_GEN_CTRL_1,
- .val = 0x03, },
- { .reg = LGDT3305_GEN_CTRL_2,
- .val = 0xb0, },
- { .reg = LGDT3305_GEN_CTRL_3,
- .val = 0x01, },
- { .reg = LGDT3305_GEN_CONTROL,
- .val = 0x6f, },
- { .reg = LGDT3305_GEN_CTRL_4,
- .val = 0x03, },
- { .reg = LGDT3305_DGTL_AGC_REF_1,
- .val = 0x32, },
- { .reg = LGDT3305_DGTL_AGC_REF_2,
- .val = 0xc4, },
- { .reg = LGDT3305_CR_CTR_FREQ_1,
- .val = 0x00, },
- { .reg = LGDT3305_CR_CTR_FREQ_2,
- .val = 0x00, },
- { .reg = LGDT3305_CR_CTR_FREQ_3,
- .val = 0x00, },
- { .reg = LGDT3305_CR_CTR_FREQ_4,
- .val = 0x00, },
- { .reg = LGDT3305_CR_CTRL_7,
- .val = 0x79, },
- { .reg = LGDT3305_AGC_POWER_REF_1,
- .val = 0x32, },
- { .reg = LGDT3305_AGC_POWER_REF_2,
- .val = 0xc4, },
- { .reg = LGDT3305_AGC_DELAY_PT_1,
- .val = 0x0d, },
- { .reg = LGDT3305_AGC_DELAY_PT_2,
- .val = 0x30, },
- { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
- .val = 0x80, },
- { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
- .val = 0x00, },
- { .reg = LGDT3305_IFBW_1,
- .val = 0x80, },
- { .reg = LGDT3305_IFBW_2,
- .val = 0x00, },
- { .reg = LGDT3305_AGC_CTRL_1,
- .val = 0x30, },
- { .reg = LGDT3305_AGC_CTRL_4,
- .val = 0x61, },
- { .reg = LGDT3305_FEC_BLOCK_CTRL,
- .val = 0xff, },
- { .reg = LGDT3305_TP_CTRL_1,
- .val = 0x1b, },
+ { .reg = LGDT3305_GEN_CTRL_1, .val = 0x03, },
+ { .reg = LGDT3305_GEN_CTRL_2, .val = 0xb0, },
+ { .reg = LGDT3305_GEN_CTRL_3, .val = 0x01, },
+ { .reg = LGDT3305_GEN_CONTROL, .val = 0x6f, },
+ { .reg = LGDT3305_GEN_CTRL_4, .val = 0x03, },
+ { .reg = LGDT3305_DGTL_AGC_REF_1, .val = 0x32, },
+ { .reg = LGDT3305_DGTL_AGC_REF_2, .val = 0xc4, },
+ { .reg = LGDT3305_CR_CTR_FREQ_1, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_2, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_3, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_4, .val = 0x00, },
+ { .reg = LGDT3305_CR_CTRL_7, .val = 0x79, },
+ { .reg = LGDT3305_AGC_POWER_REF_1, .val = 0x32, },
+ { .reg = LGDT3305_AGC_POWER_REF_2, .val = 0xc4, },
+ { .reg = LGDT3305_AGC_DELAY_PT_1, .val = 0x0d, },
+ { .reg = LGDT3305_AGC_DELAY_PT_2, .val = 0x30, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1, .val = 0x80, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2, .val = 0x00, },
+ { .reg = LGDT3305_IFBW_1, .val = 0x80, },
+ { .reg = LGDT3305_IFBW_2, .val = 0x00, },
+ { .reg = LGDT3305_AGC_CTRL_1, .val = 0x30, },
+ { .reg = LGDT3305_AGC_CTRL_4, .val = 0x61, },
+ { .reg = LGDT3305_FEC_BLOCK_CTRL, .val = 0xff, },
+ { .reg = LGDT3305_TP_CTRL_1, .val = 0x1b, },
};
lg_dbg("\n");
- ret = lgdt3305_write_regs(state, lgdt3305_init_data,
- ARRAY_SIZE(lgdt3305_init_data));
+ switch (state->cfg->demod_chip) {
+ case LGDT3304:
+ ret = lgdt3305_write_regs(state, lgdt3304_init_data,
+ ARRAY_SIZE(lgdt3304_init_data));
+ break;
+ case LGDT3305:
+ ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+ ARRAY_SIZE(lgdt3305_init_data));
+ break;
+ default:
+ ret = -EINVAL;
+ }
if (lg_fail(ret))
goto fail;
@@ -640,6 +677,76 @@ fail:
return ret;
}
+static int lgdt3304_set_parameters(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
+
+ if (fe->ops.tuner_ops.set_params) {
+ ret = fe->ops.tuner_ops.set_params(fe, param);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ if (lg_fail(ret))
+ goto fail;
+ state->current_frequency = param->frequency;
+ }
+
+ ret = lgdt3305_set_modulation(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_passband_digital_agc(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_agc_setup(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* reg 0x030d is 3304-only... seen in vsb and qam usbsnoops... */
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ lgdt3305_write_reg(state, 0x030d, 0x00);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, 0x4f);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, 0x0c);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, 0xac);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, 0xba);
+ break;
+ case QAM_64:
+ case QAM_256:
+ lgdt3305_write_reg(state, 0x030d, 0x14);
+ ret = lgdt3305_set_if(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+
+ ret = lgdt3305_spectral_inversion(state, param,
+ state->cfg->spectral_inversion
+ ? 1 : 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_modulation = param->u.vsb.modulation;
+
+ ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+ ret = lgdt3305_mpeg_mode_polarity(state,
+ state->cfg->tpclk_edge,
+ state->cfg->tpvalid_polarity);
+fail:
+ return ret;
+}
+
static int lgdt3305_set_parameters(struct dvb_frontend *fe,
struct dvb_frontend_parameters *param)
{
@@ -848,6 +955,10 @@ static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
switch (state->current_modulation) {
case QAM_256:
case QAM_64:
+ /* signal bit is unreliable on the DT3304 in QAM mode */
+ if (((LGDT3304 == state->cfg->demod_chip)) && (cr_lock))
+ *status |= FE_HAS_SIGNAL;
+
ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
if (lg_fail(ret))
goto fail;
@@ -993,6 +1104,7 @@ static void lgdt3305_release(struct dvb_frontend *fe)
kfree(state);
}
+static struct dvb_frontend_ops lgdt3304_ops;
static struct dvb_frontend_ops lgdt3305_ops;
struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
@@ -1013,11 +1125,21 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
state->cfg = config;
state->i2c_adap = i2c_adap;
- memcpy(&state->frontend.ops, &lgdt3305_ops,
- sizeof(struct dvb_frontend_ops));
+ switch (config->demod_chip) {
+ case LGDT3304:
+ memcpy(&state->frontend.ops, &lgdt3304_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ case LGDT3305:
+ memcpy(&state->frontend.ops, &lgdt3305_ops,
+ sizeof(struct dvb_frontend_ops));
+ break;
+ default:
+ goto fail;
+ }
state->frontend.demodulator_priv = state;
- /* verify that we're talking to a lg dt3305 */
+ /* verify that we're talking to a lg dt3304/5 */
ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
if ((lg_fail(ret)) | (val == 0))
goto fail;
@@ -1036,12 +1158,35 @@ struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
return &state->frontend;
fail:
- lg_warn("unable to detect LGDT3305 hardware\n");
+ lg_warn("unable to detect %s hardware\n",
+ config->demod_chip ? "LGDT3304" : "LGDT3305");
kfree(state);
return NULL;
}
EXPORT_SYMBOL(lgdt3305_attach);
+static struct dvb_frontend_ops lgdt3304_ops = {
+ .info = {
+ .name = "LG Electronics LGDT3304 VSB/QAM Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
+ .init = lgdt3305_init,
+ .set_frontend = lgdt3304_set_parameters,
+ .get_frontend = lgdt3305_get_frontend,
+ .get_tune_settings = lgdt3305_get_tune_settings,
+ .read_status = lgdt3305_read_status,
+ .read_ber = lgdt3305_read_ber,
+ .read_signal_strength = lgdt3305_read_signal_strength,
+ .read_snr = lgdt3305_read_snr,
+ .read_ucblocks = lgdt3305_read_ucblocks,
+ .release = lgdt3305_release,
+};
+
static struct dvb_frontend_ops lgdt3305_ops = {
.info = {
.name = "LG Electronics LGDT3305 VSB/QAM Frontend",
@@ -1065,10 +1210,10 @@ static struct dvb_frontend_ops lgdt3305_ops = {
.release = lgdt3305_release,
};
-MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
+MODULE_DESCRIPTION("LG Electronics LGDT3304/5 ATSC/QAM-B Demodulator Driver");
MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
/*
* Local variables:
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
index 9cb11c9cae53..02172eca4d47 100644
--- a/drivers/media/dvb/frontends/lgdt3305.h
+++ b/drivers/media/dvb/frontends/lgdt3305.h
@@ -1,7 +1,7 @@
/*
- * Support for LGDT3305 - VSB/QAM
+ * Support for LG Electronics LGDT3304 and LGDT3305 - VSB/QAM
*
- * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ * Copyright (C) 2008, 2009, 2010 Michael Krufky <mkrufky@linuxtv.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
@@ -41,6 +41,11 @@ enum lgdt3305_tp_valid_polarity {
LGDT3305_TP_VALID_HIGH = 1,
};
+enum lgdt_demod_chip_type {
+ LGDT3305 = 0,
+ LGDT3304 = 1,
+};
+
struct lgdt3305_config {
u8 i2c_addr;
@@ -65,6 +70,7 @@ struct lgdt3305_config {
enum lgdt3305_mpeg_mode mpeg_mode;
enum lgdt3305_tp_clock_edge tpclk_edge;
enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+ enum lgdt_demod_chip_type demod_chip;
};
#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
diff --git a/drivers/media/dvb/frontends/lgs8gxx.c b/drivers/media/dvb/frontends/lgs8gxx.c
index dee53960e7e8..5ea28ae2ba8f 100644
--- a/drivers/media/dvb/frontends/lgs8gxx.c
+++ b/drivers/media/dvb/frontends/lgs8gxx.c
@@ -24,6 +24,7 @@
*/
#include <asm/div64.h>
+#include <linux/firmware.h>
#include "dvb_frontend.h"
@@ -46,42 +47,6 @@ module_param(fake_signal_str, int, 0644);
MODULE_PARM_DESC(fake_signal_str, "fake signal strength for LGS8913."
"Signal strength calculation is slow.(default:on).");
-static const u8 lgs8g75_initdat[] = {
- 0x01, 0x30, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
- 0xE4, 0xF5, 0xA8, 0xF5, 0xB8, 0xF5, 0x88, 0xF5,
- 0x89, 0xF5, 0x87, 0x75, 0xD0, 0x00, 0x11, 0x50,
- 0x11, 0x50, 0xF4, 0xF5, 0x80, 0xF5, 0x90, 0xF5,
- 0xA0, 0xF5, 0xB0, 0x75, 0x81, 0x30, 0x80, 0x01,
- 0x32, 0x90, 0x80, 0x12, 0x74, 0xFF, 0xF0, 0x90,
- 0x80, 0x13, 0x74, 0x1F, 0xF0, 0x90, 0x80, 0x23,
- 0x74, 0x01, 0xF0, 0x90, 0x80, 0x22, 0xF0, 0x90,
- 0x00, 0x48, 0x74, 0x00, 0xF0, 0x90, 0x80, 0x4D,
- 0x74, 0x05, 0xF0, 0x90, 0x80, 0x09, 0xE0, 0x60,
- 0x21, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x1B, 0x12,
- 0x00, 0xDD, 0x14, 0x60, 0x15, 0x12, 0x00, 0xDD,
- 0x14, 0x60, 0x0F, 0x12, 0x00, 0xDD, 0x14, 0x60,
- 0x09, 0x12, 0x00, 0xDD, 0x14, 0x60, 0x03, 0x12,
- 0x00, 0xDD, 0x90, 0x80, 0x42, 0xE0, 0x60, 0x0B,
- 0x14, 0x60, 0x0C, 0x14, 0x60, 0x0D, 0x14, 0x60,
- 0x0E, 0x01, 0xB3, 0x74, 0x04, 0x01, 0xB9, 0x74,
- 0x05, 0x01, 0xB9, 0x74, 0x07, 0x01, 0xB9, 0x74,
- 0x0A, 0xC0, 0xE0, 0x74, 0xC8, 0x12, 0x00, 0xE2,
- 0xD0, 0xE0, 0x14, 0x70, 0xF4, 0x90, 0x80, 0x09,
- 0xE0, 0x70, 0xAE, 0x12, 0x00, 0xF6, 0x12, 0x00,
- 0xFE, 0x90, 0x00, 0x48, 0xE0, 0x04, 0xF0, 0x90,
- 0x80, 0x4E, 0xF0, 0x01, 0x73, 0x90, 0x80, 0x08,
- 0xF0, 0x22, 0xF8, 0x7A, 0x0C, 0x79, 0xFD, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9,
- 0xF6, 0xDA, 0xF2, 0xD8, 0xEE, 0x22, 0x90, 0x80,
- 0x65, 0xE0, 0x54, 0xFD, 0xF0, 0x22, 0x90, 0x80,
- 0x65, 0xE0, 0x44, 0xC2, 0xF0, 0x22
-};
-
/* LGS8GXX internal helper functions */
static int lgs8gxx_write_reg(struct lgs8gxx_state *priv, u8 reg, u8 data)
@@ -627,9 +592,14 @@ static int lgs8913_init(struct lgs8gxx_state *priv)
static int lgs8g75_init_data(struct lgs8gxx_state *priv)
{
- const u8 *p = lgs8g75_initdat;
+ const struct firmware *fw;
+ int rc;
int i;
+ rc = request_firmware(&fw, "lgs8g75.fw", &priv->i2c->dev);
+ if (rc)
+ return rc;
+
lgs8gxx_write_reg(priv, 0xC6, 0x40);
lgs8gxx_write_reg(priv, 0x3D, 0x04);
@@ -640,16 +610,16 @@ static int lgs8g75_init_data(struct lgs8gxx_state *priv)
lgs8gxx_write_reg(priv, 0x3B, 0x00);
lgs8gxx_write_reg(priv, 0x38, 0x00);
- for (i = 0; i < sizeof(lgs8g75_initdat); i++) {
+ for (i = 0; i < fw->size; i++) {
lgs8gxx_write_reg(priv, 0x38, 0x00);
lgs8gxx_write_reg(priv, 0x3A, (u8)(i&0xff));
lgs8gxx_write_reg(priv, 0x3B, (u8)(i>>8));
- lgs8gxx_write_reg(priv, 0x3C, *p);
- p++;
+ lgs8gxx_write_reg(priv, 0x3C, fw->data[i]);
}
lgs8gxx_write_reg(priv, 0x38, 0x00);
+ release_firmware(fw);
return 0;
}
diff --git a/drivers/media/dvb/frontends/mb86a16.c b/drivers/media/dvb/frontends/mb86a16.c
index 599d1aa519a3..33b63235b86e 100644
--- a/drivers/media/dvb/frontends/mb86a16.c
+++ b/drivers/media/dvb/frontends/mb86a16.c
@@ -1833,7 +1833,6 @@ static struct dvb_frontend_ops mb86a16_ops = {
.get_frontend_algo = mb86a16_frontend_algo,
.search = mb86a16_search,
- .read_status = mb86a16_read_status,
.init = mb86a16_init,
.sleep = mb86a16_sleep,
.read_status = mb86a16_read_status,
diff --git a/drivers/media/dvb/frontends/tda10048.c b/drivers/media/dvb/frontends/tda10048.c
index 4e2a7c8b2f62..93f6a75c238e 100644
--- a/drivers/media/dvb/frontends/tda10048.c
+++ b/drivers/media/dvb/frontends/tda10048.c
@@ -25,6 +25,7 @@
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/math64.h>
#include <asm/div64.h>
#include "dvb_frontend.h"
#include "dvb_math.h"
@@ -49,8 +50,8 @@
#define TDA10048_CONF_C4_1 0x1E
#define TDA10048_CONF_C4_2 0x1F
#define TDA10048_CODE_IN_RAM 0x20
-#define TDA10048_CHANNEL_INFO_1_R 0x22
-#define TDA10048_CHANNEL_INFO_2_R 0x23
+#define TDA10048_CHANNEL_INFO1_R 0x22
+#define TDA10048_CHANNEL_INFO2_R 0x23
#define TDA10048_CHANNEL_INFO1 0x24
#define TDA10048_CHANNEL_INFO2 0x25
#define TDA10048_TIME_ERROR_R 0x26
@@ -63,8 +64,8 @@
#define TDA10048_IT_STAT 0x32
#define TDA10048_DSP_AD_LSB 0x3C
#define TDA10048_DSP_AD_MSB 0x3D
-#define TDA10048_DSP_REF_LSB 0x3E
-#define TDA10048_DSP_REF_MSB 0x3F
+#define TDA10048_DSP_REG_LSB 0x3E
+#define TDA10048_DSP_REG_MSB 0x3F
#define TDA10048_CONF_TRISTATE1 0x44
#define TDA10048_CONF_TRISTATE2 0x45
#define TDA10048_CONF_POLARITY 0x46
@@ -112,7 +113,7 @@
#define TDA10048_FREE_REG_1 0xB2
#define TDA10048_FREE_REG_2 0xB3
#define TDA10048_CONF_C3_1 0xC0
-#define TDA10048_CYBER_CTRL 0xC2
+#define TDA10048_CVBER_CTRL 0xC2
#define TDA10048_CBER_NMAX_LSB 0xC4
#define TDA10048_CBER_NMAX_MSB 0xC5
#define TDA10048_CBER_LSB 0xC6
@@ -120,7 +121,7 @@
#define TDA10048_VBER_LSB 0xC8
#define TDA10048_VBER_MID 0xC9
#define TDA10048_VBER_MSB 0xCA
-#define TDA10048_CYBER_LUT 0xCC
+#define TDA10048_CVBER_LUT 0xCC
#define TDA10048_UNCOR_CTRL 0xCD
#define TDA10048_UNCOR_CPT_LSB 0xCE
#define TDA10048_UNCOR_CPT_MSB 0xCF
@@ -183,7 +184,7 @@ static struct init_tab {
{ TDA10048_AGC_IF_MAX, 0xff },
{ TDA10048_AGC_THRESHOLD_MSB, 0x00 },
{ TDA10048_AGC_THRESHOLD_LSB, 0x70 },
- { TDA10048_CYBER_CTRL, 0x38 },
+ { TDA10048_CVBER_CTRL, 0x38 },
{ TDA10048_AGC_GAINS, 0x12 },
{ TDA10048_CONF_XO, 0x00 },
{ TDA10048_CONF_TS1, 0x07 },
@@ -688,7 +689,7 @@ static int tda10048_get_tps(struct tda10048_state *state,
p->guard_interval = GUARD_INTERVAL_1_4;
break;
}
- switch (val & 0x02) {
+ switch (val & 0x03) {
case 0:
p->transmission_mode = TRANSMISSION_MODE_2K;
break;
@@ -765,6 +766,8 @@ static int tda10048_set_frontend(struct dvb_frontend *fe,
/* Enable demod TPS auto detection and begin acquisition */
tda10048_writereg(state, TDA10048_AUTO, 0x57);
+ /* trigger cber and vber acquisition */
+ tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x3B);
return 0;
}
@@ -830,12 +833,27 @@ static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status)
static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber)
{
struct tda10048_state *state = fe->demodulator_priv;
+ static u32 cber_current;
+ u32 cber_nmax;
+ u64 cber_tmp;
dprintk(1, "%s()\n", __func__);
- /* TODO: A reset may be required here */
- *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
- tda10048_readreg(state, TDA10048_CBER_LSB);
+ /* update cber on interrupt */
+ if (tda10048_readreg(state, TDA10048_SOFT_IT_C3) & 0x01) {
+ cber_tmp = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
+ tda10048_readreg(state, TDA10048_CBER_LSB);
+ cber_nmax = tda10048_readreg(state, TDA10048_CBER_NMAX_MSB) << 8 |
+ tda10048_readreg(state, TDA10048_CBER_NMAX_LSB);
+ cber_tmp *= 100000000;
+ cber_tmp *= 2;
+ cber_tmp = div_u64(cber_tmp, (cber_nmax * 32) + 1);
+ cber_current = (u32)cber_tmp;
+ /* retrigger cber acquisition */
+ tda10048_writereg(state, TDA10048_CVBER_CTRL, 0x39);
+ }
+ /* actual cber is (*ber)/1e8 */
+ *ber = cber_current;
return 0;
}
@@ -1015,6 +1033,9 @@ static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
*ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |
tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);
+ /* clear the uncorrected TS packets counter when saturated */
+ if (*ucblocks == 0xFFFF)
+ tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x80);
return 0;
}
diff --git a/drivers/media/dvb/mantis/Kconfig b/drivers/media/dvb/mantis/Kconfig
index f7b72a32adf3..decdeda840d0 100644
--- a/drivers/media/dvb/mantis/Kconfig
+++ b/drivers/media/dvb/mantis/Kconfig
@@ -10,9 +10,15 @@ config MANTIS_CORE
config DVB_MANTIS
tristate "MANTIS based cards"
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
- select DVB_MB86A16
- select DVB_ZL10353
- select DVB_STV0299
+ select DVB_MB86A16 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_STV0299 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_STB0899 if !DVB_FE_CUSTOMISE
+ select DVB_STB6100 if !DVB_FE_CUSTOMISE
+ select DVB_TDA665x if !DVB_FE_CUSTOMISE
+ select DVB_TDA10021 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10023 if !DVB_FE_CUSTOMISE
select DVB_PLL
help
Support for PCI cards based on the Mantis PCI bridge.
@@ -23,7 +29,7 @@ config DVB_MANTIS
config DVB_HOPPER
tristate "HOPPER based cards"
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
- select DVB_ZL10353
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_PLL
help
Support for PCI cards based on the Hopper PCI bridge.
diff --git a/drivers/media/dvb/mantis/mantis_input.c b/drivers/media/dvb/mantis/mantis_input.c
index 3d4e4663220c..a99489b8418b 100644
--- a/drivers/media/dvb/mantis/mantis_input.c
+++ b/drivers/media/dvb/mantis/mantis_input.c
@@ -19,7 +19,7 @@
*/
#include <linux/input.h>
-#include <media/ir-common.h>
+#include <media/ir-core.h>
#include <linux/pci.h>
#include "dmxdev.h"
@@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(ir_mantis);
int mantis_input_init(struct mantis_pci *mantis)
{
struct input_dev *rc;
- struct ir_input_state rc_state;
char name[80], dev[80];
int err;
@@ -120,8 +119,6 @@ int mantis_input_init(struct mantis_pci *mantis)
rc->name = name;
rc->phys = dev;
- ir_input_init(rc, &rc_state, IR_TYPE_OTHER);
-
rc->id.bustype = BUS_PCI;
rc->id.vendor = mantis->vendor_id;
rc->id.product = mantis->device_id;
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index 0c87a3c3899a..828bcc2e129b 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -116,9 +116,7 @@ static struct smscore_registry_entry_t *smscore_find_registry(char *devpath)
return entry;
}
}
- entry = (struct smscore_registry_entry_t *)
- kmalloc(sizeof(struct smscore_registry_entry_t),
- GFP_KERNEL);
+ entry = kmalloc(sizeof(struct smscore_registry_entry_t), GFP_KERNEL);
if (entry) {
entry->mode = default_mode;
strcpy(entry->devpath, devpath);
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 47075fc71f11..9927a595b426 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -748,7 +748,7 @@ static int si470x_vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
struct si470x_device *radio = video_drvdata(file);
- int retval = -EINVAL;
+ int retval = 0;
/* safety checks */
retval = si470x_disconnect_check(radio);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index ab63dd5b25c4..fc7f4b794649 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -1009,8 +1009,10 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
goto exit;
}
rval = copy_from_user(ps_name, control->string, len);
- if (rval < 0)
+ if (rval) {
+ rval = -EFAULT;
goto exit;
+ }
ps_name[len] = '\0';
if (strlen(ps_name) % vqc.step) {
@@ -1031,8 +1033,10 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev,
goto exit;
}
rval = copy_from_user(radio_text, control->string, len);
- if (rval < 0)
+ if (rval) {
+ rval = -EFAULT;
goto exit;
+ }
radio_text[len] = '\0';
if (strlen(radio_text) % vqc.step) {
@@ -1367,6 +1371,8 @@ static int si4713_read_econtrol_string(struct si4713_device *sdev,
}
rval = copy_to_user(control->string, sdev->rds_info.ps_name,
strlen(sdev->rds_info.ps_name) + 1);
+ if (rval)
+ rval = -EFAULT;
break;
case V4L2_CID_RDS_TX_RADIO_TEXT:
@@ -1377,6 +1383,8 @@ static int si4713_read_econtrol_string(struct si4713_device *sdev,
}
rval = copy_to_user(control->string, sdev->rds_info.radio_text,
strlen(sdev->rds_info.radio_text) + 1);
+ if (rval)
+ rval = -EFAULT;
break;
default:
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index bdbc9d305419..c627f776c1e9 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -517,19 +517,6 @@ config VIDEO_UPD64083
endmenu # encoder / decoder chips
-config DISPLAY_DAVINCI_DM646X_EVM
- tristate "DM646x EVM Video Display"
- depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
- select VIDEOBUF_DMA_CONTIG
- select VIDEO_DAVINCI_VPIF
- select VIDEO_ADV7343
- select VIDEO_THS7303
- help
- Support for DM6467 based display device.
-
- To compile this driver as a module, choose M here: the
- module will be called vpif_display.
-
config VIDEO_SH_VOU
tristate "SuperH VOU video output driver"
depends on VIDEO_DEV && ARCH_SHMOBILE
@@ -537,29 +524,22 @@ config VIDEO_SH_VOU
help
Support for the Video Output Unit (VOU) on SuperH SoCs.
-config CAPTURE_DAVINCI_DM646X_EVM
- tristate "DM646x EVM Video Capture"
- depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+config VIDEO_VIU
+ tristate "Freescale VIU Video Driver"
+ depends on VIDEO_V4L2 && PPC_MPC512x
select VIDEOBUF_DMA_CONTIG
- select VIDEO_DAVINCI_VPIF
- help
- Support for DM6467 based capture device.
-
- To compile this driver as a module, choose M here: the
- module will be called vpif_capture.
-
-config VIDEO_DAVINCI_VPIF
- tristate "DaVinci VPIF Driver"
- depends on DISPLAY_DAVINCI_DM646X_EVM
- help
- Support for DaVinci VPIF Driver.
+ default y
+ ---help---
+ Support for Freescale VIU video driver. This device captures
+ video data, or overlays video on DIU frame buffer.
- To compile this driver as a module, choose M here: the
- module will be called vpif.
+ Say Y here if you want to enable VIU device on MPC5121e Rev2+.
+ In doubt, say N.
config VIDEO_VIVI
tristate "Virtual Video Driver"
- depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 && FONTS
+ depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
+ depends on (FRAMEBUFFER_CONSOLE || STI_CONSOLE) && FONTS
select FONT_8x16
select VIDEOBUF_VMALLOC
default n
@@ -570,66 +550,7 @@ config VIDEO_VIVI
Say Y here if you want to test video apps or debug V4L devices.
In doubt, say N.
-config VIDEO_VPSS_SYSTEM
- tristate "VPSS System module driver"
- depends on ARCH_DAVINCI
- help
- Support for vpss system module for video driver
-
-config VIDEO_VPFE_CAPTURE
- tristate "VPFE Video Capture Driver"
- depends on VIDEO_V4L2 && ARCH_DAVINCI
- select VIDEOBUF_DMA_CONTIG
- help
- Support for DMXXXX VPFE based frame grabber. This is the
- common V4L2 module for following DMXXX SoCs from Texas
- Instruments:- DM6446 & DM355.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe-capture.
-
-config VIDEO_DM6446_CCDC
- tristate "DM6446 CCDC HW module"
- depends on ARCH_DAVINCI_DM644x && VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from slave decoders.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
-
-config VIDEO_DM355_CCDC
- tristate "DM355 CCDC HW module"
- depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables DM355 CCD hw module. DM355 CCDC hw interfaces
- with decoder modules such as TVP5146 over BT656 or
- sensor module such as MT9T001 over a raw interface. This
- module configures the interface and CCDC/ISIF to do
- video frame capture from a slave decoders
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
-
-config VIDEO_ISIF
- tristate "ISIF HW module"
- depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
- select VIDEO_VPSS_SYSTEM
- default y
- help
- Enables ISIF hw module. This is the hardware module for
- configuring ISIF in VPFE to capture Raw Bayer RGB data from
- a image sensor or YUV data from a YUV source.
-
- To compile this driver as a module, choose M here: the
- module will be called vpfe.
+source "drivers/media/video/davinci/Kconfig"
source "drivers/media/video/omap/Kconfig"
@@ -1000,61 +921,6 @@ source "drivers/media/video/usbvideo/Kconfig"
source "drivers/media/video/et61x251/Kconfig"
-config VIDEO_OVCAMCHIP
- tristate "OmniVision Camera Chip support (DEPRECATED)"
- depends on I2C && VIDEO_V4L1
- default n
- ---help---
- This driver is DEPRECATED please use the gspca ov519 module
- instead. Note that for the ov511 / ov518 support of the gspca module
- you need atleast version 0.6.0 of libv4l and for the w9968cf
- atleast version 0.6.3 of libv4l.
-
- Support for the OmniVision OV6xxx and OV7xxx series of camera chips.
- This driver is intended to be used with the ov511 and w9968cf USB
- camera drivers.
-
- To compile this driver as a module, choose M here: the
- module will be called ovcamchip.
-
-config USB_W9968CF
- tristate "USB W996[87]CF JPEG Dual Mode Camera support (DEPRECATED)"
- depends on VIDEO_V4L1 && I2C && VIDEO_OVCAMCHIP
- default n
- ---help---
- This driver is DEPRECATED please use the gspca ov519 module
- instead. Note that for the w9968cf support of the gspca module
- you need atleast version 0.6.3 of libv4l.
-
- Say Y here if you want support for cameras based on OV681 or
- Winbond W9967CF/W9968CF JPEG USB Dual Mode Camera Chips.
-
- This driver has an optional plugin, which is distributed as a
- separate module only (released under GPL). It allows to use higher
- resolutions and framerates, but cannot be included in the official
- Linux kernel for performance purposes.
-
- See <file:Documentation/video4linux/w9968cf.txt> for more info.
-
- To compile this driver as a module, choose M here: the
- module will be called w9968cf.
-
-config USB_OV511
- tristate "USB OV511 Camera support (DEPRECATED)"
- depends on VIDEO_V4L1
- default n
- ---help---
- This driver is DEPRECATED please use the gspca ov519 module
- instead. Note that for the ov511 / ov518 support of the gspca module
- you need atleast version 0.6.0 of libv4l.
-
- Say Y here if you want to connect this type of camera to your
- computer's USB port. See <file:Documentation/video4linux/ov511.txt>
- for more information and for a list of supported cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called ov511.
-
config USB_SE401
tristate "USB SE401 Camera support"
depends on VIDEO_V4L1
@@ -1068,25 +934,6 @@ config USB_SE401
source "drivers/media/video/sn9c102/Kconfig"
-config USB_STV680
- tristate "USB STV680 (Pencam) Camera support (DEPRECATED)"
- depends on VIDEO_V4L1
- default n
- ---help---
- This driver is DEPRECATED please use the gspca stv0680 module
- instead. Note that for the gspca stv0680 module you need
- atleast version 0.6.3 of libv4l.
-
- Say Y here if you want to connect this type of camera to your
- computer's USB port. This includes the Pencam line of cameras.
- See <file:Documentation/video4linux/stv680.txt> for more information
- and for a list of supported cameras.
-
- To compile this driver as a module, choose M here: the
- module will be called stv680.
-
-source "drivers/media/video/zc0301/Kconfig"
-
source "drivers/media/video/pwc/Kconfig"
config USB_ZR364XX
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index cc93859d3164..eba259fbf7ef 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -105,7 +105,6 @@ obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
-obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
obj-$(CONFIG_VIDEO_MXB) += mxb.o
obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o
@@ -127,17 +126,13 @@ obj-$(CONFIG_VIDEO_CX2341X) += cx2341x.o
obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
obj-$(CONFIG_USB_DABUSB) += dabusb.o
-obj-$(CONFIG_USB_OV511) += ov511.o
obj-$(CONFIG_USB_SE401) += se401.o
-obj-$(CONFIG_USB_STV680) += stv680.o
-obj-$(CONFIG_USB_W9968CF) += w9968cf.o
obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
obj-$(CONFIG_USB_SN9C102) += sn9c102/
obj-$(CONFIG_USB_ET61X251) += et61x251/
obj-$(CONFIG_USB_PWC) += pwc/
-obj-$(CONFIG_USB_ZC0301) += zc0301/
obj-$(CONFIG_USB_GSPCA) += gspca/
obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
@@ -151,6 +146,7 @@ obj-$(CONFIG_USB_S2255) += s2255drv.o
obj-$(CONFIG_VIDEO_IVTV) += ivtv/
obj-$(CONFIG_VIDEO_CX18) += cx18/
+obj-$(CONFIG_VIDEO_VIU) += fsl-viu.o
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_MEM2MEM_TESTDEV) += mem2mem_testdev.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
@@ -177,7 +173,7 @@ obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
-obj-$(CONFIG_ARCH_DAVINCI) += davinci/
+obj-y += davinci/
obj-$(CONFIG_ARCH_OMAP) += omap/
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index 4d2623158188..5c7f2f7d9805 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -1,4 +1,4 @@
-au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o
+au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o au0828-vbi.o
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
diff --git a/drivers/media/video/au0828/au0828-vbi.c b/drivers/media/video/au0828/au0828-vbi.c
new file mode 100644
index 000000000000..63f593070ee8
--- /dev/null
+++ b/drivers/media/video/au0828/au0828-vbi.c
@@ -0,0 +1,138 @@
+/*
+ au0828-vbi.c - VBI driver for au0828
+
+ Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
+
+ This work was sponsored by GetWellNetwork Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include "au0828.h"
+
+static unsigned int vbibufs = 5;
+module_param(vbibufs, int, 0644);
+MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
+
+/* ------------------------------------------------------------------ */
+
+static void
+free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ unsigned long flags = 0;
+ if (in_interrupt())
+ BUG();
+
+ /* We used to wait for the buffer to finish here, but this didn't work
+ because, as we were keeping the state as VIDEOBUF_QUEUED,
+ videobuf_queue_cancel marked it as finished for us.
+ (Also, it could wedge forever if the hardware was misconfigured.)
+
+ This should be safe; by the time we get here, the buffer isn't
+ queued anymore. If we ever start marking the buffers as
+ VIDEOBUF_ACTIVE, it won't be, though.
+ */
+ spin_lock_irqsave(&dev->slock, flags);
+ if (dev->isoc_ctl.vbi_buf == buf)
+ dev->isoc_ctl.vbi_buf = NULL;
+ spin_unlock_irqrestore(&dev->slock, flags);
+
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
+{
+ struct au0828_fh *fh = q->priv_data;
+ struct au0828_dev *dev = fh->dev;
+
+ *size = dev->vbi_width * dev->vbi_height * 2;
+
+ if (0 == *count)
+ *count = vbibufs;
+ if (*count < 2)
+ *count = 2;
+ if (*count > 32)
+ *count = 32;
+ return 0;
+}
+
+static int
+vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct au0828_fh *fh = q->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ int rc = 0;
+
+ buf->vb.size = dev->vbi_width * dev->vbi_height * 2;
+
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ buf->vb.width = dev->vbi_width;
+ buf->vb.height = dev->vbi_height;
+ buf->vb.field = field;
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(q, &buf->vb, NULL);
+ if (rc < 0)
+ goto fail;
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(q, buf);
+ return rc;
+}
+
+static void
+vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb,
+ struct au0828_buffer,
+ vb);
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ struct au0828_dmaqueue *vbiq = &dev->vbiq;
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vbiq->active);
+}
+
+static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ free_buffer(q, buf);
+}
+
+struct videobuf_queue_ops au0828_vbi_qops = {
+ .buf_setup = vbi_setup,
+ .buf_prepare = vbi_prepare,
+ .buf_queue = vbi_queue,
+ .buf_release = vbi_release,
+};
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 52f25aabb6dc..d97e0a28fb24 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -314,6 +314,23 @@ static inline void buffer_filled(struct au0828_dev *dev,
wake_up(&buf->vb.done);
}
+static inline void vbi_buffer_filled(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf)
+{
+ /* Advice that buffer was filled */
+ au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ do_gettimeofday(&buf->vb.ts);
+
+ dev->isoc_ctl.vbi_buf = NULL;
+
+ list_del(&buf->vb.queue);
+ wake_up(&buf->vb.done);
+}
+
/*
* Identify the buffer header type and properly handles
*/
@@ -327,6 +344,9 @@ static void au0828_copy_video(struct au0828_dev *dev,
int linesdone, currlinedone, offset, lencopy, remain;
int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
+ if (len == 0)
+ return;
+
if (dma_q->pos + len > buf->vb.size)
len = buf->vb.size - dma_q->pos;
@@ -414,17 +434,96 @@ static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
return;
}
+static void au0828_copy_vbi(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf,
+ unsigned char *p,
+ unsigned char *outp, unsigned long len)
+{
+ unsigned char *startwrite, *startread;
+ int bytesperline = dev->vbi_width;
+ int i, j = 0;
+
+ if (dev == NULL) {
+ au0828_isocdbg("dev is null\n");
+ return;
+ }
+
+ if (dma_q == NULL) {
+ au0828_isocdbg("dma_q is null\n");
+ return;
+ }
+ if (buf == NULL)
+ return;
+ if (p == NULL) {
+ au0828_isocdbg("p is null\n");
+ return;
+ }
+ if (outp == NULL) {
+ au0828_isocdbg("outp is null\n");
+ return;
+ }
+
+ if (dma_q->pos + len > buf->vb.size)
+ len = buf->vb.size - dma_q->pos;
+
+ startread = p;
+ startwrite = outp + (dma_q->pos / 2);
+
+ /* Make sure the bottom field populates the second half of the frame */
+ if (buf->top_field == 0)
+ startwrite += bytesperline * dev->vbi_height;
+
+ for (i = 0; i < len; i += 2)
+ startwrite[j++] = startread[i+1];
+
+ dma_q->pos += len;
+}
+
+
+/*
+ * video-buf generic routine to get the next available VBI buffer
+ */
+static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer **buf)
+{
+ struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
+ char *outp;
+
+ if (list_empty(&dma_q->active)) {
+ au0828_isocdbg("No active queue to serve\n");
+ dev->isoc_ctl.vbi_buf = NULL;
+ *buf = NULL;
+ return;
+ }
+
+ /* Get the next buffer */
+ *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
+ /* Cleans up buffer - Usefull for testing for frame/URB loss */
+ outp = videobuf_to_vmalloc(&(*buf)->vb);
+ memset(outp, 0x00, (*buf)->vb.size);
+
+ dev->isoc_ctl.vbi_buf = *buf;
+
+ return;
+}
+
/*
* Controls the isoc copy of each urb packet
*/
static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
{
struct au0828_buffer *buf;
+ struct au0828_buffer *vbi_buf;
struct au0828_dmaqueue *dma_q = urb->context;
+ struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
unsigned char *outp = NULL;
+ unsigned char *vbioutp = NULL;
int i, len = 0, rc = 1;
unsigned char *p;
unsigned char fbyte;
+ unsigned int vbi_field_size;
+ unsigned int remain, lencopy;
if (!dev)
return 0;
@@ -443,6 +542,10 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
if (buf != NULL)
outp = videobuf_to_vmalloc(&buf->vb);
+ vbi_buf = dev->isoc_ctl.vbi_buf;
+ if (vbi_buf != NULL)
+ vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
+
for (i = 0; i < urb->number_of_packets; i++) {
int status = urb->iso_frame_desc[i].status;
@@ -472,6 +575,19 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
au0828_isocdbg("Video frame %s\n",
(fbyte & 0x40) ? "odd" : "even");
if (!(fbyte & 0x40)) {
+ /* VBI */
+ if (vbi_buf != NULL)
+ vbi_buffer_filled(dev,
+ vbi_dma_q,
+ vbi_buf);
+ vbi_get_next_buf(vbi_dma_q, &vbi_buf);
+ if (vbi_buf == NULL)
+ vbioutp = NULL;
+ else
+ vbioutp = videobuf_to_vmalloc(
+ &vbi_buf->vb);
+
+ /* Video */
if (buf != NULL)
buffer_filled(dev, dma_q, buf);
get_next_buf(dma_q, &buf);
@@ -488,9 +604,36 @@ static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
buf->top_field = 0;
}
+ if (vbi_buf != NULL) {
+ if (fbyte & 0x40)
+ vbi_buf->top_field = 1;
+ else
+ vbi_buf->top_field = 0;
+ }
+
+ dev->vbi_read = 0;
+ vbi_dma_q->pos = 0;
dma_q->pos = 0;
}
- if (buf != NULL)
+
+ vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
+ if (dev->vbi_read < vbi_field_size) {
+ remain = vbi_field_size - dev->vbi_read;
+ if (len < remain)
+ lencopy = len;
+ else
+ lencopy = remain;
+
+ if (vbi_buf != NULL)
+ au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
+ vbioutp, len);
+
+ len -= lencopy;
+ p += lencopy;
+ dev->vbi_read += lencopy;
+ }
+
+ if (dev->vbi_read >= vbi_field_size && buf != NULL)
au0828_copy_video(dev, dma_q, buf, p, outp, len);
}
return rc;
@@ -642,7 +785,7 @@ int au0828_analog_stream_enable(struct au0828_dev *d)
au0828_writereg(d, 0x114, 0xa0);
au0828_writereg(d, 0x115, 0x05);
/* set y position */
- au0828_writereg(d, 0x112, 0x02);
+ au0828_writereg(d, 0x112, 0x00);
au0828_writereg(d, 0x113, 0x00);
au0828_writereg(d, 0x116, 0xf2);
au0828_writereg(d, 0x117, 0x00);
@@ -703,47 +846,83 @@ void au0828_analog_unregister(struct au0828_dev *dev)
/* Usage lock check functions */
-static int res_get(struct au0828_fh *fh)
+static int res_get(struct au0828_fh *fh, unsigned int bit)
{
- struct au0828_dev *dev = fh->dev;
- int rc = 0;
+ struct au0828_dev *dev = fh->dev;
- /* This instance already has stream_on */
- if (fh->stream_on)
- return rc;
+ if (fh->resources & bit)
+ /* have it already allocated */
+ return 1;
- if (dev->stream_on)
- return -EBUSY;
+ /* is it free? */
+ mutex_lock(&dev->lock);
+ if (dev->resources & bit) {
+ /* no, someone else uses it */
+ mutex_unlock(&dev->lock);
+ return 0;
+ }
+ /* it's free, grab it */
+ fh->resources |= bit;
+ dev->resources |= bit;
+ dprintk(1, "res: get %d\n", bit);
+ mutex_unlock(&dev->lock);
+ return 1;
+}
- dev->stream_on = 1;
- fh->stream_on = 1;
- return rc;
+static int res_check(struct au0828_fh *fh, unsigned int bit)
+{
+ return fh->resources & bit;
}
-static int res_check(struct au0828_fh *fh)
+static int res_locked(struct au0828_dev *dev, unsigned int bit)
{
- return fh->stream_on;
+ return dev->resources & bit;
}
-static void res_free(struct au0828_fh *fh)
+static void res_free(struct au0828_fh *fh, unsigned int bits)
{
- struct au0828_dev *dev = fh->dev;
+ struct au0828_dev *dev = fh->dev;
+
+ BUG_ON((fh->resources & bits) != bits);
- fh->stream_on = 0;
- dev->stream_on = 0;
+ mutex_lock(&dev->lock);
+ fh->resources &= ~bits;
+ dev->resources &= ~bits;
+ dprintk(1, "res: put %d\n", bits);
+ mutex_unlock(&dev->lock);
+}
+
+static int get_ressource(struct au0828_fh *fh)
+{
+ switch (fh->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ return AU0828_RESOURCE_VIDEO;
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ return AU0828_RESOURCE_VBI;
+ default:
+ BUG();
+ return 0;
+ }
}
static int au0828_v4l2_open(struct file *filp)
{
int ret = 0;
+ struct video_device *vdev = video_devdata(filp);
struct au0828_dev *dev = video_drvdata(filp);
struct au0828_fh *fh;
- int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ int type;
-#ifdef VBI_IS_WORKING
- if (video_devdata(filp)->vfl_type == VFL_TYPE_GRABBER)
+ switch (vdev->vfl_type) {
+ case VFL_TYPE_GRABBER:
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ break;
+ case VFL_TYPE_VBI:
type = V4L2_BUF_TYPE_VBI_CAPTURE;
-#endif
+ break;
+ default:
+ return -EINVAL;
+ }
fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
if (NULL == fh) {
@@ -781,10 +960,21 @@ static int au0828_v4l2_open(struct file *filp)
dev->users++;
videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
- NULL, &dev->slock, fh->type,
+ NULL, &dev->slock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
V4L2_FIELD_INTERLACED,
sizeof(struct au0828_buffer), fh);
+ /* VBI Setup */
+ dev->vbi_width = 720;
+ dev->vbi_height = 1;
+ videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops,
+ NULL, &dev->slock,
+ V4L2_BUF_TYPE_VBI_CAPTURE,
+ V4L2_FIELD_SEQ_TB,
+ sizeof(struct au0828_buffer), fh);
+
+
return ret;
}
@@ -794,17 +984,19 @@ static int au0828_v4l2_close(struct file *filp)
struct au0828_fh *fh = filp->private_data;
struct au0828_dev *dev = fh->dev;
- mutex_lock(&dev->lock);
- if (res_check(fh))
- res_free(fh);
-
- if (dev->users == 1) {
+ if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
videobuf_stop(&fh->vb_vidq);
- videobuf_mmap_free(&fh->vb_vidq);
+ res_free(fh, AU0828_RESOURCE_VIDEO);
+ }
+ if (res_check(fh, AU0828_RESOURCE_VBI)) {
+ videobuf_stop(&fh->vb_vbiq);
+ res_free(fh, AU0828_RESOURCE_VBI);
+ }
+
+ if (dev->users == 1) {
if (dev->dev_state & DEV_DISCONNECTED) {
au0828_analog_unregister(dev);
- mutex_unlock(&dev->lock);
kfree(dev);
return 0;
}
@@ -823,10 +1015,11 @@ static int au0828_v4l2_close(struct file *filp)
printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
}
+ videobuf_mmap_free(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vbiq);
kfree(fh);
dev->users--;
wake_up_interruptible_nr(&dev->open, 1);
- mutex_unlock(&dev->lock);
return 0;
}
@@ -842,16 +1035,21 @@ static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
return rc;
if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- mutex_lock(&dev->lock);
- rc = res_get(fh);
- mutex_unlock(&dev->lock);
-
- if (unlikely(rc < 0))
- return rc;
+ if (res_locked(dev, AU0828_RESOURCE_VIDEO))
+ return -EBUSY;
return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
filp->f_flags & O_NONBLOCK);
}
+
+ if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ if (!res_get(fh, AU0828_RESOURCE_VBI))
+ return -EBUSY;
+
+ return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
+ filp->f_flags & O_NONBLOCK);
+ }
+
return 0;
}
@@ -865,17 +1063,17 @@ static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
- rc = res_get(fh);
- mutex_unlock(&dev->lock);
-
- if (unlikely(rc < 0))
- return POLLERR;
-
- if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ if (!res_get(fh, AU0828_RESOURCE_VIDEO))
+ return POLLERR;
+ return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ if (!res_get(fh, AU0828_RESOURCE_VBI))
+ return POLLERR;
+ return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
+ } else {
return POLLERR;
-
- return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+ }
}
static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -888,14 +1086,10 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
if (rc < 0)
return rc;
- mutex_lock(&dev->lock);
- rc = res_get(fh);
- mutex_unlock(&dev->lock);
-
- if (unlikely(rc < 0))
- return rc;
-
- rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+ else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
return rc;
}
@@ -911,14 +1105,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
maxwidth = 720;
maxheight = 480;
-#ifdef VBI_IS_WORKING
- if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
- dprintk(1, "VBI format set: to be supported!\n");
- return 0;
- }
- if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE)
- return 0;
-#endif
if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -999,9 +1185,7 @@ static int vidioc_querycap(struct file *file, void *priv,
/*set the device capabilities */
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
-#ifdef VBI_IS_WORKING
V4L2_CAP_VBI_CAPTURE |
-#endif
V4L2_CAP_AUDIO |
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
@@ -1056,20 +1240,21 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct au0828_dev *dev = fh->dev;
int rc;
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+
if (videobuf_queue_is_busy(&fh->vb_vidq)) {
printk(KERN_INFO "%s queue busy\n", __func__);
rc = -EBUSY;
goto out;
}
- if (dev->stream_on && !fh->stream_on) {
- printk(KERN_INFO "%s device in use by another fh\n", __func__);
- rc = -EBUSY;
- goto out;
- }
-
- return au0828_set_format(dev, VIDIOC_S_FMT, f);
+ rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
out:
+ mutex_unlock(&dev->lock);
return rc;
}
@@ -1300,6 +1485,29 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return 0;
}
+
+/* RAW VBI ioctls */
+
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
+ struct v4l2_format *format)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ format->fmt.vbi.samples_per_line = dev->vbi_width;
+ format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
+ format->fmt.vbi.offset = 0;
+ format->fmt.vbi.flags = 0;
+ format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
+
+ format->fmt.vbi.count[0] = dev->vbi_height;
+ format->fmt.vbi.count[1] = dev->vbi_height;
+ format->fmt.vbi.start[0] = 21;
+ format->fmt.vbi.start[1] = 284;
+
+ return 0;
+}
+
static int vidioc_g_chip_ident(struct file *file, void *priv,
struct v4l2_dbg_chip_ident *chip)
{
@@ -1345,25 +1553,32 @@ static int vidioc_cropcap(struct file *file, void *priv,
static int vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int rc;
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc = -EINVAL;
rc = check_dev(dev);
if (rc < 0)
return rc;
+ if (unlikely(type != fh->type))
+ return -EINVAL;
+
+ dprintk(1, "vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
+ fh, type, fh->resources, dev->resources);
+
+ if (unlikely(!res_get(fh, get_ressource(fh))))
+ return -EBUSY;
+
if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
au0828_analog_stream_enable(dev);
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
}
- mutex_lock(&dev->lock);
- rc = res_get(fh);
-
- if (likely(rc >= 0))
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
rc = videobuf_streamon(&fh->vb_vidq);
- mutex_unlock(&dev->lock);
+ else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ rc = videobuf_streamon(&fh->vb_vbiq);
return rc;
}
@@ -1371,38 +1586,42 @@ static int vidioc_streamon(struct file *file, void *priv,
static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type type)
{
- struct au0828_fh *fh = priv;
- struct au0828_dev *dev = fh->dev;
- int i;
- int ret;
- int rc;
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+ int i;
rc = check_dev(dev);
if (rc < 0)
return rc;
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
+ fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
return -EINVAL;
if (type != fh->type)
return -EINVAL;
- if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dprintk(1, "vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
+ fh, type, fh->resources, dev->resources);
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
- ret = au0828_stream_interrupt(dev);
- if (ret != 0)
- return ret;
- }
+ rc = au0828_stream_interrupt(dev);
+ if (rc != 0)
+ return rc;
- for (i = 0; i < AU0828_MAX_INPUT; i++) {
- if (AUVI_INPUT(i).audio_setup == NULL)
- continue;
- (AUVI_INPUT(i).audio_setup)(dev, 0);
- }
+ for (i = 0; i < AU0828_MAX_INPUT; i++) {
+ if (AUVI_INPUT(i).audio_setup == NULL)
+ continue;
+ (AUVI_INPUT(i).audio_setup)(dev, 0);
+ }
- mutex_lock(&dev->lock);
- videobuf_streamoff(&fh->vb_vidq);
- res_free(fh);
- mutex_unlock(&dev->lock);
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh, AU0828_RESOURCE_VIDEO);
+ } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ videobuf_streamoff(&fh->vb_vbiq);
+ res_free(fh, AU0828_RESOURCE_VBI);
+ }
return 0;
}
@@ -1527,19 +1746,11 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
-#ifdef VBI_IS_WORKING
.vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
- .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
- .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
-#endif
+ .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
.vidioc_g_audio = vidioc_g_audio,
.vidioc_s_audio = vidioc_s_audio,
.vidioc_cropcap = vidioc_cropcap,
-#ifdef VBI_IS_WORKING
- .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
- .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
- .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
-#endif
.vidioc_reqbufs = vidioc_reqbufs,
.vidioc_querybuf = vidioc_querybuf,
.vidioc_qbuf = vidioc_qbuf,
@@ -1621,8 +1832,11 @@ int au0828_analog_register(struct au0828_dev *dev,
spin_lock_init(&dev->slock);
mutex_init(&dev->lock);
+ /* init video dma queues */
INIT_LIST_HEAD(&dev->vidq.active);
INIT_LIST_HEAD(&dev->vidq.queued);
+ INIT_LIST_HEAD(&dev->vbiq.active);
+ INIT_LIST_HEAD(&dev->vbiq.queued);
dev->width = NTSC_STD_W;
dev->height = NTSC_STD_H;
@@ -1638,26 +1852,23 @@ int au0828_analog_register(struct au0828_dev *dev,
return -ENOMEM;
}
-#ifdef VBI_IS_WORKING
+ /* allocate the VBI struct */
dev->vbi_dev = video_device_alloc();
if (NULL == dev->vbi_dev) {
dprintk(1, "Can't allocate vbi_device.\n");
kfree(dev->vdev);
return -ENOMEM;
}
-#endif
/* Fill the video capture device struct */
*dev->vdev = au0828_video_template;
dev->vdev->parent = &dev->usbdev->dev;
strcpy(dev->vdev->name, "au0828a video");
-#ifdef VBI_IS_WORKING
/* Setup the VBI device */
*dev->vbi_dev = au0828_video_template;
dev->vbi_dev->parent = &dev->usbdev->dev;
strcpy(dev->vbi_dev->name, "au0828a vbi");
-#endif
/* Register the v4l2 device */
video_set_drvdata(dev->vdev, dev);
@@ -1669,7 +1880,6 @@ int au0828_analog_register(struct au0828_dev *dev,
return -ENODEV;
}
-#ifdef VBI_IS_WORKING
/* Register the vbi device */
video_set_drvdata(dev->vbi_dev, dev);
retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
@@ -1680,7 +1890,6 @@ int au0828_analog_register(struct au0828_dev *dev,
video_device_release(dev->vdev);
return -ENODEV;
}
-#endif
dprintk(1, "%s completed!\n", __func__);
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 207f32dec6a6..9905bc4f5f59 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -60,6 +60,10 @@
#define AU0828_MAX_INPUT 4
+/* au0828 resource types (used for res_get/res_lock etc */
+#define AU0828_RESOURCE_VIDEO 0x01
+#define AU0828_RESOURCE_VBI 0x02
+
enum au0828_itype {
AU0828_VMUX_UNDEFINED = 0,
AU0828_VMUX_COMPOSITE,
@@ -115,8 +119,10 @@ enum au0828_dev_state {
struct au0828_fh {
struct au0828_dev *dev;
- unsigned int stream_on:1; /* Locks streams */
+ unsigned int resources;
+
struct videobuf_queue vb_vidq;
+ struct videobuf_queue vb_vbiq;
enum v4l2_buf_type type;
};
@@ -145,7 +151,8 @@ struct au0828_usb_isoc_ctl {
int tmp_buf_len;
/* Stores already requested buffers */
- struct au0828_buffer *buf;
+ struct au0828_buffer *buf;
+ struct au0828_buffer *vbi_buf;
/* Stores the number of received fields */
int nfields;
@@ -194,11 +201,14 @@ struct au0828_dev {
/* Analog */
struct v4l2_device v4l2_dev;
int users;
- unsigned int stream_on:1; /* Locks streams */
+ unsigned int resources; /* resources in use */
struct video_device *vdev;
struct video_device *vbi_dev;
int width;
int height;
+ int vbi_width;
+ int vbi_height;
+ u32 vbi_read;
u32 field_size;
u32 frame_size;
u32 bytesperline;
@@ -219,6 +229,7 @@ struct au0828_dev {
/* Isoc control struct */
struct au0828_dmaqueue vidq;
+ struct au0828_dmaqueue vbiq;
struct au0828_usb_isoc_ctl isoc_ctl;
spinlock_t slock;
@@ -278,6 +289,9 @@ void au0828_analog_unregister(struct au0828_dev *dev);
extern int au0828_dvb_register(struct au0828_dev *dev);
extern void au0828_dvb_unregister(struct au0828_dev *dev);
+/* au0828-vbi.c */
+extern struct videobuf_queue_ops au0828_vbi_qops;
+
#define dprintk(level, fmt, arg...)\
do { if (au0828_debug & level)\
printk(KERN_DEBUG DRIVER_NAME "/0: " fmt, ## arg);\
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 407fa61e4cda..685d6597ee79 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -411,7 +411,7 @@ void __devinit init_bttv_i2c_ir(struct bttv *btv)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
+ i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list, NULL);
}
}
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index c24b1c100e13..0fa9f39f37a3 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -583,7 +583,7 @@ bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
btcx_riscmem_free(btv->c.pci,&buf->bottom);
btcx_riscmem_free(btv->c.pci,&buf->top);
diff --git a/drivers/media/video/cpia_usb.c b/drivers/media/video/cpia_usb.c
index ef1f89399983..58d193ff591c 100644
--- a/drivers/media/video/cpia_usb.c
+++ b/drivers/media/video/cpia_usb.c
@@ -584,7 +584,6 @@ static void cpia_disconnect(struct usb_interface *intf)
{
struct cam_data *cam = usb_get_intfdata(intf);
struct usb_cpia *ucpia;
- struct usb_device *udev;
usb_set_intfdata(intf, NULL);
if (!cam)
@@ -606,8 +605,6 @@ static void cpia_disconnect(struct usb_interface *intf)
if (waitqueue_active(&ucpia->wq_stream))
wake_up_interruptible(&ucpia->wq_stream);
- udev = interface_to_usbdev(intf);
-
ucpia->curbuff = ucpia->workbuff = NULL;
vfree(ucpia->buffers[2]);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 809f7d37129c..73ce90c2f577 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -117,7 +117,8 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
break;
}
- return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
+ return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
+ -1 : 0;
}
int cx18_i2c_register(struct cx18 *cx, unsigned idx)
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index d639186f645d..2014daedee8b 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -408,10 +408,18 @@ struct cx23885_subid cx23885_subids[] = {
.card = CX23885_BOARD_HAUPPAUGE_HVR1275,
}, {
.subvendor = 0x0070,
+ .subdevice = 0x221d,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
+ }, {
+ .subvendor = 0x0070,
.subdevice = 0x2251,
.card = CX23885_BOARD_HAUPPAUGE_HVR1255,
}, {
.subvendor = 0x0070,
+ .subdevice = 0x2259,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
+ }, {
+ .subvendor = 0x0070,
.subdevice = 0x2291,
.card = CX23885_BOARD_HAUPPAUGE_HVR1210,
}, {
@@ -419,6 +427,38 @@ struct cx23885_subid cx23885_subids[] = {
.subdevice = 0x2295,
.card = CX23885_BOARD_HAUPPAUGE_HVR1210,
}, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2299,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x229d,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f0,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f1,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f2,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f3,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f4,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x22f5,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */
+ }, {
.subvendor = 0x14f1,
.subdevice = 0x8651,
.card = CX23885_BOARD_MYGICA_X8506,
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 0dde57e96d30..ff76f64edac1 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -1142,7 +1142,7 @@ void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf)
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb, 0, 0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
@@ -1953,8 +1953,12 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- err = request_irq(pci_dev->irq, cx23885_irq,
- IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
+ if (!pci_enable_msi(pci_dev))
+ err = request_irq(pci_dev->irq, cx23885_irq,
+ IRQF_DISABLED, dev->name, dev);
+ else
+ err = request_irq(pci_dev->irq, cx23885_irq,
+ IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n",
dev->name, pci_dev->irq);
@@ -2000,6 +2004,7 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
+ pci_disable_msi(pci_dev);
cx23885_dev_unregister(dev);
v4l2_device_unregister(v4l2_dev);
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 0a199d774d9b..3d70af283881 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -991,7 +991,7 @@ static int dvb_register(struct cx23885_tsport *port)
ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
&dev->pci->dev, adapter_nr, 0,
cx23885_dvb_fe_ioctl_override);
- if (!ret)
+ if (ret)
return ret;
/* init CI & MAC */
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index d4746e064516..9d2a2b0e8ad9 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -365,17 +365,10 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- /*
- * We can't call i2c_new_probed_device() because it uses
- * quick writes for probing and the IR receiver device only
- * replies to reads.
- */
- if (i2c_smbus_xfer(&bus->i2c_adap, addr_list[0], 0,
- I2C_SMBUS_READ, 0, I2C_SMBUS_QUICK,
- NULL) >= 0) {
- info.addr = addr_list[0];
- i2c_new_device(&bus->i2c_adap, &info);
- }
+ /* Use quick read command for probe, some IR chips don't
+ * support writes */
+ i2c_new_probed_device(&bus->i2c_adap, &info, addr_list,
+ i2c_probe_func_quick_read);
}
return bus->i2c_rc;
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 5de6ba98f7a8..d0b1613ede2f 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -37,161 +37,55 @@
#include <linux/input.h>
#include <linux/slab.h>
-#include <media/ir-common.h>
+#include <media/ir-core.h>
#include <media/v4l2-subdev.h>
#include "cx23885.h"
-#define RC5_BITS 14
-#define RC5_HALF_BITS (2*RC5_BITS)
-#define RC5_HALF_BITS_MASK ((1 << RC5_HALF_BITS) - 1)
-
-#define RC5_START_BITS_NORMAL 0x3 /* Command range 0 - 63 */
-#define RC5_START_BITS_EXTENDED 0x2 /* Command range 64 - 127 */
-
-#define RC5_EXTENDED_COMMAND_OFFSET 64
-
#define MODULE_NAME "cx23885"
-static inline unsigned int rc5_command(u32 rc5_baseband)
+static void convert_measurement(u32 x, struct ir_raw_event *y)
{
- return RC5_INSTR(rc5_baseband) +
- ((RC5_START(rc5_baseband) == RC5_START_BITS_EXTENDED)
- ? RC5_EXTENDED_COMMAND_OFFSET : 0);
-}
-
-static void cx23885_input_process_raw_rc5(struct cx23885_dev *dev)
-{
- struct card_ir *ir_input = dev->ir_input;
- unsigned int code, command;
- u32 rc5;
-
- /* Ignore codes that are too short to be valid RC-5 */
- if (ir_input->last_bit < (RC5_HALF_BITS - 1))
- return;
-
- /* The library has the manchester coding backwards; XOR to adapt. */
- code = (ir_input->code & RC5_HALF_BITS_MASK) ^ RC5_HALF_BITS_MASK;
- rc5 = ir_rc5_decode(code);
-
- switch (RC5_START(rc5)) {
- case RC5_START_BITS_NORMAL:
- break;
- case RC5_START_BITS_EXTENDED:
- /* Don't allow if the remote only emits standard commands */
- if (ir_input->start == RC5_START_BITS_NORMAL)
- return;
- break;
- default:
+ if (x == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
+ y->pulse = false;
+ y->duration = V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
return;
}
- if (ir_input->addr != RC5_ADDR(rc5))
- return;
-
- /* Don't generate a keypress for RC-5 auto-repeated keypresses */
- command = rc5_command(rc5);
- if (RC5_TOGGLE(rc5) != RC5_TOGGLE(ir_input->last_rc5) ||
- command != rc5_command(ir_input->last_rc5) ||
- /* Catch T == 0, CMD == 0 (e.g. '0') as first keypress after init */
- RC5_START(ir_input->last_rc5) == 0) {
- /* This keypress is differnet: not an auto repeat */
- ir_input_nokey(ir_input->dev, &ir_input->ir);
- ir_input_keydown(ir_input->dev, &ir_input->ir, command);
- }
- ir_input->last_rc5 = rc5;
-
- /* Schedule when we should do the key up event: ir_input_nokey() */
- mod_timer(&ir_input->timer_keyup,
- jiffies + msecs_to_jiffies(ir_input->rc5_key_timeout));
+ y->pulse = (x & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? true : false;
+ y->duration = x & V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
}
-static void cx23885_input_next_pulse_width_rc5(struct cx23885_dev *dev,
- u32 ns_pulse)
+static void cx23885_input_process_measurements(struct cx23885_dev *dev,
+ bool overrun)
{
- const int rc5_quarterbit_ns = 444444; /* 32 cycles/36 kHz/2 = 444 us */
- struct card_ir *ir_input = dev->ir_input;
- int i, level, quarterbits, halfbits;
-
- if (!ir_input->active) {
- ir_input->active = 1;
- /* assume an initial space that we may not detect or measure */
- ir_input->code = 0;
- ir_input->last_bit = 0;
- }
+ struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir;
+ struct ir_raw_event kernel_ir_event;
- if (ns_pulse == V4L2_SUBDEV_IR_PULSE_RX_SEQ_END) {
- ir_input->last_bit++; /* Account for the final space */
- ir_input->active = 0;
- cx23885_input_process_raw_rc5(dev);
- return;
- }
-
- level = (ns_pulse & V4L2_SUBDEV_IR_PULSE_LEVEL_MASK) ? 1 : 0;
-
- /* Skip any leading space to sync to the start bit */
- if (ir_input->last_bit == 0 && level == 0)
- return;
-
- /*
- * With valid RC-5 we can get up to two consecutive half-bits in a
- * single pulse measurment. Experiments have shown that the duration
- * of a half-bit can vary. Make sure we always end up with an even
- * number of quarter bits at the same level (mark or space).
- */
- ns_pulse &= V4L2_SUBDEV_IR_PULSE_MAX_WIDTH_NS;
- quarterbits = ns_pulse / rc5_quarterbit_ns;
- if (quarterbits & 1)
- quarterbits++;
- halfbits = quarterbits / 2;
-
- for (i = 0; i < halfbits; i++) {
- ir_input->last_bit++;
- ir_input->code |= (level << ir_input->last_bit);
-
- if (ir_input->last_bit >= RC5_HALF_BITS-1) {
- ir_input->active = 0;
- cx23885_input_process_raw_rc5(dev);
- /*
- * If level is 1, a leading mark is invalid for RC5.
- * If level is 0, we scan past extra intial space.
- * Either way we don't want to reactivate collecting
- * marks or spaces here with any left over half-bits.
- */
- break;
- }
- }
-}
-
-static void cx23885_input_process_pulse_widths_rc5(struct cx23885_dev *dev,
- bool add_eom)
-{
- struct card_ir *ir_input = dev->ir_input;
- struct ir_input_state *ir_input_state = &ir_input->ir;
-
- u32 ns_pulse[RC5_HALF_BITS+1];
- ssize_t num = 0;
+ u32 sd_ir_data[64];
+ ssize_t num;
int count, i;
+ bool handle = false;
do {
- v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ns_pulse,
- sizeof(ns_pulse), &num);
+ num = 0;
+ v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) sd_ir_data,
+ sizeof(sd_ir_data), &num);
count = num / sizeof(u32);
- /* Append an end of Rx seq, if the caller requested */
- if (add_eom && count < ARRAY_SIZE(ns_pulse)) {
- ns_pulse[count] = V4L2_SUBDEV_IR_PULSE_RX_SEQ_END;
- count++;
+ for (i = 0; i < count; i++) {
+ convert_measurement(sd_ir_data[i], &kernel_ir_event);
+ ir_raw_event_store(kernel_ir->inp_dev,
+ &kernel_ir_event);
+ handle = true;
}
-
- /* Just drain the Rx FIFO, if we're called, but not RC-5 */
- if (ir_input_state->ir_type != IR_TYPE_RC5)
- continue;
-
- for (i = 0; i < count; i++)
- cx23885_input_next_pulse_width_rc5(dev, ns_pulse[i]);
} while (num != 0);
+
+ if (overrun)
+ ir_raw_event_reset(kernel_ir->inp_dev);
+ else if (handle)
+ ir_raw_event_handle(kernel_ir->inp_dev);
}
void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
@@ -230,7 +124,7 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
}
if (data_available)
- cx23885_input_process_pulse_widths_rc5(dev, overrun);
+ cx23885_input_process_measurements(dev, overrun);
if (overrun) {
/* If there was a FIFO overrun, clear & restart the device */
@@ -241,34 +135,15 @@ void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events)
}
}
-static void cx23885_input_ir_start(struct cx23885_dev *dev)
+static int cx23885_input_ir_start(struct cx23885_dev *dev)
{
- struct card_ir *ir_input = dev->ir_input;
- struct ir_input_state *ir_input_state = &ir_input->ir;
struct v4l2_subdev_ir_parameters params;
if (dev->sd_ir == NULL)
- return;
+ return -ENODEV;
atomic_set(&dev->ir_input_stopping, 0);
- /* keyup timer set up, if needed */
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- setup_timer(&ir_input->timer_keyup,
- ir_rc5_timer_keyup, /* Not actually RC-5 specific */
- (unsigned long) ir_input);
- if (ir_input_state->ir_type == IR_TYPE_RC5) {
- /*
- * RC-5 repeats a held key every
- * 64 bits * (2 * 32/36000) sec/bit = 113.778 ms
- */
- ir_input->rc5_key_timeout = 115;
- }
- break;
- }
-
v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, &params);
switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1850:
@@ -299,11 +174,21 @@ static void cx23885_input_ir_start(struct cx23885_dev *dev)
break;
}
v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, &params);
+ return 0;
+}
+
+static int cx23885_input_ir_open(void *priv)
+{
+ struct cx23885_kernel_ir *kernel_ir = priv;
+
+ if (kernel_ir->cx == NULL)
+ return -ENODEV;
+
+ return cx23885_input_ir_start(kernel_ir->cx);
}
static void cx23885_input_ir_stop(struct cx23885_dev *dev)
{
- struct card_ir *ir_input = dev->ir_input;
struct v4l2_subdev_ir_parameters params;
if (dev->sd_ir == NULL)
@@ -327,21 +212,26 @@ static void cx23885_input_ir_stop(struct cx23885_dev *dev)
}
flush_scheduled_work();
+}
- switch (dev->board) {
- case CX23885_BOARD_HAUPPAUGE_HVR1850:
- case CX23885_BOARD_HAUPPAUGE_HVR1290:
- del_timer_sync(&ir_input->timer_keyup);
- break;
- }
+static void cx23885_input_ir_close(void *priv)
+{
+ struct cx23885_kernel_ir *kernel_ir = priv;
+
+ if (kernel_ir->cx != NULL)
+ cx23885_input_ir_stop(kernel_ir->cx);
}
int cx23885_input_init(struct cx23885_dev *dev)
{
- struct card_ir *ir;
- struct input_dev *input_dev;
- char *ir_codes = NULL;
- int ir_type, ir_addr, ir_start;
+ struct cx23885_kernel_ir *kernel_ir;
+ struct input_dev *inp_dev;
+ struct ir_dev_props *props;
+
+ char *rc_map;
+ enum rc_driver_type driver_type;
+ unsigned long allowed_protos;
+
int ret;
/*
@@ -354,53 +244,59 @@ int cx23885_input_init(struct cx23885_dev *dev)
switch (dev->board) {
case CX23885_BOARD_HAUPPAUGE_HVR1850:
case CX23885_BOARD_HAUPPAUGE_HVR1290:
- /* Parameters for the grey Hauppauge remote for the HVR-1850 */
- ir_codes = RC_MAP_HAUPPAUGE_NEW;
- ir_type = IR_TYPE_RC5;
- ir_addr = 0x1e; /* RC-5 system bits emitted by the remote */
- ir_start = RC5_START_BITS_NORMAL; /* A basic RC-5 remote */
+ /* Integrated CX23888 IR controller */
+ driver_type = RC_DRIVER_IR_RAW;
+ allowed_protos = IR_TYPE_ALL;
+ /* The grey Hauppauge RC-5 remote */
+ rc_map = RC_MAP_RC5_HAUPPAUGE_NEW;
break;
- }
- if (ir_codes == NULL)
+ default:
return -ENODEV;
-
- ir = kzalloc(sizeof(*ir), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ir || !input_dev) {
- ret = -ENOMEM;
- goto err_out_free;
}
- ir->dev = input_dev;
- ir->addr = ir_addr;
- ir->start = ir_start;
+ /* cx23885 board instance kernel IR state */
+ kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL);
+ if (kernel_ir == NULL)
+ return -ENOMEM;
- /* init input device */
- snprintf(ir->name, sizeof(ir->name), "cx23885 IR (%s)",
- cx23885_boards[dev->board].name);
- snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(dev->pci));
+ kernel_ir->cx = dev;
+ kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)",
+ cx23885_boards[dev->board].name);
+ kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0",
+ pci_name(dev->pci));
- ret = ir_input_init(input_dev, &ir->ir, ir_type);
- if (ret < 0)
+ /* input device */
+ inp_dev = input_allocate_device();
+ if (inp_dev == NULL) {
+ ret = -ENOMEM;
goto err_out_free;
+ }
- input_dev->name = ir->name;
- input_dev->phys = ir->phys;
- input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 1;
+ kernel_ir->inp_dev = inp_dev;
+ inp_dev->name = kernel_ir->name;
+ inp_dev->phys = kernel_ir->phys;
+ inp_dev->id.bustype = BUS_PCI;
+ inp_dev->id.version = 1;
if (dev->pci->subsystem_vendor) {
- input_dev->id.vendor = dev->pci->subsystem_vendor;
- input_dev->id.product = dev->pci->subsystem_device;
+ inp_dev->id.vendor = dev->pci->subsystem_vendor;
+ inp_dev->id.product = dev->pci->subsystem_device;
} else {
- input_dev->id.vendor = dev->pci->vendor;
- input_dev->id.product = dev->pci->device;
+ inp_dev->id.vendor = dev->pci->vendor;
+ inp_dev->id.product = dev->pci->device;
}
- input_dev->dev.parent = &dev->pci->dev;
-
- dev->ir_input = ir;
- cx23885_input_ir_start(dev);
-
- ret = ir_input_register(ir->dev, ir_codes, NULL, MODULE_NAME);
+ inp_dev->dev.parent = &dev->pci->dev;
+
+ /* kernel ir device properties */
+ props = &kernel_ir->props;
+ props->driver_type = driver_type;
+ props->allowed_protos = allowed_protos;
+ props->priv = kernel_ir;
+ props->open = cx23885_input_ir_open;
+ props->close = cx23885_input_ir_close;
+
+ /* Go */
+ dev->kernel_ir = kernel_ir;
+ ret = ir_input_register(inp_dev, rc_map, props, MODULE_NAME);
if (ret)
goto err_out_stop;
@@ -408,9 +304,12 @@ int cx23885_input_init(struct cx23885_dev *dev)
err_out_stop:
cx23885_input_ir_stop(dev);
- dev->ir_input = NULL;
+ dev->kernel_ir = NULL;
+ /* TODO: double check clean-up of kernel_ir->inp_dev */
err_out_free:
- kfree(ir);
+ kfree(kernel_ir->phys);
+ kfree(kernel_ir->name);
+ kfree(kernel_ir);
return ret;
}
@@ -419,9 +318,11 @@ void cx23885_input_fini(struct cx23885_dev *dev)
/* Always stop the IR hardware from generating interrupts */
cx23885_input_ir_stop(dev);
- if (dev->ir_input == NULL)
+ if (dev->kernel_ir == NULL)
return;
- ir_input_unregister(dev->ir_input->dev);
- kfree(dev->ir_input);
- dev->ir_input = NULL;
+ ir_input_unregister(dev->kernel_ir->inp_dev);
+ kfree(dev->kernel_ir->phys);
+ kfree(dev->kernel_ir->name);
+ kfree(dev->kernel_ir);
+ dev->kernel_ir = NULL;
}
diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c
index 9a677eb080af..6ceabd4fba07 100644
--- a/drivers/media/video/cx23885/cx23885-ir.c
+++ b/drivers/media/video/cx23885/cx23885-ir.c
@@ -53,7 +53,7 @@ void cx23885_ir_rx_work_handler(struct work_struct *work)
if (events == 0)
return;
- if (dev->ir_input)
+ if (dev->kernel_ir)
cx23885_input_rx_work_handler(dev, events);
}
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 8d6a55e54ee7..a33f2b71467b 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -30,6 +30,7 @@
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
#include <media/videobuf-dvb.h>
+#include <media/ir-core.h>
#include "btcx-risc.h"
#include "cx23885-reg.h"
@@ -304,6 +305,15 @@ struct cx23885_tsport {
void *port_priv;
};
+struct cx23885_kernel_ir {
+ struct cx23885_dev *cx;
+ char *name;
+ char *phys;
+
+ struct input_dev *inp_dev;
+ struct ir_dev_props props;
+};
+
struct cx23885_dev {
atomic_t refcount;
struct v4l2_device v4l2_dev;
@@ -363,7 +373,7 @@ struct cx23885_dev {
struct work_struct ir_tx_work;
unsigned long ir_tx_notifications;
- struct card_ir *ir_input;
+ struct cx23885_kernel_ir *kernel_ir;
atomic_t ir_input_stopping;
/* V4l */
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 33082c96745e..9209d5b87e04 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -54,6 +54,12 @@
Data type declarations - Can be moded to a header file later
****************************************************************************/
+struct cx88_audio_buffer {
+ unsigned int bpl;
+ struct btcx_riscmem risc;
+ struct videobuf_dmabuf dma;
+};
+
struct cx88_audio_dev {
struct cx88_core *core;
struct cx88_dmaqueue q;
@@ -75,7 +81,7 @@ struct cx88_audio_dev {
struct videobuf_dmabuf *dma_risc;
- struct cx88_buffer *buf;
+ struct cx88_audio_buffer *buf;
struct snd_pcm_substream *substream;
};
@@ -123,7 +129,7 @@ MODULE_PARM_DESC(debug,"enable debug messages");
static int _cx88_start_audio_dma(snd_cx88_card_t *chip)
{
- struct cx88_buffer *buf = chip->buf;
+ struct cx88_audio_buffer *buf = chip->buf;
struct cx88_core *core=chip->core;
struct sram_channel *audio_ch = &cx88_sram_channels[SRAM_CH25];
@@ -283,7 +289,7 @@ static int dsp_buffer_free(snd_cx88_card_t *chip)
BUG_ON(!chip->dma_size);
dprintk(2,"Freeing buffer\n");
- videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
+ videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
videobuf_dma_free(chip->dma_risc);
btcx_riscmem_free(chip->pci,&chip->buf->risc);
kfree(chip->buf);
@@ -376,7 +382,7 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
snd_cx88_card_t *chip = snd_pcm_substream_chip(substream);
struct videobuf_dmabuf *dma;
- struct cx88_buffer *buf;
+ struct cx88_audio_buffer *buf;
int ret;
if (substream->runtime->dma_area) {
@@ -391,30 +397,25 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
BUG_ON(!chip->dma_size);
BUG_ON(chip->num_periods & (chip->num_periods-1));
- buf = videobuf_sg_alloc(sizeof(*buf));
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (NULL == buf)
return -ENOMEM;
- buf->vb.memory = V4L2_MEMORY_MMAP;
- buf->vb.field = V4L2_FIELD_NONE;
- buf->vb.width = chip->period_size;
- buf->bpl = chip->period_size;
- buf->vb.height = chip->num_periods;
- buf->vb.size = chip->dma_size;
+ buf->bpl = chip->period_size;
- dma = videobuf_to_dma(&buf->vb);
+ dma = &buf->dma;
videobuf_dma_init(dma);
ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
- (PAGE_ALIGN(buf->vb.size) >> PAGE_SHIFT));
+ (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT));
if (ret < 0)
goto error;
- ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
+ ret = videobuf_dma_map(&chip->pci->dev, dma);
if (ret < 0)
goto error;
ret = cx88_risc_databuffer(chip->pci, &buf->risc, dma->sglist,
- buf->vb.width, buf->vb.height, 1);
+ chip->period_size, chip->num_periods, 1);
if (ret < 0)
goto error;
@@ -422,12 +423,10 @@ static int snd_cx88_hw_params(struct snd_pcm_substream * substream,
buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC);
buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
- buf->vb.state = VIDEOBUF_PREPARED;
-
chip->buf = buf;
chip->dma_risc = dma;
- substream->runtime->dma_area = chip->dma_risc->vmalloc;
+ substream->runtime->dma_area = chip->dma_risc->vaddr;
substream->runtime->dma_bytes = chip->dma_size;
substream->runtime->dma_addr = 0;
return 0;
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 2918a6e38fe8..e8416b76da67 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -45,6 +45,10 @@ static unsigned int latency = UNSET;
module_param(latency,int,0444);
MODULE_PARM_DESC(latency,"pci latency timer");
+static int disable_ir;
+module_param(disable_ir, int, 0444);
+MODULE_PARM_DESC(latency, "Disable IR support");
+
#define info_printk(core, fmt, arg...) \
printk(KERN_INFO "%s: " fmt, core->name , ## arg)
@@ -3498,7 +3502,10 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
}
cx88_card_setup(core);
- cx88_ir_init(core, pci);
+ if (!disable_ir) {
+ cx88_i2c_init_ir(core);
+ cx88_ir_init(core, pci);
+ }
return core;
}
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 8b21457111b1..85eb266fb351 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -218,7 +218,7 @@ cx88_free_buffer(struct videobuf_queue *q, struct cx88_buffer *buf)
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index fb39f1184558..82db555b22dd 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -181,6 +181,11 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
} else
printk("%s: i2c register FAILED\n", core->name);
+ return core->i2c_rc;
+}
+
+void cx88_i2c_init_ir(struct cx88_core *core)
+{
/* Instantiate the IR receiver device, if present */
if (0 == core->i2c_rc) {
struct i2c_board_info info;
@@ -188,26 +193,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
0x18, 0x6b, 0x71,
I2C_CLIENT_END
};
- const unsigned short *addrp;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- /*
- * We can't call i2c_new_probed_device() because it uses
- * quick writes for probing and at least some R receiver
- * devices only reply to reads.
- */
- for (addrp = addr_list; *addrp != I2C_CLIENT_END; addrp++) {
- if (i2c_smbus_xfer(&core->i2c_adap, *addrp, 0,
- I2C_SMBUS_READ, 0,
- I2C_SMBUS_QUICK, NULL) >= 0) {
- info.addr = *addrp;
- i2c_new_device(&core->i2c_adap, &info);
- break;
- }
- }
+ /* Use quick read command for probe, some IR chips don't
+ * support writes */
+ i2c_new_probed_device(&core->i2c_adap, &info, addr_list,
+ i2c_probe_func_quick_read);
}
- return core->i2c_rc;
}
/* ----------------------------------------------------------------------- */
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index e185289e446c..eccc5e49a350 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -30,6 +30,7 @@
#include <linux/module.h>
#include "cx88.h"
+#include <media/ir-core.h>
#include <media/ir-common.h>
#define MODULE_NAME "cx88xx"
@@ -39,8 +40,8 @@
struct cx88_IR {
struct cx88_core *core;
struct input_dev *input;
- struct ir_input_state ir;
struct ir_dev_props props;
+ u64 ir_type;
int users;
@@ -51,7 +52,6 @@ struct cx88_IR {
u32 sampling;
u32 samples[16];
int scount;
- unsigned long release;
/* poll external decoder */
int polling;
@@ -125,29 +125,21 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
data = (data << 4) | ((gpio_key & 0xf0) >> 4);
- ir_input_keydown(ir->input, &ir->ir, data);
- ir_input_nokey(ir->input, &ir->ir);
+ ir_keydown(ir->input, data, 0);
} else if (ir->mask_keydown) {
/* bit set on keydown */
- if (gpio & ir->mask_keydown) {
- ir_input_keydown(ir->input, &ir->ir, data);
- } else {
- ir_input_nokey(ir->input, &ir->ir);
- }
+ if (gpio & ir->mask_keydown)
+ ir_keydown(ir->input, data, 0);
} else if (ir->mask_keyup) {
/* bit cleared on keydown */
- if (0 == (gpio & ir->mask_keyup)) {
- ir_input_keydown(ir->input, &ir->ir, data);
- } else {
- ir_input_nokey(ir->input, &ir->ir);
- }
+ if (0 == (gpio & ir->mask_keyup))
+ ir_keydown(ir->input, data, 0);
} else {
/* can't distinguish keydown/up :-/ */
- ir_input_keydown(ir->input, &ir->ir, data);
- ir_input_nokey(ir->input, &ir->ir);
+ ir_keydown(ir->input, data, 0);
}
}
@@ -439,9 +431,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
snprintf(ir->name, sizeof(ir->name), "cx88 IR (%s)", core->board.name);
snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0", pci_name(pci));
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
+ ir->ir_type = ir_type;
input_dev->name = ir->name;
input_dev->phys = ir->phys;
@@ -516,8 +506,6 @@ void cx88_ir_irq(struct cx88_core *core)
}
if (!ir->scount) {
/* nothing to sample */
- if (ir->ir.keypressed && time_after(jiffies, ir->release))
- ir_input_nokey(ir->input, &ir->ir);
return;
}
@@ -553,7 +541,7 @@ void cx88_ir_irq(struct cx88_core *core)
if (ircode == 0) { /* key still pressed */
ir_dprintk("pulse distance decoded repeat code\n");
- ir->release = jiffies + msecs_to_jiffies(120);
+ ir_repeat(ir->input);
break;
}
@@ -567,10 +555,8 @@ void cx88_ir_irq(struct cx88_core *core)
break;
}
- ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
-
- ir_input_keydown(ir->input, &ir->ir, (ircode >> 16) & 0x7f);
- ir->release = jiffies + msecs_to_jiffies(120);
+ ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0xff);
+ ir_keydown(ir->input, (ircode >> 16) & 0xff, 0);
break;
case CX88_BOARD_HAUPPAUGE:
case CX88_BOARD_HAUPPAUGE_DVB_T1:
@@ -606,16 +592,16 @@ void cx88_ir_irq(struct cx88_core *core)
if ( dev != 0x1e && dev != 0x1f )
/* not a hauppauge remote */
break;
- ir_input_keydown(ir->input, &ir->ir, code);
- ir->release = jiffies + msecs_to_jiffies(120);
+ ir_keydown(ir->input, code, toggle);
break;
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
if ((ircode & 0xfffff000) != 0x3000)
break;
- ir_input_keydown(ir->input, &ir->ir, ircode & 0x3f);
- ir->release = jiffies + msecs_to_jiffies(120);
+ /* Note: bit 0x800 being the toggle is assumed, not checked
+ with real hardware */
+ ir_keydown(ir->input, ircode & 0x3f, ircode & 0x0800 ? 1 : 0);
break;
}
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index bdb03d336536..33d161a11725 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -636,6 +636,7 @@ extern struct videobuf_queue_ops cx8800_vbi_qops;
/* cx88-i2c.c */
extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
+extern void cx88_i2c_init_ir(struct cx88_core *core);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 0f505086774c..5b176bd7afdb 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -706,16 +706,11 @@ static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg
switch (cmd) {
case IOCTL_DAB_BULK:
- pbulk = kmalloc(sizeof (bulk_transfer_t), GFP_KERNEL);
+ pbulk = memdup_user((void __user *)arg,
+ sizeof(bulk_transfer_t));
- if (!pbulk) {
- ret = -ENOMEM;
- break;
- }
-
- if (copy_from_user (pbulk, (void __user *) arg, sizeof (bulk_transfer_t))) {
- ret = -EFAULT;
- kfree (pbulk);
+ if (IS_ERR(pbulk)) {
+ ret = PTR_ERR(pbulk);
break;
}
diff --git a/drivers/media/video/davinci/Kconfig b/drivers/media/video/davinci/Kconfig
new file mode 100644
index 000000000000..6b1954035649
--- /dev/null
+++ b/drivers/media/video/davinci/Kconfig
@@ -0,0 +1,93 @@
+config DISPLAY_DAVINCI_DM646X_EVM
+ tristate "DM646x EVM Video Display"
+ depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+ select VIDEOBUF_DMA_CONTIG
+ select VIDEO_DAVINCI_VPIF
+ select VIDEO_ADV7343
+ select VIDEO_THS7303
+ help
+ Support for DM6467 based display device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpif_display.
+
+config CAPTURE_DAVINCI_DM646X_EVM
+ tristate "DM646x EVM Video Capture"
+ depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
+ select VIDEOBUF_DMA_CONTIG
+ select VIDEO_DAVINCI_VPIF
+ help
+ Support for DM6467 based capture device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpif_capture.
+
+config VIDEO_DAVINCI_VPIF
+ tristate "DaVinci VPIF Driver"
+ depends on DISPLAY_DAVINCI_DM646X_EVM
+ help
+ Support for DaVinci VPIF Driver.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpif.
+
+config VIDEO_VPSS_SYSTEM
+ tristate "VPSS System module driver"
+ depends on ARCH_DAVINCI
+ help
+ Support for vpss system module for video driver
+
+config VIDEO_VPFE_CAPTURE
+ tristate "VPFE Video Capture Driver"
+ depends on VIDEO_V4L2 && (ARCH_DAVINCI || ARCH_OMAP3)
+ select VIDEOBUF_DMA_CONTIG
+ help
+ Support for DMx/AMx VPFE based frame grabber. This is the
+ common V4L2 module for following DMx/AMx SoCs from Texas
+ Instruments:- DM6446, DM365, DM355 & AM3517/05.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpfe-capture.
+
+config VIDEO_DM6446_CCDC
+ tristate "DM6446 CCDC HW module"
+ depends on VIDEO_VPFE_CAPTURE
+ select VIDEO_VPSS_SYSTEM
+ default y
+ help
+ Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
+ with decoder modules such as TVP5146 over BT656 or
+ sensor module such as MT9T001 over a raw interface. This
+ module configures the interface and CCDC/ISIF to do
+ video frame capture from slave decoders.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpfe.
+
+config VIDEO_DM355_CCDC
+ tristate "DM355 CCDC HW module"
+ depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
+ select VIDEO_VPSS_SYSTEM
+ default y
+ help
+ Enables DM355 CCD hw module. DM355 CCDC hw interfaces
+ with decoder modules such as TVP5146 over BT656 or
+ sensor module such as MT9T001 over a raw interface. This
+ module configures the interface and CCDC/ISIF to do
+ video frame capture from a slave decoders
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpfe.
+
+config VIDEO_ISIF
+ tristate "ISIF HW module"
+ depends on ARCH_DAVINCI_DM365 && VIDEO_VPFE_CAPTURE
+ select VIDEO_VPSS_SYSTEM
+ default y
+ help
+ Enables ISIF hw module. This is the hardware module for
+ configuring ISIF in VPFE to capture Raw Bayer RGB data from
+ a image sensor or YUV data from a YUV source.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vpfe.
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3a4fd8514511..12b3d3567932 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -2357,7 +2357,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
if (dev->init_data.name)
info.platform_data = &dev->init_data;
- i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
+ i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL);
}
void em28xx_card_setup(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 5c3fd9411b1f..6759cd5570dd 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -65,17 +65,14 @@ struct em28xx_ir_poll_result {
struct em28xx_IR {
struct em28xx *dev;
struct input_dev *input;
- struct ir_input_state ir;
char name[32];
char phys[32];
/* poll external decoder */
int polling;
struct delayed_work work;
- unsigned int last_toggle:1;
unsigned int full_code:1;
unsigned int last_readcount;
- unsigned int repeat_interval;
int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *);
@@ -291,67 +288,39 @@ static int em2874_polling_getkey(struct em28xx_IR *ir,
static void em28xx_ir_handle_key(struct em28xx_IR *ir)
{
int result;
- int do_sendkey = 0;
struct em28xx_ir_poll_result poll_result;
/* read the registers containing the IR status */
result = ir->get_key(ir, &poll_result);
- if (result < 0) {
+ if (unlikely(result < 0)) {
dprintk("ir->get_key() failed %d\n", result);
return;
}
- dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x%02x\n",
- poll_result.toggle_bit, poll_result.read_count,
- ir->last_readcount, poll_result.rc_address,
- poll_result.rc_data[0]);
-
- if (ir->dev->chip_id == CHIP_ID_EM2874) {
- /* The em2874 clears the readcount field every time the
- register is read. The em2860/2880 datasheet says that it
- is supposed to clear the readcount, but it doesn't. So with
- the em2874, we are looking for a non-zero read count as
- opposed to a readcount that is incrementing */
- ir->last_readcount = 0;
- }
-
- if (poll_result.read_count == 0) {
- /* The button has not been pressed since the last read */
- } else if (ir->last_toggle != poll_result.toggle_bit) {
- /* A button has been pressed */
- dprintk("button has been pressed\n");
- ir->last_toggle = poll_result.toggle_bit;
- ir->repeat_interval = 0;
- do_sendkey = 1;
- } else if (poll_result.toggle_bit == ir->last_toggle &&
- poll_result.read_count > 0 &&
- poll_result.read_count != ir->last_readcount) {
- /* The button is still being held down */
- dprintk("button being held down\n");
-
- /* Debouncer for first keypress */
- if (ir->repeat_interval++ > 9) {
- /* Start repeating after 1 second */
- do_sendkey = 1;
- }
- }
-
- if (do_sendkey) {
- dprintk("sending keypress\n");
-
+ if (unlikely(poll_result.read_count != ir->last_readcount)) {
+ dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__,
+ poll_result.toggle_bit, poll_result.read_count,
+ poll_result.rc_address, poll_result.rc_data[0]);
if (ir->full_code)
- ir_input_keydown(ir->input, &ir->ir,
- poll_result.rc_address << 8 |
- poll_result.rc_data[0]);
+ ir_keydown(ir->input,
+ poll_result.rc_address << 8 |
+ poll_result.rc_data[0],
+ poll_result.toggle_bit);
else
- ir_input_keydown(ir->input, &ir->ir,
- poll_result.rc_data[0]);
-
- ir_input_nokey(ir->input, &ir->ir);
+ ir_keydown(ir->input,
+ poll_result.rc_data[0],
+ poll_result.toggle_bit);
+
+ if (ir->dev->chip_id == CHIP_ID_EM2874)
+ /* The em2874 clears the readcount field every time the
+ register is read. The em2860/2880 datasheet says that it
+ is supposed to clear the readcount, but it doesn't. So with
+ the em2874, we are looking for a non-zero read count as
+ opposed to a readcount that is incrementing */
+ ir->last_readcount = 0;
+ else
+ ir->last_readcount = poll_result.read_count;
}
-
- ir->last_readcount = poll_result.read_count;
- return;
}
static void em28xx_ir_work(struct work_struct *work)
@@ -466,11 +435,6 @@ int em28xx_ir_init(struct em28xx *dev)
usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
strlcat(ir->phys, "/input0", sizeof(ir->phys));
- /* Set IR protocol */
- err = ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER);
- if (err < 0)
- goto err_out_free;
-
input_dev->name = ir->name;
input_dev->phys = ir->phys;
input_dev->id.bustype = BUS_USB;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 20090e34173a..7b9ec6e493e4 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -654,12 +654,12 @@ static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
}
if (buf != NULL && dev->capture_type == 2) {
- if (len > 4 && p[0] == 0x88 && p[1] == 0x88 &&
+ if (len >= 4 && p[0] == 0x88 && p[1] == 0x88 &&
p[2] == 0x88 && p[3] == 0x88) {
p += 4;
len -= 4;
}
- if (len > 4 && p[0] == 0x22 && p[1] == 0x5a) {
+ if (len >= 4 && p[0] == 0x22 && p[1] == 0x5a) {
em28xx_isocdbg("Video frame %d, len=%i, %s\n",
p[2], len, (p[2] & 1) ?
"odd" : "even");
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index b252d1b1b2a7..6216786565c2 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -32,6 +32,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <media/ir-kbd-i2c.h>
+#include <media/ir-core.h>
#if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE)
#include <media/videobuf-dvb.h>
#endif
diff --git a/drivers/media/video/fsl-viu.c b/drivers/media/video/fsl-viu.c
new file mode 100644
index 000000000000..8f1c94f7e00c
--- /dev/null
+++ b/drivers/media/video/fsl-viu.c
@@ -0,0 +1,1632 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Freescale VIU video driver
+ *
+ * Authors: Hongjun Chen <hong-jun.chen@freescale.com>
+ * Porting to 2.6.35 by DENX Software Engineering,
+ * Anatolij Gustschin <agust@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf-dma-contig.h>
+
+#define DRV_NAME "fsl_viu"
+#define VIU_MAJOR_VERSION 0
+#define VIU_MINOR_VERSION 5
+#define VIU_RELEASE 0
+#define VIU_VERSION KERNEL_VERSION(VIU_MAJOR_VERSION, \
+ VIU_MINOR_VERSION, \
+ VIU_RELEASE)
+
+#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
+
+#define VIU_VID_MEM_LIMIT 4 /* Video memory limit, in Mb */
+
+/* I2C address of video decoder chip is 0x4A */
+#define VIU_VIDEO_DECODER_ADDR 0x25
+
+/* supported controls */
+static struct v4l2_queryctrl viu_qctrl[] = {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 127,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = 0x10,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 0x1,
+ .default_value = 127,
+ .flags = 0,
+ }, {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = -128,
+ .maximum = 127,
+ .step = 0x1,
+ .default_value = 0,
+ .flags = 0,
+ }
+};
+
+static int qctl_regs[ARRAY_SIZE(viu_qctrl)];
+
+static int info_level;
+
+#define dprintk(level, fmt, arg...) \
+ do { \
+ if (level <= info_level) \
+ printk(KERN_DEBUG "viu: " fmt , ## arg); \
+ } while (0)
+
+/*
+ * Basic structures
+ */
+struct viu_fmt {
+ char name[32];
+ u32 fourcc; /* v4l2 format id */
+ u32 pixelformat;
+ int depth;
+};
+
+static struct viu_fmt formats[] = {
+ {
+ .name = "RGB-16 (5/B-6/G-5/R)",
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .pixelformat = V4L2_PIX_FMT_RGB565,
+ .depth = 16,
+ }, {
+ .name = "RGB-32 (A-R-G-B)",
+ .fourcc = V4L2_PIX_FMT_RGB32,
+ .pixelformat = V4L2_PIX_FMT_RGB32,
+ .depth = 32,
+ }
+};
+
+struct viu_dev;
+struct viu_buf;
+
+/* buffer for one video frame */
+struct viu_buf {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ struct viu_fmt *fmt;
+};
+
+struct viu_dmaqueue {
+ struct viu_dev *dev;
+ struct list_head active;
+ struct list_head queued;
+ struct timer_list timeout;
+};
+
+struct viu_status {
+ u32 field_irq;
+ u32 vsync_irq;
+ u32 hsync_irq;
+ u32 vstart_irq;
+ u32 dma_end_irq;
+ u32 error_irq;
+};
+
+struct viu_reg {
+ u32 status_cfg;
+ u32 luminance;
+ u32 chroma_r;
+ u32 chroma_g;
+ u32 chroma_b;
+ u32 field_base_addr;
+ u32 dma_inc;
+ u32 picture_count;
+ u32 req_alarm;
+ u32 alpha;
+} __attribute__ ((packed));
+
+struct viu_dev {
+ struct v4l2_device v4l2_dev;
+ struct mutex lock;
+ spinlock_t slock;
+ int users;
+
+ struct device *dev;
+ /* various device info */
+ struct video_device *vdev;
+ struct viu_dmaqueue vidq;
+ enum v4l2_field capfield;
+ int field;
+ int first;
+ int dma_done;
+
+ /* Hardware register area */
+ struct viu_reg *vr;
+
+ /* Interrupt vector */
+ int irq;
+ struct viu_status irqs;
+
+ /* video overlay */
+ struct v4l2_framebuffer ovbuf;
+ struct viu_fmt *ovfmt;
+ unsigned int ovenable;
+ enum v4l2_field ovfield;
+
+ /* crop */
+ struct v4l2_rect crop_current;
+
+ /* clock pointer */
+ struct clk *clk;
+
+ /* decoder */
+ struct v4l2_subdev *decoder;
+};
+
+struct viu_fh {
+ struct viu_dev *dev;
+
+ /* video capture */
+ struct videobuf_queue vb_vidq;
+ spinlock_t vbq_lock; /* spinlock for the videobuf queue */
+
+ /* video overlay */
+ struct v4l2_window win;
+ struct v4l2_clip clips[1];
+
+ /* video capture */
+ struct viu_fmt *fmt;
+ int width, height, sizeimage;
+ enum v4l2_buf_type type;
+};
+
+static struct viu_reg reg_val;
+
+/*
+ * Macro definitions of VIU registers
+ */
+
+/* STATUS_CONFIG register */
+enum status_config {
+ SOFT_RST = 1 << 0,
+
+ ERR_MASK = 0x0f << 4, /* Error code mask */
+ ERR_NO = 0x00, /* No error */
+ ERR_DMA_V = 0x01 << 4, /* DMA in vertical active */
+ ERR_DMA_VB = 0x02 << 4, /* DMA in vertical blanking */
+ ERR_LINE_TOO_LONG = 0x04 << 4, /* Line too long */
+ ERR_TOO_MANG_LINES = 0x05 << 4, /* Too many lines in field */
+ ERR_LINE_TOO_SHORT = 0x06 << 4, /* Line too short */
+ ERR_NOT_ENOUGH_LINE = 0x07 << 4, /* Not enough lines in field */
+ ERR_FIFO_OVERFLOW = 0x08 << 4, /* FIFO overflow */
+ ERR_FIFO_UNDERFLOW = 0x09 << 4, /* FIFO underflow */
+ ERR_1bit_ECC = 0x0a << 4, /* One bit ECC error */
+ ERR_MORE_ECC = 0x0b << 4, /* Two/more bits ECC error */
+
+ INT_FIELD_EN = 0x01 << 8, /* Enable field interrupt */
+ INT_VSYNC_EN = 0x01 << 9, /* Enable vsync interrupt */
+ INT_HSYNC_EN = 0x01 << 10, /* Enable hsync interrupt */
+ INT_VSTART_EN = 0x01 << 11, /* Enable vstart interrupt */
+ INT_DMA_END_EN = 0x01 << 12, /* Enable DMA end interrupt */
+ INT_ERROR_EN = 0x01 << 13, /* Enable error interrupt */
+ INT_ECC_EN = 0x01 << 14, /* Enable ECC interrupt */
+
+ INT_FIELD_STATUS = 0x01 << 16, /* field interrupt status */
+ INT_VSYNC_STATUS = 0x01 << 17, /* vsync interrupt status */
+ INT_HSYNC_STATUS = 0x01 << 18, /* hsync interrupt status */
+ INT_VSTART_STATUS = 0x01 << 19, /* vstart interrupt status */
+ INT_DMA_END_STATUS = 0x01 << 20, /* DMA end interrupt status */
+ INT_ERROR_STATUS = 0x01 << 21, /* error interrupt status */
+
+ DMA_ACT = 0x01 << 27, /* Enable DMA transfer */
+ FIELD_NO = 0x01 << 28, /* Field number */
+ DITHER_ON = 0x01 << 29, /* Dithering is on */
+ ROUND_ON = 0x01 << 30, /* Round is on */
+ MODE_32BIT = 0x01 << 31, /* Data in RGBa888,
+ * 0 in RGB565
+ */
+};
+
+#define norm_maxw() 720
+#define norm_maxh() 576
+
+#define INT_ALL_STATUS (INT_FIELD_STATUS | INT_VSYNC_STATUS | \
+ INT_HSYNC_STATUS | INT_VSTART_STATUS | \
+ INT_DMA_END_STATUS | INT_ERROR_STATUS)
+
+#define NUM_FORMATS ARRAY_SIZE(formats)
+
+static irqreturn_t viu_intr(int irq, void *dev_id);
+
+struct viu_fmt *format_by_fourcc(int fourcc)
+{
+ int i;
+
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (formats[i].pixelformat == fourcc)
+ return formats + i;
+ }
+
+ dprintk(0, "unknown pixelformat:'%4.4s'\n", (char *)&fourcc);
+ return NULL;
+}
+
+void viu_start_dma(struct viu_dev *dev)
+{
+ struct viu_reg *vr = dev->vr;
+
+ dev->field = 0;
+
+ /* Enable DMA operation */
+ out_be32(&vr->status_cfg, SOFT_RST);
+ out_be32(&vr->status_cfg, INT_FIELD_EN);
+}
+
+void viu_stop_dma(struct viu_dev *dev)
+{
+ struct viu_reg *vr = dev->vr;
+ int cnt = 100;
+ u32 status_cfg;
+
+ out_be32(&vr->status_cfg, 0);
+
+ /* Clear pending interrupts */
+ status_cfg = in_be32(&vr->status_cfg);
+ if (status_cfg & 0x3f0000)
+ out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
+
+ if (status_cfg & DMA_ACT) {
+ do {
+ status_cfg = in_be32(&vr->status_cfg);
+ if (status_cfg & INT_DMA_END_STATUS)
+ break;
+ } while (cnt--);
+
+ if (cnt < 0) {
+ /* timed out, issue soft reset */
+ out_be32(&vr->status_cfg, SOFT_RST);
+ out_be32(&vr->status_cfg, 0);
+ } else {
+ /* clear DMA_END and other pending irqs */
+ out_be32(&vr->status_cfg, status_cfg & 0x3f0000);
+ }
+ }
+
+ dev->field = 0;
+}
+
+static int restart_video_queue(struct viu_dmaqueue *vidq)
+{
+ struct viu_buf *buf, *prev;
+
+ dprintk(1, "%s vidq=0x%08lx\n", __func__, (unsigned long)vidq);
+ if (!list_empty(&vidq->active)) {
+ buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
+ dprintk(2, "restart_queue [%p/%d]: restart dma\n",
+ buf, buf->vb.i);
+
+ viu_stop_dma(vidq->dev);
+
+ /* cancel all outstanding capture requests */
+ list_for_each_entry_safe(buf, prev, &vidq->active, vb.queue) {
+ list_del(&buf->vb.queue);
+ buf->vb.state = VIDEOBUF_ERROR;
+ wake_up(&buf->vb.done);
+ }
+ mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
+ return 0;
+ }
+
+ prev = NULL;
+ for (;;) {
+ if (list_empty(&vidq->queued))
+ return 0;
+ buf = list_entry(vidq->queued.next, struct viu_buf, vb.queue);
+ if (prev == NULL) {
+ list_del(&buf->vb.queue);
+ list_add_tail(&buf->vb.queue, &vidq->active);
+
+ dprintk(1, "Restarting video dma\n");
+ viu_stop_dma(vidq->dev);
+ viu_start_dma(vidq->dev);
+
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
+ dprintk(2, "[%p/%d] restart_queue - first active\n",
+ buf, buf->vb.i);
+
+ } else if (prev->vb.width == buf->vb.width &&
+ prev->vb.height == buf->vb.height &&
+ prev->fmt == buf->fmt) {
+ list_del(&buf->vb.queue);
+ list_add_tail(&buf->vb.queue, &vidq->active);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ dprintk(2, "[%p/%d] restart_queue - move to active\n",
+ buf, buf->vb.i);
+ } else {
+ return 0;
+ }
+ prev = buf;
+ }
+}
+
+static void viu_vid_timeout(unsigned long data)
+{
+ struct viu_dev *dev = (struct viu_dev *)data;
+ struct viu_buf *buf;
+ struct viu_dmaqueue *vidq = &dev->vidq;
+
+ while (!list_empty(&vidq->active)) {
+ buf = list_entry(vidq->active.next, struct viu_buf, vb.queue);
+ list_del(&buf->vb.queue);
+ buf->vb.state = VIDEOBUF_ERROR;
+ wake_up(&buf->vb.done);
+ dprintk(1, "viu/0: [%p/%d] timeout\n", buf, buf->vb.i);
+ }
+
+ restart_video_queue(vidq);
+}
+
+/*
+ * Videobuf operations
+ */
+static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct viu_fh *fh = vq->priv_data;
+
+ *size = fh->width * fh->height * fh->fmt->depth >> 3;
+ if (*count == 0)
+ *count = 32;
+
+ while (*size * *count > VIU_VID_MEM_LIMIT * 1024 * 1024)
+ (*count)--;
+
+ dprintk(1, "%s, count=%d, size=%d\n", __func__, *count, *size);
+ return 0;
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct viu_buf *buf)
+{
+ struct videobuf_buffer *vb = &buf->vb;
+ void *vaddr = NULL;
+
+ BUG_ON(in_interrupt());
+
+ videobuf_waiton(&buf->vb, 0, 0);
+
+ if (vq->int_ops && vq->int_ops->vaddr)
+ vaddr = vq->int_ops->vaddr(vb);
+
+ if (vaddr)
+ videobuf_dma_contig_free(vq, &buf->vb);
+
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+inline int buffer_activate(struct viu_dev *dev, struct viu_buf *buf)
+{
+ struct viu_reg *vr = dev->vr;
+ int bpp;
+
+ /* setup the DMA base address */
+ reg_val.field_base_addr = videobuf_to_dma_contig(&buf->vb);
+
+ dprintk(1, "buffer_activate [%p/%d]: dma addr 0x%lx\n",
+ buf, buf->vb.i, (unsigned long)reg_val.field_base_addr);
+
+ /* interlace is on by default, set horizontal DMA increment */
+ reg_val.status_cfg = 0;
+ bpp = buf->fmt->depth >> 3;
+ switch (bpp) {
+ case 2:
+ reg_val.status_cfg &= ~MODE_32BIT;
+ reg_val.dma_inc = buf->vb.width * 2;
+ break;
+ case 4:
+ reg_val.status_cfg |= MODE_32BIT;
+ reg_val.dma_inc = buf->vb.width * 4;
+ break;
+ default:
+ dprintk(0, "doesn't support color depth(%d)\n",
+ bpp * 8);
+ return -EINVAL;
+ }
+
+ /* setup picture_count register */
+ reg_val.picture_count = (buf->vb.height / 2) << 16 |
+ buf->vb.width;
+
+ reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
+
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ dev->capfield = buf->vb.field;
+
+ /* reset dma increment if needed */
+ if (!V4L2_FIELD_HAS_BOTH(buf->vb.field))
+ reg_val.dma_inc = 0;
+
+ out_be32(&vr->dma_inc, reg_val.dma_inc);
+ out_be32(&vr->picture_count, reg_val.picture_count);
+ out_be32(&vr->field_base_addr, reg_val.field_base_addr);
+ mod_timer(&dev->vidq.timeout, jiffies + BUFFER_TIMEOUT);
+ return 0;
+}
+
+static int buffer_prepare(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct viu_fh *fh = vq->priv_data;
+ struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
+ int rc;
+
+ BUG_ON(fh->fmt == NULL);
+
+ if (fh->width < 48 || fh->width > norm_maxw() ||
+ fh->height < 32 || fh->height > norm_maxh())
+ return -EINVAL;
+ buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
+ if (buf->vb.baddr != 0 && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ if (buf->fmt != fh->fmt ||
+ buf->vb.width != fh->width ||
+ buf->vb.height != fh->height ||
+ buf->vb.field != field) {
+ buf->fmt = fh->fmt;
+ buf->vb.width = fh->width;
+ buf->vb.height = fh->height;
+ buf->vb.field = field;
+ }
+
+ if (buf->vb.state == VIDEOBUF_NEEDS_INIT) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc != 0)
+ goto fail;
+
+ buf->vb.width = fh->width;
+ buf->vb.height = fh->height;
+ buf->vb.field = field;
+ buf->fmt = fh->fmt;
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
+ struct viu_fh *fh = vq->priv_data;
+ struct viu_dev *dev = fh->dev;
+ struct viu_dmaqueue *vidq = &dev->vidq;
+ struct viu_buf *prev;
+
+ if (!list_empty(&vidq->queued)) {
+ dprintk(1, "adding vb queue=0x%08lx\n",
+ (unsigned long)&buf->vb.queue);
+ dprintk(1, "vidq pointer 0x%p, queued 0x%p\n",
+ vidq, &vidq->queued);
+ dprintk(1, "dev %p, queued: self %p, next %p, head %p\n",
+ dev, &vidq->queued, vidq->queued.next,
+ vidq->queued.prev);
+ list_add_tail(&buf->vb.queue, &vidq->queued);
+ buf->vb.state = VIDEOBUF_QUEUED;
+ dprintk(2, "[%p/%d] buffer_queue - append to queued\n",
+ buf, buf->vb.i);
+ } else if (list_empty(&vidq->active)) {
+ dprintk(1, "adding vb active=0x%08lx\n",
+ (unsigned long)&buf->vb.queue);
+ list_add_tail(&buf->vb.queue, &vidq->active);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ mod_timer(&vidq->timeout, jiffies+BUFFER_TIMEOUT);
+ dprintk(2, "[%p/%d] buffer_queue - first active\n",
+ buf, buf->vb.i);
+
+ buffer_activate(dev, buf);
+ } else {
+ dprintk(1, "adding vb queue2=0x%08lx\n",
+ (unsigned long)&buf->vb.queue);
+ prev = list_entry(vidq->active.prev, struct viu_buf, vb.queue);
+ if (prev->vb.width == buf->vb.width &&
+ prev->vb.height == buf->vb.height &&
+ prev->fmt == buf->fmt) {
+ list_add_tail(&buf->vb.queue, &vidq->active);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ dprintk(2, "[%p/%d] buffer_queue - append to active\n",
+ buf, buf->vb.i);
+ } else {
+ list_add_tail(&buf->vb.queue, &vidq->queued);
+ buf->vb.state = VIDEOBUF_QUEUED;
+ dprintk(2, "[%p/%d] buffer_queue - first queued\n",
+ buf, buf->vb.i);
+ }
+ }
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct viu_buf *buf = container_of(vb, struct viu_buf, vb);
+ struct viu_fh *fh = vq->priv_data;
+ struct viu_dev *dev = (struct viu_dev *)fh->dev;
+
+ viu_stop_dma(dev);
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops viu_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/*
+ * IOCTL vidioc handling
+ */
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ strcpy(cap->driver, "viu");
+ strcpy(cap->card, "viu");
+ cap->version = VIU_VERSION;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_READWRITE;
+ return 0;
+}
+
+static int vidioc_enum_fmt(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ int index = f->index;
+
+ if (f->index > NUM_FORMATS)
+ return -EINVAL;
+
+ strlcpy(f->description, formats[index].name, sizeof(f->description));
+ f->pixelformat = formats[index].fourcc;
+ return 0;
+}
+
+static int vidioc_g_fmt_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct viu_fh *fh = priv;
+
+ f->fmt.pix.width = fh->width;
+ f->fmt.pix.height = fh->height;
+ f->fmt.pix.field = fh->vb_vidq.field;
+ f->fmt.pix.pixelformat = fh->fmt->pixelformat;
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * fh->fmt->depth) >> 3;
+ f->fmt.pix.sizeimage = fh->sizeimage;
+ return 0;
+}
+
+static int vidioc_try_fmt_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct viu_fmt *fmt;
+ enum v4l2_field field;
+ unsigned int maxw, maxh;
+
+ fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ if (!fmt) {
+ dprintk(1, "Fourcc format (0x%08x) invalid.",
+ f->fmt.pix.pixelformat);
+ return -EINVAL;
+ }
+
+ field = f->fmt.pix.field;
+
+ if (field == V4L2_FIELD_ANY) {
+ field = V4L2_FIELD_INTERLACED;
+ } else if (field != V4L2_FIELD_INTERLACED) {
+ dprintk(1, "Field type invalid.\n");
+ return -EINVAL;
+ }
+
+ maxw = norm_maxw();
+ maxh = norm_maxh();
+
+ f->fmt.pix.field = field;
+ if (f->fmt.pix.height < 32)
+ f->fmt.pix.height = 32;
+ if (f->fmt.pix.height > maxh)
+ f->fmt.pix.height = maxh;
+ if (f->fmt.pix.width < 48)
+ f->fmt.pix.width = 48;
+ if (f->fmt.pix.width > maxw)
+ f->fmt.pix.width = maxw;
+ f->fmt.pix.width &= ~0x03;
+ f->fmt.pix.bytesperline =
+ (f->fmt.pix.width * fmt->depth) >> 3;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct viu_fh *fh = priv;
+ int ret;
+
+ ret = vidioc_try_fmt_cap(file, fh, f);
+ if (ret < 0)
+ return ret;
+
+ fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fh->width = f->fmt.pix.width;
+ fh->height = f->fmt.pix.height;
+ fh->sizeimage = f->fmt.pix.sizeimage;
+ fh->vb_vidq.field = f->fmt.pix.field;
+ fh->type = f->type;
+ dprintk(1, "set to pixelformat '%4.6s'\n", (char *)&fh->fmt->name);
+ return 0;
+}
+
+static int vidioc_g_fmt_overlay(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct viu_fh *fh = priv;
+
+ f->fmt.win = fh->win;
+ return 0;
+}
+
+static int verify_preview(struct viu_dev *dev, struct v4l2_window *win)
+{
+ enum v4l2_field field;
+ int maxw, maxh;
+
+ if (dev->ovbuf.base == NULL)
+ return -EINVAL;
+ if (dev->ovfmt == NULL)
+ return -EINVAL;
+ if (win->w.width < 48 || win->w.height < 32)
+ return -EINVAL;
+
+ field = win->field;
+ maxw = dev->crop_current.width;
+ maxh = dev->crop_current.height;
+
+ if (field == V4L2_FIELD_ANY) {
+ field = (win->w.height > maxh/2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ win->field = field;
+ if (win->w.width > maxw)
+ win->w.width = maxw;
+ if (win->w.height > maxh)
+ win->w.height = maxh;
+ return 0;
+}
+
+inline void viu_activate_overlay(struct viu_reg *viu_reg)
+{
+ struct viu_reg *vr = viu_reg;
+
+ out_be32(&vr->field_base_addr, reg_val.field_base_addr);
+ out_be32(&vr->dma_inc, reg_val.dma_inc);
+ out_be32(&vr->picture_count, reg_val.picture_count);
+}
+
+static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh)
+{
+ int bpp;
+
+ dprintk(1, "%s %dx%d %s\n", __func__,
+ fh->win.w.width, fh->win.w.height, dev->ovfmt->name);
+
+ reg_val.status_cfg = 0;
+
+ /* setup window */
+ reg_val.picture_count = (fh->win.w.height / 2) << 16 |
+ fh->win.w.width;
+
+ /* setup color depth and dma increment */
+ bpp = dev->ovfmt->depth / 8;
+ switch (bpp) {
+ case 2:
+ reg_val.status_cfg &= ~MODE_32BIT;
+ reg_val.dma_inc = fh->win.w.width * 2;
+ break;
+ case 4:
+ reg_val.status_cfg |= MODE_32BIT;
+ reg_val.dma_inc = fh->win.w.width * 4;
+ break;
+ default:
+ dprintk(0, "device doesn't support color depth(%d)\n",
+ bpp * 8);
+ return -EINVAL;
+ }
+
+ dev->ovfield = fh->win.field;
+ if (!V4L2_FIELD_HAS_BOTH(dev->ovfield))
+ reg_val.dma_inc = 0;
+
+ reg_val.status_cfg |= DMA_ACT | INT_DMA_END_EN | INT_FIELD_EN;
+
+ /* setup the base address of the overlay buffer */
+ reg_val.field_base_addr = (u32)dev->ovbuf.base;
+
+ dev->ovenable = 1;
+ viu_activate_overlay(dev->vr);
+
+ /* start dma */
+ viu_start_dma(dev);
+ return 0;
+}
+
+static int vidioc_s_fmt_overlay(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct viu_fh *fh = priv;
+ struct viu_dev *dev = (struct viu_dev *)fh->dev;
+ unsigned long flags;
+ int err;
+
+ err = verify_preview(dev, &f->fmt.win);
+ if (err)
+ return err;
+
+ mutex_lock(&dev->lock);
+ fh->win = f->fmt.win;
+
+ spin_lock_irqsave(&dev->slock, flags);
+ viu_start_preview(dev, fh);
+ spin_unlock_irqrestore(&dev->slock, flags);
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static int vidioc_try_fmt_overlay(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ return 0;
+}
+
+int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
+{
+ struct viu_fh *fh = priv;
+ struct viu_dev *dev = fh->dev;
+ struct v4l2_framebuffer *fb = arg;
+
+ *fb = dev->ovbuf;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+ return 0;
+}
+
+int vidioc_s_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
+{
+ struct viu_fh *fh = priv;
+ struct viu_dev *dev = fh->dev;
+ struct v4l2_framebuffer *fb = arg;
+ struct viu_fmt *fmt;
+
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+ return -EPERM;
+
+ /* check args */
+ fmt = format_by_fourcc(fb->fmt.pixelformat);
+ if (fmt == NULL)
+ return -EINVAL;
+
+ /* ok, accept it */
+ dev->ovbuf = *fb;
+ dev->ovfmt = fmt;
+ if (dev->ovbuf.fmt.bytesperline == 0) {
+ dev->ovbuf.fmt.bytesperline =
+ dev->ovbuf.fmt.width * fmt->depth / 8;
+ }
+ return 0;
+}
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *p)
+{
+ struct viu_fh *fh = priv;
+
+ return videobuf_reqbufs(&fh->vb_vidq, p);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *p)
+{
+ struct viu_fh *fh = priv;
+
+ return videobuf_querybuf(&fh->vb_vidq, p);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct viu_fh *fh = priv;
+
+ return videobuf_qbuf(&fh->vb_vidq, p);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ struct viu_fh *fh = priv;
+
+ return videobuf_dqbuf(&fh->vb_vidq, p,
+ file->f_flags & O_NONBLOCK);
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct viu_fh *fh = priv;
+
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (fh->type != i)
+ return -EINVAL;
+
+ return videobuf_streamon(&fh->vb_vidq);
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct viu_fh *fh = priv;
+
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (fh->type != i)
+ return -EINVAL;
+
+ return videobuf_streamoff(&fh->vb_vidq);
+}
+
+#define decoder_call(viu, o, f, args...) \
+ v4l2_subdev_call(viu->decoder, o, f, ##args)
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
+{
+ struct viu_fh *fh = priv;
+
+ decoder_call(fh->dev, core, s_std, *id);
+ return 0;
+}
+
+/* only one input in this driver */
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *inp)
+{
+ struct viu_fh *fh = priv;
+
+ if (inp->index != 0)
+ return -EINVAL;
+
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ inp->std = fh->dev->vdev->tvnorms;
+ strcpy(inp->name, "Camera");
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
+{
+ struct viu_fh *fh = priv;
+
+ if (i > 1)
+ return -EINVAL;
+
+ decoder_call(fh->dev, video, s_routing, i, 0, 0);
+ return 0;
+}
+
+/* Controls */
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
+ if (qc->id && qc->id == viu_qctrl[i].id) {
+ memcpy(qc, &(viu_qctrl[i]), sizeof(*qc));
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
+ if (ctrl->id == viu_qctrl[i].id) {
+ ctrl->value = qctl_regs[i];
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++) {
+ if (ctrl->id == viu_qctrl[i].id) {
+ if (ctrl->value < viu_qctrl[i].minimum
+ || ctrl->value > viu_qctrl[i].maximum)
+ return -ERANGE;
+ qctl_regs[i] = ctrl->value;
+ return 0;
+ }
+ }
+ return -EINVAL;
+}
+
+inline void viu_activate_next_buf(struct viu_dev *dev,
+ struct viu_dmaqueue *viuq)
+{
+ struct viu_dmaqueue *vidq = viuq;
+ struct viu_buf *buf;
+
+ /* launch another DMA operation for an active/queued buffer */
+ if (!list_empty(&vidq->active)) {
+ buf = list_entry(vidq->active.next, struct viu_buf,
+ vb.queue);
+ dprintk(1, "start another queued buffer: 0x%p\n", buf);
+ buffer_activate(dev, buf);
+ } else if (!list_empty(&vidq->queued)) {
+ buf = list_entry(vidq->queued.next, struct viu_buf,
+ vb.queue);
+ list_del(&buf->vb.queue);
+
+ dprintk(1, "start another queued buffer: 0x%p\n", buf);
+ list_add_tail(&buf->vb.queue, &vidq->active);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ buffer_activate(dev, buf);
+ }
+}
+
+inline void viu_default_settings(struct viu_reg *viu_reg)
+{
+ struct viu_reg *vr = viu_reg;
+
+ out_be32(&vr->luminance, 0x9512A254);
+ out_be32(&vr->chroma_r, 0x03310000);
+ out_be32(&vr->chroma_g, 0x06600F38);
+ out_be32(&vr->chroma_b, 0x00000409);
+ out_be32(&vr->alpha, 0x000000ff);
+ out_be32(&vr->req_alarm, 0x00000090);
+ dprintk(1, "status reg: 0x%08x, field base: 0x%08x\n",
+ in_be32(&vr->status_cfg), in_be32(&vr->field_base_addr));
+}
+
+static void viu_overlay_intr(struct viu_dev *dev, u32 status)
+{
+ struct viu_reg *vr = dev->vr;
+
+ if (status & INT_DMA_END_STATUS)
+ dev->dma_done = 1;
+
+ if (status & INT_FIELD_STATUS) {
+ if (dev->dma_done) {
+ u32 addr = reg_val.field_base_addr;
+
+ dev->dma_done = 0;
+ if (status & FIELD_NO)
+ addr += reg_val.dma_inc;
+
+ out_be32(&vr->field_base_addr, addr);
+ out_be32(&vr->dma_inc, reg_val.dma_inc);
+ out_be32(&vr->status_cfg,
+ (status & 0xffc0ffff) |
+ (status & INT_ALL_STATUS) |
+ reg_val.status_cfg);
+ } else if (status & INT_VSYNC_STATUS) {
+ out_be32(&vr->status_cfg,
+ (status & 0xffc0ffff) |
+ (status & INT_ALL_STATUS) |
+ reg_val.status_cfg);
+ }
+ }
+}
+
+static void viu_capture_intr(struct viu_dev *dev, u32 status)
+{
+ struct viu_dmaqueue *vidq = &dev->vidq;
+ struct viu_reg *vr = dev->vr;
+ struct viu_buf *buf;
+ int field_num;
+ int need_two;
+ int dma_done = 0;
+
+ field_num = status & FIELD_NO;
+ need_two = V4L2_FIELD_HAS_BOTH(dev->capfield);
+
+ if (status & INT_DMA_END_STATUS) {
+ dma_done = 1;
+ if (((field_num == 0) && (dev->field == 0)) ||
+ (field_num && (dev->field == 1)))
+ dev->field++;
+ }
+
+ if (status & INT_FIELD_STATUS) {
+ dprintk(1, "irq: field %d, done %d\n",
+ !!field_num, dma_done);
+ if (unlikely(dev->first)) {
+ if (field_num == 0) {
+ dev->first = 0;
+ dprintk(1, "activate first buf\n");
+ viu_activate_next_buf(dev, vidq);
+ } else
+ dprintk(1, "wait field 0\n");
+ return;
+ }
+
+ /* setup buffer address for next dma operation */
+ if (!list_empty(&vidq->active)) {
+ u32 addr = reg_val.field_base_addr;
+
+ if (field_num && need_two) {
+ addr += reg_val.dma_inc;
+ dprintk(1, "field 1, 0x%lx, dev field %d\n",
+ (unsigned long)addr, dev->field);
+ }
+ out_be32(&vr->field_base_addr, addr);
+ out_be32(&vr->dma_inc, reg_val.dma_inc);
+ out_be32(&vr->status_cfg,
+ (status & 0xffc0ffff) |
+ (status & INT_ALL_STATUS) |
+ reg_val.status_cfg);
+ return;
+ }
+ }
+
+ if (dma_done && field_num && (dev->field == 2)) {
+ dev->field = 0;
+ buf = list_entry(vidq->active.next,
+ struct viu_buf, vb.queue);
+ dprintk(1, "viu/0: [%p/%d] 0x%lx/0x%lx: dma complete\n",
+ buf, buf->vb.i,
+ (unsigned long)videobuf_to_dma_contig(&buf->vb),
+ (unsigned long)in_be32(&vr->field_base_addr));
+
+ if (waitqueue_active(&buf->vb.done)) {
+ list_del(&buf->vb.queue);
+ do_gettimeofday(&buf->vb.ts);
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ wake_up(&buf->vb.done);
+ }
+ /* activate next dma buffer */
+ viu_activate_next_buf(dev, vidq);
+ }
+}
+
+static irqreturn_t viu_intr(int irq, void *dev_id)
+{
+ struct viu_dev *dev = (struct viu_dev *)dev_id;
+ struct viu_reg *vr = dev->vr;
+ u32 status;
+ u32 error;
+
+ status = in_be32(&vr->status_cfg);
+
+ if (status & INT_ERROR_STATUS) {
+ dev->irqs.error_irq++;
+ error = status & ERR_MASK;
+ if (error)
+ dprintk(1, "Err: error(%d), times:%d!\n",
+ error >> 4, dev->irqs.error_irq);
+ /* Clear interrupt error bit and error flags */
+ out_be32(&vr->status_cfg,
+ (status & 0xffc0ffff) | INT_ERROR_STATUS);
+ }
+
+ if (status & INT_DMA_END_STATUS) {
+ dev->irqs.dma_end_irq++;
+ dev->dma_done = 1;
+ dprintk(2, "VIU DMA end interrupt times: %d\n",
+ dev->irqs.dma_end_irq);
+ }
+
+ if (status & INT_HSYNC_STATUS)
+ dev->irqs.hsync_irq++;
+
+ if (status & INT_FIELD_STATUS) {
+ dev->irqs.field_irq++;
+ dprintk(2, "VIU field interrupt times: %d\n",
+ dev->irqs.field_irq);
+ }
+
+ if (status & INT_VSTART_STATUS)
+ dev->irqs.vstart_irq++;
+
+ if (status & INT_VSYNC_STATUS) {
+ dev->irqs.vsync_irq++;
+ dprintk(2, "VIU vsync interrupt times: %d\n",
+ dev->irqs.vsync_irq);
+ }
+
+ /* clear all pending irqs */
+ status = in_be32(&vr->status_cfg);
+ out_be32(&vr->status_cfg,
+ (status & 0xffc0ffff) | (status & INT_ALL_STATUS));
+
+ if (dev->ovenable) {
+ viu_overlay_intr(dev, status);
+ return IRQ_HANDLED;
+ }
+
+ /* Capture mode */
+ viu_capture_intr(dev, status);
+ return IRQ_HANDLED;
+}
+
+/*
+ * File operations for the device
+ */
+static int viu_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct viu_dev *dev = video_get_drvdata(vdev);
+ struct viu_fh *fh;
+ struct viu_reg *vr;
+ int minor = vdev->minor;
+ u32 status_cfg;
+ int i;
+
+ dprintk(1, "viu: open (minor=%d)\n", minor);
+
+ dev->users++;
+ if (dev->users > 1) {
+ dev->users--;
+ return -EBUSY;
+ }
+
+ vr = dev->vr;
+
+ dprintk(1, "open minor=%d type=%s users=%d\n", minor,
+ v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
+
+ /* allocate and initialize per filehandle data */
+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ if (!fh) {
+ dev->users--;
+ return -ENOMEM;
+ }
+
+ file->private_data = fh;
+ fh->dev = dev;
+
+ fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fh->fmt = format_by_fourcc(V4L2_PIX_FMT_RGB32);
+ fh->width = norm_maxw();
+ fh->height = norm_maxh();
+ dev->crop_current.width = fh->width;
+ dev->crop_current.height = fh->height;
+
+ /* Put all controls at a sane state */
+ for (i = 0; i < ARRAY_SIZE(viu_qctrl); i++)
+ qctl_regs[i] = viu_qctrl[i].default_value;
+
+ dprintk(1, "Open: fh=0x%08lx, dev=0x%08lx, dev->vidq=0x%08lx\n",
+ (unsigned long)fh, (unsigned long)dev,
+ (unsigned long)&dev->vidq);
+ dprintk(1, "Open: list_empty queued=%d\n",
+ list_empty(&dev->vidq.queued));
+ dprintk(1, "Open: list_empty active=%d\n",
+ list_empty(&dev->vidq.active));
+
+ viu_default_settings(vr);
+
+ status_cfg = in_be32(&vr->status_cfg);
+ out_be32(&vr->status_cfg,
+ status_cfg & ~(INT_VSYNC_EN | INT_HSYNC_EN |
+ INT_FIELD_EN | INT_VSTART_EN |
+ INT_DMA_END_EN | INT_ERROR_EN | INT_ECC_EN));
+
+ status_cfg = in_be32(&vr->status_cfg);
+ out_be32(&vr->status_cfg, status_cfg | INT_ALL_STATUS);
+
+ spin_lock_init(&fh->vbq_lock);
+ videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
+ dev->dev, &fh->vbq_lock,
+ fh->type, V4L2_FIELD_INTERLACED,
+ sizeof(struct viu_buf), fh);
+ return 0;
+}
+
+static ssize_t viu_read(struct file *file, char __user *data, size_t count,
+ loff_t *ppos)
+{
+ struct viu_fh *fh = file->private_data;
+ struct viu_dev *dev = fh->dev;
+ int ret = 0;
+
+ dprintk(2, "%s\n", __func__);
+ if (dev->ovenable)
+ dev->ovenable = 0;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ viu_start_dma(dev);
+ ret = videobuf_read_stream(&fh->vb_vidq, data, count,
+ ppos, 0, file->f_flags & O_NONBLOCK);
+ return ret;
+ }
+ return 0;
+}
+
+static unsigned int viu_poll(struct file *file, struct poll_table_struct *wait)
+{
+ struct viu_fh *fh = file->private_data;
+ struct videobuf_queue *q = &fh->vb_vidq;
+
+ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+ return POLLERR;
+
+ return videobuf_poll_stream(file, q, wait);
+}
+
+static int viu_release(struct file *file)
+{
+ struct viu_fh *fh = file->private_data;
+ struct viu_dev *dev = fh->dev;
+ int minor = video_devdata(file)->minor;
+
+ viu_stop_dma(dev);
+ videobuf_stop(&fh->vb_vidq);
+
+ kfree(fh);
+
+ dev->users--;
+ dprintk(1, "close (minor=%d, users=%d)\n",
+ minor, dev->users);
+ return 0;
+}
+
+void viu_reset(struct viu_reg *reg)
+{
+ out_be32(&reg->status_cfg, 0);
+ out_be32(&reg->luminance, 0x9512a254);
+ out_be32(&reg->chroma_r, 0x03310000);
+ out_be32(&reg->chroma_g, 0x06600f38);
+ out_be32(&reg->chroma_b, 0x00000409);
+ out_be32(&reg->field_base_addr, 0);
+ out_be32(&reg->dma_inc, 0);
+ out_be32(&reg->picture_count, 0x01e002d0);
+ out_be32(&reg->req_alarm, 0x00000090);
+ out_be32(&reg->alpha, 0x000000ff);
+}
+
+static int viu_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ struct viu_fh *fh = file->private_data;
+ int ret;
+
+ dprintk(1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
+
+ ret = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+ dprintk(1, "vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
+ ret);
+
+ return ret;
+}
+
+static struct v4l2_file_operations viu_fops = {
+ .owner = THIS_MODULE,
+ .open = viu_open,
+ .release = viu_release,
+ .read = viu_read,
+ .poll = viu_poll,
+ .ioctl = video_ioctl2, /* V4L2 ioctl handler */
+ .mmap = viu_mmap,
+};
+
+static const struct v4l2_ioctl_ops viu_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_cap,
+ .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt,
+ .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
+ .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
+ .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
+ .vidioc_g_fbuf = vidioc_g_fbuf,
+ .vidioc_s_fbuf = vidioc_s_fbuf,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+};
+
+static struct video_device viu_template = {
+ .name = "FSL viu",
+ .fops = &viu_fops,
+ .minor = -1,
+ .ioctl_ops = &viu_ioctl_ops,
+ .release = video_device_release,
+
+ .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL,
+ .current_norm = V4L2_STD_NTSC_M,
+};
+
+static int __devinit viu_of_probe(struct of_device *op,
+ const struct of_device_id *match)
+{
+ struct viu_dev *viu_dev;
+ struct video_device *vdev;
+ struct resource r;
+ struct viu_reg __iomem *viu_regs;
+ struct i2c_adapter *ad;
+ int ret, viu_irq;
+
+ ret = of_address_to_resource(op->dev.of_node, 0, &r);
+ if (ret) {
+ dev_err(&op->dev, "Can't parse device node resource\n");
+ return -ENODEV;
+ }
+
+ viu_irq = irq_of_parse_and_map(op->dev.of_node, 0);
+ if (viu_irq == NO_IRQ) {
+ dev_err(&op->dev, "Error while mapping the irq\n");
+ return -EINVAL;
+ }
+
+ /* request mem region */
+ if (!devm_request_mem_region(&op->dev, r.start,
+ sizeof(struct viu_reg), DRV_NAME)) {
+ dev_err(&op->dev, "Error while requesting mem region\n");
+ ret = -EBUSY;
+ goto err;
+ }
+
+ /* remap registers */
+ viu_regs = devm_ioremap(&op->dev, r.start, sizeof(struct viu_reg));
+ if (!viu_regs) {
+ dev_err(&op->dev, "Can't map register set\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /* Prepare our private structure */
+ viu_dev = devm_kzalloc(&op->dev, sizeof(struct viu_dev), GFP_ATOMIC);
+ if (!viu_dev) {
+ dev_err(&op->dev, "Can't allocate private structure\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ viu_dev->vr = viu_regs;
+ viu_dev->irq = viu_irq;
+ viu_dev->dev = &op->dev;
+
+ /* init video dma queues */
+ INIT_LIST_HEAD(&viu_dev->vidq.active);
+ INIT_LIST_HEAD(&viu_dev->vidq.queued);
+
+ /* initialize locks */
+ mutex_init(&viu_dev->lock);
+
+ snprintf(viu_dev->v4l2_dev.name,
+ sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
+ ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
+ if (ret < 0) {
+ dev_err(&op->dev, "v4l2_device_register() failed: %d\n", ret);
+ goto err;
+ }
+
+ ad = i2c_get_adapter(0);
+ viu_dev->decoder = v4l2_i2c_new_subdev(&viu_dev->v4l2_dev, ad,
+ "saa7115", "saa7113", VIU_VIDEO_DECODER_ADDR, NULL);
+
+ viu_dev->vidq.timeout.function = viu_vid_timeout;
+ viu_dev->vidq.timeout.data = (unsigned long)viu_dev;
+ init_timer(&viu_dev->vidq.timeout);
+ viu_dev->first = 1;
+
+ /* Allocate memory for video device */
+ vdev = video_device_alloc();
+ if (vdev == NULL) {
+ ret = -ENOMEM;
+ goto err_vdev;
+ }
+
+ memcpy(vdev, &viu_template, sizeof(viu_template));
+
+ vdev->v4l2_dev = &viu_dev->v4l2_dev;
+
+ viu_dev->vdev = vdev;
+
+ video_set_drvdata(viu_dev->vdev, viu_dev);
+
+ ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
+ if (ret < 0) {
+ video_device_release(viu_dev->vdev);
+ goto err_vdev;
+ }
+
+ /* enable VIU clock */
+ viu_dev->clk = clk_get(&op->dev, "viu_clk");
+ if (IS_ERR(viu_dev->clk)) {
+ dev_err(&op->dev, "failed to find the clock module!\n");
+ ret = -ENODEV;
+ goto err_clk;
+ } else {
+ clk_enable(viu_dev->clk);
+ }
+
+ /* reset VIU module */
+ viu_reset(viu_dev->vr);
+
+ /* install interrupt handler */
+ if (request_irq(viu_dev->irq, viu_intr, 0, "viu", (void *)viu_dev)) {
+ dev_err(&op->dev, "Request VIU IRQ failed.\n");
+ ret = -ENODEV;
+ goto err_irq;
+ }
+
+ dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
+ return ret;
+
+err_irq:
+ clk_disable(viu_dev->clk);
+ clk_put(viu_dev->clk);
+err_clk:
+ video_unregister_device(viu_dev->vdev);
+err_vdev:
+ i2c_put_adapter(ad);
+ v4l2_device_unregister(&viu_dev->v4l2_dev);
+err:
+ irq_dispose_mapping(viu_irq);
+ return ret;
+}
+
+static int __devexit viu_of_remove(struct of_device *op)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
+ struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
+ struct v4l2_subdev *sdev = list_entry(v4l2_dev->subdevs.next,
+ struct v4l2_subdev, list);
+ struct i2c_client *client = v4l2_get_subdevdata(sdev);
+
+ free_irq(dev->irq, (void *)dev);
+ irq_dispose_mapping(dev->irq);
+
+ clk_disable(dev->clk);
+ clk_put(dev->clk);
+
+ video_unregister_device(dev->vdev);
+ i2c_put_adapter(client->adapter);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int viu_suspend(struct of_device *op, pm_message_t state)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
+ struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
+
+ clk_disable(dev->clk);
+ return 0;
+}
+
+static int viu_resume(struct of_device *op)
+{
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&op->dev);
+ struct viu_dev *dev = container_of(v4l2_dev, struct viu_dev, v4l2_dev);
+
+ clk_enable(dev->clk);
+ return 0;
+}
+#endif
+
+/*
+ * Initialization and module stuff
+ */
+static struct of_device_id mpc512x_viu_of_match[] = {
+ {
+ .compatible = "fsl,mpc5121-viu",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mpc512x_viu_of_match);
+
+static struct of_platform_driver viu_of_platform_driver = {
+ .probe = viu_of_probe,
+ .remove = __devexit_p(viu_of_remove),
+#ifdef CONFIG_PM
+ .suspend = viu_suspend,
+ .resume = viu_resume,
+#endif
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = mpc512x_viu_of_match,
+ },
+};
+
+static int __init viu_init(void)
+{
+ return of_register_platform_driver(&viu_of_platform_driver);
+}
+
+static void __exit viu_exit(void)
+{
+ of_unregister_platform_driver(&viu_of_platform_driver);
+}
+
+module_init(viu_init);
+module_exit(viu_exit);
+
+MODULE_DESCRIPTION("Freescale Video-In(VIU)");
+MODULE_AUTHOR("Hongjun Chen");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 5d920e584de7..23db0c29f68c 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -246,6 +246,15 @@ config USB_GSPCA_SPCA561
To compile this driver as a module, choose M here: the
module will be called gspca_spca561.
+config USB_GSPCA_SPCA1528
+ tristate "SPCA1528 USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SPCA1528 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_spca1528.
+
config USB_GSPCA_SQ905
tristate "SQ Technologies SQ905 based USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -264,6 +273,15 @@ config USB_GSPCA_SQ905C
To compile this driver as a module, choose M here: the
module will be called gspca_sq905c.
+config USB_GSPCA_SQ930X
+ tristate "SQ Technologies SQ930X based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ930X chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq930x.
+
config USB_GSPCA_STK014
tristate "Syntek DV4000 (STK014) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 6e4cf1ce01c9..f6616db0b7f8 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -23,8 +23,10 @@ obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SPCA1528) += gspca_spca1528.o
obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
+obj-$(CONFIG_USB_GSPCA_SQ930X) += gspca_sq930x.o
obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
@@ -58,8 +60,10 @@ gspca_spca505-objs := spca505.o
gspca_spca506-objs := spca506.o
gspca_spca508-objs := spca508.o
gspca_spca561-objs := spca561.o
+gspca_spca1528-objs := spca1528.o
gspca_sq905-objs := sq905.o
gspca_sq905c-objs := sq905c.o
+gspca_sq930x-objs := sq930x.o
gspca_stk014-objs := stk014.o
gspca_stv0680-objs := stv0680.o
gspca_sunplus-objs := sunplus.o
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 19fe6b24c9a3..d6a75772f3f8 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -41,7 +41,7 @@ struct sd {
#define QUALITY_MAX 60
#define QUALITY_DEF 40
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
@@ -845,9 +845,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x22); /* JPEG 411 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -862,11 +859,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
- struct sd *sd = (struct sd *) gspca_dev;
int retry = 50;
- kfree(sd->jpeg_hdr);
-
if (!gspca_dev->present)
return;
reg_w_val(gspca_dev, 0x0000, 0x00);
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 58b696f455be..3747a1dcff54 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1760,22 +1760,19 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data[25] == sd->params.roi.colEnd &&
data[26] == sd->params.roi.rowStart &&
data[27] == sd->params.roi.rowEnd) {
- struct gspca_frame *frame = gspca_get_i_frame(gspca_dev);
+ u8 *image;
atomic_set(&sd->cam_exposure, data[39] * 2);
atomic_set(&sd->fps, data[41]);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
/* Check for proper EOF for last frame */
- if ((frame->data_end - frame->data) > 4 &&
- frame->data_end[-4] == 0xff &&
- frame->data_end[-3] == 0xff &&
- frame->data_end[-2] == 0xff &&
- frame->data_end[-1] == 0xff)
+ image = gspca_dev->image;
+ if (image != NULL &&
+ gspca_dev->image_len > 4 &&
+ image[gspca_dev->image_len - 4] == 0xff &&
+ image[gspca_dev->image_len - 3] == 0xff &&
+ image[gspca_dev->image_len - 2] == 0xff &&
+ image[gspca_dev->image_len - 1] == 0xff)
gspca_frame_add(gspca_dev, LAST_PACKET,
NULL, 0);
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
index 7c31b4f2abea..57782e011c9e 100644
--- a/drivers/media/video/gspca/gl860/gl860-mi2020.c
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -1,6 +1,7 @@
/* Subdriver for the GL860 chip with the MI2020 sensor
- * Author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
- * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
+ * Author Olivier LORIN, from logs by Iceman/Soro2005 + Fret_saw/Hulkie/Tricid
+ * with the help of Kytrix/BUGabundo/Blazercist.
+ * Driver achieved thanks to a webcam gift by Kytrix.
*
* 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,47 +21,70 @@
#include "gl860.h"
+static u8 dat_wbal1[] = {0x8c, 0xa2, 0x0c};
+
static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
static u8 dat_bright6[] = {0x90, 0x00, 0x05};
-static u8 dat_dummy1[] = {0x90, 0x00, 0x06};
-/*static u8 dummy2[] = {0x8c, 0xa1, 0x02};*/
-/*static u8 dummy3[] = {0x90, 0x00, 0x1f};*/
-
static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
+static struct idxdata tbl_middle_hvflip_low[] = {
+ {0x33, "\x90\x00\x06"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x90\x00\x06"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x90\x00\x06"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x90\x00\x06"},
+ {6, "\xff\xff\xff"},
+};
+
+static struct idxdata tbl_middle_hvflip_big[] = {
+ {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa1\x20"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
+ {102, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x20"},
+ {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
+};
+
+static struct idxdata tbl_end_hvflip[] = {
+ {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+ {6, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
+};
+
static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
-static struct validx tbl_common1[] = {
- {0x0000, 0x0000},
- {1, 0xffff}, /* msleep(35); */
- {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
- {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0004, 0x00d8},
- {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
+static struct validx tbl_init_at_startup[] = {
+ {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001,0x00c1},
+ {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
+ {53, 0xffff},
+ {0x0040, 0x0000}, {0x0063, 0x0006},
};
-static struct validx tbl_common2[] = {
- {0x006a, 0x0007},
- {35, 0xffff},
- {0x00ef, 0x0006},
- {35, 0xffff},
- {0x006a, 0x000d},
- {35, 0xffff},
- {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
+static struct validx tbl_common_0B[] = {
+ {0x0002, 0x0004}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a,0x000d},
+ {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042,0x00c2},
{0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
};
-static struct idxdata tbl_common3[] = {
- {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
+static struct idxdata tbl_common_3B[] = {
+ {0x33, "\x86\x25\x01"}, {0x33, "\x86\x25\x00"},
+ {2, "\xff\xff\xff"},
+ {0x30, "\x1a\x0a\xcc"}, {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
{6, "\xff\xff\xff"}, /* 12 */
{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
{2, "\xff\xff\xff"}, /* - */
@@ -98,85 +122,58 @@ static struct idxdata tbl_common3[] = {
{0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
{0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
- {1, "\xff\xff\xff"},
{0x33, "\x78\x00\x00"},
- {1, "\xff\xff\xff"},
+ {2, "\xff\xff\xff"},
{0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
{0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
{0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
{0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
- {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
-};
-
-static struct idxdata tbl_common4[] = {
- {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
+ {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"}, {0x33, "\x8c\xa4\x04"},
+ {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"}, {0x33, "\x90\x00\x00"},
+ {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0c"},
+ {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"}, {0x33, "\x90\x00\x04"},
+ {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"}, {0x33, "\x8c\xa1\x03"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"},
+ {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x25"},
+ {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"},
+ {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x47"},
+ {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x02\x84"},
+ {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"}, {0x33, "\x8c\x27\x07"},
+ {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"}, {0x33, "\x90\x04\xb0"},
+ {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x0f"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"}, {0x33, "\x90\x04\xbd"},
+ {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"}, {0x33, "\x8c\x27\x15"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"}, {0x33, "\x90\x21\x11"},
+ {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"}, {0x33, "\x8c\x27\x1b"},
+ {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"}, {0x33, "\x90\x01\x02"},
+ {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"}, {0x33, "\x8c\x27\x21"},
+ {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"}, {0x33, "\x90\x02\x85"},
+ {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x27"},
+ {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"}, {0x33, "\x90\x20\x20"},
+ {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"}, {0x33, "\x8c\x27\x2d"},
+ {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"}, {0x33, "\x90\x00\x04"},
+ {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x33"},
+ {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"}, {0x33, "\x90\x06\x4b"},
+ {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x39"},
+ {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"},
+ {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"}, {0x33, "\x8c\x27\x41"},
+ {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"}, {0x33, "\x90\x04\xed"},
+ {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x51"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"}, {0x33, "\x90\x03\x20"},
+ {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x57"},
+ {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"}, {0x33, "\x90\x00\x00"},
+ {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x63"},
+ {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"}, {0x33, "\x90\x04\xb0"},
+ {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\xa4\x08"},
{0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
{0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
- {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa0"},
- {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc0"}, {0x33, "\x8c\x24\x15"},
- {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
-};
-
-static struct idxdata tbl_common5[] = {
- {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
- {0x33, "\x90\x00\x04"}, {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"},
- {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
- /* msleep(53); */
- {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"},
- {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"},
- {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
- {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"},
- {0x33, "\x90\x02\x84"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"},
- {0x33, "\x8c\x27\x07"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"},
- {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\x27\x0f"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"},
- {0x33, "\x90\x04\xbd"}, {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"},
- {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
- {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
- {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"},
- {0x33, "\x90\x01\x02"}, {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"},
- {0x33, "\x8c\x27\x21"}, {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"},
- {0x33, "\x90\x02\x85"}, {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"},
- {0x33, "\x8c\x27\x27"}, {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"},
- {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"},
- {0x33, "\x8c\x27\x2d"}, {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"},
- {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"},
- {0x33, "\x8c\x27\x33"}, {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"},
- {0x33, "\x90\x06\x4b"}, {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"},
- {0x33, "\x90\x00\x24"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
- {0x33, "\x8c\x27\x41"}, {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"},
- {0x33, "\x90\x04\xed"}, {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"},
- {0x33, "\x8c\x27\x51"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"},
- {0x33, "\x90\x03\x20"}, {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"},
- {0x33, "\x8c\x27\x57"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"},
- {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"},
- {0x33, "\x8c\x27\x63"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"},
- {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"},
- {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"},
- {0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"},
- {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"},
- {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"},
- {0x33, "\x8c\x24\x15"},
-};
-
-static struct validx tbl_init_at_startup[] = {
- {0x0000, 0x0000},
- {53, 0xffff},
- {0x0010, 0x0010},
- {53, 0xffff},
- {0x0008, 0x00c0},
- {53, 0xffff},
- {0x0001, 0x00c1},
- {53, 0xffff},
- {0x0001, 0x00c2},
- {53, 0xffff},
- {0x0020, 0x0006},
- {53, 0xffff},
- {0x006a, 0x000d},
- {53, 0xffff},
+ {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa1"},
+ {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"}, {0x33, "\x8c\x24\x15"},
+ {0x33, "\x90\x00\x6a"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\x80"},
+ {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
+ {2, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
+ {3, "\xff\xff\xff"},
};
static struct idxdata tbl_init_post_alt_low1[] = {
@@ -209,7 +206,7 @@ static struct idxdata tbl_init_post_alt_low3[] = {
{2, "\xff\xff\xff"},
{0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
{0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
- {2, "\xff\xff\xff"}, /* - * */
+ {2, "\xff\xff\xff"},
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
{2, "\xff\xff\xff"},
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
@@ -217,61 +214,15 @@ static struct idxdata tbl_init_post_alt_low3[] = {
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
{2, "\xff\xff\xff"},
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
- {1, "\xff\xff\xff"},
-};
-
-static struct idxdata tbl_init_post_alt_low4[] = {
- {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
- {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
- {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
- {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
- {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
- {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
- {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
- {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
- {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
- {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
- {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
- {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
- {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
- {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
- {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
- {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
- {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
- {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
- {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
- {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
- {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
- {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
- {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
- {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
- {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
- {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"},
- /* Flip/Mirror h/v=1 */
- {0x33, "\x90\x00\x3c"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
- {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, {0x33, "\x8c\xa1\x03"},
- {0x33, "\x90\x00\x06"},
- {130, "\xff\xff\xff"},
- {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
- {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
- {100, "\xff\xff\xff"},
- /* ?? */
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
- {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
- /* Brigthness=70 */
- {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x46"}, {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x0f"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
- /* Sharpness=20 */
- {0x32, "\x6c\x14\x08"},
};
-static struct idxdata tbl_init_post_alt_big1[] = {
+static struct idxdata tbl_init_post_alt_big[] = {
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
{2, "\xff\xff\xff"},
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
{2, "\xff\xff\xff"},
{0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
+ {2, "\xff\xff\xff"},
{0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
{0x33, "\x90\x00\x05"},
{2, "\xff\xff\xff"},
@@ -285,9 +236,17 @@ static struct idxdata tbl_init_post_alt_big1[] = {
{0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
{0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
{0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
+ {0x33, "\x8c\x27\x97"}, {0x33, "\x90\x01\x00"},
+ {51, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
+ {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
+ {51, "\xff\xff\xff"},
+ {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
+ {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
+ {51, "\xff\xff\xff"},
};
-static struct idxdata tbl_init_post_alt_big2[] = {
+static struct idxdata tbl_init_post_alt_3B[] = {
{0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
{0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
{0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
@@ -316,17 +275,6 @@ static struct idxdata tbl_init_post_alt_big2[] = {
{0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
};
-static struct idxdata tbl_init_post_alt_big3[] = {
- {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x1f"},
- {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x1f"},
- {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x1f"},
- {0x33, "\x8c\xa1\x02"},
- {0x33, "\x90\x00\x1f"},
-};
-
static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
@@ -351,7 +299,7 @@ void mi2020_init_settings(struct gspca_dev *gspca_dev)
sd->vcur.gamma = 0;
sd->vcur.hue = 0;
sd->vcur.saturation = 60;
- sd->vcur.whitebal = 50;
+ sd->vcur.whitebal = 0; /* 50, not done by hardware */
sd->vcur.mirror = 0;
sd->vcur.flip = 0;
sd->vcur.AC50Hz = 1;
@@ -361,17 +309,12 @@ void mi2020_init_settings(struct gspca_dev *gspca_dev)
sd->vmax.sharpness = 40;
sd->vmax.contrast = 3;
sd->vmax.gamma = 2;
- sd->vmax.hue = 0 + 1; /* 200 */
- sd->vmax.saturation = 0; /* 100 */
- sd->vmax.whitebal = 0; /* 100 */
+ sd->vmax.hue = 0 + 1; /* 200, not done by hardware */
+ sd->vmax.saturation = 0; /* 100, not done by hardware */
+ sd->vmax.whitebal = 2; /* 100, not done by hardware */
sd->vmax.mirror = 1;
sd->vmax.flip = 1;
sd->vmax.AC50Hz = 1;
- if (_MI2020b_) {
- sd->vmax.contrast = 0;
- sd->vmax.gamma = 0;
- sd->vmax.backlight = 0;
- }
sd->dev_camera_settings = mi2020_camera_settings;
sd->dev_init_at_startup = mi2020_init_at_startup;
@@ -384,51 +327,9 @@ void mi2020_init_settings(struct gspca_dev *gspca_dev)
static void common(struct gspca_dev *gspca_dev)
{
- s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
-
- if (_MI2020b_) {
- fetch_validx(gspca_dev, tbl_common1, ARRAY_SIZE(tbl_common1));
- } else {
- if (_MI2020_)
- ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL);
- else
- ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL);
- msleep(35);
- fetch_validx(gspca_dev, tbl_common2, ARRAY_SIZE(tbl_common2));
- }
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00");
- msleep(2); /* - * */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc");
- if (reso == IMAGE_1600)
- msleep(2); /* 1600 */
- fetch_idxdata(gspca_dev, tbl_common3, ARRAY_SIZE(tbl_common3));
-
- if (_MI2020b_ || _MI2020_)
- fetch_idxdata(gspca_dev, tbl_common4,
- ARRAY_SIZE(tbl_common4));
-
- fetch_idxdata(gspca_dev, tbl_common5, ARRAY_SIZE(tbl_common5));
- if (_MI2020b_ || _MI2020_) {
- /* Different from fret */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
- /* Same as fret */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
- /* Different from fret */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x90");
- } else {
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x6a");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x80");
- }
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x05");
- msleep(2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- if (reso == IMAGE_1600)
- msleep(14); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x06");
- msleep(2);
+ fetch_validx(gspca_dev, tbl_common_0B, ARRAY_SIZE(tbl_common_0B));
+ fetch_idxdata(gspca_dev, tbl_common_3B, ARRAY_SIZE(tbl_common_3B));
+ ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
}
static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
@@ -441,8 +342,16 @@ static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
fetch_validx(gspca_dev, tbl_init_at_startup,
ARRAY_SIZE(tbl_init_at_startup));
+ ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
+ ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &c);
+
common(gspca_dev);
+ msleep(61);
+/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
+/* msleep(36); */
+ ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
+
return 0;
}
@@ -450,17 +359,17 @@ static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->mirrorMask = 0;
+ sd->mirrorMask = 0;
+ sd->vold.hue = -1;
- sd->vold.backlight = -1;
+ /* These controls need to be reset */
sd->vold.brightness = -1;
sd->vold.sharpness = -1;
- sd->vold.contrast = -1;
- sd->vold.gamma = -1;
- sd->vold.hue = -1;
- sd->vold.mirror = -1;
- sd->vold.flip = -1;
- sd->vold.AC50Hz = -1;
+
+ /* If not different from default, they do not need to be set */
+ sd->vold.contrast = 0;
+ sd->vold.gamma = 0;
+ sd->vold.backlight = 0;
mi2020_init_post_alt(gspca_dev);
@@ -472,10 +381,10 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
- s32 backlight = sd->vcur.backlight;
s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
s32 freq = (sd->vcur.AC50Hz > 0);
+ s32 wbal = sd->vcur.whitebal;
u8 dat_freq2[] = {0x90, 0x00, 0x80};
u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
@@ -484,6 +393,7 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
u8 dat_multi4[] = {0x90, 0x00, 0x00};
u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
+ u8 dat_wbal2[] = {0x90, 0x00, 0x00};
u8 c;
sd->nbIm = -1;
@@ -491,23 +401,26 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
dat_freq2[2] = freq ? 0xc0 : 0x80;
dat_multi1[2] = 0x9d;
dat_multi3[2] = dat_multi1[2] + 1;
- dat_multi4[2] = dat_multi2[2] = backlight;
+ if (wbal == 0) {
+ dat_multi4[2] = dat_multi2[2] = 0;
+ dat_wbal2[2] = 0x17;
+ } else if (wbal == 1) {
+ dat_multi4[2] = dat_multi2[2] = 0;
+ dat_wbal2[2] = 0x35;
+ } else if (wbal == 2) {
+ dat_multi4[2] = dat_multi2[2] = 0x20;
+ dat_wbal2[2] = 0x17;
+ }
dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
msleep(200);
-
ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
- msleep(3); /* 35 * */
+ msleep(2);
common(gspca_dev);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
- msleep(70);
-
- if (_MI2020b_)
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
-
+ msleep(142);
ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL);
ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL);
@@ -523,8 +436,7 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
12, dat_800);
- if (_MI2020c_)
- fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
+ fetch_idxdata(gspca_dev, tbl_init_post_alt_low1,
ARRAY_SIZE(tbl_init_post_alt_low1));
if (reso == IMAGE_800)
@@ -534,87 +446,10 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
fetch_idxdata(gspca_dev, tbl_init_post_alt_low3,
ARRAY_SIZE(tbl_init_post_alt_low3));
- if (_MI2020b_) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(150);
- } else if (_MI2020c_) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(120);
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
- msleep(30);
- } else if (_MI2020_) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(120);
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
- msleep(30);
- }
-
- /* AC power frequency */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
- msleep(20);
- /* backlight */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- /* at init time but not after */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
- /* finish the backlight */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- msleep(5);/* " */
-
- if (_MI2020c_) {
- fetch_idxdata(gspca_dev, tbl_init_post_alt_low4,
- ARRAY_SIZE(tbl_init_post_alt_low4));
- } else {
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
- msleep(14); /* 0xd8 */
-
- /* flip/mirror */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_hvflip6);
- msleep(21);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- msleep(5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- msleep(5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- msleep(5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- msleep(5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- msleep(5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
- 3, dat_dummy1);
- /* end of flip/mirror main part */
- msleep(246); /* 146 */
-
- sd->nbIm = 0;
- }
+ ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+ msleep(120);
break;
case IMAGE_1280:
@@ -643,108 +478,62 @@ static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
3, "\x90\x04\xb0");
}
- fetch_idxdata(gspca_dev, tbl_init_post_alt_big1,
- ARRAY_SIZE(tbl_init_post_alt_big1));
-
- if (reso == IMAGE_1600)
- msleep(13); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x27\x97");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x01\x00");
- msleep(53);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
- if (reso == IMAGE_1600)
- msleep(13); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
- msleep(53);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
- if (reso == IMAGE_1600)
- msleep(13); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
- msleep(53);
-
- if (_MI2020b_) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
- if (reso == IMAGE_1600)
- msleep(500); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(1850);
- } else if (_MI2020c_ || _MI2020_) {
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
- msleep(1850);
- ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
- msleep(30);
- }
+ fetch_idxdata(gspca_dev, tbl_init_post_alt_big,
+ ARRAY_SIZE(tbl_init_post_alt_big));
- /* AC power frequency */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
- msleep(20);
- /* backlight */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- /* at init time but not after */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
- /* finish the backlight */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
- msleep(6); /* " */
+ ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
+ msleep(1850);
+ }
- ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
- msleep(14);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
+ msleep(40);
+
+ /* AC power frequency */
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
+ msleep(33);
+ /* light source */
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+ msleep(7);
+ ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
+
+ fetch_idxdata(gspca_dev, tbl_init_post_alt_3B,
+ ARRAY_SIZE(tbl_init_post_alt_3B));
+
+ /* hvflip */
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
+ msleep(250);
+
+ if (reso == IMAGE_640 || reso == IMAGE_800)
+ fetch_idxdata(gspca_dev, tbl_middle_hvflip_low,
+ ARRAY_SIZE(tbl_middle_hvflip_low));
+ else
+ fetch_idxdata(gspca_dev, tbl_middle_hvflip_big,
+ ARRAY_SIZE(tbl_middle_hvflip_big));
- if (_MI2020c_)
- fetch_idxdata(gspca_dev, tbl_init_post_alt_big2,
- ARRAY_SIZE(tbl_init_post_alt_big2));
+ fetch_idxdata(gspca_dev, tbl_end_hvflip,
+ ARRAY_SIZE(tbl_end_hvflip));
- /* flip/mirror */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
- /* end of flip/mirror main part */
- msleep(16);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
- if (reso == IMAGE_1600)
- msleep(25); /* 1600 */
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
- msleep(103);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
- sd->nbIm = 0;
-
- if (_MI2020c_)
- fetch_idxdata(gspca_dev, tbl_init_post_alt_big3,
- ARRAY_SIZE(tbl_init_post_alt_big3));
- }
+ sd->nbIm = 0;
sd->vold.mirror = mirror;
sd->vold.flip = flip;
sd->vold.AC50Hz = freq;
- sd->vold.backlight = backlight;
+ sd->vold.whitebal = wbal;
mi2020_camera_settings(gspca_dev);
@@ -772,6 +561,7 @@ static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
s32 backlight = sd->vcur.backlight;
s32 bright = sd->vcur.brightness;
@@ -782,6 +572,7 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
s32 freq = (sd->vcur.AC50Hz > 0);
+ s32 wbal = sd->vcur.whitebal;
u8 dat_sharp[] = {0x6c, 0x00, 0x08};
u8 dat_bright2[] = {0x90, 0x00, 0x00};
@@ -792,6 +583,7 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
u8 dat_multi4[] = {0x90, 0x00, 0x00};
u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
+ u8 dat_wbal2[] = {0x90, 0x00, 0x00};
/* Less than 4 images received -> too early to set the settings */
if (sd->nbIm < 4) {
@@ -809,67 +601,89 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
msleep(20);
}
+ if (wbal != sd->vold.whitebal) {
+ sd->vold.whitebal = wbal;
+ if (wbal < 0 || wbal > sd->vmax.whitebal)
+ wbal = 0;
+
+ dat_multi1[2] = 0x9d;
+ dat_multi3[2] = dat_multi1[2] + 1;
+ if (wbal == 0) {
+ dat_multi4[2] = dat_multi2[2] = 0;
+ dat_wbal2[2] = 0x17;
+ } else if (wbal == 1) {
+ dat_multi4[2] = dat_multi2[2] = 0;
+ dat_wbal2[2] = 0x35;
+ } else if (wbal == 2) {
+ dat_multi4[2] = dat_multi2[2] = 0x20;
+ dat_wbal2[2] = 0x17;
+ }
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_wbal2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+ }
+
if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
sd->vold.mirror = mirror;
sd->vold.flip = flip;
dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
+
+ fetch_idxdata(gspca_dev, tbl_init_post_alt_3B,
+ ARRAY_SIZE(tbl_init_post_alt_3B));
+
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
- msleep(130);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
- msleep(6);
-
- /* Sometimes present, sometimes not, useful? */
- /* ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
- * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);*/
+ msleep(40);
+
+ if (reso == IMAGE_640 || reso == IMAGE_800)
+ fetch_idxdata(gspca_dev, tbl_middle_hvflip_low,
+ ARRAY_SIZE(tbl_middle_hvflip_low));
+ else
+ fetch_idxdata(gspca_dev, tbl_middle_hvflip_big,
+ ARRAY_SIZE(tbl_middle_hvflip_big));
+
+ fetch_idxdata(gspca_dev, tbl_end_hvflip,
+ ARRAY_SIZE(tbl_end_hvflip));
}
- if (backlight != sd->vold.backlight) {
- sd->vold.backlight = backlight;
- if (backlight < 0 || backlight > sd->vmax.backlight)
- backlight = 0;
+ if (bright != sd->vold.brightness) {
+ sd->vold.brightness = bright;
+ if (bright < 0 || bright > sd->vmax.brightness)
+ bright = 0;
- dat_multi1[2] = 0x9d;
- dat_multi3[2] = dat_multi1[2] + 1;
- dat_multi4[2] = dat_multi2[2] = backlight;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
+ dat_bright2[2] = bright;
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
+ ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
}
- if (gam != sd->vold.gamma) {
+ if (cntr != sd->vold.contrast || gam != sd->vold.gamma) {
+ sd->vold.contrast = cntr;
+ if (cntr < 0 || cntr > sd->vmax.contrast)
+ cntr = 0;
sd->vold.gamma = gam;
if (gam < 0 || gam > sd->vmax.gamma)
gam = 0;
dat_multi1[2] = 0x6d;
dat_multi3[2] = dat_multi1[2] + 1;
- dat_multi4[2] = dat_multi2[2] = 0x40 + gam;
+ if (cntr == 0)
+ cntr = 4;
+ dat_multi4[2] = dat_multi2[2] = cntr * 0x10 + 2 - gam;
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
@@ -878,14 +692,14 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
}
- if (cntr != sd->vold.contrast) {
- sd->vold.contrast = cntr;
- if (cntr < 0 || cntr > sd->vmax.contrast)
- cntr = 0;
+ if (backlight != sd->vold.backlight) {
+ sd->vold.backlight = backlight;
+ if (backlight < 0 || backlight > sd->vmax.backlight)
+ backlight = 0;
- dat_multi1[2] = 0x6d;
+ dat_multi1[2] = 0x9d;
dat_multi3[2] = dat_multi1[2] + 1;
- dat_multi4[2] = dat_multi2[2] = 0x12 + 16 * cntr;
+ dat_multi4[2] = dat_multi2[2] = backlight;
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
@@ -894,20 +708,6 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
}
- if (bright != sd->vold.brightness) {
- sd->vold.brightness = bright;
- if (bright < 0 || bright > sd->vmax.brightness)
- bright = 0;
-
- dat_bright2[2] = bright;
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
- ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
- }
-
if (sharp != sd->vold.sharpness) {
sd->vold.sharpness = sharp;
if (sharp < 0 || sharp > sd->vmax.sharpness)
@@ -928,9 +728,6 @@ static int mi2020_camera_settings(struct gspca_dev *gspca_dev)
static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
{
ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
- msleep(20);
- if (_MI2020c_ || _MI2020_)
- ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
- else
- ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
+ msleep(40);
+ ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
index d412694c50af..5ae9619d72a5 100644
--- a/drivers/media/video/gspca/gl860/gl860-ov9655.c
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -69,7 +69,7 @@ static u8 *tbl_640[] = {
"\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80"
};
-static u8 *tbl_800[] = {
+static u8 *tbl_1280[] = {
"\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
,
"\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61"
@@ -217,7 +217,7 @@ static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
- tbl = (reso == IMAGE_640) ? tbl_640 : tbl_800;
+ tbl = (reso == IMAGE_640) ? tbl_640 : tbl_1280;
ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
tbl_length[0], tbl[0]);
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
index 9e42476c0eaf..e86eb8b4aedc 100644
--- a/drivers/media/video/gspca/gl860/gl860.c
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -63,7 +63,7 @@ static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\
\
sd->vcur.thename = val;\
if (gspca_dev->streaming)\
- sd->dev_camera_settings(gspca_dev);\
+ sd->waitSet = 1;\
return 0;\
} \
static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\
@@ -91,7 +91,6 @@ SD_SETGET(contrast)
/* control table */
static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS];
static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS];
-static struct ctrl sd_ctrls_mi2020b[GL860_NCTRLS];
static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS];
static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS];
@@ -121,8 +120,6 @@ static int gl860_build_control_table(struct gspca_dev *gspca_dev)
sd_ctrls = sd_ctrls_mi1320;
else if (_MI2020_)
sd_ctrls = sd_ctrls_mi2020;
- else if (_MI2020b_)
- sd_ctrls = sd_ctrls_mi2020b;
else if (_OV2640_)
sd_ctrls = sd_ctrls_ov2640;
else if (_OV9655_)
@@ -187,19 +184,6 @@ static const struct sd_desc sd_desc_mi2020 = {
.dq_callback = sd_callback,
};
-static const struct sd_desc sd_desc_mi2020b = {
- .name = MODULE_NAME,
- .ctrls = sd_ctrls_mi2020b,
- .nctrls = GL860_NCTRLS,
- .config = sd_config,
- .init = sd_init,
- .isoc_init = sd_isoc_init,
- .start = sd_start,
- .stop0 = sd_stop0,
- .pkt_scan = sd_pkt_scan,
- .dq_callback = sd_callback,
-};
-
static const struct sd_desc sd_desc_ov2640 = {
.name = MODULE_NAME,
.ctrls = sd_ctrls_ov2640,
@@ -235,9 +219,9 @@ static struct v4l2_pix_format mi2020_mode[] = {
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 0
},
- { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+ { 800, 598, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
.bytesperline = 800,
- .sizeimage = 800 * 600,
+ .sizeimage = 800 * 598,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 1
},
@@ -247,9 +231,9 @@ static struct v4l2_pix_format mi2020_mode[] = {
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 2
},
- {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
+ {1600, 1198, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
.bytesperline = 1600,
- .sizeimage = 1600 * 1200,
+ .sizeimage = 1600 * 1198,
.colorspace = V4L2_COLORSPACE_SRGB,
.priv = 3
},
@@ -344,8 +328,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = ID_OV9655;
else if (strcmp(sensor, "MI2020") == 0)
sd->sensor = ID_MI2020;
- else if (strcmp(sensor, "MI2020b") == 0)
- sd->sensor = ID_MI2020b;
/* Get sensor and set the suitable init/start/../stop functions */
if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
@@ -369,13 +351,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
dev_init_settings = mi2020_init_settings;
break;
- case ID_MI2020b:
- gspca_dev->sd_desc = &sd_desc_mi2020b;
- cam->cam_mode = mi2020_mode;
- cam->nmodes = ARRAY_SIZE(mi2020_mode);
- dev_init_settings = mi2020_init_settings;
- break;
-
case ID_OV2640:
gspca_dev->sd_desc = &sd_desc_ov2640;
cam->cam_mode = ov2640_mode;
@@ -620,10 +595,7 @@ int gl860_RTx(struct gspca_dev *gspca_dev,
else if (len > 1 && r < len)
PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len);
- if ((_MI2020_ || _MI2020b_ || _MI2020c_) && (val || index))
- msleep(1);
- if (_OV2640_)
- msleep(1);
+ msleep(1);
return r;
}
@@ -767,8 +739,6 @@ static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
} else if (_MI2020_) {
PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
- } else if (_MI2020b_) {
- PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 alt. driver (2.0M)");
} else if (_OV9655_) {
PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
} else if (_OV2640_) {
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
index 305061ff8387..49ad4acbf602 100644
--- a/drivers/media/video/gspca/gl860/gl860.h
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -32,19 +32,16 @@
#define ID_OV2640 2
#define ID_OV9655 4
#define ID_MI2020 8
-#define ID_MI2020b 16
#define _MI1320_ (((struct sd *) gspca_dev)->sensor == ID_MI1320)
#define _MI2020_ (((struct sd *) gspca_dev)->sensor == ID_MI2020)
-#define _MI2020b_ (((struct sd *) gspca_dev)->sensor == ID_MI2020b)
-#define _MI2020c_ 0
#define _OV2640_ (((struct sd *) gspca_dev)->sensor == ID_OV2640)
#define _OV9655_ (((struct sd *) gspca_dev)->sensor == ID_OV9655)
#define IMAGE_640 0
#define IMAGE_800 1
#define IMAGE_1280 2
-#define IMAGE_1600 3
+#define IMAGE_1600 3
struct sd_gl860 {
u16 backlight;
@@ -75,10 +72,10 @@ struct sd {
int (*dev_camera_settings)(struct gspca_dev *);
u8 swapRB;
- u8 mirrorMask;
- u8 sensor;
- s32 nbIm;
- s32 nbRightUp;
+ u8 mirrorMask;
+ u8 sensor;
+ s32 nbIm;
+ s32 nbRightUp;
u8 waitSet;
};
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 678675bb3652..11b0e3557c1b 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -294,19 +294,6 @@ static inline int gspca_input_connect(struct gspca_dev *dev)
}
#endif
-/* get the current input frame buffer */
-struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev)
-{
- struct gspca_frame *frame;
-
- frame = gspca_dev->cur_frame;
- if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
- != V4L2_BUF_FLAG_QUEUED)
- return NULL;
- return frame;
-}
-EXPORT_SYMBOL(gspca_get_i_frame);
-
/*
* fill a video frame from an URB and resubmit
*/
@@ -439,20 +426,20 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
PDEBUG(D_PACK, "add t:%d l:%d", packet_type, len);
- /* check the availability of the frame buffer */
- frame = gspca_dev->cur_frame;
- if ((frame->v4l2_buf.flags & BUF_ALL_FLAGS)
- != V4L2_BUF_FLAG_QUEUED) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
- /* when start of a new frame, if the current frame buffer
- * is not queued, discard the whole frame */
if (packet_type == FIRST_PACKET) {
- frame->data_end = frame->data;
+ i = atomic_read(&gspca_dev->fr_i);
+
+ /* if there are no queued buffer, discard the whole frame */
+ if (i == atomic_read(&gspca_dev->fr_q)) {
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ return;
+ }
+ j = gspca_dev->fr_queue[i];
+ frame = &gspca_dev->frame[j];
frame->v4l2_buf.timestamp = ktime_to_timeval(ktime_get());
frame->v4l2_buf.sequence = ++gspca_dev->sequence;
+ gspca_dev->image = frame->data;
+ gspca_dev->image_len = 0;
} else if (gspca_dev->last_packet_type == DISCARD_PACKET) {
if (packet_type == LAST_PACKET)
gspca_dev->last_packet_type = packet_type;
@@ -461,34 +448,37 @@ void gspca_frame_add(struct gspca_dev *gspca_dev,
/* append the packet to the frame buffer */
if (len > 0) {
- if (frame->data_end - frame->data + len
- > frame->v4l2_buf.length) {
- PDEBUG(D_ERR|D_PACK, "frame overflow %zd > %d",
- frame->data_end - frame->data + len,
- frame->v4l2_buf.length);
+ if (gspca_dev->image_len + len > gspca_dev->frsz) {
+ PDEBUG(D_ERR|D_PACK, "frame overflow %d > %d",
+ gspca_dev->image_len + len,
+ gspca_dev->frsz);
packet_type = DISCARD_PACKET;
} else {
- memcpy(frame->data_end, data, len);
- frame->data_end += len;
+ memcpy(gspca_dev->image + gspca_dev->image_len,
+ data, len);
+ gspca_dev->image_len += len;
}
}
gspca_dev->last_packet_type = packet_type;
- /* if last packet, wake up the application and advance in the queue */
+ /* if last packet, invalidate packet concatenation until
+ * next first packet, wake up the application and advance
+ * in the queue */
if (packet_type == LAST_PACKET) {
- frame->v4l2_buf.bytesused = frame->data_end - frame->data;
- frame->v4l2_buf.flags &= ~V4L2_BUF_FLAG_QUEUED;
- frame->v4l2_buf.flags |= V4L2_BUF_FLAG_DONE;
- wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
- i = (gspca_dev->fr_i + 1) % gspca_dev->nframes;
- gspca_dev->fr_i = i;
- PDEBUG(D_FRAM, "frame complete len:%d q:%d i:%d o:%d",
- frame->v4l2_buf.bytesused,
- gspca_dev->fr_q,
- i,
- gspca_dev->fr_o);
+ i = atomic_read(&gspca_dev->fr_i);
j = gspca_dev->fr_queue[i];
- gspca_dev->cur_frame = &gspca_dev->frame[j];
+ frame = &gspca_dev->frame[j];
+ frame->v4l2_buf.bytesused = gspca_dev->image_len;
+ frame->v4l2_buf.flags = (frame->v4l2_buf.flags
+ | V4L2_BUF_FLAG_DONE)
+ & ~V4L2_BUF_FLAG_QUEUED;
+ i = (i + 1) % GSPCA_MAX_FRAMES;
+ atomic_set(&gspca_dev->fr_i, i);
+ wake_up_interruptible(&gspca_dev->wq); /* event = new frame */
+ PDEBUG(D_FRAM, "frame complete len:%d",
+ frame->v4l2_buf.bytesused);
+ gspca_dev->image = NULL;
+ gspca_dev->image_len = 0;
}
}
EXPORT_SYMBOL(gspca_frame_add);
@@ -506,36 +496,6 @@ static int gspca_is_compressed(__u32 format)
return 0;
}
-static void *rvmalloc(long size)
-{
- void *mem;
- unsigned long adr;
-
- mem = vmalloc_32(size);
- if (mem != NULL) {
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *) adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- }
- return mem;
-}
-
-static void rvfree(void *mem, long size)
-{
- unsigned long adr;
-
- adr = (unsigned long) mem;
- while (size > 0) {
- ClearPageReserved(vmalloc_to_page((void *) adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
-
static int frame_alloc(struct gspca_dev *gspca_dev,
unsigned int count)
{
@@ -548,9 +508,9 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
PDEBUG(D_STREAM, "frame alloc frsz: %d", frsz);
frsz = PAGE_ALIGN(frsz);
gspca_dev->frsz = frsz;
- if (count > GSPCA_MAX_FRAMES)
- count = GSPCA_MAX_FRAMES;
- gspca_dev->frbuf = rvmalloc(frsz * count);
+ if (count >= GSPCA_MAX_FRAMES)
+ count = GSPCA_MAX_FRAMES - 1;
+ gspca_dev->frbuf = vmalloc_32(frsz * count);
if (!gspca_dev->frbuf) {
err("frame alloc failed");
return -ENOMEM;
@@ -565,14 +525,12 @@ static int frame_alloc(struct gspca_dev *gspca_dev,
frame->v4l2_buf.length = frsz;
frame->v4l2_buf.memory = gspca_dev->memory;
frame->v4l2_buf.sequence = 0;
- frame->data = frame->data_end =
- gspca_dev->frbuf + i * frsz;
+ frame->data = gspca_dev->frbuf + i * frsz;
frame->v4l2_buf.m.offset = i * frsz;
}
- gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
- gspca_dev->cur_frame = &gspca_dev->frame[0];
- gspca_dev->last_packet_type = DISCARD_PACKET;
- gspca_dev->sequence = 0;
+ atomic_set(&gspca_dev->fr_q, 0);
+ atomic_set(&gspca_dev->fr_i, 0);
+ gspca_dev->fr_o = 0;
return 0;
}
@@ -582,8 +540,7 @@ static void frame_free(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "frame free");
if (gspca_dev->frbuf != NULL) {
- rvfree(gspca_dev->frbuf,
- gspca_dev->nframes * gspca_dev->frsz);
+ vfree(gspca_dev->frbuf);
gspca_dev->frbuf = NULL;
for (i = 0; i < gspca_dev->nframes; i++)
gspca_dev->frame[i].data = NULL;
@@ -811,6 +768,12 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
goto out;
}
+ /* reset the streaming variables */
+ gspca_dev->image = NULL;
+ gspca_dev->image_len = 0;
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ gspca_dev->sequence = 0;
+
gspca_dev->usb_err = 0;
/* set the higher alternate setting and
@@ -1626,7 +1589,7 @@ static int vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type buf_type)
{
struct gspca_dev *gspca_dev = priv;
- int i, ret;
+ int ret;
if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -1650,12 +1613,10 @@ static int vidioc_streamoff(struct file *file, void *priv,
gspca_stream_off(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
- /* empty the application queues */
- for (i = 0; i < gspca_dev->nframes; i++)
- gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS;
- gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0;
- gspca_dev->last_packet_type = DISCARD_PACKET;
- gspca_dev->sequence = 0;
+ /* empty the transfer queues */
+ atomic_set(&gspca_dev->fr_q, 0);
+ atomic_set(&gspca_dev->fr_i, 0);
+ gspca_dev->fr_o = 0;
ret = 0;
out:
mutex_unlock(&gspca_dev->queue_lock);
@@ -1732,7 +1693,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
int n;
n = parm->parm.capture.readbuffers;
- if (n == 0 || n > GSPCA_MAX_FRAMES)
+ if (n == 0 || n >= GSPCA_MAX_FRAMES)
parm->parm.capture.readbuffers = gspca_dev->nbufread;
else
gspca_dev->nbufread = n;
@@ -1755,49 +1716,6 @@ static int vidioc_s_parm(struct file *filp, void *priv,
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-static int vidiocgmbuf(struct file *file, void *priv,
- struct video_mbuf *mbuf)
-{
- struct gspca_dev *gspca_dev = file->private_data;
- int i;
-
- PDEBUG(D_STREAM, "cgmbuf");
- if (gspca_dev->nframes == 0) {
- int ret;
-
- {
- struct v4l2_format fmt;
-
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- i = gspca_dev->cam.nmodes - 1; /* highest mode */
- fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
- fmt.fmt.pix.height = gspca_dev->cam.cam_mode[i].height;
- fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;
- ret = vidioc_s_fmt_vid_cap(file, priv, &fmt);
- if (ret != 0)
- return ret;
- }
- {
- struct v4l2_requestbuffers rb;
-
- memset(&rb, 0, sizeof rb);
- rb.count = 4;
- rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- rb.memory = V4L2_MEMORY_MMAP;
- ret = vidioc_reqbufs(file, priv, &rb);
- if (ret != 0)
- return ret;
- }
- }
- mbuf->frames = gspca_dev->nframes;
- mbuf->size = gspca_dev->frsz * gspca_dev->nframes;
- for (i = 0; i < mbuf->frames; i++)
- mbuf->offsets[i] = gspca_dev->frame[i].v4l2_buf.m.offset;
- return 0;
-}
-#endif
-
static int dev_mmap(struct file *file, struct vm_area_struct *vma)
{
struct gspca_dev *gspca_dev = file->private_data;
@@ -1838,12 +1756,7 @@ static int dev_mmap(struct file *file, struct vm_area_struct *vma)
ret = -EINVAL;
goto out;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- /* v4l1 maps all the buffers */
- if (i != 0
- || size != frame->v4l2_buf.length * gspca_dev->nframes)
-#endif
- if (size != frame->v4l2_buf.length) {
+ if (size != frame->v4l2_buf.length) {
PDEBUG(D_STREAM, "mmap bad size");
ret = -EINVAL;
goto out;
@@ -1883,21 +1796,17 @@ out:
static int frame_wait(struct gspca_dev *gspca_dev,
int nonblock_ing)
{
- struct gspca_frame *frame;
- int i, j, ret;
+ int i, ret;
/* check if a frame is ready */
i = gspca_dev->fr_o;
- j = gspca_dev->fr_queue[i];
- frame = &gspca_dev->frame[j];
-
- if (!(frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE)) {
+ if (i == atomic_read(&gspca_dev->fr_i)) {
if (nonblock_ing)
return -EAGAIN;
/* wait till a frame is ready */
ret = wait_event_interruptible_timeout(gspca_dev->wq,
- (frame->v4l2_buf.flags & V4L2_BUF_FLAG_DONE) ||
+ i != atomic_read(&gspca_dev->fr_i) ||
!gspca_dev->streaming || !gspca_dev->present,
msecs_to_jiffies(3000));
if (ret < 0)
@@ -1906,11 +1815,7 @@ static int frame_wait(struct gspca_dev *gspca_dev,
return -EIO;
}
- gspca_dev->fr_o = (i + 1) % gspca_dev->nframes;
- PDEBUG(D_FRAM, "frame wait q:%d i:%d o:%d",
- gspca_dev->fr_q,
- gspca_dev->fr_i,
- gspca_dev->fr_o);
+ gspca_dev->fr_o = (i + 1) % GSPCA_MAX_FRAMES;
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
@@ -1919,7 +1824,7 @@ static int frame_wait(struct gspca_dev *gspca_dev,
gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
- return j;
+ return gspca_dev->fr_queue[i];
}
/*
@@ -2024,15 +1929,9 @@ static int vidioc_qbuf(struct file *file, void *priv,
}
/* put the buffer in the 'queued' queue */
- i = gspca_dev->fr_q;
+ i = atomic_read(&gspca_dev->fr_q);
gspca_dev->fr_queue[i] = index;
- if (gspca_dev->fr_i == i)
- gspca_dev->cur_frame = frame;
- gspca_dev->fr_q = (i + 1) % gspca_dev->nframes;
- PDEBUG(D_FRAM, "qbuf q:%d i:%d o:%d",
- gspca_dev->fr_q,
- gspca_dev->fr_i,
- gspca_dev->fr_o);
+ atomic_set(&gspca_dev->fr_q, (i + 1) % GSPCA_MAX_FRAMES);
v4l2_buf->flags |= V4L2_BUF_FLAG_QUEUED;
v4l2_buf->flags &= ~V4L2_BUF_FLAG_DONE;
@@ -2088,7 +1987,7 @@ static int read_alloc(struct gspca_dev *gspca_dev,
static unsigned int dev_poll(struct file *file, poll_table *wait)
{
struct gspca_dev *gspca_dev = file->private_data;
- int i, ret;
+ int ret;
PDEBUG(D_FRAM, "poll");
@@ -2106,11 +2005,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
return POLLERR;
- /* check the next incoming buffer */
- i = gspca_dev->fr_o;
- i = gspca_dev->fr_queue[i];
- if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE)
- ret = POLLIN | POLLRDNORM; /* something to read */
+ /* check if an image has been received */
+ if (gspca_dev->fr_o != atomic_read(&gspca_dev->fr_i))
+ ret = POLLIN | POLLRDNORM; /* yes */
else
ret = 0;
mutex_unlock(&gspca_dev->queue_lock);
@@ -2235,9 +2132,6 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
.vidioc_s_register = vidioc_s_register,
#endif
.vidioc_g_chip_ident = vidioc_g_chip_ident,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = vidiocgmbuf,
-#endif
};
static struct video_device gspca_template = {
@@ -2253,31 +2147,18 @@ static struct video_device gspca_template = {
* This function must be called by the sub-driver when it is
* called for probing a new device.
*/
-int gspca_dev_probe(struct usb_interface *intf,
+int gspca_dev_probe2(struct usb_interface *intf,
const struct usb_device_id *id,
const struct sd_desc *sd_desc,
int dev_size,
struct module *module)
{
- struct usb_interface_descriptor *interface;
struct gspca_dev *gspca_dev;
struct usb_device *dev = interface_to_usbdev(intf);
int ret;
PDEBUG(D_PROBE, "probing %04x:%04x", id->idVendor, id->idProduct);
- /* we don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1) {
- PDEBUG(D_ERR, "Too many config");
- return -ENODEV;
- }
-
- /* the USB video interface must be the first one */
- interface = &intf->cur_altsetting->desc;
- if (dev->config->desc.bNumInterfaces != 1 &&
- interface->bInterfaceNumber != 0)
- return -ENODEV;
-
/* create the device */
if (dev_size < sizeof *gspca_dev)
dev_size = sizeof *gspca_dev;
@@ -2293,7 +2174,7 @@ int gspca_dev_probe(struct usb_interface *intf,
goto out;
}
gspca_dev->dev = dev;
- gspca_dev->iface = interface->bInterfaceNumber;
+ gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;
gspca_dev->nbalt = intf->num_altsetting;
gspca_dev->sd_desc = sd_desc;
gspca_dev->nbufread = 2;
@@ -2345,6 +2226,35 @@ out:
kfree(gspca_dev);
return ret;
}
+EXPORT_SYMBOL(gspca_dev_probe2);
+
+/* same function as the previous one, but check the interface */
+int gspca_dev_probe(struct usb_interface *intf,
+ const struct usb_device_id *id,
+ const struct sd_desc *sd_desc,
+ int dev_size,
+ struct module *module)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+
+ /* we don't handle multi-config cameras */
+ if (dev->descriptor.bNumConfigurations != 1) {
+ PDEBUG(D_ERR, "%04x:%04x too many config",
+ id->idVendor, id->idProduct);
+ return -ENODEV;
+ }
+
+ /* the USB video interface must be the first one */
+ if (dev->config->desc.bNumInterfaces != 1
+ && intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+ PDEBUG(D_ERR, "%04x:%04x bad interface %d",
+ id->idVendor, id->idProduct,
+ intf->cur_altsetting->desc.bInterfaceNumber);
+ return -ENODEV;
+ }
+
+ return gspca_dev_probe2(intf, id, sd_desc, dev_size, module);
+}
EXPORT_SYMBOL(gspca_dev_probe);
/*
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index 8b963dfae861..17e55580631e 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -7,7 +7,6 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
#include <linux/mutex.h>
-#include <linux/slab.h>
/* compilation option */
#define GSPCA_DEBUG 1
@@ -148,7 +147,6 @@ enum gspca_packet_type {
struct gspca_frame {
__u8 *data; /* frame buffer */
- __u8 *data_end; /* end of frame while filling */
int vma_use_count;
struct v4l2_buffer v4l2_buf;
};
@@ -177,13 +175,14 @@ struct gspca_dev {
__u8 *frbuf; /* buffer for nframes */
struct gspca_frame frame[GSPCA_MAX_FRAMES];
- struct gspca_frame *cur_frame; /* frame beeing filled */
+ u8 *image; /* image beeing filled */
__u32 frsz; /* frame size */
- char nframes; /* number of frames */
- char fr_i; /* frame being filled */
- char fr_q; /* next frame to queue */
- char fr_o; /* next frame to dequeue */
+ u32 image_len; /* current length of image */
+ atomic_t fr_q; /* next frame to queue */
+ atomic_t fr_i; /* frame being filled */
signed char fr_queue[GSPCA_MAX_FRAMES]; /* frame queue */
+ char nframes; /* number of frames */
+ u8 fr_o; /* next frame to dequeue */
__u8 last_packet_type;
__s8 empty_packet; /* if (-1) don't check empty packets */
__u8 streaming;
@@ -217,12 +216,16 @@ int gspca_dev_probe(struct usb_interface *intf,
const struct sd_desc *sd_desc,
int dev_size,
struct module *module);
+int gspca_dev_probe2(struct usb_interface *intf,
+ const struct usb_device_id *id,
+ const struct sd_desc *sd_desc,
+ int dev_size,
+ struct module *module);
void gspca_disconnect(struct usb_interface *intf);
void gspca_frame_add(struct gspca_dev *gspca_dev,
enum gspca_packet_type packet_type,
const u8 *data,
int len);
-struct gspca_frame *gspca_get_i_frame(struct gspca_dev *gspca_dev);
#ifdef CONFIG_PM
int gspca_suspend(struct usb_interface *intf, pm_message_t message);
int gspca_resume(struct usb_interface *intf);
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 84ecd56c6470..12d9cf4caba2 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -50,7 +50,7 @@ struct sd {
struct workqueue_struct *work_thread;
u8 quality; /* image quality */
u8 jpegqual; /* webcam quality */
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
struct jlj_command {
@@ -282,7 +282,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
destroy_workqueue(dev->work_thread);
dev->work_thread = NULL;
mutex_lock(&gspca_dev->usb_lock);
- kfree(dev->jpeg_hdr);
}
/* this function is called at probe and resume time */
@@ -298,9 +297,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int ret;
/* create the JPEG header */
- dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (dev->jpeg_hdr == NULL)
- return -ENOMEM;
jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */
jpeg_set_qual(dev->jpeg_hdr, dev->quality);
diff --git a/drivers/media/video/gspca/m5602/m5602_bridge.h b/drivers/media/video/gspca/m5602/m5602_bridge.h
index 1127a405c9b2..51af3ee3ab85 100644
--- a/drivers/media/video/gspca/m5602/m5602_bridge.h
+++ b/drivers/media/video/gspca/m5602/m5602_bridge.h
@@ -19,6 +19,7 @@
#ifndef M5602_BRIDGE_H_
#define M5602_BRIDGE_H_
+#include <linux/slab.h>
#include "gspca.h"
#define MODULE_NAME "ALi m5602"
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 4294c75e3b11..b073d66acd04 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -305,30 +305,23 @@ static void m5602_urb_complete(struct gspca_dev *gspca_dev,
sd->frame_count);
} else {
- struct gspca_frame *frame;
int cur_frame_len;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
- cur_frame_len = frame->data_end - frame->data;
+ cur_frame_len = gspca_dev->image_len;
/* Remove urb header */
data += 4;
len -= 4;
- if (cur_frame_len + len <= frame->v4l2_buf.length) {
+ if (cur_frame_len + len <= gspca_dev->frsz) {
PDEBUG(D_FRAM, "Continuing frame %d copying %d bytes",
sd->frame_count, len);
gspca_frame_add(gspca_dev, INTER_PACKET,
data, len);
- } else if (frame->v4l2_buf.length - cur_frame_len > 0) {
+ } else {
/* Add the remaining data up to frame size */
gspca_frame_add(gspca_dev, INTER_PACKET, data,
- frame->v4l2_buf.length - cur_frame_len);
+ gspca_dev->frsz - cur_frame_len);
}
}
}
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.c b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
index 6b3be4fa2c06..fbd91545497a 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.c
@@ -17,7 +17,6 @@
*/
#include <linux/kthread.h>
-#include <linux/slab.h>
#include "m5602_s5k83a.h"
static int s5k83a_set_gain(struct gspca_dev *gspca_dev, __s32 val);
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 3d9229e22b25..031f7195ce0d 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -41,7 +41,7 @@ struct sd {
#define QUALITY_MAX 70
#define QUALITY_DEF 50
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
@@ -200,9 +200,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int i;
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -317,13 +314,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_ERR, "Camera Stop failed");
}
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- kfree(sd->jpeg_hdr);
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
@@ -486,7 +476,6 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
- .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.get_jcomp = sd_get_jcomp,
.set_jcomp = sd_set_jcomp,
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index f36e11a0458d..2b2cbdbf03fe 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -41,6 +41,11 @@
#include <linux/input.h>
#include "gspca.h"
+/* The jpeg_hdr is used by w996Xcf only */
+/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
+#define CONEX_CAM
+#include "jpeg.h"
+
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("OV519 USB Camera Driver");
MODULE_LICENSE("GPL");
@@ -90,6 +95,7 @@ struct sd {
#define QUALITY_DEF 50
__u8 stopped; /* Streaming is temporarily paused */
+ __u8 first_frame;
__u8 frame_rate; /* current Framerate */
__u8 clockdiv; /* clockdiv override */
@@ -115,7 +121,7 @@ struct sd {
int sensor_height;
int sensor_reg_cache[256];
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* Note this is a bit of a hack, but the w9968cf driver needs the code for all
@@ -3147,7 +3153,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->autobrightness = AUTOBRIGHT_DEF;
if (sd->sensor == SEN_OV7670) {
sd->freq = OV7670_FREQ_DEF;
- gspca_dev->ctrl_dis = 1 << FREQ_IDX;
+ gspca_dev->ctrl_dis = (1 << FREQ_IDX) | (1 << COLOR_IDX);
} else {
sd->freq = FREQ_DEF;
gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX) |
@@ -3961,6 +3967,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
sd_reset_snapshot(gspca_dev);
sd->snapshot_pressed = 0;
+ sd->first_frame = 3;
+
ret = ov51x_restart(sd);
if (ret < 0)
goto out;
@@ -4153,13 +4161,23 @@ static void ovfx2_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+
/* A short read signals EOF */
if (len < OVFX2_BULK_SIZE) {
- gspca_frame_add(gspca_dev, LAST_PACKET, data, len);
+ /* If the frame is short, and it is one of the first ones
+ the sensor and bridge are still syncing, so drop it. */
+ if (sd->first_frame) {
+ sd->first_frame--;
+ if (gspca_dev->image_len <
+ sd->gspca_dev.width * sd->gspca_dev.height)
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+ }
+ gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
gspca_frame_add(gspca_dev, FIRST_PACKET, NULL, 0);
- return;
}
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index dc1e4efe30fb..96cb3a976581 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -987,13 +987,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data + 12, len - 12);
/* If this packet is marked as EOF, end the frame */
} else if (data[1] & UVC_STREAM_EOF) {
- struct gspca_frame *frame;
-
sd->last_pts = 0;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL)
- goto discard;
- if (frame->data_end - frame->data + (len - 12) !=
+ if (gspca_dev->image_len + len - 12 !=
gspca_dev->width * gspca_dev->height * 2) {
PDEBUG(D_PACK, "wrong sized frame");
goto discard;
diff --git a/drivers/media/video/gspca/pac7302.c b/drivers/media/video/gspca/pac7302.c
index 2a68220d1ada..a66df07d7625 100644
--- a/drivers/media/video/gspca/pac7302.c
+++ b/drivers/media/video/gspca/pac7302.c
@@ -402,7 +402,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
memcpy(gspca_dev->usb_buf, buffer, len);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- 1, /* request */
+ 0, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, len,
@@ -804,7 +804,6 @@ static const unsigned char pac_jpeg_header2[] = {
};
static void pac_start_frame(struct gspca_dev *gspca_dev,
- struct gspca_frame *frame,
__u16 lines, __u16 samples_per_line)
{
unsigned char tmpbuf[4];
@@ -829,19 +828,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
- struct gspca_frame *frame;
+ u8 *image;
unsigned char *sof;
sof = pac_find_sof(&sd->sof_read, data, len);
if (sof) {
int n, lum_offset, footer_length;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
/* 6 bytes after the FF D9 EOF marker a number of lumination
bytes are send corresponding to different parts of the
image, the 14th and 15th byte after the EOF seem to
@@ -852,16 +845,17 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* Finish decoding current frame */
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
if (n < 0) {
- frame->data_end += n;
+ gspca_dev->image_len += n;
n = 0;
+ } else {
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
}
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, n);
- if (gspca_dev->last_packet_type != DISCARD_PACKET &&
- frame->data_end[-2] == 0xff &&
- frame->data_end[-1] == 0xd9)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
+
+ image = gspca_dev->image;
+ if (image != NULL
+ && image[gspca_dev->image_len - 2] == 0xff
+ && image[gspca_dev->image_len - 1] == 0xd9)
+ gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
n = sof - data;
len -= n;
@@ -877,7 +871,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* Start the new frame with the jpeg header */
/* The PAC7302 has the image rotated 90 degrees */
- pac_start_frame(gspca_dev, frame,
+ pac_start_frame(gspca_dev,
gspca_dev->width, gspca_dev->height);
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
@@ -1200,6 +1194,7 @@ static const struct usb_device_id device_table[] __devinitconst = {
{USB_DEVICE(0x093a, 0x2621)},
{USB_DEVICE(0x093a, 0x2622), .driver_info = FL_VFLIP},
{USB_DEVICE(0x093a, 0x2624), .driver_info = FL_VFLIP},
+ {USB_DEVICE(0x093a, 0x2625)},
{USB_DEVICE(0x093a, 0x2626)},
{USB_DEVICE(0x093a, 0x2628)},
{USB_DEVICE(0x093a, 0x2629), .driver_info = FL_VFLIP},
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index 44fed9686729..1cb7e99e92bd 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -270,7 +270,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
memcpy(gspca_dev->usb_buf, buffer, len);
ret = usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- 1, /* request */
+ 0, /* request */
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, len,
@@ -599,7 +599,6 @@ static const unsigned char pac_jpeg_header2[] = {
};
static void pac_start_frame(struct gspca_dev *gspca_dev,
- struct gspca_frame *frame,
__u16 lines, __u16 samples_per_line)
{
unsigned char tmpbuf[4];
@@ -624,19 +623,13 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
+ u8 *image;
unsigned char *sof;
- struct gspca_frame *frame;
sof = pac_find_sof(&sd->sof_read, data, len);
if (sof) {
int n, lum_offset, footer_length;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
-
/* 6 bytes after the FF D9 EOF marker a number of lumination
bytes are send corresponding to different parts of the
image, the 14th and 15th byte after the EOF seem to
@@ -647,16 +640,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* Finish decoding current frame */
n = (sof - data) - (footer_length + sizeof pac_sof_marker);
if (n < 0) {
- frame->data_end += n;
+ gspca_dev->image_len += n;
n = 0;
+ } else {
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, n);
}
- gspca_frame_add(gspca_dev, INTER_PACKET,
- data, n);
- if (gspca_dev->last_packet_type != DISCARD_PACKET &&
- frame->data_end[-2] == 0xff &&
- frame->data_end[-1] == 0xd9)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- NULL, 0);
+ image = gspca_dev->image;
+ if (image != NULL
+ && image[gspca_dev->image_len - 2] == 0xff
+ && image[gspca_dev->image_len - 1] == 0xd9)
+ gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
n = sof - data;
len -= n;
@@ -671,7 +664,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
atomic_set(&sd->avg_lum, -1);
/* Start the new frame with the jpeg header */
- pac_start_frame(gspca_dev, frame,
+ pac_start_frame(gspca_dev,
gspca_dev->height, gspca_dev->width);
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 644a7fd4701a..83a718f0f3f9 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -20,7 +20,6 @@
#ifdef CONFIG_INPUT
#include <linux/input.h>
-#include <linux/slab.h>
#endif
#include "gspca.h"
@@ -89,7 +88,7 @@ struct sd {
u8 hstart;
u8 vstart;
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
u8 quality;
u8 flags;
@@ -2162,10 +2161,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int height = gspca_dev->height;
u8 fmt, scale = 0;
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (sd->jpeg_hdr == NULL)
- return -ENOMEM;
-
jpeg_define(sd->jpeg_hdr, height, width,
0x21);
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -2197,8 +2192,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
configure_sensor_output(gspca_dev, mode);
- reg_w(gspca_dev, 0x1100, sd->jpeg_hdr + JPEG_QT0_OFFSET, 64);
- reg_w(gspca_dev, 0x1140, sd->jpeg_hdr + JPEG_QT1_OFFSET, 64);
+ reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
+ reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
reg_w(gspca_dev, 0x10fb, CLR_WIN(width, height), 5);
reg_w(gspca_dev, 0x1180, HW_WIN(mode, sd->hstart, sd->vstart), 6);
reg_w1(gspca_dev, 0x1189, scale);
@@ -2226,12 +2221,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x1061, gspca_dev->usb_buf[0] & ~0x02);
}
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- kfree(sd->jpeg_hdr);
-}
-
static void do_autoexposure(struct gspca_dev *gspca_dev, u16 avg_lum)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -2397,7 +2386,6 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
- .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
#ifdef CONFIG_INPUT
.int_pkt_scan = sd_int_pkt_scan,
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index 95354a339e3d..204bb3af4559 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1251,16 +1251,10 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
/* In raw mode we sometimes get some garbage after the frame
ignore this */
- struct gspca_frame *frame;
int used;
int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- used = frame->data_end - frame->data;
+ used = gspca_dev->image_len;
if (used + len > size)
len = size - used;
}
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 176c5b3d5e6f..d5fe1f6f4264 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -22,7 +22,6 @@
#define MODULE_NAME "sonixj"
#include <linux/input.h>
-#include <linux/slab.h>
#include "gspca.h"
#include "jpeg.h"
diff --git a/drivers/media/video/gspca/spca1528.c b/drivers/media/video/gspca/spca1528.c
new file mode 100644
index 000000000000..3f514eb1d99d
--- /dev/null
+++ b/drivers/media/video/gspca/spca1528.c
@@ -0,0 +1,605 @@
+/*
+ * spca1528 subdriver
+ *
+ * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
+ *
+ * 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
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "spca1528"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
+MODULE_DESCRIPTION("SPCA1528 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ u8 brightness;
+ u8 contrast;
+ u8 hue;
+ u8 color;
+ u8 sharpness;
+
+ u8 pkt_seq;
+
+ u8 jpeg_hdr[JPEG_HDR_SZ];
+};
+
+/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
+static const struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 128
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_CONTRAST,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Contrast",
+ .minimum = 0,
+ .maximum = 8,
+ .step = 1,
+#define CONTRAST_DEF 1
+ .default_value = CONTRAST_DEF,
+ },
+ .set = sd_setcontrast,
+ .get = sd_getcontrast,
+ },
+ {
+ {
+ .id = V4L2_CID_HUE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Hue",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define HUE_DEF 0
+ .default_value = HUE_DEF,
+ },
+ .set = sd_sethue,
+ .get = sd_gethue,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Saturation",
+ .minimum = 0,
+ .maximum = 8,
+ .step = 1,
+#define COLOR_DEF 1
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolor,
+ .get = sd_getcolor,
+ },
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define SHARPNESS_DEF 0
+ .default_value = SHARPNESS_DEF,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+/* (does not work correctly)
+ {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144 * 5 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+*/
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 4 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+};
+
+/* read <len> bytes to gspca usb_buf */
+static void reg_r(struct gspca_dev *gspca_dev,
+ u8 req,
+ u16 index,
+ int len)
+{
+#if USB_BUF_SZ < 64
+#error "USB buffer too small"
+#endif
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+ req,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x0000, /* value */
+ index,
+ gspca_dev->usb_buf, len,
+ 500);
+ PDEBUG(D_USBI, "GET %02x 0000 %04x %02x", req, index,
+ gspca_dev->usb_buf[0]);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void reg_w(struct gspca_dev *gspca_dev,
+ u8 req,
+ u16 value,
+ u16 index)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index,
+ NULL, 0, 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void reg_wb(struct gspca_dev *gspca_dev,
+ u8 req,
+ u16 value,
+ u16 index,
+ u8 byte)
+{
+ struct usb_device *dev = gspca_dev->dev;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ PDEBUG(D_USBO, "SET %02x %04x %04x %02x", req, value, index, byte);
+ gspca_dev->usb_buf[0] = byte;
+ ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+ req,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index,
+ gspca_dev->usb_buf, 1, 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void wait_status_0(struct gspca_dev *gspca_dev)
+{
+ int i;
+
+ i = 20;
+ do {
+ reg_r(gspca_dev, 0x21, 0x0000, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ return;
+ msleep(30);
+ } while (--i > 0);
+ PDEBUG(D_ERR, "wait_status_0 timeout");
+ gspca_dev->usb_err = -ETIME;
+}
+
+static void wait_status_1(struct gspca_dev *gspca_dev)
+{
+ int i;
+
+ i = 10;
+ do {
+ reg_r(gspca_dev, 0x21, 0x0001, 1);
+ msleep(10);
+ if (gspca_dev->usb_buf[0] == 1) {
+ reg_wb(gspca_dev, 0x21, 0x0000, 0x0001, 0x00);
+ reg_r(gspca_dev, 0x21, 0x0001, 1);
+ return;
+ }
+ } while (--i > 0);
+ PDEBUG(D_ERR, "wait_status_1 timeout");
+ gspca_dev->usb_err = -ETIME;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_wb(gspca_dev, 0xc0, 0x0000, 0x00c0, sd->brightness);
+}
+
+static void setcontrast(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_wb(gspca_dev, 0xc1, 0x0000, 0x00c1, sd->contrast);
+}
+
+static void sethue(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_wb(gspca_dev, 0xc2, 0x0000, 0x0000, sd->hue);
+}
+
+static void setcolor(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_wb(gspca_dev, 0xc3, 0x0000, 0x00c3, sd->color);
+}
+
+static void setsharpness(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ reg_wb(gspca_dev, 0xc4, 0x0000, 0x00c4, sd->sharpness);
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ gspca_dev->cam.cam_mode = vga_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
+ gspca_dev->cam.npkt = 128; /* number of packets per ISOC message */
+ /*fixme: 256 in ms-win traces*/
+
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->hue = HUE_DEF;
+ sd->color = COLOR_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+
+ gspca_dev->nbalt = 4; /* use alternate setting 3 */
+
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, 0x00, 0x0001, 0x2067);
+ reg_w(gspca_dev, 0x00, 0x00d0, 0x206b);
+ reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
+ reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
+ msleep(8);
+ reg_w(gspca_dev, 0x00, 0x00c0, 0x206b);
+ reg_w(gspca_dev, 0x00, 0x0000, 0x206c);
+ reg_w(gspca_dev, 0x00, 0x0001, 0x2069);
+
+ reg_r(gspca_dev, 0x20, 0x0000, 1);
+ reg_r(gspca_dev, 0x20, 0x0000, 5);
+ reg_r(gspca_dev, 0x23, 0x0000, 64);
+ PDEBUG(D_PROBE, "%s%s", &gspca_dev->usb_buf[0x1c],
+ &gspca_dev->usb_buf[0x30]);
+ reg_r(gspca_dev, 0x23, 0x0001, 64);
+ return gspca_dev->usb_err;
+}
+
+/* function called at start time before URB creation */
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+ u8 mode;
+
+ reg_r(gspca_dev, 0x00, 0x2520, 1);
+ wait_status_0(gspca_dev);
+ reg_w(gspca_dev, 0xc5, 0x0003, 0x0000);
+ wait_status_1(gspca_dev);
+
+ wait_status_0(gspca_dev);
+ mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+ reg_wb(gspca_dev, 0x25, 0x0000, 0x0004, mode);
+ reg_r(gspca_dev, 0x25, 0x0004, 1);
+ reg_wb(gspca_dev, 0x27, 0x0000, 0x0000, 0x06);
+ reg_r(gspca_dev, 0x27, 0x0000, 1);
+ return gspca_dev->usb_err;
+}
+
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* initialize the JPEG header */
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+
+ /* the JPEG quality seems to be 82% */
+ jpeg_set_qual(sd->jpeg_hdr, 82);
+
+ /* set the controls */
+ setbrightness(gspca_dev);
+ setcontrast(gspca_dev);
+ sethue(gspca_dev);
+ setcolor(gspca_dev);
+ setsharpness(gspca_dev);
+
+ msleep(5);
+ reg_r(gspca_dev, 0x00, 0x2520, 1);
+ msleep(8);
+
+ /* start the capture */
+ wait_status_0(gspca_dev);
+ reg_w(gspca_dev, 0x31, 0x0000, 0x0004);
+ wait_status_1(gspca_dev);
+ wait_status_0(gspca_dev);
+ msleep(200);
+
+ sd->pkt_seq = 0;
+ return gspca_dev->usb_err;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ /* stop the capture */
+ wait_status_0(gspca_dev);
+ reg_w(gspca_dev, 0x31, 0x0000, 0x0000);
+ wait_status_1(gspca_dev);
+ wait_status_0(gspca_dev);
+}
+
+/* move a packet adding 0x00 after 0xff */
+static void add_packet(struct gspca_dev *gspca_dev,
+ u8 *data,
+ int len)
+{
+ int i;
+
+ i = 0;
+ do {
+ if (data[i] == 0xff) {
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ data, i + 1);
+ len -= i;
+ data += i;
+ *data = 0x00;
+ i = 0;
+ }
+ } while (++i < len);
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ static const u8 ffd9[] = {0xff, 0xd9};
+
+ /* image packets start with:
+ * 02 8n
+ * with <n> bit:
+ * 0x01: even (0) / odd (1) image
+ * 0x02: end of image when set
+ */
+ if (len < 3)
+ return; /* empty packet */
+ if (*data == 0x02) {
+ if (data[1] & 0x02) {
+ sd->pkt_seq = !(data[1] & 1);
+ add_packet(gspca_dev, data + 2, len - 2);
+ gspca_frame_add(gspca_dev, LAST_PACKET,
+ ffd9, 2);
+ return;
+ }
+ if ((data[1] & 1) != sd->pkt_seq)
+ goto err;
+ if (gspca_dev->last_packet_type == LAST_PACKET)
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+ add_packet(gspca_dev, data + 2, len - 2);
+ return;
+ }
+err:
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+}
+
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setbrightness(gspca_dev);
+ return gspca_dev->usb_err;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->contrast = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return gspca_dev->usb_err;
+}
+
+static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->contrast;
+ return 0;
+}
+
+static int sd_sethue(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->hue = val;
+ if (gspca_dev->streaming)
+ sethue(gspca_dev);
+ return gspca_dev->usb_err;
+}
+
+static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->hue;
+ return 0;
+}
+
+static int sd_setcolor(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->color = val;
+ if (gspca_dev->streaming)
+ setcolor(gspca_dev);
+ return gspca_dev->usb_err;
+}
+
+static int sd_getcolor(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->color;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming)
+ setsharpness(gspca_dev);
+ return gspca_dev->usb_err;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .isoc_init = sd_isoc_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x04fc, 0x1528)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ /* the video interface for isochronous transfer is 1 */
+ if (intf->cur_altsetting->desc.bInterfaceNumber != 1)
+ return -ENODEV;
+
+ return gspca_dev_probe2(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ info("registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index b866c73c97db..c02beb6c1e93 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -57,7 +57,7 @@ struct sd {
#define PalmPixDC85 13
#define ToptroIndus 14
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
@@ -669,9 +669,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 xmult, ymult;
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x22); /* JPEG 411 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -891,13 +888,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0]);
}
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- kfree(sd->jpeg_hdr);
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
@@ -1055,7 +1045,6 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
- .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.get_jcomp = sd_get_jcomp,
.set_jcomp = sd_set_jcomp,
diff --git a/drivers/media/video/gspca/sq930x.c b/drivers/media/video/gspca/sq930x.c
new file mode 100644
index 000000000000..37cee5e063cf
--- /dev/null
+++ b/drivers/media/video/gspca/sq930x.c
@@ -0,0 +1,1402 @@
+/*
+ * SQ930x subdriver
+ *
+ * Copyright (C) 2010 Jean-François Moine <http://moinejf.free.fr>
+ * Copyright (C) 2006 -2008 Gerard Klaver <gerard at gkall dot hobby dot nl>
+ * Copyright (C) 2007 Sam Revitch <samr7@cs.washington.edu>
+ *
+ * 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
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define MODULE_NAME "sq930x"
+
+#include "gspca.h"
+#include "jpeg.h"
+
+MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>\n"
+ "Gerard Klaver <gerard at gkall dot hobby dot nl\n"
+ "Sam Revitch <samr7@cs.washington.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ930x USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+#define BULK_TRANSFER_LEN 5128
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ u16 expo;
+ u8 gain;
+
+ u8 quality; /* webcam quality 0..3 */
+#define QUALITY_DEF 1
+
+ u8 gpio[2];
+
+ u8 eof_len;
+ u8 do_ctrl;
+
+ u8 sensor;
+enum {
+ SENSOR_ICX098BQ,
+ SENSOR_LZ24BP,
+ SENSOR_MI0360,
+ SENSOR_MT9V111,
+ SENSOR_OV7660,
+ SENSOR_OV9630,
+} sensors;
+ u8 type;
+#define Generic 0
+#define Creative_live_motion 1
+
+ u8 jpeg_hdr[JPEG_HDR_SZ];
+};
+
+static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static const struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 0x0001,
+ .maximum = 0x0fff,
+ .step = 1,
+#define EXPO_DEF 0x027d
+ .default_value = EXPO_DEF,
+ },
+ .set = sd_setexpo,
+ .get = sd_getexpo,
+ },
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0x01,
+ .maximum = 0xff,
+ .step = 1,
+#define GAIN_DEF 0x61
+ .default_value = GAIN_DEF,
+ },
+ .set = sd_setgain,
+ .get = sd_getgain,
+ },
+};
+
+static struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120 * 5 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 0},
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 4 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+};
+
+/* JPEG quality indexed by webcam quality */
+#define QUAL_0 90
+#define QUAL_1 85
+#define QUAL_2 75
+#define QUAL_3 70
+static const u8 quality_tb[4] = { QUAL_0, QUAL_1, QUAL_2, QUAL_3 };
+
+/* sq930x registers */
+#define SQ930_CTRL_UCBUS_IO 0x0001
+#define SQ930_CTRL_I2C_IO 0x0002
+#define SQ930_CTRL_GPIO 0x0005
+#define SQ930_CTRL_CAP_START 0x0010
+#define SQ930_CTRL_CAP_STOP 0x0011
+#define SQ930_CTRL_SET_EXPOSURE 0x001d
+#define SQ930_CTRL_RESET 0x001e
+#define SQ930_CTRL_GET_DEV_INFO 0x001f
+
+/* gpio 1 (8..15) */
+#define SQ930_GPIO_DFL_I2C_SDA 0x0001
+#define SQ930_GPIO_DFL_I2C_SCL 0x0002
+#define SQ930_GPIO_RSTBAR 0x0004
+#define SQ930_GPIO_EXTRA1 0x0040
+#define SQ930_GPIO_EXTRA2 0x0080
+/* gpio 3 (24..31) */
+#define SQ930_GPIO_POWER 0x0200
+#define SQ930_GPIO_DFL_LED 0x1000
+
+struct ucbus_write_cmd {
+ u16 bw_addr;
+ u8 bw_data;
+};
+struct i2c_write_cmd {
+ u8 reg;
+ u16 val;
+};
+
+static const struct ucbus_write_cmd icx098bq_start_0[] = {
+ {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xce},
+ {0xf802, 0xc1}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x0e},
+ {0xf80a, 0x01}, {0xf80b, 0xee}, {0xf807, 0x60}, {0xf80c, 0x02},
+ {0xf80d, 0xf0}, {0xf80e, 0x03}, {0xf80f, 0x0a}, {0xf81c, 0x02},
+ {0xf81d, 0xf0}, {0xf81e, 0x03}, {0xf81f, 0x0a}, {0xf83a, 0x00},
+ {0xf83b, 0x10}, {0xf83c, 0x00}, {0xf83d, 0x4e}, {0xf810, 0x04},
+ {0xf811, 0x00}, {0xf812, 0x02}, {0xf813, 0x10}, {0xf803, 0x00},
+ {0xf814, 0x01}, {0xf815, 0x18}, {0xf816, 0x00}, {0xf817, 0x48},
+ {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
+ {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
+ {0xf823, 0x07}, {0xf824, 0xff}, {0xf825, 0x03}, {0xf826, 0xff},
+ {0xf827, 0x06}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
+ {0xf82b, 0x0c}, {0xf82c, 0xfd}, {0xf82d, 0x01}, {0xf82e, 0x00},
+ {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
+ {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
+ {0xf854, 0x00}, {0xf855, 0x18}, {0xf856, 0x00}, {0xf857, 0x3c},
+ {0xf858, 0x00}, {0xf859, 0x0c}, {0xf85a, 0x00}, {0xf85b, 0x30},
+ {0xf85c, 0x00}, {0xf85d, 0x0c}, {0xf85e, 0x00}, {0xf85f, 0x30},
+ {0xf860, 0x00}, {0xf861, 0x48}, {0xf862, 0x01}, {0xf863, 0xdc},
+ {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
+ {0xf868, 0xff}, {0xf869, 0x70}, {0xf86c, 0xff}, {0xf86d, 0x00},
+ {0xf86a, 0xff}, {0xf86b, 0x48}, {0xf86e, 0xff}, {0xf86f, 0x00},
+ {0xf870, 0x01}, {0xf871, 0xdb}, {0xf872, 0x01}, {0xf873, 0xfa},
+ {0xf874, 0x01}, {0xf875, 0xdb}, {0xf876, 0x01}, {0xf877, 0xfa},
+ {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
+ {0xf800, 0x03}
+};
+static const struct ucbus_write_cmd icx098bq_start_1[] = {
+ {0xf5f0, 0x00}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xc0},
+ {0xf5f0, 0x49}, {0xf5f1, 0xcd}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xc0},
+ {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
+ {0xf5f9, 0x00}
+};
+
+static const struct ucbus_write_cmd icx098bq_start_2[] = {
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x82}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x40}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xcf}, {0xf806, 0xd0},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03}
+};
+
+static const struct ucbus_write_cmd lz24bp_start_0[] = {
+ {0x0354, 0x00}, {0x03fa, 0x00}, {0xf800, 0x02}, {0xf801, 0xbe},
+ {0xf802, 0xc6}, {0xf804, 0x00}, {0xf808, 0x00}, {0xf809, 0x06},
+ {0xf80a, 0x01}, {0xf80b, 0xfe}, {0xf807, 0x84}, {0xf80c, 0x02},
+ {0xf80d, 0xf7}, {0xf80e, 0x03}, {0xf80f, 0x0b}, {0xf81c, 0x00},
+ {0xf81d, 0x49}, {0xf81e, 0x03}, {0xf81f, 0x0b}, {0xf83a, 0x00},
+ {0xf83b, 0x01}, {0xf83c, 0x00}, {0xf83d, 0x6b}, {0xf810, 0x03},
+ {0xf811, 0x10}, {0xf812, 0x02}, {0xf813, 0x6f}, {0xf803, 0x00},
+ {0xf814, 0x00}, {0xf815, 0x44}, {0xf816, 0x00}, {0xf817, 0x48},
+ {0xf818, 0x00}, {0xf819, 0x25}, {0xf81a, 0x00}, {0xf81b, 0x3c},
+ {0xf82f, 0x03}, {0xf820, 0xff}, {0xf821, 0x0d}, {0xf822, 0xff},
+ {0xf823, 0x07}, {0xf824, 0xfd}, {0xf825, 0x07}, {0xf826, 0xf0},
+ {0xf827, 0x0c}, {0xf828, 0xff}, {0xf829, 0x03}, {0xf82a, 0xff},
+ {0xf82b, 0x0c}, {0xf82c, 0xfc}, {0xf82d, 0x01}, {0xf82e, 0x00},
+ {0xf830, 0x00}, {0xf831, 0x47}, {0xf832, 0x00}, {0xf833, 0x00},
+ {0xf850, 0x00}, {0xf851, 0x00}, {0xf852, 0x00}, {0xf853, 0x24},
+ {0xf854, 0x00}, {0xf855, 0x0c}, {0xf856, 0x00}, {0xf857, 0x30},
+ {0xf858, 0x00}, {0xf859, 0x18}, {0xf85a, 0x00}, {0xf85b, 0x3c},
+ {0xf85c, 0x00}, {0xf85d, 0x18}, {0xf85e, 0x00}, {0xf85f, 0x3c},
+ {0xf860, 0xff}, {0xf861, 0x37}, {0xf862, 0xff}, {0xf863, 0x1d},
+ {0xf864, 0xff}, {0xf865, 0x98}, {0xf866, 0xff}, {0xf867, 0xc0},
+ {0xf868, 0x00}, {0xf869, 0x37}, {0xf86c, 0x02}, {0xf86d, 0x1d},
+ {0xf86a, 0x00}, {0xf86b, 0x37}, {0xf86e, 0x02}, {0xf86f, 0x1d},
+ {0xf870, 0x01}, {0xf871, 0xc6}, {0xf872, 0x02}, {0xf873, 0x04},
+ {0xf874, 0x01}, {0xf875, 0xc6}, {0xf876, 0x02}, {0xf877, 0x04},
+ {0xf878, 0x0f}, {0xf879, 0x0f}, {0xf87a, 0xff}, {0xf87b, 0xff},
+ {0xf800, 0x03}
+};
+static const struct ucbus_write_cmd lz24bp_start_1_gen[] = {
+ {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xb3},
+ {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xb3},
+ {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
+ {0xf5f9, 0x00}
+};
+
+static const struct ucbus_write_cmd lz24bp_start_1_clm[] = {
+ {0xf5f0, 0x00}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
+ {0xf5f4, 0xc0},
+ {0xf5f0, 0x40}, {0xf5f1, 0xff}, {0xf5f2, 0x88}, {0xf5f3, 0x88},
+ {0xf5f4, 0xc0},
+ {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
+ {0xf5f9, 0x00}
+};
+
+static const struct ucbus_write_cmd lz24bp_start_2[] = {
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x80}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x4e}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0xc0}, {0xf806, 0x48},
+ {0xf807, 0x7f}, {0xf800, 0x03},
+ {0xf800, 0x02}, {0xf807, 0xff}, {0xf805, 0x00}, {0xf806, 0x00},
+ {0xf807, 0x7f}, {0xf800, 0x03}
+};
+
+static const struct ucbus_write_cmd mi0360_start_0[] = {
+ {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0xcc}, {0xf333, 0xcc},
+ {0xf334, 0xcc}, {0xf335, 0xcc}, {0xf33f, 0x00}
+};
+static const struct i2c_write_cmd mi0360_init_23[] = {
+ {0x30, 0x0040}, /* reserved - def 0x0005 */
+ {0x31, 0x0000}, /* reserved - def 0x002a */
+ {0x34, 0x0100}, /* reserved - def 0x0100 */
+ {0x3d, 0x068f}, /* reserved - def 0x068f */
+};
+static const struct i2c_write_cmd mi0360_init_24[] = {
+ {0x03, 0x01e5}, /* window height */
+ {0x04, 0x0285}, /* window width */
+};
+static const struct i2c_write_cmd mi0360_init_25[] = {
+ {0x35, 0x0020}, /* global gain */
+ {0x2b, 0x0020}, /* green1 gain */
+ {0x2c, 0x002a}, /* blue gain */
+ {0x2d, 0x0028}, /* red gain */
+ {0x2e, 0x0020}, /* green2 gain */
+};
+static const struct ucbus_write_cmd mi0360_start_1[] = {
+ {0xf5f0, 0x11}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xa6},
+ {0xf5f0, 0x51}, {0xf5f1, 0x99}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xa6},
+ {0xf5fa, 0x00}, {0xf5f6, 0x00}, {0xf5f7, 0x00}, {0xf5f8, 0x00},
+ {0xf5f9, 0x00}
+};
+static const struct i2c_write_cmd mi0360_start_2[] = {
+ {0x62, 0x041d}, /* reserved - def 0x0418 */
+};
+static const struct i2c_write_cmd mi0360_start_3[] = {
+ {0x05, 0x007b}, /* horiz blanking */
+};
+static const struct i2c_write_cmd mi0360_start_4[] = {
+ {0x05, 0x03f5}, /* horiz blanking */
+};
+
+static const struct i2c_write_cmd mt9v111_init_0[] = {
+ {0x01, 0x0001}, /* select IFP/SOC registers */
+ {0x06, 0x300c}, /* operating mode control */
+ {0x08, 0xcc00}, /* output format control (RGB) */
+ {0x01, 0x0004}, /* select core registers */
+};
+static const struct i2c_write_cmd mt9v111_init_1[] = {
+ {0x03, 0x01e5}, /* window height */
+ {0x04, 0x0285}, /* window width */
+};
+static const struct i2c_write_cmd mt9v111_init_2[] = {
+ {0x30, 0x7800},
+ {0x31, 0x0000},
+ {0x07, 0x3002}, /* output control */
+ {0x35, 0x0020}, /* global gain */
+ {0x2b, 0x0020}, /* green1 gain */
+ {0x2c, 0x0020}, /* blue gain */
+ {0x2d, 0x0020}, /* red gain */
+ {0x2e, 0x0020}, /* green2 gain */
+};
+static const struct ucbus_write_cmd mt9v111_start_1[] = {
+ {0xf5f0, 0x11}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xaa},
+ {0xf5f0, 0x51}, {0xf5f1, 0x96}, {0xf5f2, 0x80}, {0xf5f3, 0x80},
+ {0xf5f4, 0xaa},
+ {0xf5fa, 0x00}, {0xf5f6, 0x0a}, {0xf5f7, 0x0a}, {0xf5f8, 0x0a},
+ {0xf5f9, 0x0a}
+};
+static const struct i2c_write_cmd mt9v111_init_3[] = {
+ {0x62, 0x0405},
+};
+static const struct i2c_write_cmd mt9v111_init_4[] = {
+ {0x05, 0x00ce}, /* horizontal blanking */
+};
+
+static const struct ucbus_write_cmd ov7660_start_0[] = {
+ {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0xc0},
+ {0xf334, 0x39}, {0xf335, 0xe7}, {0xf33f, 0x03}
+};
+
+static const struct ucbus_write_cmd ov9630_start_0[] = {
+ {0x0354, 0x00}, {0x03fa, 0x00}, {0xf332, 0x00}, {0xf333, 0x00},
+ {0xf334, 0x3e}, {0xf335, 0xf8}, {0xf33f, 0x03}
+};
+
+static const struct cap_s {
+ u8 cc_sizeid;
+ u8 cc_bytes[32];
+} capconfig[4][3] = {
+ [SENSOR_ICX098BQ] = {
+ {0, /* JPEG, 160x120 */
+ {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41,
+ 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {2, /* JPEG, 320x240 */
+ {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
+ 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {4, /* JPEG, 640x480 */
+ {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
+ 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
+ },
+ [SENSOR_LZ24BP] = {
+ {0, /* JPEG, 160x120 */
+ {0x01, 0x1f, 0x20, 0x0e, 0x00, 0x9f, 0x02, 0xee,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0x8b, 0x00, 0x8b, 0x00, 0x41, 0x01, 0x41,
+ 0x01, 0x41, 0x01, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {2, /* JPEG, 320x240 */
+ {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xee,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
+ 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {4, /* JPEG, 640x480 */
+ {0x01, 0x22, 0x20, 0x0e, 0x00, 0xa2, 0x02, 0xf0,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
+ 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
+ },
+ [SENSOR_MI0360] = {
+ {0, /* JPEG, 160x120 */
+ {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b,
+ 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f,
+ 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} },
+ {2, /* JPEG, 320x240 */
+ {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe1,
+/*fixme 03 e3 */
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
+ 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {4, /* JPEG, 640x480 */
+ {0x01, 0x02, 0x20, 0x01, 0x20, 0x82, 0x02, 0xe3,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
+ 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
+ },
+ [SENSOR_MT9V111] = {
+ {0, /* JPEG, 160x120 */
+ {0x05, 0x3d, 0x20, 0x0b, 0x00, 0xbd, 0x02, 0x0b,
+ 0x02, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x9f, 0x00, 0x9f,
+ 0x00, 0x9f, 0x01, 0x05, 0xa0, 0x00, 0x80, 0x00} },
+ {2, /* JPEG, 320x240 */
+ {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x02, 0xdf, 0x01, 0x00, 0x00, 0x3f, 0x01, 0x3f,
+ 0x01, 0x00, 0x00, 0x05, 0x40, 0x01, 0xf0, 0x00} },
+ {4, /* JPEG, 640x480 */
+ {0x01, 0x02, 0x20, 0x03, 0x20, 0x82, 0x02, 0xe3,
+ 0x01, 0x02, 0x00, 0x08, 0x18, 0x12, 0x78, 0xc8,
+ 0x07, 0xe1, 0x01, 0xe1, 0x01, 0x3f, 0x01, 0x3f,
+ 0x01, 0x3f, 0x01, 0x05, 0x80, 0x02, 0xe0, 0x01} },
+ },
+};
+
+struct sensor_s {
+ const char *name;
+ u8 i2c_addr;
+ u8 i2c_dum;
+ u8 gpio[5];
+ u8 cmd_len;
+ const struct ucbus_write_cmd *cmd;
+};
+
+static const struct sensor_s sensor_tb[] = {
+ [SENSOR_ICX098BQ] = {
+ "icx098bp",
+ 0x00, 0x00,
+ {0,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ SQ930_GPIO_RSTBAR
+ },
+ 8, icx098bq_start_0
+ },
+ [SENSOR_LZ24BP] = {
+ "lz24bp",
+ 0x00, 0x00,
+ {0,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ SQ930_GPIO_RSTBAR
+ },
+ 8, lz24bp_start_0
+ },
+ [SENSOR_MI0360] = {
+ "mi0360",
+ 0x5d, 0x80,
+ {SQ930_GPIO_RSTBAR,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ 0
+ },
+ 7, mi0360_start_0
+ },
+ [SENSOR_MT9V111] = {
+ "mt9v111",
+ 0x5c, 0x7f,
+ {SQ930_GPIO_RSTBAR,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ 0
+ },
+ 7, mi0360_start_0
+ },
+ [SENSOR_OV7660] = {
+ "ov7660",
+ 0x21, 0x00,
+ {0,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ SQ930_GPIO_RSTBAR
+ },
+ 7, ov7660_start_0
+ },
+ [SENSOR_OV9630] = {
+ "ov9630",
+ 0x30, 0x00,
+ {0,
+ SQ930_GPIO_DFL_I2C_SDA | SQ930_GPIO_DFL_I2C_SCL,
+ SQ930_GPIO_DFL_I2C_SDA,
+ 0,
+ SQ930_GPIO_RSTBAR
+ },
+ 7, ov9630_start_0
+ },
+};
+
+static void reg_r(struct gspca_dev *gspca_dev,
+ u16 value, int len)
+{
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_rcvctrlpipe(gspca_dev->dev, 0),
+ 0x0c,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, 0, gspca_dev->usb_buf, len,
+ 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r %04x failed %d", value, ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void reg_w(struct gspca_dev *gspca_dev, u16 value, u16 index)
+{
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ PDEBUG(D_USBO, "reg_w v: %04x i: %04x", value, index);
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x0c, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, NULL, 0,
+ 500);
+ msleep(30);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w %04x %04x failed %d", value, index, ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void reg_wb(struct gspca_dev *gspca_dev, u16 value, u16 index,
+ const u8 *data, int len)
+{
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ PDEBUG(D_USBO, "reg_wb v: %04x i: %04x %02x...%02x",
+ value, index, *data, data[len - 1]);
+ memcpy(gspca_dev->usb_buf, data, len);
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x0c, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ value, index, gspca_dev->usb_buf, len,
+ 1000);
+ msleep(30);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_wb %04x %04x failed %d", value, index, ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void i2c_write(struct sd *sd,
+ const struct i2c_write_cmd *cmd,
+ int ncmds)
+{
+ struct gspca_dev *gspca_dev = &sd->gspca_dev;
+ const struct sensor_s *sensor;
+ u16 val, idx;
+ u8 *buf;
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+
+ sensor = &sensor_tb[sd->sensor];
+
+ val = (sensor->i2c_addr << 8) | SQ930_CTRL_I2C_IO;
+ idx = (cmd->val & 0xff00) | cmd->reg;
+
+ buf = gspca_dev->usb_buf;
+ *buf++ = sensor->i2c_dum;
+ *buf++ = cmd->val;
+
+ while (--ncmds > 0) {
+ cmd++;
+ *buf++ = cmd->reg;
+ *buf++ = cmd->val >> 8;
+ *buf++ = sensor->i2c_dum;
+ *buf++ = cmd->val;
+ }
+
+ PDEBUG(D_USBO, "i2c_w v: %04x i: %04x %02x...%02x",
+ val, idx, gspca_dev->usb_buf[0], buf[-1]);
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x0c, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ val, idx,
+ gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
+ 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "i2c_write failed %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+
+static void ucbus_write(struct gspca_dev *gspca_dev,
+ const struct ucbus_write_cmd *cmd,
+ int ncmds,
+ int batchsize)
+{
+ u8 *buf;
+ u16 val, idx;
+ int len, ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+
+#ifdef GSPCA_DEBUG
+ if ((batchsize - 1) * 3 > USB_BUF_SZ) {
+ err("Bug: usb_buf overflow");
+ gspca_dev->usb_err = -ENOMEM;
+ return;
+ }
+#endif
+
+ for (;;) {
+ len = ncmds;
+ if (len > batchsize)
+ len = batchsize;
+ ncmds -= len;
+
+ val = (cmd->bw_addr << 8) | SQ930_CTRL_UCBUS_IO;
+ idx = (cmd->bw_data << 8) | (cmd->bw_addr >> 8);
+
+ buf = gspca_dev->usb_buf;
+ while (--len > 0) {
+ cmd++;
+ *buf++ = cmd->bw_addr;
+ *buf++ = cmd->bw_addr >> 8;
+ *buf++ = cmd->bw_data;
+ }
+ if (buf != gspca_dev->usb_buf)
+ PDEBUG(D_USBO, "ucbus v: %04x i: %04x %02x...%02x",
+ val, idx,
+ gspca_dev->usb_buf[0], buf[-1]);
+ else
+ PDEBUG(D_USBO, "ucbus v: %04x i: %04x",
+ val, idx);
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x0c, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ val, idx,
+ gspca_dev->usb_buf, buf - gspca_dev->usb_buf,
+ 500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "ucbus_write failed %d", ret);
+ gspca_dev->usb_err = ret;
+ return;
+ }
+ msleep(30);
+ if (ncmds <= 0)
+ break;
+ cmd++;
+ }
+}
+
+static void gpio_set(struct sd *sd, u16 val, u16 mask)
+{
+ struct gspca_dev *gspca_dev = &sd->gspca_dev;
+
+ if (mask & 0x00ff) {
+ sd->gpio[0] &= ~mask;
+ sd->gpio[0] |= val;
+ reg_w(gspca_dev, 0x0100 | SQ930_CTRL_GPIO,
+ ~sd->gpio[0] << 8);
+ }
+ mask >>= 8;
+ val >>= 8;
+ if (mask) {
+ sd->gpio[1] &= ~mask;
+ sd->gpio[1] |= val;
+ reg_w(gspca_dev, 0x0300 | SQ930_CTRL_GPIO,
+ ~sd->gpio[1] << 8);
+ }
+}
+
+static void gpio_init(struct sd *sd,
+ const u8 *gpio)
+{
+ gpio_set(sd, *gpio++, 0x000f);
+ gpio_set(sd, *gpio++, 0x000f);
+ gpio_set(sd, *gpio++, 0x000f);
+ gpio_set(sd, *gpio++, 0x000f);
+ gpio_set(sd, *gpio, 0x000f);
+}
+
+static void bridge_init(struct sd *sd)
+{
+ static const struct ucbus_write_cmd clkfreq_cmd = {
+ 0xf031, 0 /* SQ930_CLKFREQ_60MHZ */
+ };
+
+ ucbus_write(&sd->gspca_dev, &clkfreq_cmd, 1, 1);
+
+ gpio_set(sd, SQ930_GPIO_POWER, 0xff00);
+}
+
+static void cmos_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ const struct sensor_s *sensor;
+ static const u8 probe_order[] = {
+/* SENSOR_LZ24BP, (tested as ccd) */
+ SENSOR_OV9630,
+ SENSOR_MI0360,
+ SENSOR_OV7660,
+ SENSOR_MT9V111,
+ };
+
+ for (i = 0; i < ARRAY_SIZE(probe_order); i++) {
+ sensor = &sensor_tb[probe_order[i]];
+ ucbus_write(&sd->gspca_dev, sensor->cmd, sensor->cmd_len, 8);
+ gpio_init(sd, sensor->gpio);
+ msleep(100);
+ reg_r(gspca_dev, (sensor->i2c_addr << 8) | 0x001c, 1);
+ msleep(100);
+ if (gspca_dev->usb_buf[0] != 0)
+ break;
+ }
+ if (i >= ARRAY_SIZE(probe_order))
+ PDEBUG(D_PROBE, "Unknown sensor");
+ else
+ sd->sensor = probe_order[i];
+}
+
+static void mt9v111_init(struct gspca_dev *gspca_dev)
+{
+ int i, nwait;
+ static const u8 cmd_001b[] = {
+ 0x00, 0x3b, 0xf6, 0x01, 0x03, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00
+ };
+ static const u8 cmd_011b[][7] = {
+ {0x10, 0x01, 0x66, 0x08, 0x00, 0x00, 0x00},
+ {0x01, 0x00, 0x1a, 0x04, 0x00, 0x00, 0x00},
+ {0x20, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00},
+ {0x02, 0x01, 0xae, 0x01, 0x00, 0x00, 0x00},
+ };
+
+ reg_wb(gspca_dev, 0x001b, 0x0000, cmd_001b, sizeof cmd_001b);
+ for (i = 0; i < ARRAY_SIZE(cmd_011b); i++) {
+ reg_wb(gspca_dev, 0x001b, 0x0000, cmd_011b[i],
+ ARRAY_SIZE(cmd_011b[0]));
+ msleep(400);
+ nwait = 20;
+ for (;;) {
+ reg_r(gspca_dev, 0x031b, 1);
+ if (gspca_dev->usb_buf[0] == 0
+ || gspca_dev->usb_err != 0)
+ break;
+ if (--nwait < 0) {
+ PDEBUG(D_PROBE, "mt9v111_init timeout");
+ gspca_dev->usb_err = -ETIME;
+ return;
+ }
+ msleep(50);
+ }
+ }
+}
+
+static void global_init(struct sd *sd, int first_time)
+{
+ switch (sd->sensor) {
+ case SENSOR_ICX098BQ:
+ if (first_time)
+ ucbus_write(&sd->gspca_dev,
+ icx098bq_start_0,
+ 8, 8);
+ gpio_init(sd, sensor_tb[sd->sensor].gpio);
+ break;
+ case SENSOR_LZ24BP:
+ if (sd->type != Creative_live_motion)
+ gpio_set(sd, SQ930_GPIO_EXTRA1, 0x00ff);
+ else
+ gpio_set(sd, 0, 0x00ff);
+ msleep(50);
+ if (first_time)
+ ucbus_write(&sd->gspca_dev,
+ lz24bp_start_0,
+ 8, 8);
+ gpio_init(sd, sensor_tb[sd->sensor].gpio);
+ break;
+ case SENSOR_MI0360:
+ if (first_time)
+ ucbus_write(&sd->gspca_dev,
+ mi0360_start_0,
+ ARRAY_SIZE(mi0360_start_0),
+ 8);
+ gpio_init(sd, sensor_tb[sd->sensor].gpio);
+ gpio_set(sd, SQ930_GPIO_EXTRA2, SQ930_GPIO_EXTRA2);
+ break;
+ default:
+/* case SENSOR_MT9V111: */
+ if (first_time)
+ mt9v111_init(&sd->gspca_dev);
+ else
+ gpio_init(sd, sensor_tb[sd->sensor].gpio);
+ break;
+ }
+}
+
+static void lz24bp_ppl(struct sd *sd, u16 ppl)
+{
+ struct ucbus_write_cmd cmds[2] = {
+ {0xf810, ppl >> 8},
+ {0xf811, ppl}
+ };
+
+ ucbus_write(&sd->gspca_dev, cmds, ARRAY_SIZE(cmds), 2);
+}
+
+static void setexposure(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, integclks, intstartclk, frameclks, min_frclk;
+ const struct sensor_s *sensor;
+ u16 cmd;
+ u8 buf[15];
+
+ integclks = sd->expo;
+ i = 0;
+ cmd = SQ930_CTRL_SET_EXPOSURE;
+
+ switch (sd->sensor) {
+ case SENSOR_ICX098BQ: /* ccd */
+ case SENSOR_LZ24BP:
+ min_frclk = sd->sensor == SENSOR_ICX098BQ ? 0x210 : 0x26f;
+ if (integclks >= min_frclk) {
+ intstartclk = 0;
+ frameclks = integclks;
+ } else {
+ intstartclk = min_frclk - integclks;
+ frameclks = min_frclk;
+ }
+ buf[i++] = intstartclk >> 8;
+ buf[i++] = intstartclk;
+ buf[i++] = frameclks >> 8;
+ buf[i++] = frameclks;
+ buf[i++] = sd->gain;
+ break;
+ default: /* cmos */
+/* case SENSOR_MI0360: */
+/* case SENSOR_MT9V111: */
+ cmd |= 0x0100;
+ sensor = &sensor_tb[sd->sensor];
+ buf[i++] = sensor->i2c_addr; /* i2c_slave_addr */
+ buf[i++] = 0x08; /* 2 * ni2c */
+ buf[i++] = 0x09; /* reg = shutter width */
+ buf[i++] = integclks >> 8; /* val H */
+ buf[i++] = sensor->i2c_dum;
+ buf[i++] = integclks; /* val L */
+ buf[i++] = 0x35; /* reg = global gain */
+ buf[i++] = 0x00; /* val H */
+ buf[i++] = sensor->i2c_dum;
+ buf[i++] = sd->gain; /* val L */
+ buf[i++] = 0x00;
+ buf[i++] = 0x00;
+ buf[i++] = 0x00;
+ buf[i++] = 0x00;
+ buf[i++] = 0x83;
+ break;
+ }
+ reg_wb(gspca_dev, cmd, 0, buf, i);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct cam *cam = &gspca_dev->cam;
+
+ sd->sensor = id->driver_info >> 8;
+ sd->type = id->driver_info;
+
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+
+ cam->bulk = 1;
+ cam->bulk_size = BULK_TRANSFER_LEN;
+/* cam->bulk_nurbs = 2; fixme: if no setexpo sync */
+
+ sd->quality = QUALITY_DEF;
+ sd->gain = GAIN_DEF;
+ sd->expo = EXPO_DEF;
+
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gpio[0] = sd->gpio[1] = 0xff; /* force gpio rewrite */
+
+/*fixme: is this needed for icx098bp and mi0360?
+ if (sd->sensor != SENSOR_LZ24BP)
+ reg_w(gspca_dev, SQ930_CTRL_RESET, 0x0000);
+ */
+
+ reg_r(gspca_dev, SQ930_CTRL_GET_DEV_INFO, 8);
+/* it returns:
+ * 03 00 12 93 0b f6 c9 00 live! ultra
+ * 03 00 07 93 0b f6 ca 00 live! ultra for notebook
+ * 03 00 12 93 0b fe c8 00 Trust WB-3500T
+ * 02 00 06 93 0b fe c8 00 Joy-IT 318S
+ * 03 00 12 93 0b f6 cf 00 icam tracer - sensor icx098bq
+ * 02 00 12 93 0b fe cf 00 ProQ Motion Webcam
+ *
+ * byte
+ * 0: 02 = usb 1.0 (12Mbit) / 03 = usb2.0 (480Mbit)
+ * 1: 00
+ * 2: 06 / 07 / 12 = mode webcam? firmware??
+ * 3: 93 chip = 930b (930b or 930c)
+ * 4: 0b
+ * 5: f6 = cdd (icx098bq, lz24bp) / fe or de = cmos (i2c) (other sensors)
+ * 6: c8 / c9 / ca / cf = mode webcam?, sensor? webcam?
+ * 7: 00
+ */
+ PDEBUG(D_PROBE, "info: %02x %02x %02x %02x %02x %02x %02x %02x",
+ gspca_dev->usb_buf[0],
+ gspca_dev->usb_buf[1],
+ gspca_dev->usb_buf[2],
+ gspca_dev->usb_buf[3],
+ gspca_dev->usb_buf[4],
+ gspca_dev->usb_buf[5],
+ gspca_dev->usb_buf[6],
+ gspca_dev->usb_buf[7]);
+
+ bridge_init(sd);
+
+ if (sd->sensor == SENSOR_MI0360) {
+
+ /* no sensor probe for icam tracer */
+ if (gspca_dev->usb_buf[5] == 0xf6) { /* if CMOS */
+ sd->sensor = SENSOR_ICX098BQ;
+ gspca_dev->cam.cam_mode = &vga_mode[1];
+ gspca_dev->cam.nmodes = 1; /* only 320x240 */
+ } else {
+ cmos_probe(gspca_dev);
+ }
+ }
+
+ PDEBUG(D_PROBE, "Sensor %s", sensor_tb[sd->sensor].name);
+
+ global_init(sd, 1);
+ return gspca_dev->usb_err;
+}
+
+/* special function to create the quantization tables of the JPEG header */
+static void sd_jpeg_set_qual(u8 *jpeg_hdr,
+ int quality)
+{
+ int i, sc1, sc2;
+
+ quality = quality_tb[quality]; /* convert to JPEG quality */
+/*
+ * approximative qualities for Y and U/V:
+ * quant = 0:94%/91% 1:91%/87% 2:82%/73% 3:69%/56%
+ * should have:
+ * quant = 0:94%/91% 1:91%/87.5% 2:81.5%/72% 3:69%/54.5%
+ */
+ sc1 = 200 - quality * 2;
+ quality = quality * 7 / 5 - 40; /* UV quality */
+ sc2 = 200 - quality * 2;
+ for (i = 0; i < 64; i++) {
+ jpeg_hdr[JPEG_QT0_OFFSET + i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc1 + 50) / 100;
+ jpeg_hdr[JPEG_QT1_OFFSET + i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc2 + 50) / 100;
+ }
+}
+
+/* send the start/stop commands to the webcam */
+static void send_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ const struct cap_s *cap;
+ int mode, quality;
+
+ mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+ cap = &capconfig[sd->sensor][mode];
+ quality = sd->quality;
+ reg_wb(gspca_dev, (quality << 12)
+ | 0x0a00 /* 900 for Bayer */
+ | SQ930_CTRL_CAP_START,
+ 0x0500 /* a00 for Bayer */
+ | cap->cc_sizeid,
+ cap->cc_bytes, 32);
+};
+static void send_stop(struct gspca_dev *gspca_dev)
+{
+ reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0);
+};
+
+/* function called at start time before URB creation */
+static int sd_isoc_init(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ gspca_dev->cam.bulk_nurbs = 1; /* there must be one URB only */
+ sd->do_ctrl = 0;
+ return 0;
+}
+
+/* start the capture */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int mode;
+
+ /* initialize the JPEG header */
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
+ bridge_init(sd);
+ global_init(sd, 0);
+ msleep(100);
+
+ switch (sd->sensor) {
+ case SENSOR_ICX098BQ:
+ ucbus_write(gspca_dev, icx098bq_start_0,
+ ARRAY_SIZE(icx098bq_start_0),
+ 8);
+ ucbus_write(gspca_dev, icx098bq_start_1,
+ ARRAY_SIZE(icx098bq_start_1),
+ 5);
+ ucbus_write(gspca_dev, icx098bq_start_2,
+ ARRAY_SIZE(icx098bq_start_2),
+ 6);
+ msleep(50);
+
+ /* 1st start */
+ send_start(gspca_dev);
+ gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
+ msleep(70);
+ reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
+ gpio_set(sd, 0x7f, 0x00ff);
+
+ /* 2nd start */
+ send_start(gspca_dev);
+ gpio_set(sd, SQ930_GPIO_EXTRA2 | SQ930_GPIO_RSTBAR, 0x00ff);
+ goto out;
+ case SENSOR_LZ24BP:
+ ucbus_write(gspca_dev, lz24bp_start_0,
+ ARRAY_SIZE(lz24bp_start_0),
+ 8);
+ if (sd->type != Creative_live_motion)
+ ucbus_write(gspca_dev, lz24bp_start_1_gen,
+ ARRAY_SIZE(lz24bp_start_1_gen),
+ 5);
+ else
+ ucbus_write(gspca_dev, lz24bp_start_1_clm,
+ ARRAY_SIZE(lz24bp_start_1_clm),
+ 5);
+ ucbus_write(gspca_dev, lz24bp_start_2,
+ ARRAY_SIZE(lz24bp_start_2),
+ 6);
+ mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+ lz24bp_ppl(sd, mode == 2 ? 0x0564 : 0x0310);
+ msleep(10);
+ break;
+ case SENSOR_MI0360:
+ ucbus_write(gspca_dev, mi0360_start_0,
+ ARRAY_SIZE(mi0360_start_0),
+ 8);
+ i2c_write(sd, mi0360_init_23,
+ ARRAY_SIZE(mi0360_init_23));
+ i2c_write(sd, mi0360_init_24,
+ ARRAY_SIZE(mi0360_init_24));
+ i2c_write(sd, mi0360_init_25,
+ ARRAY_SIZE(mi0360_init_25));
+ ucbus_write(gspca_dev, mi0360_start_1,
+ ARRAY_SIZE(mi0360_start_1),
+ 5);
+ i2c_write(sd, mi0360_start_2,
+ ARRAY_SIZE(mi0360_start_2));
+ i2c_write(sd, mi0360_start_3,
+ ARRAY_SIZE(mi0360_start_3));
+
+ /* 1st start */
+ send_start(gspca_dev);
+ msleep(60);
+ reg_w(gspca_dev, SQ930_CTRL_CAP_STOP, 0x0000);
+
+ i2c_write(sd,
+ mi0360_start_4, ARRAY_SIZE(mi0360_start_4));
+ break;
+ default:
+/* case SENSOR_MT9V111: */
+ ucbus_write(gspca_dev, mi0360_start_0,
+ ARRAY_SIZE(mi0360_start_0),
+ 8);
+ i2c_write(sd, mt9v111_init_0,
+ ARRAY_SIZE(mt9v111_init_0));
+ i2c_write(sd, mt9v111_init_1,
+ ARRAY_SIZE(mt9v111_init_1));
+ i2c_write(sd, mt9v111_init_2,
+ ARRAY_SIZE(mt9v111_init_2));
+ ucbus_write(gspca_dev, mt9v111_start_1,
+ ARRAY_SIZE(mt9v111_start_1),
+ 8);
+ i2c_write(sd, mt9v111_init_3,
+ ARRAY_SIZE(mt9v111_init_3));
+ i2c_write(sd, mt9v111_init_4,
+ ARRAY_SIZE(mt9v111_init_4));
+ break;
+ }
+
+ send_start(gspca_dev);
+out:
+ msleep(1000);
+
+ sd->eof_len = 0; /* init packet scan */
+
+ if (sd->sensor == SENSOR_MT9V111)
+ gpio_set(sd, SQ930_GPIO_DFL_LED, SQ930_GPIO_DFL_LED);
+
+ sd->do_ctrl = 1; /* set the exposure */
+
+ return gspca_dev->usb_err;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (sd->sensor == SENSOR_MT9V111)
+ gpio_set(sd, 0, SQ930_GPIO_DFL_LED);
+ send_stop(gspca_dev);
+}
+
+/* function called when the application gets a new frame */
+/* It sets the exposure if required and restart the bulk transfer. */
+static void sd_dq_callback(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int ret;
+
+ if (!sd->do_ctrl || gspca_dev->cam.bulk_nurbs != 0)
+ return;
+ sd->do_ctrl = 0;
+
+ setexposure(gspca_dev);
+
+ gspca_dev->cam.bulk_nurbs = 1;
+ ret = usb_submit_urb(gspca_dev->urb[0], GFP_ATOMIC);
+ if (ret < 0)
+ PDEBUG(D_ERR|D_PACK, "sd_dq_callback() err %d", ret);
+
+ /* wait a little time, otherwise the webcam crashes */
+ msleep(100);
+}
+
+/* move a packet adding 0x00 after 0xff */
+static void add_packet(struct gspca_dev *gspca_dev,
+ u8 *data,
+ int len)
+{
+ int i;
+
+ i = 0;
+ do {
+ if (data[i] == 0xff) {
+ gspca_frame_add(gspca_dev, INTER_PACKET,
+ data, i + 1);
+ len -= i;
+ data += i;
+ *data = 0x00;
+ i = 0;
+ }
+ } while (++i < len);
+ gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+}
+
+/* end a frame and start a new one */
+static void eof_sof(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ static const u8 ffd9[] = {0xff, 0xd9};
+
+ /* if control set, stop bulk transfer */
+ if (sd->do_ctrl
+ && gspca_dev->last_packet_type == INTER_PACKET)
+ gspca_dev->cam.bulk_nurbs = 0;
+ gspca_frame_add(gspca_dev, LAST_PACKET,
+ ffd9, 2);
+ gspca_frame_add(gspca_dev, FIRST_PACKET,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 *p;
+ int l;
+
+ len -= 8; /* ignore last 8 bytes (00 00 55 aa 55 aa 00 00) */
+
+ /*
+ * the end/start of frame is indicated by
+ * 0x00 * 16 - 0xab * 8
+ * aligned on 8 bytes boundary
+ */
+ if (sd->eof_len != 0) { /* if 'abababab' in previous pkt */
+ if (*((u32 *) data) == 0xabababab) {
+ /*fixme: should remove previous 0000ababab*/
+ eof_sof(gspca_dev);
+ data += 4;
+ len -= 4;
+ }
+ sd->eof_len = 0;
+ }
+ p = data;
+ l = len;
+ for (;;) {
+ if (*((u32 *) p) == 0xabababab) {
+ if (l < 8) { /* (may be 4 only) */
+ sd->eof_len = 1;
+ break;
+ }
+ if (*((u32 *) p + 1) == 0xabababab) {
+ add_packet(gspca_dev, data, p - data - 16);
+ /* remove previous zeros */
+ eof_sof(gspca_dev);
+ p += 8;
+ l -= 8;
+ if (l <= 0)
+ return;
+ len = l;
+ data = p;
+ continue;
+ }
+ }
+ p += 4;
+ l -= 4;
+ if (l <= 0)
+ break;
+ }
+ add_packet(gspca_dev, data, len);
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gain = val;
+ if (gspca_dev->streaming)
+ sd->do_ctrl = 1;
+ return 0;
+}
+
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gain;
+ return 0;
+}
+static int sd_setexpo(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->expo = val;
+ if (gspca_dev->streaming)
+ sd->do_ctrl = 1;
+ return 0;
+}
+
+static int sd_getexpo(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->expo;
+ return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int quality;
+
+ if (jcomp->quality >= (QUAL_0 + QUAL_1) / 2)
+ quality = 0;
+ else if (jcomp->quality >= (QUAL_1 + QUAL_2) / 2)
+ quality = 1;
+ else if (jcomp->quality >= (QUAL_2 + QUAL_3) / 2)
+ quality = 2;
+ else
+ quality = 3;
+
+ if (quality != sd->quality) {
+ sd->quality = quality;
+ if (gspca_dev->streaming) {
+ send_stop(gspca_dev);
+ sd_jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ msleep(70);
+ send_start(gspca_dev);
+ }
+ }
+ return gspca_dev->usb_err;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = quality_tb[sd->quality];
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .isoc_init = sd_isoc_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+ .dq_callback = sd_dq_callback,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
+};
+
+/* Table of supported USB devices */
+#define ST(sensor, type) \
+ .driver_info = (SENSOR_ ## sensor << 8) \
+ | (type)
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x4038), ST(MI0360, 0)},
+ {USB_DEVICE(0x041e, 0x403c), ST(LZ24BP, 0)},
+ {USB_DEVICE(0x041e, 0x403d), ST(LZ24BP, 0)},
+ {USB_DEVICE(0x041e, 0x4041), ST(LZ24BP, Creative_live_motion)},
+ {USB_DEVICE(0x2770, 0x930b), ST(MI0360, 0)},
+ {USB_DEVICE(0x2770, 0x930c), ST(MI0360, 0)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ info("registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ info("deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 0fb534210a2c..2aedf4b1bfa3 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -36,11 +36,11 @@ struct sd {
unsigned char colors;
unsigned char lightfreq;
u8 quality;
-#define QUALITY_MIN 60
+#define QUALITY_MIN 70
#define QUALITY_MAX 95
-#define QUALITY_DEF 80
+#define QUALITY_DEF 88
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
@@ -337,9 +337,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int ret, value;
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x22); /* JPEG 411 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -412,13 +409,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "camera stopped");
}
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- kfree(sd->jpeg_hdr);
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
@@ -578,7 +568,6 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
- .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
.get_jcomp = sd_get_jcomp,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.h b/drivers/media/video/gspca/stv06xx/stv06xx.h
index 992ce530f138..053a27e3a400 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.h
@@ -30,6 +30,7 @@
#ifndef STV06XX_H_
#define STV06XX_H_
+#include <linux/slab.h>
#include "gspca.h"
#define MODULE_NAME "STV06xx"
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 0c786e00ebcf..21d82bab0c2e 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -54,7 +54,7 @@ struct sd {
#define MegapixV4 4
#define MegaImageVI 5
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
@@ -842,9 +842,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
int enable;
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x22); /* JPEG 411 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -954,13 +951,6 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- kfree(sd->jpeg_hdr);
-}
-
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
@@ -1162,7 +1152,6 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
- .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.get_jcomp = sd_get_jcomp,
.set_jcomp = sd_set_jcomp,
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 63014372adbc..2a0f12d55e48 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -1,5 +1,7 @@
/*
- * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
+ * T613 subdriver
+ *
+ * Copyright (C) 2010 Jean-Francois Moine (http://moinejf.free.fr)
*
* 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
@@ -26,6 +28,7 @@
#define MODULE_NAME "t613"
+#include <linux/slab.h>
#include "gspca.h"
#define V4L2_CID_EFFECTS (V4L2_CID_PRIVATE_BASE + 0)
@@ -44,18 +47,20 @@ struct sd {
u8 gamma;
u8 sharpness;
u8 freq;
- u8 red_balance; /* split balance */
- u8 blue_balance;
- u8 global_gain; /* aka gain */
- u8 whitebalance; /* set default r/g/b and activate */
+ u8 red_gain;
+ u8 blue_gain;
+ u8 green_gain;
+ u8 awb; /* set default r/g/b and activate */
u8 mirror;
u8 effect;
u8 sensor;
-#define SENSOR_OM6802 0
-#define SENSOR_OTHER 1
-#define SENSOR_TAS5130A 2
-#define SENSOR_LT168G 3 /* must verify if this is the actual model */
+enum {
+ SENSOR_OM6802,
+ SENSOR_OTHER,
+ SENSOR_TAS5130A,
+ SENSOR_LT168G, /* must verify if this is the actual model */
+} sensors;
};
/* V4L2 controls supported by the driver */
@@ -74,24 +79,22 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
-
-static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val);
-
-static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
+
+static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu);
-
static const struct ctrl sd_ctrls[] = {
{
{
@@ -177,8 +180,8 @@ static const struct ctrl sd_ctrls[] = {
#define MIRROR_DEF 0
.default_value = MIRROR_DEF,
},
- .set = sd_setflip,
- .get = sd_getflip
+ .set = sd_setmirror,
+ .get = sd_getmirror
},
{
{
@@ -198,15 +201,15 @@ static const struct ctrl sd_ctrls[] = {
{
.id = V4L2_CID_AUTO_WHITE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "White Balance",
+ .name = "Auto White Balance",
.minimum = 0,
.maximum = 1,
.step = 1,
-#define WHITE_BALANCE_DEF 0
- .default_value = WHITE_BALANCE_DEF,
+#define AWB_DEF 0
+ .default_value = AWB_DEF,
},
- .set = sd_setwhitebalance,
- .get = sd_getwhitebalance
+ .set = sd_setawb,
+ .get = sd_getawb
},
{
{
@@ -244,11 +247,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0x10,
.maximum = 0x40,
.step = 1,
-#define BLUE_BALANCE_DEF 0x20
- .default_value = BLUE_BALANCE_DEF,
+#define BLUE_GAIN_DEF 0x20
+ .default_value = BLUE_GAIN_DEF,
},
- .set = sd_setblue_balance,
- .get = sd_getblue_balance,
+ .set = sd_setblue_gain,
+ .get = sd_getblue_gain,
},
{
{
@@ -258,11 +261,11 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0x10,
.maximum = 0x40,
.step = 1,
-#define RED_BALANCE_DEF 0x20
- .default_value = RED_BALANCE_DEF,
+#define RED_GAIN_DEF 0x20
+ .default_value = RED_GAIN_DEF,
},
- .set = sd_setred_balance,
- .get = sd_getred_balance,
+ .set = sd_setred_gain,
+ .get = sd_getred_gain,
},
{
{
@@ -272,24 +275,14 @@ static const struct ctrl sd_ctrls[] = {
.minimum = 0x10,
.maximum = 0x40,
.step = 1,
-#define global_gain_DEF 0x20
- .default_value = global_gain_DEF,
+#define GAIN_DEF 0x20
+ .default_value = GAIN_DEF,
},
- .set = sd_setglobal_gain,
- .get = sd_getglobal_gain,
+ .set = sd_setgain,
+ .get = sd_getgain,
},
};
-static char *effects_control[] = {
- "Normal",
- "Emboss", /* disabled */
- "Monochrome",
- "Sepia",
- "Sketch",
- "Sun Effect", /* disabled */
- "Negative",
-};
-
static const struct v4l2_pix_format vga_mode_t16[] = {
{160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 160,
@@ -327,7 +320,6 @@ struct additional_sensor_data {
const u8 data1[10];
const u8 data2[9];
const u8 data3[9];
- const u8 data4[4];
const u8 data5[6];
const u8 stream[4];
};
@@ -375,7 +367,7 @@ static const u8 n4_lt168g[] = {
};
static const struct additional_sensor_data sensor_data[] = {
- { /* 0: OM6802 */
+[SENSOR_OM6802] = {
.n3 =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04},
.n4 = n4_om6802,
@@ -392,14 +384,12 @@ static const struct additional_sensor_data sensor_data[] = {
.data3 =
{0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
0xff},
- .data4 = /*Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0xca, 0xa8, 0xf0},
.data5 = /* this could be removed later */
{0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
.stream =
{0x0b, 0x04, 0x0a, 0x78},
},
- { /* 1: OTHER */
+[SENSOR_OTHER] = {
.n3 =
{0x61, 0xc2, 0x65, 0x88, 0x60, 0x00},
.n4 = n4_other,
@@ -416,14 +406,12 @@ static const struct additional_sensor_data sensor_data[] = {
.data3 =
{0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
0xd9},
- .data4 =
- {0x66, 0x00, 0xa8, 0xa8},
.data5 =
{0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
.stream =
{0x0b, 0x04, 0x0a, 0x00},
},
- { /* 2: TAS5130A */
+[SENSOR_TAS5130A] = {
.n3 =
{0x61, 0xc2, 0x65, 0x0d, 0x60, 0x08},
.n4 = n4_tas5130a,
@@ -440,14 +428,12 @@ static const struct additional_sensor_data sensor_data[] = {
.data3 =
{0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
0xe0},
- .data4 = /* Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0x00, 0xa8, 0xe8},
.data5 =
{0x0c, 0x03, 0xab, 0x10, 0x81, 0x20},
.stream =
{0x0b, 0x04, 0x0a, 0x40},
},
- { /* 3: LT168G */
+[SENSOR_LT168G] = {
.n3 = {0x61, 0xc2, 0x65, 0x68, 0x60, 0x00},
.n4 = n4_lt168g,
.n4sz = sizeof n4_lt168g,
@@ -460,7 +446,6 @@ static const struct additional_sensor_data sensor_data[] = {
0xff},
.data3 = {0x40, 0x80, 0xc0, 0x50, 0xa0, 0xf0, 0x53, 0xa6,
0xff},
- .data4 = {0x66, 0x41, 0xa8, 0xf0},
.data5 = {0x0c, 0x03, 0xab, 0x4b, 0x81, 0x2b},
.stream = {0x0b, 0x04, 0x0a, 0x28},
},
@@ -469,6 +454,15 @@ static const struct additional_sensor_data sensor_data[] = {
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
+static char *effects_control[MAX_EFFECTS] = {
+ "Normal",
+ "Emboss", /* disabled */
+ "Monochrome",
+ "Sepia",
+ "Sketch",
+ "Sun Effect", /* disabled */
+ "Negative",
+};
static const u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
@@ -480,40 +474,41 @@ static const u8 effects_table[MAX_EFFECTS][6] = {
};
static const u8 gamma_table[GAMMA_MAX][17] = {
- {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
- 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+/* gamma table from cam1690.ini */
+ {0x00, 0x00, 0x01, 0x04, 0x08, 0x0e, 0x16, 0x21, /* 0 */
+ 0x2e, 0x3d, 0x50, 0x65, 0x7d, 0x99, 0xb8, 0xdb,
0xff},
- {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
- 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+ {0x00, 0x01, 0x03, 0x08, 0x0e, 0x16, 0x21, 0x2d, /* 1 */
+ 0x3c, 0x4d, 0x60, 0x75, 0x8d, 0xa6, 0xc2, 0xe1,
0xff},
- {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
- 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+ {0x00, 0x01, 0x05, 0x0b, 0x12, 0x1c, 0x28, 0x35, /* 2 */
+ 0x45, 0x56, 0x69, 0x7e, 0x95, 0xad, 0xc7, 0xe3,
0xff},
- {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
- 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ {0x00, 0x02, 0x07, 0x0f, 0x18, 0x24, 0x30, 0x3f, /* 3 */
+ 0x4f, 0x61, 0x73, 0x88, 0x9d, 0xb4, 0xcd, 0xe6,
0xff},
- {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
- 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+ {0x00, 0x04, 0x0B, 0x15, 0x20, 0x2d, 0x3b, 0x4a, /* 4 */
+ 0x5b, 0x6c, 0x7f, 0x92, 0xa7, 0xbc, 0xd2, 0xe9,
0xff},
- {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
- 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+ {0x00, 0x07, 0x11, 0x15, 0x20, 0x2d, 0x48, 0x58, /* 5 */
+ 0x68, 0x79, 0x8b, 0x9d, 0xb0, 0xc4, 0xd7, 0xec,
0xff},
- {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
+ {0x00, 0x0c, 0x1a, 0x29, 0x38, 0x47, 0x57, 0x67, /* 6 */
0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
0xff},
- {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
+ {0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, /* 7 */
0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
0xff},
- {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
- 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+ {0x00, 0x15, 0x27, 0x38, 0x49, 0x59, 0x69, 0x79, /* 8 */
+ 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe2, 0xf0,
0xff},
- {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
- 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+ {0x00, 0x1c, 0x30, 0x43, 0x54, 0x65, 0x75, 0x84, /* 9 */
+ 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd8, 0xe5, 0xf2,
0xff},
- {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
- 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+ {0x00, 0x24, 0x3b, 0x4f, 0x60, 0x70, 0x80, 0x8e, /* 10 */
+ 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xdc, 0xe8, 0xf3,
0xff},
- {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8d, 0x9b, /* 11 */
+ {0x00, 0x2a, 0x3c, 0x5d, 0x6e, 0x7e, 0x8d, 0x9b, /* 11 */
0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
0xff},
{0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
@@ -577,12 +572,11 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
} else {
u8 *tmpbuf;
- tmpbuf = kmalloc(len, GFP_KERNEL);
+ tmpbuf = kmemdup(buffer, len, GFP_KERNEL);
if (!tmpbuf) {
err("Out of memory");
return;
}
- memcpy(tmpbuf, buffer, len);
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
0,
@@ -625,7 +619,6 @@ static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
kfree(tmpbuf);
}
-/* Reported as OM6802*/
static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
@@ -703,12 +696,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->autogain = AUTOGAIN_DEF;
sd->mirror = MIRROR_DEF;
sd->freq = FREQ_DEF;
- sd->whitebalance = WHITE_BALANCE_DEF;
+ sd->awb = AWB_DEF;
sd->sharpness = SHARPNESS_DEF;
sd->effect = EFFECTS_DEF;
- sd->red_balance = RED_BALANCE_DEF;
- sd->blue_balance = BLUE_BALANCE_DEF;
- sd->global_gain = global_gain_DEF;
+ sd->red_gain = RED_GAIN_DEF;
+ sd->blue_gain = BLUE_GAIN_DEF;
+ sd->green_gain = GAIN_DEF * 3 - RED_GAIN_DEF - BLUE_GAIN_DEF;
return 0;
}
@@ -761,40 +754,59 @@ static void setgamma(struct gspca_dev *gspca_dev)
reg_w_ixbuf(gspca_dev, 0x90,
gamma_table[sd->gamma], sizeof gamma_table[0]);
}
-static void setglobalgain(struct gspca_dev *gspca_dev)
-{
+static void setRGB(struct gspca_dev *gspca_dev)
+{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w(gspca_dev, (sd->red_balance << 8) + 0x87);
- reg_w(gspca_dev, (sd->blue_balance << 8) + 0x88);
- reg_w(gspca_dev, (sd->global_gain << 8) + 0x89);
+ u8 all_gain_reg[6] =
+ {0x87, 0x00, 0x88, 0x00, 0x89, 0x00};
+
+ all_gain_reg[1] = sd->red_gain;
+ all_gain_reg[3] = sd->blue_gain;
+ all_gain_reg[5] = sd->green_gain;
+ reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
}
-/* Generic fnc for r/b balance, exposure and whitebalance */
-static void setbalance(struct gspca_dev *gspca_dev)
+/* Generic fnc for r/b balance, exposure and awb */
+static void setawb(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ u16 reg80;
- /* on whitebalance leave defaults values */
- if (sd->whitebalance) {
- reg_w(gspca_dev, 0x3c80);
- } else {
- reg_w(gspca_dev, 0x3880);
+ reg80 = (sensor_data[sd->sensor].reg80 << 8) | 0x80;
+
+ /* on awb leave defaults values */
+ if (!sd->awb) {
/* shoud we wait here.. */
- /* update and reset 'global gain' with webcam parameters */
- sd->red_balance = reg_r(gspca_dev, 0x0087);
- sd->blue_balance = reg_r(gspca_dev, 0x0088);
- sd->global_gain = reg_r(gspca_dev, 0x0089);
- setglobalgain(gspca_dev);
+ /* update and reset RGB gains with webcam values */
+ sd->red_gain = reg_r(gspca_dev, 0x0087);
+ sd->blue_gain = reg_r(gspca_dev, 0x0088);
+ sd->green_gain = reg_r(gspca_dev, 0x0089);
+ reg80 &= ~0x0400; /* AWB off */
}
-
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg80);
}
-
-
-static void setwhitebalance(struct gspca_dev *gspca_dev)
+static void init_gains(struct gspca_dev *gspca_dev)
{
- setbalance(gspca_dev);
+ struct sd *sd = (struct sd *) gspca_dev;
+ u16 reg80;
+ u8 all_gain_reg[8] =
+ {0x87, 0x00, 0x88, 0x00, 0x89, 0x00, 0x80, 0x00};
+
+ all_gain_reg[1] = sd->red_gain;
+ all_gain_reg[3] = sd->blue_gain;
+ all_gain_reg[5] = sd->green_gain;
+ reg80 = sensor_data[sd->sensor].reg80;
+ if (!sd->awb)
+ reg80 &= ~0x04;
+ all_gain_reg[7] = reg80;
+ reg_w_buf(gspca_dev, all_gain_reg, sizeof all_gain_reg);
+
+ reg_w(gspca_dev, (sd->red_gain << 8) + 0x87);
+ reg_w(gspca_dev, (sd->blue_gain << 8) + 0x88);
+ reg_w(gspca_dev, (sd->green_gain << 8) + 0x89);
}
static void setsharpness(struct gspca_dev *gspca_dev)
@@ -807,6 +819,38 @@ static void setsharpness(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, reg_to_write);
}
+static void setfreq(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ u8 reg66;
+ u8 freq[4] = { 0x66, 0x00, 0xa8, 0xe8 };
+
+ switch (sd->sensor) {
+ case SENSOR_LT168G:
+ if (sd->freq != 0)
+ freq[3] = 0xa8;
+ reg66 = 0x41;
+ break;
+ case SENSOR_OM6802:
+ reg66 = 0xca;
+ break;
+ default:
+ reg66 = 0x40;
+ break;
+ }
+ switch (sd->freq) {
+ case 0: /* no flicker */
+ freq[3] = 0xf0;
+ break;
+ case 2: /* 60Hz */
+ reg66 &= ~0x40;
+ break;
+ }
+ freq[1] = reg66;
+
+ reg_w_buf(gspca_dev, freq, sizeof freq);
+}
+
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
@@ -901,13 +945,9 @@ static int sd_init(struct gspca_dev *gspca_dev)
setgamma(gspca_dev);
setcolors(gspca_dev);
setsharpness(gspca_dev);
- setwhitebalance(gspca_dev);
-
- reg_w(gspca_dev, 0x2087); /* tied to white balance? */
- reg_w(gspca_dev, 0x2088);
- reg_w(gspca_dev, 0x2089);
+ init_gains(gspca_dev);
+ setfreq(gspca_dev);
- reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
reg_w_buf(gspca_dev, sensor->data5, sizeof sensor->data5);
reg_w_buf(gspca_dev, sensor->nset8, sizeof sensor->nset8);
reg_w_buf(gspca_dev, sensor->stream, sizeof sensor->stream);
@@ -926,16 +966,16 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static void setflip(struct gspca_dev *gspca_dev)
+static void setmirror(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- u8 flipcmd[8] =
+ u8 hflipcmd[8] =
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
if (sd->mirror)
- flipcmd[3] = 0x01;
+ hflipcmd[3] = 0x01;
- reg_w_buf(gspca_dev, flipcmd, sizeof flipcmd);
+ reg_w_buf(gspca_dev, hflipcmd, sizeof hflipcmd);
}
static void seteffect(struct gspca_dev *gspca_dev)
@@ -956,17 +996,6 @@ static void seteffect(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0xfaa6);
}
-static void setlightfreq(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
-
- if (sd->freq == 2) /* 60hz */
- freq[1] = 0x00;
-
- reg_w_buf(gspca_dev, freq, sizeof freq);
-}
-
/* Is this really needed?
* i added some module parameters for test with some users */
static void poll_sensor(struct gspca_dev *gspca_dev)
@@ -979,9 +1008,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
static const u8 poll2[] =
{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const u8 poll3[] =
- {0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
- static const u8 poll4[] =
+ static const u8 noise03[] = /* (some differences / ms-drv) */
{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
@@ -989,8 +1016,7 @@ static void poll_sensor(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "[Sensor requires polling]");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
- reg_w_buf(gspca_dev, poll3, sizeof poll3);
- reg_w_buf(gspca_dev, poll4, sizeof poll4);
+ reg_w_buf(gspca_dev, noise03, sizeof noise03);
}
static int sd_start(struct gspca_dev *gspca_dev)
@@ -1025,12 +1051,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_OM6802:
om6802_sensor_init(gspca_dev);
break;
- case SENSOR_LT168G:
- break;
- case SENSOR_OTHER:
- break;
- default:
-/* case SENSOR_TAS5130A: */
+ case SENSOR_TAS5130A:
i = 0;
for (;;) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -1047,7 +1068,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
break;
}
sensor = &sensor_data[sd->sensor];
- reg_w_buf(gspca_dev, sensor->data4, sizeof sensor->data4);
+ setfreq(gspca_dev);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
@@ -1080,7 +1101,7 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- static u8 ffd9[] = { 0xff, 0xd9 };
+ int pkt_type;
if (data[0] == 0x5a) {
/* Control Packet, after this came the header again,
@@ -1090,84 +1111,88 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
data += 2;
len -= 2;
- if (data[0] == 0xff && data[1] == 0xd8) {
- /* extra bytes....., could be processed too but would be
- * a waste of time, right now leave the application and
- * libjpeg do it for ourserlves.. */
- gspca_frame_add(gspca_dev, LAST_PACKET,
- ffd9, 2);
- gspca_frame_add(gspca_dev, FIRST_PACKET, data, len);
- return;
- }
-
- if (data[len - 2] == 0xff && data[len - 1] == 0xd9) {
- /* Just in case, i have seen packets with the marker,
- * other's do not include it... */
- len -= 2;
- }
- gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
+ if (data[0] == 0xff && data[1] == 0xd8)
+ pkt_type = FIRST_PACKET;
+ else if (data[len - 2] == 0xff && data[len - 1] == 0xd9)
+ pkt_type = LAST_PACKET;
+ else
+ pkt_type = INTER_PACKET;
+ gspca_frame_add(gspca_dev, pkt_type, data, len);
}
-
-static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setblue_gain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->blue_balance = val;
+ sd->blue_gain = val;
if (gspca_dev->streaming)
reg_w(gspca_dev, (val << 8) + 0x88);
return 0;
}
-static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getblue_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- *val = sd->blue_balance;
+ *val = sd->blue_gain;
return 0;
}
-static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setred_gain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->red_balance = val;
+ sd->red_gain = val;
if (gspca_dev->streaming)
reg_w(gspca_dev, (val << 8) + 0x87);
return 0;
}
-static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getred_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- *val = sd->red_balance;
+ *val = sd->red_gain;
return 0;
}
-
-
-static int sd_setglobal_gain(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
+ u16 psg, nsg;
+
+ psg = sd->red_gain + sd->blue_gain + sd->green_gain;
+ nsg = val * 3;
+ sd->red_gain = sd->red_gain * nsg / psg;
+ if (sd->red_gain > 0x40)
+ sd->red_gain = 0x40;
+ else if (sd->red_gain < 0x10)
+ sd->red_gain = 0x10;
+ sd->blue_gain = sd->blue_gain * nsg / psg;
+ if (sd->blue_gain > 0x40)
+ sd->blue_gain = 0x40;
+ else if (sd->blue_gain < 0x10)
+ sd->blue_gain = 0x10;
+ sd->green_gain = sd->green_gain * nsg / psg;
+ if (sd->green_gain > 0x40)
+ sd->green_gain = 0x40;
+ else if (sd->green_gain < 0x10)
+ sd->green_gain = 0x10;
- sd->global_gain = val;
if (gspca_dev->streaming)
- setglobalgain(gspca_dev);
-
+ setRGB(gspca_dev);
return 0;
}
-static int sd_getglobal_gain(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- *val = sd->global_gain;
+ *val = (sd->red_gain + sd->blue_gain + sd->green_gain) / 3;
return 0;
}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1186,35 +1211,35 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
return *val;
}
-static int sd_setwhitebalance(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->whitebalance = val;
+ sd->awb = val;
if (gspca_dev->streaming)
- setwhitebalance(gspca_dev);
+ setawb(gspca_dev);
return 0;
}
-static int sd_getwhitebalance(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- *val = sd->whitebalance;
+ *val = sd->awb;
return *val;
}
-static int sd_setflip(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setmirror(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
sd->mirror = val;
if (gspca_dev->streaming)
- setflip(gspca_dev);
+ setmirror(gspca_dev);
return 0;
}
-static int sd_getflip(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1300,7 +1325,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
sd->freq = val;
if (gspca_dev->streaming)
- setlightfreq(gspca_dev);
+ setfreq(gspca_dev);
return 0;
}
@@ -1368,7 +1393,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
case V4L2_CID_EFFECTS:
if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
strncpy((char *) menu->name,
- effects_control[menu->index], 32);
+ effects_control[menu->index],
+ sizeof menu->name);
return 0;
}
break;
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index c7b6eb1e04d5..d9c5bf3449d4 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -30,29 +30,46 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u16 brightness;
+ __u16 exposure;
+ __u16 gain;
__u8 packet;
};
/* V4L2 controls supported by the driver */
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
static const struct ctrl sd_ctrls[] = {
{
{
- .id = V4L2_CID_BRIGHTNESS,
+ .id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
+ .name = "Exposure",
.minimum = 1,
- .maximum = 0x15f, /* = 352 - 1 */
+ .maximum = 0x18f,
.step = 1,
-#define BRIGHTNESS_DEF 0x14c
- .default_value = BRIGHTNESS_DEF,
+#define EXPOSURE_DEF 0x18f
+ .default_value = EXPOSURE_DEF,
},
- .set = sd_setbrightness,
- .get = sd_getbrightness,
+ .set = sd_setexposure,
+ .get = sd_getexposure,
+ },
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 0x7ff,
+ .step = 1,
+#define GAIN_DEF 0x100
+ .default_value = GAIN_DEF,
+ },
+ .set = sd_setgain,
+ .get = sd_getgain,
},
};
@@ -92,6 +109,14 @@ static const struct v4l2_pix_format sif_mode[] = {
#define R14_AD_ROW_BEGINL 0x14
#define R15_AD_ROWBEGINH 0x15
#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R20_GAIN_G1L 0x20
+#define R21_GAIN_G1H 0x21
+#define R22_GAIN_RL 0x22
+#define R23_GAIN_RH 0x23
+#define R24_GAIN_BL 0x24
+#define R25_GAIN_BH 0x25
+#define R26_GAIN_G2L 0x26
+#define R27_GAIN_G2H 0x27
#define R28_QUANT 0x28
#define R29_LINE 0x29
#define R2C_POLARITY 0x2c
@@ -129,18 +154,6 @@ static const u8 eeprom_data[][3] = {
{0x05, 0x09, 0xf1},
};
-static int reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
-{
- usb_control_msg(gspca_dev->dev,
- usb_rcvctrlpipe(gspca_dev->dev, 0),
- 0x03,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, /* value */
- index, gspca_dev->usb_buf, 1,
- 500);
- return gspca_dev->usb_buf[0];
-}
/* write 1 byte */
static void reg_w1(struct gspca_dev *gspca_dev,
@@ -183,7 +196,6 @@ static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
}
reg_w1(gspca_dev, R07_TABLE_LEN, i);
reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
- msleep(10);
}
/* this function is called at probe time */
@@ -197,53 +209,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
- sd->brightness = BRIGHTNESS_DEF;
+ sd->exposure = EXPOSURE_DEF;
+ sd->gain = GAIN_DEF;
return 0;
}
-static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
-{
- int i;
- static u8 reg_tb[] = {
- R0C_AD_WIDTHL,
- R0D_AD_WIDTHH,
- R28_QUANT,
- R29_LINE,
- R2C_POLARITY,
- R2D_POINT,
- R2E_POINTH,
- R2F_POINTB,
- R30_POINTBH,
- R2A_HIGH_BUDGET,
- R2B_LOW_BUDGET,
- R34_VID,
- R35_VIDH,
- R36_PID,
- R37_PIDH,
- R83_AD_IDH,
- R10_AD_COL_BEGINL,
- R11_AD_COL_BEGINH,
- R14_AD_ROW_BEGINL,
- R15_AD_ROWBEGINH,
- 0
- };
-
- i = 0;
- do {
- reg_r(gspca_dev, reg_tb[i]);
- i++;
- } while (reg_tb[i] != 0);
-}
-
static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{
- reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
- /* begin active line */
- reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
- /* mirror and digital gain */
- reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
- /* = 0x84 */
-
reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
/******************************************************/
reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
@@ -255,100 +227,43 @@ static void tv_8532_setReg(struct gspca_dev *gspca_dev)
/* mirror and digital gain */
reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
- reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
-
- reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
-
reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/* = 0x84 */
}
-static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
-{
- int i;
-
- /* strange polling from tgc */
- for (i = 0; i < 10; i++) {
- reg_w1(gspca_dev, R2C_POLARITY, 0x10);
- reg_w1(gspca_dev, R00_PART_CONTROL,
- LATENT_CHANGE | EXPO_CHANGE);
- reg_w1(gspca_dev, R31_UPD, 0x01);
- }
-}
-
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
tv_8532WriteEEprom(gspca_dev);
- reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
- * slope rate 2 */
- reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
- tv_8532ReadRegisters(gspca_dev);
- reg_w1(gspca_dev, R3B_Test3, 0x0b);
- reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
- reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
- reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
- reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
-
- /*******************************************************************/
- reg_w1(gspca_dev, R28_QUANT, 0x90);
- /* no compress - fixed Q - quant 0 */
- reg_w1(gspca_dev, R29_LINE, 0x81);
- /* 0x84; // CIF | 4 packet 0x29 */
-
- /************************************************/
- reg_w1(gspca_dev, R2C_POLARITY, 0x10);
- /* 0x48; //0x08; 0x2c */
- reg_w1(gspca_dev, R2D_POINT, 0x14);
- /* 0x38; 0x2d */
- reg_w1(gspca_dev, R2E_POINTH, 0x01);
- /* 0x04; 0x2e */
- reg_w1(gspca_dev, R2F_POINTB, 0x12);
- /* 0x04; 0x2f */
- reg_w1(gspca_dev, R30_POINTBH, 0x01);
- /* 0x04; 0x30 */
- reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
- /* 0x00<-0x84 */
- /*************************************************/
- reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
- msleep(200);
- reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
- /*************************************************/
- tv_8532_setReg(gspca_dev);
- /*************************************************/
- reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
- /*************************************************/
- tv_8532_setReg(gspca_dev);
- /*************************************************/
- tv_8532_PollReg(gspca_dev);
return 0;
}
-static void setbrightness(struct gspca_dev *gspca_dev)
+static void setexposure(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->exposure);
reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/* 0x84 */
}
-/* -- start the camera -- */
-static int sd_start(struct gspca_dev *gspca_dev)
+static void setgain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
- * slope rate 2 */
- reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
- tv_8532ReadRegisters(gspca_dev);
- reg_w1(gspca_dev, R3B_Test3, 0x0b);
+ reg_w2(gspca_dev, R20_GAIN_G1L, sd->gain);
+ reg_w2(gspca_dev, R22_GAIN_RL, sd->gain);
+ reg_w2(gspca_dev, R24_GAIN_BL, sd->gain);
+ reg_w2(gspca_dev, R26_GAIN_G2L, sd->gain);
+}
- reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
- setbrightness(gspca_dev);
+/* -- start the camera -- */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
@@ -371,19 +286,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, R2E_POINTH, 0x01);
reg_w1(gspca_dev, R2F_POINTB, 0x12);
reg_w1(gspca_dev, R30_POINTBH, 0x01);
- reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+
+ tv_8532_setReg(gspca_dev);
+
+ setexposure(gspca_dev);
+ setgain(gspca_dev);
+
/************************************************/
reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
- /************************************************/
- tv_8532_setReg(gspca_dev);
- /************************************************/
- reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
- /************************************************/
- tv_8532_setReg(gspca_dev);
- /************************************************/
- tv_8532_PollReg(gspca_dev);
reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
gspca_dev->empty_packet = 0; /* check the empty packets */
@@ -428,21 +339,39 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data + gspca_dev->width + 5, gspca_dev->width);
}
-static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->exposure = val;
+ if (gspca_dev->streaming)
+ setexposure(gspca_dev);
+ return 0;
+}
+
+static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->exposure;
+ return 0;
+}
+
+static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
- sd->brightness = val;
+ sd->gain = val;
if (gspca_dev->streaming)
- setbrightness(gspca_dev);
+ setgain(gspca_dev);
return 0;
}
-static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- *val = sd->brightness;
+ *val = sd->gain;
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 732c3dfe46ff..072785368265 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2748,11 +2748,11 @@ static const u8 poxxxx_init_common[][4] = {
{0xb3, 0x04, 0x15, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc}, /* sensor height = 1024 */
{0xb3, 0x23, 0x00, 0xcc},
{0xb3, 0x14, 0x00, 0xcc},
{0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc}, /* sensor width = 1280 */
{0xb3, 0x17, 0xff, 0xcc},
{0xb3, 0x2c, 0x03, 0xcc},
{0xb3, 0x2d, 0x56, 0xcc},
@@ -2919,7 +2919,7 @@ static const u8 poxxxx_initVGA[][4] = {
{0x00, 0x20, 0x11, 0xaa},
{0x00, 0x33, 0x38, 0xaa},
{0x00, 0xbb, 0x0d, 0xaa},
- {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc}, /* change to 640x480 */
{0xb3, 0x23, 0xe0, 0xcc},
{0xb3, 0x16, 0x02, 0xcc},
{0xb3, 0x17, 0x7f, 0xcc},
@@ -2935,7 +2935,7 @@ static const u8 poxxxx_initQVGA[][4] = {
{0x00, 0x20, 0x33, 0xaa},
{0x00, 0x33, 0x38, 0xaa},
{0x00, 0xbb, 0x0d, 0xaa},
- {0xb3, 0x22, 0x00, 0xcc},
+ {0xb3, 0x22, 0x00, 0xcc}, /* change to 320x240 */
{0xb3, 0x23, 0xf0, 0xcc},
{0xb3, 0x16, 0x01, 0xcc},
{0xb3, 0x17, 0x3f, 0xcc},
@@ -3068,37 +3068,84 @@ static const struct sensor_info vc0323_probe_data[] = {
};
/* read 'len' bytes in gspca_dev->usb_buf */
-static void reg_r(struct gspca_dev *gspca_dev,
+static void reg_r_i(struct gspca_dev *gspca_dev,
u16 req,
u16 index,
u16 len)
{
- usb_control_msg(gspca_dev->dev,
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1, /* value */
index, gspca_dev->usb_buf, len,
500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_r err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+static void reg_r(struct gspca_dev *gspca_dev,
+ u16 req,
+ u16 index,
+ u16 len)
+{
+ reg_r_i(gspca_dev, req, index, len);
+#ifdef GSPCA_DEBUG
+ if (gspca_dev->usb_err < 0)
+ return;
+ if (len == 1)
+ PDEBUG(D_USBI, "GET %02x 0001 %04x %02x", req, index,
+ gspca_dev->usb_buf[0]);
+ else
+ PDEBUG(D_USBI, "GET %02x 0001 %04x %02x %02x %02x",
+ req, index,
+ gspca_dev->usb_buf[0],
+ gspca_dev->usb_buf[1],
+ gspca_dev->usb_buf[2]);
+#endif
}
-static void reg_w(struct usb_device *dev,
+static void reg_w_i(struct gspca_dev *gspca_dev,
u16 req,
u16 value,
u16 index)
{
- usb_control_msg(dev,
- usb_sndctrlpipe(dev, 0),
+ int ret;
+
+ if (gspca_dev->usb_err < 0)
+ return;
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
req,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0,
500);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "reg_w err %d", ret);
+ gspca_dev->usb_err = ret;
+ }
+}
+static void reg_w(struct gspca_dev *gspca_dev,
+ u16 req,
+ u16 value,
+ u16 index)
+{
+#ifdef GSPCA_DEBUG
+ if (gspca_dev->usb_err < 0)
+ return;
+ PDEBUG(D_USBO, "SET %02x %04x %04x", req, value, index);
+#endif
+ reg_w_i(gspca_dev, req, value, index);
}
static u16 read_sensor_register(struct gspca_dev *gspca_dev,
u16 address)
{
- struct usb_device *dev = gspca_dev->dev;
u8 ldata, mdata, hdata;
int retry = 50;
@@ -3108,8 +3155,8 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
gspca_dev->usb_buf[0]);
return 0;
}
- reg_w(dev, 0xa0, address, 0xb33a);
- reg_w(dev, 0xa0, 0x02, 0xb339);
+ reg_w(gspca_dev, 0xa0, address, 0xb33a);
+ reg_w(gspca_dev, 0xa0, 0x02, 0xb339);
do {
reg_r(gspca_dev, 0xa1, 0xb33b, 1);
@@ -3136,15 +3183,15 @@ static u16 read_sensor_register(struct gspca_dev *gspca_dev,
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
int i, n;
u16 value;
const struct sensor_info *ptsensor_info;
/*fixme: should also check the other sensor (back mi1320_soc, front mc501cb)*/
if (sd->flags & FL_SAMSUNG) {
- reg_w(dev, 0xa0, 0x01, 0xb301);
- reg_w(dev, 0x89, 0xf0ff, 0xffff); /* select the back sensor */
+ reg_w(gspca_dev, 0xa0, 0x01, 0xb301);
+ reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff);
+ /* select the back sensor */
}
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
@@ -3158,13 +3205,13 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
n = ARRAY_SIZE(vc0323_probe_data);
}
for (i = 0; i < n; i++) {
- reg_w(dev, 0xa0, 0x02, 0xb334);
- reg_w(dev, 0xa0, ptsensor_info->m1, 0xb300);
- reg_w(dev, 0xa0, ptsensor_info->m2, 0xb300);
- reg_w(dev, 0xa0, 0x01, 0xb308);
- reg_w(dev, 0xa0, 0x0c, 0xb309);
- reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
- reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
+ reg_w(gspca_dev, 0xa0, 0x02, 0xb334);
+ reg_w(gspca_dev, 0xa0, ptsensor_info->m1, 0xb300);
+ reg_w(gspca_dev, 0xa0, ptsensor_info->m2, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x01, 0xb308);
+ reg_w(gspca_dev, 0xa0, 0x0c, 0xb309);
+ reg_w(gspca_dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
+ reg_w(gspca_dev, 0xa0, ptsensor_info->op, 0xb301);
value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
if (value == 0 && ptsensor_info->IdAdd == 0x82)
value = read_sensor_register(gspca_dev, 0x83);
@@ -3192,26 +3239,33 @@ static void i2c_write(struct gspca_dev *gspca_dev,
u8 reg, const u8 *val,
u8 size) /* 1 or 2 */
{
- struct usb_device *dev = gspca_dev->dev;
int retry;
- reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+#ifdef GSPCA_DEBUG
+ if (gspca_dev->usb_err < 0)
+ return;
+ if (size == 1)
+ PDEBUG(D_USBO, "i2c_w %02x %02x", reg, *val);
+ else
+ PDEBUG(D_USBO, "i2c_w %02x %02x%02x", reg, *val, val[1]);
+#endif
+ reg_r_i(gspca_dev, 0xa1, 0xb33f, 1);
/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
- reg_w(dev, 0xa0, size, 0xb334);
- reg_w(dev, 0xa0, reg, 0xb33a);
- reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w_i(gspca_dev, 0xa0, size, 0xb334);
+ reg_w_i(gspca_dev, 0xa0, reg, 0xb33a);
+ reg_w_i(gspca_dev, 0xa0, val[0], 0xb336);
if (size > 1)
- reg_w(dev, 0xa0, val[1], 0xb337);
- reg_w(dev, 0xa0, 0x01, 0xb339);
+ reg_w_i(gspca_dev, 0xa0, val[1], 0xb337);
+ reg_w_i(gspca_dev, 0xa0, 0x01, 0xb339);
retry = 4;
do {
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ reg_r_i(gspca_dev, 0xa1, 0xb33b, 1);
if (gspca_dev->usb_buf[0] == 0)
break;
msleep(20);
} while (--retry > 0);
if (retry <= 0)
- PDEBUG(D_ERR, "i2c_write failed");
+ PDEBUG(D_ERR, "i2c_write timeout");
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -3221,13 +3275,12 @@ static void put_tab_to_reg(struct gspca_dev *gspca_dev,
u16 ad = addr;
for (j = 0; j < tabsize; j++)
- reg_w(gspca_dev->dev, 0xa0, tab[j], ad++);
+ reg_w(gspca_dev, 0xa0, tab[j], ad++);
}
static void usb_exchange(struct gspca_dev *gspca_dev,
const u8 data[][4])
{
- struct usb_device *dev = gspca_dev->dev;
int i = 0;
for (;;) {
@@ -3235,7 +3288,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
default:
return;
case 0xcc: /* normal write */
- reg_w(dev, 0xa0, data[i][2],
+ reg_w(gspca_dev, 0xa0, data[i][2],
(data[i][0]) << 8 | data[i][1]);
break;
case 0xaa: /* i2c op */
@@ -3259,7 +3312,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct usb_device *dev = gspca_dev->dev;
struct cam *cam;
int sensor;
static u8 npkt[] = { /* number of packets per ISOC message */
@@ -3365,10 +3417,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
if (sd->bridge == BRIDGE_VC0321) {
reg_r(gspca_dev, 0x8a, 0, 3);
- reg_w(dev, 0x87, 0x00, 0x0f0f);
+ reg_w(gspca_dev, 0x87, 0x00, 0x0f0f);
reg_r(gspca_dev, 0x8b, 0, 3);
- reg_w(dev, 0x88, 0x00, 0x0202);
+ reg_w(gspca_dev, 0x88, 0x00, 0x0202);
}
return 0;
}
@@ -3381,12 +3433,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
if (sd->sensor == SENSOR_POxxxx) {
reg_r(gspca_dev, 0xa1, 0xb300, 1);
if (gspca_dev->usb_buf[0] != 0) {
- reg_w(gspca_dev->dev, 0xa0, 0x26, 0xb300);
- reg_w(gspca_dev->dev, 0xa0, 0x04, 0xb300);
- reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x26, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x04, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x00, 0xb300);
}
}
- return 0;
+ return gspca_dev->usb_err;
}
static void setbrightness(struct gspca_dev *gspca_dev)
@@ -3516,17 +3568,17 @@ static int sd_start(struct gspca_dev *gspca_dev)
/*fixme: back sensor only*/
if (sd->flags & FL_SAMSUNG) {
- reg_w(gspca_dev->dev, 0x89, 0xf0ff, 0xffff);
- reg_w(gspca_dev->dev, 0xa9, 0x8348, 0x000e);
- reg_w(gspca_dev->dev, 0xa9, 0x0000, 0x001a);
+ reg_w(gspca_dev, 0x89, 0xf0ff, 0xffff);
+ reg_w(gspca_dev, 0xa9, 0x8348, 0x000e);
+ reg_w(gspca_dev, 0xa9, 0x0000, 0x001a);
}
/* Assume start use the good resolution from gspca_dev->mode */
if (sd->bridge == BRIDGE_VC0321) {
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfec);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+ reg_w(gspca_dev, 0xa0, 0xff, 0xbfec);
+ reg_w(gspca_dev, 0xa0, 0xff, 0xbfed);
+ reg_w(gspca_dev, 0xa0, 0xff, 0xbfee);
+ reg_w(gspca_dev, 0xa0, 0xff, 0xbfef);
sd->image_offset = 46;
} else {
if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
@@ -3617,7 +3669,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
init = poxxxx_initVGA;
usb_exchange(gspca_dev, init);
reg_r(gspca_dev, 0x8c, 0x0000, 3);
- reg_w(gspca_dev->dev, 0xa0,
+ reg_w(gspca_dev, 0xa0,
gspca_dev->usb_buf[2] & 1 ? 0 : 1,
0xb35c);
msleep(300);
@@ -3635,10 +3687,10 @@ static int sd_start(struct gspca_dev *gspca_dev)
switch (sd->sensor) {
case SENSOR_PO1200:
case SENSOR_HV7131R:
- reg_w(gspca_dev->dev, 0x89, 0x0400, 0x1415);
+ reg_w(gspca_dev, 0x89, 0x0400, 0x1415);
break;
case SENSOR_MI1310_SOC:
- reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
+ reg_w(gspca_dev, 0x89, 0x058c, 0x0000);
break;
}
msleep(100);
@@ -3648,9 +3700,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
switch (sd->sensor) {
case SENSOR_OV7670:
- reg_w(gspca_dev->dev, 0x87, 0xffff, 0xffff);
- reg_w(gspca_dev->dev, 0x88, 0xff00, 0xf0f1);
- reg_w(gspca_dev->dev, 0xa0, 0x0000, 0xbfff);
+ reg_w(gspca_dev, 0x87, 0xffff, 0xffff);
+ reg_w(gspca_dev, 0x88, 0xff00, 0xf0f1);
+ reg_w(gspca_dev, 0xa0, 0x0000, 0xbfff);
break;
case SENSOR_POxxxx:
setcolors(gspca_dev);
@@ -3659,51 +3711,49 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* led on */
msleep(80);
- reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
+ reg_w(gspca_dev, 0x89, 0xffff, 0xfdff);
usb_exchange(gspca_dev, poxxxx_init_end_2);
break;
}
- return 0;
+ return gspca_dev->usb_err;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- struct usb_device *dev = gspca_dev->dev;
struct sd *sd = (struct sd *) gspca_dev;
switch (sd->sensor) {
case SENSOR_MI1310_SOC:
- reg_w(dev, 0x89, 0x058c, 0x00ff);
+ reg_w(gspca_dev, 0x89, 0x058c, 0x00ff);
break;
case SENSOR_POxxxx:
return;
default:
if (!(sd->flags & FL_SAMSUNG))
- reg_w(dev, 0x89, 0xffff, 0xffff);
+ reg_w(gspca_dev, 0x89, 0xffff, 0xffff);
break;
}
- reg_w(dev, 0xa0, 0x01, 0xb301);
- reg_w(dev, 0xa0, 0x09, 0xb003);
+ reg_w(gspca_dev, 0xa0, 0x01, 0xb301);
+ reg_w(gspca_dev, 0xa0, 0x09, 0xb003);
}
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
- struct usb_device *dev = gspca_dev->dev;
struct sd *sd = (struct sd *) gspca_dev;
if (!gspca_dev->present)
return;
/*fixme: is this useful?*/
if (sd->sensor == SENSOR_MI1310_SOC)
- reg_w(dev, 0x89, 0x058c, 0x00ff);
+ reg_w(gspca_dev, 0x89, 0x058c, 0x00ff);
else if (!(sd->flags & FL_SAMSUNG))
- reg_w(dev, 0x89, 0xffff, 0xffff);
+ reg_w(gspca_dev, 0x89, 0xffff, 0xffff);
if (sd->sensor == SENSOR_POxxxx) {
- reg_w(dev, 0xa0, 0x26, 0xb300);
- reg_w(dev, 0xa0, 0x04, 0xb300);
- reg_w(dev, 0xa0, 0x00, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x26, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x04, 0xb300);
+ reg_w(gspca_dev, 0xa0, 0x00, 0xb300);
}
}
@@ -3726,17 +3776,12 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* The vc0321 sends some additional data after sending the complete
* frame, we ignore this. */
if (sd->bridge == BRIDGE_VC0321) {
- struct gspca_frame *frame;
- int l;
+ int size, l;
- frame = gspca_get_i_frame(gspca_dev);
- if (frame == NULL) {
- gspca_dev->last_packet_type = DISCARD_PACKET;
- return;
- }
- l = frame->data_end - frame->data;
- if (len > frame->v4l2_buf.length - l)
- len = frame->v4l2_buf.length - l;
+ l = gspca_dev->image_len;
+ size = gspca_dev->frsz;
+ if (len > size - l)
+ len = size - l;
}
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
@@ -3748,7 +3793,7 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
sd->brightness = val;
if (gspca_dev->streaming)
setbrightness(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3766,7 +3811,7 @@ static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
sd->contrast = val;
if (gspca_dev->streaming)
setcontrast(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3784,7 +3829,7 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
sd->colors = val;
if (gspca_dev->streaming)
setcolors(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3802,7 +3847,7 @@ static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
sd->hflip = val;
if (gspca_dev->streaming)
sethvflip(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3820,7 +3865,7 @@ static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
sd->vflip = val;
if (gspca_dev->streaming)
sethvflip(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3838,7 +3883,7 @@ static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
sd->lightfreq = val;
if (gspca_dev->streaming)
setlightfreq(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
@@ -3856,7 +3901,7 @@ static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
sd->sharpness = val;
if (gspca_dev->streaming)
setsharpness(gspca_dev);
- return 0;
+ return gspca_dev->usb_err;
}
static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
diff --git a/drivers/media/video/gspca/w996Xcf.c b/drivers/media/video/gspca/w996Xcf.c
index 2fffe203bed8..38a68591ce48 100644
--- a/drivers/media/video/gspca/w996Xcf.c
+++ b/drivers/media/video/gspca/w996Xcf.c
@@ -31,14 +31,10 @@
the sensor drivers to v4l2 sub drivers, and properly split of this
driver from ov519.c */
-/* The CONEX_CAM define for jpeg.h needs renaming, now its used here too */
-#define CONEX_CAM
-#include "jpeg.h"
-
#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
-#define Y_QUANTABLE (sd->jpeg_hdr + JPEG_QT0_OFFSET)
-#define UV_QUANTABLE (sd->jpeg_hdr + JPEG_QT1_OFFSET)
+#define Y_QUANTABLE (&sd->jpeg_hdr[JPEG_QT0_OFFSET])
+#define UV_QUANTABLE (&sd->jpeg_hdr[JPEG_QT1_OFFSET])
static const struct v4l2_pix_format w9968cf_vga_mode[] = {
{160, 120, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
@@ -509,11 +505,6 @@ static int w9968cf_mode_init_regs(struct sd *sd)
if (w9968cf_vga_mode[sd->gspca_dev.curr_mode].pixelformat ==
V4L2_PIX_FMT_JPEG) {
/* We may get called multiple times (usb isoc bw negotiat.) */
- if (!sd->jpeg_hdr)
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
-
jpeg_define(sd->jpeg_hdr, sd->gspca_dev.height,
sd->gspca_dev.width, 0x22); /* JPEG 420 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -562,9 +553,6 @@ static void w9968cf_stop0(struct sd *sd)
reg_w(sd, 0x39, 0x0000); /* disable JPEG encoder */
reg_w(sd, 0x16, 0x0000); /* stop video capture */
}
-
- kfree(sd->jpeg_hdr);
- sd->jpeg_hdr = NULL;
}
/* The w9968cf docs say that a 0 sized packet means EOF (and also SOF
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index d02aa5c8472a..4473f0fb8b73 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -22,7 +22,6 @@
#define MODULE_NAME "zc3xx"
#include <linux/input.h>
-#include <linux/slab.h>
#include "gspca.h"
#include "jpeg.h"
@@ -40,15 +39,16 @@ static int force_sensor = -1;
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
+ u8 brightness;
u8 contrast;
u8 gamma;
u8 autogain;
u8 lightfreq;
u8 sharpness;
u8 quality; /* image quality */
-#define QUALITY_MIN 40
-#define QUALITY_MAX 60
-#define QUALITY_DEF 50
+#define QUALITY_MIN 50
+#define QUALITY_MAX 80
+#define QUALITY_DEF 70
u8 sensor; /* Type of image sensor chip */
/* !! values used in different tables */
@@ -75,10 +75,12 @@ struct sd {
#define SENSOR_MAX 19
unsigned short chip_revision;
- u8 *jpeg_hdr;
+ u8 jpeg_hdr[JPEG_HDR_SZ];
};
/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
@@ -93,6 +95,20 @@ static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
static const struct ctrl sd_ctrls[] = {
{
{
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+#define BRIGHTNESS_DEF 128
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Contrast",
@@ -132,7 +148,7 @@ static const struct ctrl sd_ctrls[] = {
.set = sd_setautogain,
.get = sd_getautogain,
},
-#define LIGHTFREQ_IDX 3
+#define LIGHTFREQ_IDX 4
{
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -6011,9 +6027,12 @@ static void setcontrast(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
const u8 *Tgamma;
- int g, i, k, adj, gp;
+ int g, i, brightness, contrast, adj, gp1, gp2;
u8 gr[16];
- static const u8 delta_tb[16] = /* delta for contrast */
+ static const u8 delta_b[16] = /* delta for brightness */
+ {0x50, 0x38, 0x2d, 0x28, 0x24, 0x21, 0x1e, 0x1d,
+ 0x1d, 0x1b, 0x1b, 0x1b, 0x19, 0x18, 0x18, 0x18};
+ static const u8 delta_c[16] = /* delta for contrast */
{0x2c, 0x1a, 0x12, 0x0c, 0x0a, 0x06, 0x06, 0x06,
0x04, 0x06, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02};
static const u8 gamma_tb[6][16] = {
@@ -6033,30 +6052,30 @@ static void setcontrast(struct gspca_dev *gspca_dev)
Tgamma = gamma_tb[sd->gamma - 1];
- k = ((int) sd->contrast - 128); /* -128 / 128 */
+ contrast = ((int) sd->contrast - 128); /* -128 / 127 */
+ brightness = ((int) sd->brightness - 128); /* -128 / 92 */
adj = 0;
- gp = 0;
+ gp1 = gp2 = 0;
for (i = 0; i < 16; i++) {
- g = Tgamma[i] - delta_tb[i] * k / 256 - adj / 2;
+ g = Tgamma[i] + delta_b[i] * brightness / 256
+ - delta_c[i] * contrast / 256 - adj / 2;
if (g > 0xff)
g = 0xff;
else if (g < 0)
g = 0;
reg_w(dev, g, 0x0120 + i); /* gamma */
- if (k > 0)
+ if (contrast > 0)
adj--;
- else
+ else if (contrast < 0)
adj++;
-
- if (i != 0) {
- if (gp == 0)
- gr[i - 1] = 0;
- else
- gr[i - 1] = g - gp;
- }
- gp = g;
+ if (i > 1)
+ gr[i - 1] = (g - gp2) / 2;
+ else if (i != 0)
+ gr[0] = gp1 == 0 ? 0 : (g - gp1);
+ gp2 = gp1;
+ gp1 = g;
}
- gr[15] = gr[14] / 2;
+ gr[15] = (0xff - gp2) / 2;
for (i = 0; i < 16; i++)
reg_w(dev, gr[i], 0x0130 + i); /* gradient */
}
@@ -6744,6 +6763,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = ARRAY_SIZE(broken_vga_mode);
break;
}
+ sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->gamma = gamma[sd->sensor];
sd->autogain = AUTOGAIN_DEF;
@@ -6798,9 +6818,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
};
/* create the JPEG header */
- sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
- if (!sd->jpeg_hdr)
- return -ENOMEM;
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
@@ -6918,10 +6935,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(dev, 0x00, 0x0007); /* (from win traces) */
reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
- case SENSOR_PAS202B:
- reg_w(dev, 0x32, 0x0007); /* (from win traces) */
- reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
- break;
}
return 0;
}
@@ -6931,7 +6944,6 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- kfree(sd->jpeg_hdr);
if (!gspca_dev->present)
return;
send_unknown(gspca_dev->dev, sd->sensor);
@@ -6962,6 +6974,24 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
}
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming)
+ setcontrast(gspca_dev);
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -7163,9 +7193,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x046d, 0x08aa)},
{USB_DEVICE(0x046d, 0x08ac)},
{USB_DEVICE(0x046d, 0x08ad)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
{USB_DEVICE(0x046d, 0x08ae)},
-#endif
{USB_DEVICE(0x046d, 0x08af)},
{USB_DEVICE(0x046d, 0x08b9)},
{USB_DEVICE(0x046d, 0x08d7)},
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 830d47b05e1d..0cae5b82e1a2 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -286,6 +286,8 @@ static int hdpvr_probe(struct usb_interface *interface,
goto error;
}
+ dev->workqueue = 0;
+
/* register v4l2_device early so it can be used for printks */
if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
err("v4l2_device_register failed");
@@ -380,6 +382,9 @@ static int hdpvr_probe(struct usb_interface *interface,
error:
if (dev) {
+ /* Destroy single thread */
+ if (dev->workqueue)
+ destroy_workqueue(dev->workqueue);
/* this frees allocated memory */
hdpvr_delete(dev);
}
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index 29d439742653..27ae8bbfb477 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -47,7 +47,7 @@
#include <linux/i2c-id.h>
#include <linux/workqueue.h>
-#include <media/ir-common.h>
+#include <media/ir-core.h>
#include <media/ir-kbd-i2c.h>
/* ----------------------------------------------------------------------- */
@@ -272,11 +272,8 @@ static void ir_key_poll(struct IR_i2c *ir)
return;
}
- if (0 == rc) {
- ir_input_nokey(ir->input, &ir->ir);
- } else {
- ir_input_keydown(ir->input, &ir->ir, ir_key);
- }
+ if (rc)
+ ir_keydown(ir->input, ir_key, 0);
}
static void ir_work(struct work_struct *work)
@@ -439,10 +436,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_name(&client->dev));
/* init + register input device */
- err = ir_input_init(input_dev, &ir->ir, ir_type);
- if (err < 0)
- goto err_out_free;
-
+ ir->ir_type = ir_type;
input_dev->id.bustype = BUS_I2C;
input_dev->name = ir->name;
input_dev->phys = ir->phys;
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 1b79475ca134..90daa6e751d8 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -130,6 +130,9 @@ static int ivtv_yuv_threshold = -1;
static int ivtv_pci_latency = 1;
int ivtv_debug;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+int ivtv_fw_debug;
+#endif
static int tunertype = -1;
static int newi2c = -1;
@@ -141,6 +144,9 @@ module_param_string(pal, pal, sizeof(pal), 0644);
module_param_string(secam, secam, sizeof(secam), 0644);
module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
module_param_named(debug,ivtv_debug, int, 0644);
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+module_param_named(fw_debug, ivtv_fw_debug, int, 0644);
+#endif
module_param(ivtv_pci_latency, int, 0644);
module_param(ivtv_yuv_mode, int, 0644);
module_param(ivtv_yuv_threshold, int, 0644);
@@ -217,6 +223,10 @@ MODULE_PARM_DESC(debug,
"\t\t\t 256/0x0100: yuv\n"
"\t\t\t 512/0x0200: i2c\n"
"\t\t\t1024/0x0400: high volume\n");
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+MODULE_PARM_DESC(fw_debug,
+ "Enable code for debugging firmware problems. Default: 0\n");
+#endif
MODULE_PARM_DESC(ivtv_pci_latency,
"Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n"
"\t\t\tDefault: Yes");
@@ -1425,12 +1435,16 @@ EXPORT_SYMBOL(ivtv_vapi);
EXPORT_SYMBOL(ivtv_vapi_result);
EXPORT_SYMBOL(ivtv_clear_irq_mask);
EXPORT_SYMBOL(ivtv_debug);
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+EXPORT_SYMBOL(ivtv_fw_debug);
+#endif
EXPORT_SYMBOL(ivtv_reset_ir_gpio);
EXPORT_SYMBOL(ivtv_udma_setup);
EXPORT_SYMBOL(ivtv_udma_unmap);
EXPORT_SYMBOL(ivtv_udma_alloc);
EXPORT_SYMBOL(ivtv_udma_prepare);
EXPORT_SYMBOL(ivtv_init_on_first_open);
+EXPORT_SYMBOL(ivtv_firmware_check);
module_init(module_start);
module_exit(module_cleanup);
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 5b45fd2b2645..bd084df4448a 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -122,6 +122,9 @@
/* debugging */
extern int ivtv_debug;
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+extern int ivtv_fw_debug;
+#endif
#define IVTV_DBGFLG_WARN (1 << 0)
#define IVTV_DBGFLG_INFO (1 << 1)
@@ -734,6 +737,7 @@ struct ivtv {
struct v4l2_rect osd_rect; /* current OSD position and size */
struct v4l2_rect main_rect; /* current Main window position and size */
struct osd_info *osd_info; /* ivtvfb private OSD info */
+ void (*ivtvfb_restore)(struct ivtv *itv); /* Used for a warm start */
};
static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index 3c2cc270ccd5..a6a2cdb81566 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -32,6 +32,7 @@
#include "ivtv-yuv.h"
#include "ivtv-ioctl.h"
#include "ivtv-cards.h"
+#include "ivtv-firmware.h"
#include <media/v4l2-event.h>
#include <media/saa7115.h>
@@ -526,6 +527,7 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
{
struct ivtv *itv = id->itv;
struct ivtv_stream *s = &itv->streams[id->type];
+ int rc;
if (atomic_read(&itv->decoding) == 0) {
if (ivtv_claim_stream(id, s->type)) {
@@ -533,7 +535,13 @@ int ivtv_start_decoding(struct ivtv_open_id *id, int speed)
IVTV_DEBUG_WARN("start decode, stream already claimed\n");
return -EBUSY;
}
- ivtv_start_v4l2_decode_stream(s, 0);
+ rc = ivtv_start_v4l2_decode_stream(s, 0);
+ if (rc < 0) {
+ if (rc == -EAGAIN)
+ rc = ivtv_start_v4l2_decode_stream(s, 0);
+ if (rc < 0)
+ return rc;
+ }
}
if (s->type == IVTV_DEC_STREAM_TYPE_MPG)
return ivtv_set_speed(itv, speed);
@@ -912,12 +920,32 @@ int ivtv_v4l2_close(struct file *filp)
static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
{
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ struct video_device *vdev = video_devdata(filp);
+#endif
struct ivtv *itv = s->itv;
struct ivtv_open_id *item;
int res = 0;
IVTV_DEBUG_FILE("open %s\n", s->name);
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ /* Unless ivtv_fw_debug is set, error out if firmware dead. */
+ if (ivtv_fw_debug) {
+ IVTV_WARN("Opening %s with dead firmware lockout disabled\n",
+ video_device_node_name(vdev));
+ IVTV_WARN("Selected firmware errors will be ignored\n");
+ } else {
+#else
+ if (1) {
+#endif
+ res = ivtv_firmware_check(itv, "ivtv_serialized_open");
+ if (res == -EAGAIN)
+ res = ivtv_firmware_check(itv, "ivtv_serialized_open");
+ if (res < 0)
+ return -EIO;
+ }
+
if (s->type == IVTV_DEC_STREAM_TYPE_MPG &&
test_bit(IVTV_F_S_CLAIMED, &itv->streams[IVTV_DEC_STREAM_TYPE_YUV].s_flags))
return -EBUSY;
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index a71e8ba306b0..d8bf2b01729d 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -23,7 +23,10 @@
#include "ivtv-mailbox.h"
#include "ivtv-firmware.h"
#include "ivtv-yuv.h"
+#include "ivtv-ioctl.h"
+#include "ivtv-cards.h"
#include <linux/firmware.h>
+#include <media/saa7127.h>
#define IVTV_MASK_SPU_ENABLE 0xFFFFFFFE
#define IVTV_MASK_VPU_ENABLE15 0xFFFFFFF6
@@ -271,3 +274,122 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
}
ivtv_vapi(itv, CX2341X_DEC_STOP_PLAYBACK, 4, 0, 0, 0, 1);
}
+
+/* Try to restart the card & restore previous settings */
+int ivtv_firmware_restart(struct ivtv *itv)
+{
+ int rc = 0;
+ v4l2_std_id std;
+ struct ivtv_open_id fh;
+ fh.itv = itv;
+
+ if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+ /* Display test image during restart */
+ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
+ SAA7127_INPUT_TYPE_TEST_IMAGE,
+ itv->card->video_outputs[itv->active_output].video_output,
+ 0);
+
+ mutex_lock(&itv->udma.lock);
+
+ rc = ivtv_firmware_init(itv);
+ if (rc) {
+ mutex_unlock(&itv->udma.lock);
+ return rc;
+ }
+
+ /* Allow settings to reload */
+ ivtv_mailbox_cache_invalidate(itv);
+
+ /* Restore video standard */
+ std = itv->std;
+ itv->std = 0;
+ ivtv_s_std(NULL, &fh, &std);
+
+ if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+ ivtv_init_mpeg_decoder(itv);
+
+ /* Restore framebuffer if active */
+ if (itv->ivtvfb_restore)
+ itv->ivtvfb_restore(itv);
+
+ /* Restore alpha settings */
+ ivtv_set_osd_alpha(itv);
+
+ /* Restore normal output */
+ ivtv_call_hw(itv, IVTV_HW_SAA7127, video, s_routing,
+ SAA7127_INPUT_TYPE_NORMAL,
+ itv->card->video_outputs[itv->active_output].video_output,
+ 0);
+ }
+
+ mutex_unlock(&itv->udma.lock);
+ return rc;
+}
+
+/* Check firmware running state. The checks fall through
+ allowing multiple failures to be logged. */
+int ivtv_firmware_check(struct ivtv *itv, char *where)
+{
+ int res = 0;
+
+ /* Check encoder is still running */
+ if (ivtv_vapi(itv, CX2341X_ENC_PING_FW, 0) < 0) {
+ IVTV_WARN("Encoder has died : %s\n", where);
+ res = -1;
+ }
+
+ /* Also check audio. Only check if not in use & encoder is okay */
+ if (!res && !atomic_read(&itv->capturing) &&
+ (!atomic_read(&itv->decoding) ||
+ (atomic_read(&itv->decoding) < 2 && test_bit(IVTV_F_I_DEC_YUV,
+ &itv->i_flags)))) {
+
+ if (ivtv_vapi(itv, CX2341X_ENC_MISC, 1, 12) < 0) {
+ IVTV_WARN("Audio has died (Encoder OK) : %s\n", where);
+ res = -2;
+ }
+ }
+
+ if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
+ /* Second audio check. Skip if audio already failed */
+ if (res != -2 && read_dec(0x100) != read_dec(0x104)) {
+ /* Wait & try again to be certain. */
+ ivtv_msleep_timeout(14, 0);
+ if (read_dec(0x100) != read_dec(0x104)) {
+ IVTV_WARN("Audio has died (Decoder) : %s\n",
+ where);
+ res = -1;
+ }
+ }
+
+ /* Check decoder is still running */
+ if (ivtv_vapi(itv, CX2341X_DEC_PING_FW, 0) < 0) {
+ IVTV_WARN("Decoder has died : %s\n", where);
+ res = -1;
+ }
+ }
+
+ /* If something failed & currently idle, try to reload */
+ if (res && !atomic_read(&itv->capturing) &&
+ !atomic_read(&itv->decoding)) {
+ IVTV_INFO("Detected in %s that firmware had failed - "
+ "Reloading\n", where);
+ res = ivtv_firmware_restart(itv);
+ /*
+ * Even if restarted ok, still signal a problem had occured.
+ * The caller can come through this function again to check
+ * if things are really ok after the restart.
+ */
+ if (!res) {
+ IVTV_INFO("Firmware restart okay\n");
+ res = -EAGAIN;
+ } else {
+ IVTV_INFO("Firmware restart failed\n");
+ }
+ } else if (res) {
+ res = -EIO;
+ }
+
+ return res;
+}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.h b/drivers/media/video/ivtv/ivtv-firmware.h
index 041ba94e65bc..52bb4e5598fd 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.h
+++ b/drivers/media/video/ivtv/ivtv-firmware.h
@@ -26,5 +26,6 @@ int ivtv_firmware_init(struct ivtv *itv);
void ivtv_firmware_versions(struct ivtv *itv);
void ivtv_halt_firmware(struct ivtv *itv);
void ivtv_init_mpeg_decoder(struct ivtv *itv);
+int ivtv_firmware_check(struct ivtv *itv, char *where);
#endif
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index a5b92d109c6c..499016f5d32f 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -182,8 +182,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
return -1;
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, type, I2C_NAME_SIZE);
- return i2c_new_probed_device(adap, &info, addr_list) == NULL
- ? -1 : 0;
+ return i2c_new_probed_device(adap, &info, addr_list, NULL)
+ == NULL ? -1 : 0;
}
/* Only allow one IR receiver to be registered per board */
@@ -220,7 +220,8 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
info.platform_data = init_data;
strlcpy(info.type, type, I2C_NAME_SIZE);
- return i2c_new_probed_device(adap, &info, addr_list) == NULL ? -1 : 0;
+ return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ?
+ -1 : 0;
}
/* Instantiate the IR receiver device using probing -- undesirable */
@@ -248,7 +249,7 @@ struct i2c_client *ivtv_i2c_new_ir_legacy(struct ivtv *itv)
memset(&info, 0, sizeof(struct i2c_board_info));
strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
- return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+ return i2c_new_probed_device(&itv->i2c_adap, &info, addr_list, NULL);
}
int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.c b/drivers/media/video/ivtv/ivtv-mailbox.c
index 84577f6f41a2..e3ce96763785 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.c
+++ b/drivers/media/video/ivtv/ivtv-mailbox.c
@@ -377,3 +377,11 @@ void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb,
for (i = 0; i < argc; i++, p++)
data[i] = readl(p);
}
+
+/* Wipe api cache */
+void ivtv_mailbox_cache_invalidate(struct ivtv *itv)
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ itv->api_cache[i].last_jiffies = 0;
+}
diff --git a/drivers/media/video/ivtv/ivtv-mailbox.h b/drivers/media/video/ivtv/ivtv-mailbox.h
index 8247662c928e..2c834d2cb56f 100644
--- a/drivers/media/video/ivtv/ivtv-mailbox.h
+++ b/drivers/media/video/ivtv/ivtv-mailbox.h
@@ -30,5 +30,6 @@ int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[]);
int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...);
int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...);
int ivtv_api_func(void *priv, u32 cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA]);
+void ivtv_mailbox_cache_invalidate(struct ivtv *itv);
#endif
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index a937e2ff9b6e..55df4190c28d 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -42,6 +42,7 @@
#include "ivtv-yuv.h"
#include "ivtv-cards.h"
#include "ivtv-streams.h"
+#include "ivtv-firmware.h"
#include <media/v4l2-event.h>
static const struct v4l2_file_operations ivtv_v4l2_enc_fops = {
@@ -674,12 +675,14 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
/* Decoder sometimes dies here, so wait a moment */
ivtv_msleep_timeout(10, 0);
- return 0;
+ /* Known failure point for firmware, so check */
+ return ivtv_firmware_check(itv, "ivtv_setup_v4l2_decode_stream");
}
int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
{
struct ivtv *itv = s->itv;
+ int rc;
if (s->vdev == NULL)
return -EINVAL;
@@ -689,7 +692,11 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
IVTV_DEBUG_INFO("Starting decode stream %s (gop_offset %d)\n", s->name, gop_offset);
- ivtv_setup_v4l2_decode_stream(s);
+ rc = ivtv_setup_v4l2_decode_stream(s);
+ if (rc < 0) {
+ clear_bit(IVTV_F_S_STREAMING, &s->s_flags);
+ return rc;
+ }
/* set dma size to 65536 bytes */
ivtv_vapi(itv, CX2341X_DEC_SET_DMA_BLOCK_SIZE, 1, 65536);
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index b530dec399d3..b67a4048f5aa 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -23,7 +23,7 @@
#define IVTV_DRIVER_NAME "ivtv"
#define IVTV_DRIVER_VERSION_MAJOR 1
#define IVTV_DRIVER_VERSION_MINOR 4
-#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
+#define IVTV_DRIVER_VERSION_PATCHLEVEL 2
#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 9ff3425891ed..2c2d862ca89f 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -53,6 +53,7 @@
#include "ivtv-i2c.h"
#include "ivtv-udma.h"
#include "ivtv-mailbox.h"
+#include "ivtv-firmware.h"
/* card parameters */
static int ivtvfb_card_id = -1;
@@ -178,6 +179,12 @@ struct osd_info {
struct fb_info ivtvfb_info;
struct fb_var_screeninfo ivtvfb_defined;
struct fb_fix_screeninfo ivtvfb_fix;
+
+ /* Used for a warm start */
+ struct fb_var_screeninfo fbvar_cur;
+ int blank_cur;
+ u32 palette_cur[256];
+ u32 pan_cur;
};
struct ivtv_osd_coords {
@@ -199,6 +206,7 @@ static int ivtvfb_get_framebuffer(struct ivtv *itv, u32 *fbbase,
u32 data[CX2341X_MBOX_MAX_DATA];
int rc;
+ ivtv_firmware_check(itv, "ivtvfb_get_framebuffer");
rc = ivtv_vapi_result(itv, data, CX2341X_OSD_GET_FRAMEBUFFER, 0);
*fbbase = data[0];
*fblength = data[1];
@@ -581,8 +589,10 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
ivtv_window.height = var->yres;
/* Minimum margin cannot be 0, as X won't allow such a mode */
- if (!var->upper_margin) var->upper_margin++;
- if (!var->left_margin) var->left_margin++;
+ if (!var->upper_margin)
+ var->upper_margin++;
+ if (!var->left_margin)
+ var->left_margin++;
ivtv_window.top = var->upper_margin - 1;
ivtv_window.left = var->left_margin - 1;
@@ -595,6 +605,9 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
/* Force update of yuv registers */
itv->yuv_info.yuv_forced_update = 1;
+ /* Keep a copy of these settings */
+ memcpy(&oi->fbvar_cur, var, sizeof(oi->fbvar_cur));
+
IVTVFB_DEBUG_INFO("Display size: %dx%d (virtual %dx%d) @ %dbpp\n",
var->xres, var->yres,
var->xres_virtual, var->yres_virtual,
@@ -829,6 +842,8 @@ static int ivtvfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *inf
itv->yuv_info.osd_y_pan = var->yoffset;
/* Force update of yuv registers */
itv->yuv_info.yuv_forced_update = 1;
+ /* Remember this value */
+ itv->osd_info->pan_cur = osd_pan_index;
return 0;
}
@@ -842,6 +857,7 @@ static int ivtvfb_set_par(struct fb_info *info)
rc = ivtvfb_set_var(itv, &info->var);
ivtvfb_pan_display(&info->var, info);
ivtvfb_get_fix(itv, &info->fix);
+ ivtv_firmware_check(itv, "ivtvfb_set_par");
return rc;
}
@@ -859,6 +875,7 @@ static int ivtvfb_setcolreg(unsigned regno, unsigned red, unsigned green,
if (info->var.bits_per_pixel <= 8) {
write_reg(regno, 0x02a30);
write_reg(color, 0x02a34);
+ itv->osd_info->palette_cur[regno] = color;
return 0;
}
if (regno >= 16)
@@ -911,6 +928,7 @@ static int ivtvfb_blank(int blank_mode, struct fb_info *info)
ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, 0);
break;
}
+ itv->osd_info->blank_cur = blank_mode;
return 0;
}
@@ -929,6 +947,21 @@ static struct fb_ops ivtvfb_ops = {
.fb_blank = ivtvfb_blank,
};
+/* Restore hardware after firmware restart */
+static void ivtvfb_restore(struct ivtv *itv)
+{
+ struct osd_info *oi = itv->osd_info;
+ int i;
+
+ ivtvfb_set_var(itv, &oi->fbvar_cur);
+ ivtvfb_blank(oi->blank_cur, &oi->ivtvfb_info);
+ for (i = 0; i < 256; i++) {
+ write_reg(i, 0x02a30);
+ write_reg(oi->palette_cur[i], 0x02a34);
+ }
+ write_reg(oi->pan_cur, 0x02a0c);
+}
+
/* Initialization */
@@ -1192,6 +1225,9 @@ static int ivtvfb_init_card(struct ivtv *itv)
/* Enable the osd */
ivtvfb_blank(FB_BLANK_UNBLANK, &itv->osd_info->ivtvfb_info);
+ /* Enable restart */
+ itv->ivtvfb_restore = ivtvfb_restore;
+
/* Allocate DMA */
ivtv_udma_alloc(itv);
return 0;
@@ -1226,6 +1262,7 @@ static int ivtvfb_callback_cleanup(struct device *dev, void *p)
return 0;
}
IVTVFB_INFO("Unregister framebuffer %d\n", itv->instance);
+ itv->ivtvfb_restore = NULL;
ivtvfb_blank(FB_BLANK_VSYNC_SUSPEND, &oi->ivtvfb_info);
ivtvfb_release_buffers(itv);
itv->osd_video_pbase = 0;
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index f85b2ed8a2d8..926a5aa6f7f8 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -426,7 +426,7 @@ static void omap24xxcam_vbq_release(struct videobuf_queue *vbq,
dma->direction);
dma->direction = DMA_NONE;
} else {
- videobuf_dma_unmap(vbq, videobuf_to_dma(vb));
+ videobuf_dma_unmap(vbq->dev, videobuf_to_dma(vb));
videobuf_dma_free(videobuf_to_dma(vb));
}
diff --git a/drivers/media/video/ov511.c b/drivers/media/video/ov511.c
deleted file mode 100644
index a10912097b7a..000000000000
--- a/drivers/media/video/ov511.c
+++ /dev/null
@@ -1,5995 +0,0 @@
-/*
- * OmniVision OV511 Camera-to-USB Bridge Driver
- *
- * Copyright (c) 1999-2003 Mark W. McClelland
- * Original decompression code Copyright 1998-2000 OmniVision Technologies
- * Many improvements by Bret Wallach <bwallac1@san.rr.com>
- * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
- * Snapshot code by Kevin Moore
- * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
- * Changes by Claudio Matsuoka <claudio@conectiva.com>
- * Original SAA7111A code by Dave Perks <dperks@ibm.net>
- * URB error messages from pwc driver by Nemosoft
- * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox
- * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others
- *
- * Based on the Linux CPiA driver written by Peter Pregler,
- * Scott J. Bertin and Johannes Erdfelt.
- *
- * Please see the file: Documentation/usb/ov511.txt
- * and the website at: http://alpha.dyndns.org/ov511
- * for more info.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/pagemap.h>
-#include <asm/processor.h>
-#include <linux/mm.h>
-#include <linux/device.h>
-
-#if defined (__i386__)
- #include <asm/cpufeature.h>
-#endif
-
-#include "ov511.h"
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v1.64 for Linux 2.5"
-#define EMAIL "mark@alpha.dyndns.org"
-#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org> & Bret Wallach \
-& Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha \
-<cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
-#define DRIVER_DESC "ov511 USB Camera Driver"
-
-#define OV511_I2C_RETRIES 3
-#define ENABLE_Y_QUANTABLE 1
-#define ENABLE_UV_QUANTABLE 1
-
-#define OV511_MAX_UNIT_VIDEO 16
-
-/* Pixel count * bytes per YUV420 pixel (1.5) */
-#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2)
-
-#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval))
-
-/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */
-#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024)
-
-#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM)
-
-/**********************************************************************
- * Module Parameters
- * (See ov511.txt for detailed descriptions of these)
- **********************************************************************/
-
-/* These variables (and all static globals) default to zero */
-static int autobright = 1;
-static int autogain = 1;
-static int autoexp = 1;
-static int debug;
-static int snapshot;
-static int cams = 1;
-static int compress;
-static int testpat;
-static int dumppix;
-static int led = 1;
-static int dump_bridge;
-static int dump_sensor;
-static int printph;
-static int phy = 0x1f;
-static int phuv = 0x05;
-static int pvy = 0x06;
-static int pvuv = 0x06;
-static int qhy = 0x14;
-static int qhuv = 0x03;
-static int qvy = 0x04;
-static int qvuv = 0x04;
-static int lightfreq;
-static int bandingfilter;
-static int clockdiv = -1;
-static int packetsize = -1;
-static int framedrop = -1;
-static int fastset;
-static int force_palette;
-static int backlight;
-/* Bitmask marking allocated devices from 0 to OV511_MAX_UNIT_VIDEO */
-static unsigned long ov511_devused;
-static int unit_video[OV511_MAX_UNIT_VIDEO];
-static int remove_zeros;
-static int mirror;
-static int ov518_color;
-
-module_param(autobright, int, 0);
-MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness");
-module_param(autogain, int, 0);
-MODULE_PARM_DESC(autogain, "Sensor automatically changes gain");
-module_param(autoexp, int, 0);
-MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure");
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug,
- "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max");
-module_param(snapshot, int, 0);
-MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
-module_param(cams, int, 0);
-MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
-module_param(compress, int, 0);
-MODULE_PARM_DESC(compress, "Turn on compression");
-module_param(testpat, int, 0);
-MODULE_PARM_DESC(testpat,
- "Replace image with vertical bar testpattern (only partially working)");
-module_param(dumppix, int, 0);
-MODULE_PARM_DESC(dumppix, "Dump raw pixel data");
-module_param(led, int, 0);
-MODULE_PARM_DESC(led,
- "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)");
-module_param(dump_bridge, int, 0);
-MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers");
-module_param(dump_sensor, int, 0);
-MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers");
-module_param(printph, int, 0);
-MODULE_PARM_DESC(printph, "Print frame start/end headers");
-module_param(phy, int, 0);
-MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)");
-module_param(phuv, int, 0);
-MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)");
-module_param(pvy, int, 0);
-MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)");
-module_param(pvuv, int, 0);
-MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)");
-module_param(qhy, int, 0);
-MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)");
-module_param(qhuv, int, 0);
-MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)");
-module_param(qvy, int, 0);
-MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)");
-module_param(qvuv, int, 0);
-MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)");
-module_param(lightfreq, int, 0);
-MODULE_PARM_DESC(lightfreq,
- "Light frequency. Set to 50 or 60 Hz, or zero for default settings");
-module_param(bandingfilter, int, 0);
-MODULE_PARM_DESC(bandingfilter,
- "Enable banding filter (to reduce effects of fluorescent lighting)");
-module_param(clockdiv, int, 0);
-MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value");
-module_param(packetsize, int, 0);
-MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size");
-module_param(framedrop, int, 0);
-MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting");
-module_param(fastset, int, 0);
-MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately");
-module_param(force_palette, int, 0);
-MODULE_PARM_DESC(force_palette, "Force the palette to a specific value");
-module_param(backlight, int, 0);
-MODULE_PARM_DESC(backlight, "For objects that are lit from behind");
-static unsigned int num_uv;
-module_param_array(unit_video, int, &num_uv, 0);
-MODULE_PARM_DESC(unit_video,
- "Force use of specific minor number(s). 0 is not allowed.");
-module_param(remove_zeros, int, 0);
-MODULE_PARM_DESC(remove_zeros,
- "Remove zero-padding from uncompressed incoming data");
-module_param(mirror, int, 0);
-MODULE_PARM_DESC(mirror, "Reverse image horizontally");
-module_param(ov518_color, int, 0);
-MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)");
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-/**********************************************************************
- * Miscellaneous Globals
- **********************************************************************/
-
-static struct usb_driver ov511_driver;
-
-/* Number of times to retry a failed I2C transaction. Increase this if you
- * are getting "Failed to read sensor ID..." */
-static const int i2c_detect_tries = 5;
-
-static struct usb_device_id device_table [] = {
- { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) },
- { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) },
- { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) },
- { } /* Terminating entry */
-};
-
-MODULE_DEVICE_TABLE (usb, device_table);
-
-static unsigned char yQuanTable511[] = OV511_YQUANTABLE;
-static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE;
-static unsigned char yQuanTable518[] = OV518_YQUANTABLE;
-static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE;
-
-/**********************************************************************
- * Symbolic Names
- **********************************************************************/
-
-/* Known OV511-based cameras */
-static struct symbolic_list camlist[] = {
- { 0, "Generic Camera (no ID)" },
- { 1, "Mustek WCam 3X" },
- { 3, "D-Link DSB-C300" },
- { 4, "Generic OV511/OV7610" },
- { 5, "Puretek PT-6007" },
- { 6, "Lifeview USB Life TV (NTSC)" },
- { 21, "Creative Labs WebCam 3" },
- { 22, "Lifeview USB Life TV (PAL D/K+B/G)" },
- { 36, "Koala-Cam" },
- { 38, "Lifeview USB Life TV (PAL)" },
- { 41, "Samsung Anycam MPC-M10" },
- { 43, "Mtekvision Zeca MV402" },
- { 46, "Suma eON" },
- { 70, "Lifeview USB Life TV (PAL/SECAM)" },
- { 100, "Lifeview RoboCam" },
- { 102, "AverMedia InterCam Elite" },
- { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */
- { 134, "Ezonics EZCam II" },
- { 192, "Webeye 2000B" },
- { 253, "Alpha Vision Tech. AlphaCam SE" },
- { -1, NULL }
-};
-
-/* Video4Linux1 Palettes */
-static struct symbolic_list v4l1_plist[] = {
- { VIDEO_PALETTE_GREY, "GREY" },
- { VIDEO_PALETTE_HI240, "HI240" },
- { VIDEO_PALETTE_RGB565, "RGB565" },
- { VIDEO_PALETTE_RGB24, "RGB24" },
- { VIDEO_PALETTE_RGB32, "RGB32" },
- { VIDEO_PALETTE_RGB555, "RGB555" },
- { VIDEO_PALETTE_YUV422, "YUV422" },
- { VIDEO_PALETTE_YUYV, "YUYV" },
- { VIDEO_PALETTE_UYVY, "UYVY" },
- { VIDEO_PALETTE_YUV420, "YUV420" },
- { VIDEO_PALETTE_YUV411, "YUV411" },
- { VIDEO_PALETTE_RAW, "RAW" },
- { VIDEO_PALETTE_YUV422P,"YUV422P" },
- { VIDEO_PALETTE_YUV411P,"YUV411P" },
- { VIDEO_PALETTE_YUV420P,"YUV420P" },
- { VIDEO_PALETTE_YUV410P,"YUV410P" },
- { -1, NULL }
-};
-
-static struct symbolic_list brglist[] = {
- { BRG_OV511, "OV511" },
- { BRG_OV511PLUS, "OV511+" },
- { BRG_OV518, "OV518" },
- { BRG_OV518PLUS, "OV518+" },
- { -1, NULL }
-};
-
-static struct symbolic_list senlist[] = {
- { SEN_OV76BE, "OV76BE" },
- { SEN_OV7610, "OV7610" },
- { SEN_OV7620, "OV7620" },
- { SEN_OV7620AE, "OV7620AE" },
- { SEN_OV6620, "OV6620" },
- { SEN_OV6630, "OV6630" },
- { SEN_OV6630AE, "OV6630AE" },
- { SEN_OV6630AF, "OV6630AF" },
- { SEN_OV8600, "OV8600" },
- { SEN_KS0127, "KS0127" },
- { SEN_KS0127B, "KS0127B" },
- { SEN_SAA7111A, "SAA7111A" },
- { -1, NULL }
-};
-
-/* URB error codes: */
-static struct symbolic_list urb_errlist[] = {
- { -ENOSR, "Buffer error (overrun)" },
- { -EPIPE, "Stalled (device not responding)" },
- { -EOVERFLOW, "Babble (device sends too much data)" },
- { -EPROTO, "Bit-stuff error (bad cable?)" },
- { -EILSEQ, "CRC/Timeout (bad cable?)" },
- { -ETIME, "Device does not respond to token" },
- { -ETIMEDOUT, "Device does not respond to command" },
- { -1, NULL }
-};
-
-/**********************************************************************
- * Memory management
- **********************************************************************/
-static void *
-rvmalloc(unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return mem;
-}
-
-static void
-rvfree(void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
-
-/**********************************************************************
- *
- * Register I/O
- *
- **********************************************************************/
-
-/* Write an OV51x register */
-static int
-reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
-{
- int rc;
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
- mutex_lock(&ov->cbuf_lock);
- ov->cbuf[0] = value;
- rc = usb_control_msg(ov->dev,
- usb_sndctrlpipe(ov->dev, 0),
- (ov->bclass == BCL_OV518)?1:2 /* REG_IO */,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
- mutex_unlock(&ov->cbuf_lock);
-
- if (rc < 0)
- err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc));
-
- return rc;
-}
-
-/* Read from an OV51x register */
-/* returns: negative is error, pos or zero is data */
-static int
-reg_r(struct usb_ov511 *ov, unsigned char reg)
-{
- int rc;
-
- mutex_lock(&ov->cbuf_lock);
- rc = usb_control_msg(ov->dev,
- usb_rcvctrlpipe(ov->dev, 0),
- (ov->bclass == BCL_OV518)?1:3 /* REG_IO */,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, &ov->cbuf[0], 1, 1000);
-
- if (rc < 0) {
- err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc));
- } else {
- rc = ov->cbuf[0];
- PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]);
- }
-
- mutex_unlock(&ov->cbuf_lock);
-
- return rc;
-}
-
-/*
- * Writes bits at positions specified by mask to an OV51x reg. Bits that are in
- * the same position as 1's in "mask" are cleared and set to "value". Bits
- * that are in the same position as 0's in "mask" are preserved, regardless
- * of their respective state in "value".
- */
-static int
-reg_w_mask(struct usb_ov511 *ov,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
-{
- int ret;
- unsigned char oldval, newval;
-
- ret = reg_r(ov, reg);
- if (ret < 0)
- return ret;
-
- oldval = (unsigned char) ret;
- oldval &= (~mask); /* Clear the masked bits */
- value &= mask; /* Enforce mask on value */
- newval = oldval | value; /* Set the desired bits */
-
- return (reg_w(ov, reg, newval));
-}
-
-/*
- * Writes multiple (n) byte value to a single register. Only valid with certain
- * registers (0x30 and 0xc4 - 0xce).
- */
-static int
-ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n)
-{
- int rc;
-
- PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n);
-
- mutex_lock(&ov->cbuf_lock);
-
- *((__le32 *)ov->cbuf) = __cpu_to_le32(val);
-
- rc = usb_control_msg(ov->dev,
- usb_sndctrlpipe(ov->dev, 0),
- 1 /* REG_IO */,
- USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, (__u16)reg, ov->cbuf, n, 1000);
- mutex_unlock(&ov->cbuf_lock);
-
- if (rc < 0)
- err("reg write multiple: error %d: %s", rc,
- symbolic(urb_errlist, rc));
-
- return rc;
-}
-
-static int
-ov511_upload_quan_tables(struct usb_ov511 *ov)
-{
- unsigned char *pYTable = yQuanTable511;
- unsigned char *pUVTable = uvQuanTable511;
- unsigned char val0, val1;
- int i, rc, reg = R511_COMP_LUT_BEGIN;
-
- PDEBUG(4, "Uploading quantization tables");
-
- for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) {
- if (ENABLE_Y_QUANTABLE) {
- val0 = *pYTable++;
- val1 = *pYTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- rc = reg_w(ov, reg, val0);
- if (rc < 0)
- return rc;
- }
-
- if (ENABLE_UV_QUANTABLE) {
- val0 = *pUVTable++;
- val1 = *pUVTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0);
- if (rc < 0)
- return rc;
- }
-
- reg++;
- }
-
- return 0;
-}
-
-/* OV518 quantization tables are 8x4 (instead of 8x8) */
-static int
-ov518_upload_quan_tables(struct usb_ov511 *ov)
-{
- unsigned char *pYTable = yQuanTable518;
- unsigned char *pUVTable = uvQuanTable518;
- unsigned char val0, val1;
- int i, rc, reg = R511_COMP_LUT_BEGIN;
-
- PDEBUG(4, "Uploading quantization tables");
-
- for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) {
- if (ENABLE_Y_QUANTABLE) {
- val0 = *pYTable++;
- val1 = *pYTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- rc = reg_w(ov, reg, val0);
- if (rc < 0)
- return rc;
- }
-
- if (ENABLE_UV_QUANTABLE) {
- val0 = *pUVTable++;
- val1 = *pUVTable++;
- val0 &= 0x0f;
- val1 &= 0x0f;
- val0 |= val1 << 4;
- rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0);
- if (rc < 0)
- return rc;
- }
-
- reg++;
- }
-
- return 0;
-}
-
-static int
-ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type)
-{
- int rc;
-
- /* Setting bit 0 not allowed on 518/518Plus */
- if (ov->bclass == BCL_OV518)
- reset_type &= 0xfe;
-
- PDEBUG(4, "Reset: type=0x%02X", reset_type);
-
- rc = reg_w(ov, R51x_SYS_RESET, reset_type);
- rc = reg_w(ov, R51x_SYS_RESET, 0);
-
- if (rc < 0)
- err("reset: command failed");
-
- return rc;
-}
-
-/**********************************************************************
- *
- * Low-level I2C I/O functions
- *
- **********************************************************************/
-
-/* NOTE: Do not call this function directly!
- * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from i2c_w(). Note that this function
- * always succeeds regardless of whether the sensor is present and working.
- */
-static int
-ov518_i2c_write_internal(struct usb_ov511 *ov,
- unsigned char reg,
- unsigned char value)
-{
- int rc;
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
- /* Select camera register */
- rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- return rc;
-
- /* Write "value" to I2C data port of OV511 */
- rc = reg_w(ov, R51x_I2C_DATA, value);
- if (rc < 0)
- return rc;
-
- /* Initiate 3-byte write cycle */
- rc = reg_w(ov, R518_I2C_CTL, 0x01);
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-/* NOTE: Do not call this function directly! */
-static int
-ov511_i2c_write_internal(struct usb_ov511 *ov,
- unsigned char reg,
- unsigned char value)
-{
- int rc, retries;
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
- /* Three byte write cycle */
- for (retries = OV511_I2C_RETRIES; ; ) {
- /* Select camera register */
- rc = reg_w(ov, R51x_I2C_SADDR_3, reg);
- if (rc < 0)
- break;
-
- /* Write "value" to I2C data port of OV511 */
- rc = reg_w(ov, R51x_I2C_DATA, value);
- if (rc < 0)
- break;
-
- /* Initiate 3-byte write cycle */
- rc = reg_w(ov, R511_I2C_CTL, 0x01);
- if (rc < 0)
- break;
-
- /* Retry until idle */
- do {
- rc = reg_r(ov, R511_I2C_CTL);
- } while (rc > 0 && ((rc&1) == 0));
- if (rc < 0)
- break;
-
- /* Ack? */
- if ((rc&2) == 0) {
- rc = 0;
- break;
- }
-#if 0
- /* I2C abort */
- reg_w(ov, R511_I2C_CTL, 0x10);
-#endif
- if (--retries < 0) {
- err("i2c write retries exhausted");
- rc = -1;
- break;
- }
- }
-
- return rc;
-}
-
-/* NOTE: Do not call this function directly!
- * The OV518 I2C I/O procedure is different, hence, this function.
- * This is normally only called from i2c_r(). Note that this function
- * always succeeds regardless of whether the sensor is present and working.
- */
-static int
-ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
-{
- int rc, value;
-
- /* Select camera register */
- rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
-
- /* Initiate 2-byte write cycle */
- rc = reg_w(ov, R518_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
-
- /* Initiate 2-byte read cycle */
- rc = reg_w(ov, R518_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
-
- value = reg_r(ov, R51x_I2C_DATA);
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
- return value;
-}
-
-/* NOTE: Do not call this function directly!
- * returns: negative is error, pos or zero is data */
-static int
-ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg)
-{
- int rc, value, retries;
-
- /* Two byte write cycle */
- for (retries = OV511_I2C_RETRIES; ; ) {
- /* Select camera register */
- rc = reg_w(ov, R51x_I2C_SADDR_2, reg);
- if (rc < 0)
- return rc;
-
- /* Initiate 2-byte write cycle */
- rc = reg_w(ov, R511_I2C_CTL, 0x03);
- if (rc < 0)
- return rc;
-
- /* Retry until idle */
- do {
- rc = reg_r(ov, R511_I2C_CTL);
- } while (rc > 0 && ((rc & 1) == 0));
- if (rc < 0)
- return rc;
-
- if ((rc&2) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- reg_w(ov, R511_I2C_CTL, 0x10);
-
- if (--retries < 0) {
- err("i2c write retries exhausted");
- return -1;
- }
- }
-
- /* Two byte read cycle */
- for (retries = OV511_I2C_RETRIES; ; ) {
- /* Initiate 2-byte read cycle */
- rc = reg_w(ov, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
-
- /* Retry until idle */
- do {
- rc = reg_r(ov, R511_I2C_CTL);
- } while (rc > 0 && ((rc&1) == 0));
- if (rc < 0)
- return rc;
-
- if ((rc&2) == 0) /* Ack? */
- break;
-
- /* I2C abort */
- rc = reg_w(ov, R511_I2C_CTL, 0x10);
- if (rc < 0)
- return rc;
-
- if (--retries < 0) {
- err("i2c read retries exhausted");
- return -1;
- }
- }
-
- value = reg_r(ov, R51x_I2C_DATA);
-
- PDEBUG(5, "0x%02X:0x%02X", reg, value);
-
- /* This is needed to make i2c_w() work */
- rc = reg_w(ov, R511_I2C_CTL, 0x05);
- if (rc < 0)
- return rc;
-
- return value;
-}
-
-/* returns: negative is error, pos or zero is data */
-static int
-i2c_r(struct usb_ov511 *ov, unsigned char reg)
-{
- int rc;
-
- mutex_lock(&ov->i2c_lock);
-
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_read_internal(ov, reg);
- else
- rc = ov511_i2c_read_internal(ov, reg);
-
- mutex_unlock(&ov->i2c_lock);
-
- return rc;
-}
-
-static int
-i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value)
-{
- int rc;
-
- mutex_lock(&ov->i2c_lock);
-
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_write_internal(ov, reg, value);
- else
- rc = ov511_i2c_write_internal(ov, reg, value);
-
- mutex_unlock(&ov->i2c_lock);
-
- return rc;
-}
-
-/* Do not call this function directly! */
-static int
-ov51x_i2c_write_mask_internal(struct usb_ov511 *ov,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
-{
- int rc;
- unsigned char oldval, newval;
-
- if (mask == 0xff) {
- newval = value;
- } else {
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_read_internal(ov, reg);
- else
- rc = ov511_i2c_read_internal(ov, reg);
- if (rc < 0)
- return rc;
-
- oldval = (unsigned char) rc;
- oldval &= (~mask); /* Clear the masked bits */
- value &= mask; /* Enforce mask on value */
- newval = oldval | value; /* Set the desired bits */
- }
-
- if (ov->bclass == BCL_OV518)
- return (ov518_i2c_write_internal(ov, reg, newval));
- else
- return (ov511_i2c_write_internal(ov, reg, newval));
-}
-
-/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
- * the same position as 1's in "mask" are cleared and set to "value". Bits
- * that are in the same position as 0's in "mask" are preserved, regardless
- * of their respective state in "value".
- */
-static int
-i2c_w_mask(struct usb_ov511 *ov,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
-{
- int rc;
-
- mutex_lock(&ov->i2c_lock);
- rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
- mutex_unlock(&ov->i2c_lock);
-
- return rc;
-}
-
-/* Set the read and write slave IDs. The "slave" argument is the write slave,
- * and the read slave will be set to (slave + 1). ov->i2c_lock should be held
- * when calling this. This should not be called from outside the i2c I/O
- * functions.
- */
-static int
-i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave)
-{
- int rc;
-
- rc = reg_w(ov, R51x_I2C_W_SID, slave);
- if (rc < 0)
- return rc;
-
- rc = reg_w(ov, R51x_I2C_R_SID, slave + 1);
- if (rc < 0)
- return rc;
-
- return 0;
-}
-
-/* Write to a specific I2C slave ID and register, using the specified mask */
-static int
-i2c_w_slave(struct usb_ov511 *ov,
- unsigned char slave,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
-{
- int rc = 0;
-
- mutex_lock(&ov->i2c_lock);
-
- /* Set new slave IDs */
- rc = i2c_set_slave_internal(ov, slave);
- if (rc < 0)
- goto out;
-
- rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask);
-
-out:
- /* Restore primary IDs */
- if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
- err("Couldn't restore primary I2C slave");
-
- mutex_unlock(&ov->i2c_lock);
- return rc;
-}
-
-/* Read from a specific I2C slave ID and register */
-static int
-i2c_r_slave(struct usb_ov511 *ov,
- unsigned char slave,
- unsigned char reg)
-{
- int rc;
-
- mutex_lock(&ov->i2c_lock);
-
- /* Set new slave IDs */
- rc = i2c_set_slave_internal(ov, slave);
- if (rc < 0)
- goto out;
-
- if (ov->bclass == BCL_OV518)
- rc = ov518_i2c_read_internal(ov, reg);
- else
- rc = ov511_i2c_read_internal(ov, reg);
-
-out:
- /* Restore primary IDs */
- if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0)
- err("Couldn't restore primary I2C slave");
-
- mutex_unlock(&ov->i2c_lock);
- return rc;
-}
-
-/* Sets I2C read and write slave IDs. Returns <0 for error */
-static int
-ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid)
-{
- int rc;
-
- mutex_lock(&ov->i2c_lock);
-
- rc = i2c_set_slave_internal(ov, sid);
- if (rc < 0)
- goto out;
-
- // FIXME: Is this actually necessary?
- rc = ov51x_reset(ov, OV511_RESET_NOREGS);
-out:
- mutex_unlock(&ov->i2c_lock);
- return rc;
-}
-
-static int
-write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals)
-{
- int rc;
-
- while (pRegvals->bus != OV511_DONE_BUS) {
- if (pRegvals->bus == OV511_REG_BUS) {
- if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0)
- return rc;
- } else if (pRegvals->bus == OV511_I2C_BUS) {
- if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0)
- return rc;
- } else {
- err("Bad regval array");
- return -1;
- }
- pRegvals++;
- }
- return 0;
-}
-
-#ifdef OV511_DEBUG
-static void
-dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn)
-{
- int i, rc;
-
- for (i = reg1; i <= regn; i++) {
- rc = i2c_r(ov, i);
- dev_info(&ov->dev->dev, "Sensor[0x%02X] = 0x%02X\n", i, rc);
- }
-}
-
-static void
-dump_i2c_regs(struct usb_ov511 *ov)
-{
- dev_info(&ov->dev->dev, "I2C REGS\n");
- dump_i2c_range(ov, 0x00, 0x7C);
-}
-
-static void
-dump_reg_range(struct usb_ov511 *ov, int reg1, int regn)
-{
- int i, rc;
-
- for (i = reg1; i <= regn; i++) {
- rc = reg_r(ov, i);
- dev_info(&ov->dev->dev, "OV511[0x%02X] = 0x%02X\n", i, rc);
- }
-}
-
-static void
-ov511_dump_regs(struct usb_ov511 *ov)
-{
- dev_info(&ov->dev->dev, "CAMERA INTERFACE REGS\n");
- dump_reg_range(ov, 0x10, 0x1f);
- dev_info(&ov->dev->dev, "DRAM INTERFACE REGS\n");
- dump_reg_range(ov, 0x20, 0x23);
- dev_info(&ov->dev->dev, "ISO FIFO REGS\n");
- dump_reg_range(ov, 0x30, 0x31);
- dev_info(&ov->dev->dev, "PIO REGS\n");
- dump_reg_range(ov, 0x38, 0x39);
- dump_reg_range(ov, 0x3e, 0x3e);
- dev_info(&ov->dev->dev, "I2C REGS\n");
- dump_reg_range(ov, 0x40, 0x49);
- dev_info(&ov->dev->dev, "SYSTEM CONTROL REGS\n");
- dump_reg_range(ov, 0x50, 0x55);
- dump_reg_range(ov, 0x5e, 0x5f);
- dev_info(&ov->dev->dev, "OmniCE REGS\n");
- dump_reg_range(ov, 0x70, 0x79);
- /* NOTE: Quantization tables are not readable. You will get the value
- * in reg. 0x79 for every table register */
- dump_reg_range(ov, 0x80, 0x9f);
- dump_reg_range(ov, 0xa0, 0xbf);
-
-}
-
-static void
-ov518_dump_regs(struct usb_ov511 *ov)
-{
- dev_info(&ov->dev->dev, "VIDEO MODE REGS\n");
- dump_reg_range(ov, 0x20, 0x2f);
- dev_info(&ov->dev->dev, "DATA PUMP AND SNAPSHOT REGS\n");
- dump_reg_range(ov, 0x30, 0x3f);
- dev_info(&ov->dev->dev, "I2C REGS\n");
- dump_reg_range(ov, 0x40, 0x4f);
- dev_info(&ov->dev->dev, "SYSTEM CONTROL AND VENDOR REGS\n");
- dump_reg_range(ov, 0x50, 0x5f);
- dev_info(&ov->dev->dev, "60 - 6F\n");
- dump_reg_range(ov, 0x60, 0x6f);
- dev_info(&ov->dev->dev, "70 - 7F\n");
- dump_reg_range(ov, 0x70, 0x7f);
- dev_info(&ov->dev->dev, "Y QUANTIZATION TABLE\n");
- dump_reg_range(ov, 0x80, 0x8f);
- dev_info(&ov->dev->dev, "UV QUANTIZATION TABLE\n");
- dump_reg_range(ov, 0x90, 0x9f);
- dev_info(&ov->dev->dev, "A0 - BF\n");
- dump_reg_range(ov, 0xa0, 0xbf);
- dev_info(&ov->dev->dev, "CBR\n");
- dump_reg_range(ov, 0xc0, 0xcf);
-}
-#endif
-
-/*****************************************************************************/
-
-/* Temporarily stops OV511 from functioning. Must do this before changing
- * registers while the camera is streaming */
-static inline int
-ov51x_stop(struct usb_ov511 *ov)
-{
- PDEBUG(4, "stopping");
- ov->stopped = 1;
- if (ov->bclass == BCL_OV518)
- return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a));
- else
- return (reg_w(ov, R51x_SYS_RESET, 0x3d));
-}
-
-/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not
- * actually stopped (for performance). */
-static inline int
-ov51x_restart(struct usb_ov511 *ov)
-{
- if (ov->stopped) {
- PDEBUG(4, "restarting");
- ov->stopped = 0;
-
- /* Reinitialize the stream */
- if (ov->bclass == BCL_OV518)
- reg_w(ov, 0x2f, 0x80);
-
- return (reg_w(ov, R51x_SYS_RESET, 0x00));
- }
-
- return 0;
-}
-
-/* Sleeps until no frames are active. Returns !0 if got signal */
-static int
-ov51x_wait_frames_inactive(struct usb_ov511 *ov)
-{
- return wait_event_interruptible(ov->wq, ov->curframe < 0);
-}
-
-/* Resets the hardware snapshot button */
-static void
-ov51x_clear_snapshot(struct usb_ov511 *ov)
-{
- if (ov->bclass == BCL_OV511) {
- reg_w(ov, R51x_SYS_SNAP, 0x00);
- reg_w(ov, R51x_SYS_SNAP, 0x02);
- reg_w(ov, R51x_SYS_SNAP, 0x00);
- } else if (ov->bclass == BCL_OV518) {
- dev_warn(&ov->dev->dev,
- "snapshot reset not supported yet on OV518(+)\n");
- } else {
- dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
- }
-}
-
-#if 0
-/* Checks the status of the snapshot button. Returns 1 if it was pressed since
- * it was last cleared, and zero in all other cases (including errors) */
-static int
-ov51x_check_snapshot(struct usb_ov511 *ov)
-{
- int ret, status = 0;
-
- if (ov->bclass == BCL_OV511) {
- ret = reg_r(ov, R51x_SYS_SNAP);
- if (ret < 0) {
- dev_err(&ov->dev->dev,
- "Error checking snspshot status (%d)\n", ret);
- } else if (ret & 0x08) {
- status = 1;
- }
- } else if (ov->bclass == BCL_OV518) {
- dev_warn(&ov->dev->dev,
- "snapshot check not supported yet on OV518(+)\n");
- } else {
- dev_err(&ov->dev->dev, "clear snap: invalid bridge type\n");
- }
-
- return status;
-}
-#endif
-
-/* This does an initial reset of an OmniVision sensor and ensures that I2C
- * is synchronized. Returns <0 for failure.
- */
-static int
-init_ov_sensor(struct usb_ov511 *ov)
-{
- int i, success;
-
- /* Reset the sensor */
- if (i2c_w(ov, 0x12, 0x80) < 0)
- return -EIO;
-
- /* Wait for it to initialize */
- msleep(150);
-
- for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
- if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
- (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
- success = 1;
- continue;
- }
-
- /* Reset the sensor */
- if (i2c_w(ov, 0x12, 0x80) < 0)
- return -EIO;
- /* Wait for it to initialize */
- msleep(150);
- /* Dummy read to sync I2C */
- if (i2c_r(ov, 0x00) < 0)
- return -EIO;
- }
-
- if (!success)
- return -EIO;
-
- PDEBUG(1, "I2C synced in %d attempt(s)", i);
-
- return 0;
-}
-
-static int
-ov511_set_packet_size(struct usb_ov511 *ov, int size)
-{
- int alt, mult;
-
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- mult = size >> 5;
-
- if (ov->bridge == BRG_OV511) {
- if (size == 0)
- alt = OV511_ALT_SIZE_0;
- else if (size == 257)
- alt = OV511_ALT_SIZE_257;
- else if (size == 513)
- alt = OV511_ALT_SIZE_513;
- else if (size == 769)
- alt = OV511_ALT_SIZE_769;
- else if (size == 993)
- alt = OV511_ALT_SIZE_993;
- else {
- err("Set packet size: invalid size (%d)", size);
- return -EINVAL;
- }
- } else if (ov->bridge == BRG_OV511PLUS) {
- if (size == 0)
- alt = OV511PLUS_ALT_SIZE_0;
- else if (size == 33)
- alt = OV511PLUS_ALT_SIZE_33;
- else if (size == 129)
- alt = OV511PLUS_ALT_SIZE_129;
- else if (size == 257)
- alt = OV511PLUS_ALT_SIZE_257;
- else if (size == 385)
- alt = OV511PLUS_ALT_SIZE_385;
- else if (size == 513)
- alt = OV511PLUS_ALT_SIZE_513;
- else if (size == 769)
- alt = OV511PLUS_ALT_SIZE_769;
- else if (size == 961)
- alt = OV511PLUS_ALT_SIZE_961;
- else {
- err("Set packet size: invalid size (%d)", size);
- return -EINVAL;
- }
- } else {
- err("Set packet size: Invalid bridge type");
- return -EINVAL;
- }
-
- PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt);
-
- if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0)
- return -EIO;
-
- if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
- err("Set packet size: set interface error");
- return -EBUSY;
- }
-
- if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
- return -EIO;
-
- ov->packet_size = size;
-
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return 0;
-}
-
-/* Note: Unlike the OV511/OV511+, the size argument does NOT include the
- * optional packet number byte. The actual size *is* stored in ov->packet_size,
- * though. */
-static int
-ov518_set_packet_size(struct usb_ov511 *ov, int size)
-{
- int alt;
-
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- if (ov->bclass == BCL_OV518) {
- if (size == 0)
- alt = OV518_ALT_SIZE_0;
- else if (size == 128)
- alt = OV518_ALT_SIZE_128;
- else if (size == 256)
- alt = OV518_ALT_SIZE_256;
- else if (size == 384)
- alt = OV518_ALT_SIZE_384;
- else if (size == 512)
- alt = OV518_ALT_SIZE_512;
- else if (size == 640)
- alt = OV518_ALT_SIZE_640;
- else if (size == 768)
- alt = OV518_ALT_SIZE_768;
- else if (size == 896)
- alt = OV518_ALT_SIZE_896;
- else {
- err("Set packet size: invalid size (%d)", size);
- return -EINVAL;
- }
- } else {
- err("Set packet size: Invalid bridge type");
- return -EINVAL;
- }
-
- PDEBUG(3, "%d, alt=%d", size, alt);
-
- ov->packet_size = size;
- if (size > 0) {
- /* Program ISO FIFO size reg (packet number isn't included) */
- ov518_reg_w32(ov, 0x30, size, 2);
-
- if (ov->packet_numbering)
- ++ov->packet_size;
- }
-
- if (usb_set_interface(ov->dev, ov->iface, alt) < 0) {
- err("Set packet size: set interface error");
- return -EBUSY;
- }
-
- /* Initialize the stream */
- if (reg_w(ov, 0x2f, 0x80) < 0)
- return -EIO;
-
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
- return -EIO;
-
- return 0;
-}
-
-/* Upload compression params and quantization tables. Returns 0 for success. */
-static int
-ov511_init_compression(struct usb_ov511 *ov)
-{
- int rc = 0;
-
- if (!ov->compress_inited) {
- reg_w(ov, 0x70, phy);
- reg_w(ov, 0x71, phuv);
- reg_w(ov, 0x72, pvy);
- reg_w(ov, 0x73, pvuv);
- reg_w(ov, 0x74, qhy);
- reg_w(ov, 0x75, qhuv);
- reg_w(ov, 0x76, qvy);
- reg_w(ov, 0x77, qvuv);
-
- if (ov511_upload_quan_tables(ov) < 0) {
- err("Error uploading quantization tables");
- rc = -EIO;
- goto out;
- }
- }
-
- ov->compress_inited = 1;
-out:
- return rc;
-}
-
-/* Upload compression params and quantization tables. Returns 0 for success. */
-static int
-ov518_init_compression(struct usb_ov511 *ov)
-{
- int rc = 0;
-
- if (!ov->compress_inited) {
- if (ov518_upload_quan_tables(ov) < 0) {
- err("Error uploading quantization tables");
- rc = -EIO;
- goto out;
- }
- }
-
- ov->compress_inited = 1;
-out:
- return rc;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Sets sensor's contrast setting to "val" */
-static int
-sensor_set_contrast(struct usb_ov511 *ov, unsigned short val)
-{
- int rc;
-
- PDEBUG(3, "%d", val);
-
- if (ov->stop_during_set)
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- {
- rc = i2c_w(ov, OV7610_REG_CNT, val >> 8);
- if (rc < 0)
- goto out;
- break;
- }
- case SEN_OV6630:
- {
- rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f);
- if (rc < 0)
- goto out;
- break;
- }
- case SEN_OV7620:
- {
- unsigned char ctab[] = {
- 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
- 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
- };
-
- /* Use Y gamma control instead. Bit 0 enables it. */
- rc = i2c_w(ov, 0x64, ctab[val>>12]);
- if (rc < 0)
- goto out;
- break;
- }
- case SEN_SAA7111A:
- {
- rc = i2c_w(ov, 0x0b, val >> 9);
- if (rc < 0)
- goto out;
- break;
- }
- default:
- {
- PDEBUG(3, "Unsupported with this sensor");
- rc = -EPERM;
- goto out;
- }
- }
-
- rc = 0; /* Success */
- ov->contrast = val;
-out:
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return rc;
-}
-
-/* Gets sensor's contrast setting */
-static int
-sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val)
-{
- int rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- rc = i2c_r(ov, OV7610_REG_CNT);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_OV6630:
- rc = i2c_r(ov, OV7610_REG_CNT);
- if (rc < 0)
- return rc;
- else
- *val = rc << 12;
- break;
- case SEN_OV7620:
- /* Use Y gamma reg instead. Bit 0 is the enable bit. */
- rc = i2c_r(ov, 0x64);
- if (rc < 0)
- return rc;
- else
- *val = (rc & 0xfe) << 8;
- break;
- case SEN_SAA7111A:
- *val = ov->contrast;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- }
-
- PDEBUG(3, "%d", *val);
- ov->contrast = *val;
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Sets sensor's brightness setting to "val" */
-static int
-sensor_set_brightness(struct usb_ov511 *ov, unsigned short val)
-{
- int rc;
-
- PDEBUG(4, "%d", val);
-
- if (ov->stop_during_set)
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
- if (rc < 0)
- goto out;
- break;
- case SEN_OV7620:
- /* 7620 doesn't like manual changes when in auto mode */
- if (!ov->auto_brt) {
- rc = i2c_w(ov, OV7610_REG_BRT, val >> 8);
- if (rc < 0)
- goto out;
- }
- break;
- case SEN_SAA7111A:
- rc = i2c_w(ov, 0x0a, val >> 8);
- if (rc < 0)
- goto out;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- rc = -EPERM;
- goto out;
- }
-
- rc = 0; /* Success */
- ov->brightness = val;
-out:
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return rc;
-}
-
-/* Gets sensor's brightness setting */
-static int
-sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val)
-{
- int rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV7620:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_r(ov, OV7610_REG_BRT);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_SAA7111A:
- *val = ov->brightness;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- }
-
- PDEBUG(3, "%d", *val);
- ov->brightness = *val;
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Sets sensor's saturation (color intensity) setting to "val" */
-static int
-sensor_set_saturation(struct usb_ov511 *ov, unsigned short val)
-{
- int rc;
-
- PDEBUG(3, "%d", val);
-
- if (ov->stop_during_set)
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
- if (rc < 0)
- goto out;
- break;
- case SEN_OV7620:
-// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */
-// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e);
-// if (rc < 0)
-// goto out;
- rc = i2c_w(ov, OV7610_REG_SAT, val >> 8);
- if (rc < 0)
- goto out;
- break;
- case SEN_SAA7111A:
- rc = i2c_w(ov, 0x0c, val >> 9);
- if (rc < 0)
- goto out;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- rc = -EPERM;
- goto out;
- }
-
- rc = 0; /* Success */
- ov->colour = val;
-out:
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return rc;
-}
-
-/* Gets sensor's saturation (color intensity) setting */
-static int
-sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val)
-{
- int rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_r(ov, OV7610_REG_SAT);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_OV7620:
-// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */
-// rc = i2c_r(ov, 0x62);
-// if (rc < 0)
-// return rc;
-// else
-// *val = (rc & 0x7e) << 9;
- rc = i2c_r(ov, OV7610_REG_SAT);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_SAA7111A:
- *val = ov->colour;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- }
-
- PDEBUG(3, "%d", *val);
- ov->colour = *val;
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-/* Sets sensor's hue (red/blue balance) setting to "val" */
-static int
-sensor_set_hue(struct usb_ov511 *ov, unsigned short val)
-{
- int rc;
-
- PDEBUG(3, "%d", val);
-
- if (ov->stop_during_set)
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8));
- if (rc < 0)
- goto out;
-
- rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8);
- if (rc < 0)
- goto out;
- break;
- case SEN_OV7620:
-// Hue control is causing problems. I will enable it once it's fixed.
-#if 0
- rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb);
- if (rc < 0)
- goto out;
-
- rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb);
- if (rc < 0)
- goto out;
-#endif
- break;
- case SEN_SAA7111A:
- rc = i2c_w(ov, 0x0d, (val + 32768) >> 8);
- if (rc < 0)
- goto out;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- rc = -EPERM;
- goto out;
- }
-
- rc = 0; /* Success */
- ov->hue = val;
-out:
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return rc;
-}
-
-/* Gets sensor's hue (red/blue balance) setting */
-static int
-sensor_get_hue(struct usb_ov511 *ov, unsigned short *val)
-{
- int rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = i2c_r(ov, OV7610_REG_BLUE);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_OV7620:
- rc = i2c_r(ov, 0x7a);
- if (rc < 0)
- return rc;
- else
- *val = rc << 8;
- break;
- case SEN_SAA7111A:
- *val = ov->hue;
- break;
- default:
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- }
-
- PDEBUG(3, "%d", *val);
- ov->hue = *val;
-
- return 0;
-}
-
-/* -------------------------------------------------------------------------- */
-
-static int
-sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p)
-{
- int rc;
-
- PDEBUG(4, "sensor_set_picture");
-
- ov->whiteness = p->whiteness;
-
- /* Don't return error if a setting is unsupported, or rest of settings
- * will not be performed */
-
- rc = sensor_set_contrast(ov, p->contrast);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_brightness(ov, p->brightness);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_saturation(ov, p->colour);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_hue(ov, p->hue);
- if (FATAL_ERROR(rc))
- return rc;
-
- return 0;
-}
-
-static int
-sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p)
-{
- int rc;
-
- PDEBUG(4, "sensor_get_picture");
-
- /* Don't return error if a setting is unsupported, or rest of settings
- * will not be performed */
-
- rc = sensor_get_contrast(ov, &(p->contrast));
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_get_brightness(ov, &(p->brightness));
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_get_saturation(ov, &(p->colour));
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_get_hue(ov, &(p->hue));
- if (FATAL_ERROR(rc))
- return rc;
-
- p->whiteness = 105 << 8;
-
- return 0;
-}
-
-#if 0
-// FIXME: Exposure range is only 0x00-0x7f in interlace mode
-/* Sets current exposure for sensor. This only has an effect if auto-exposure
- * is off */
-static inline int
-sensor_set_exposure(struct usb_ov511 *ov, unsigned char val)
-{
- int rc;
-
- PDEBUG(3, "%d", val);
-
- if (ov->stop_during_set)
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- switch (ov->sensor) {
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV7610:
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- rc = i2c_w(ov, 0x10, val);
- if (rc < 0)
- goto out;
-
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for set_exposure");
- return -EINVAL;
- }
-
- rc = 0; /* Success */
- ov->exposure = val;
-out:
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return rc;
-}
-#endif
-
-/* Gets current exposure level from sensor, regardless of whether it is under
- * manual control. */
-static int
-sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val)
-{
- int rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- rc = i2c_r(ov, 0x10);
- if (rc < 0)
- return rc;
- else
- *val = rc;
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- val = NULL;
- PDEBUG(3, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for get_exposure");
- return -EINVAL;
- }
-
- PDEBUG(3, "%d", *val);
- ov->exposure = *val;
-
- return 0;
-}
-
-/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */
-static void
-ov51x_led_control(struct usb_ov511 *ov, int enable)
-{
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- if (ov->bridge == BRG_OV511PLUS)
- reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0);
- else if (ov->bclass == BCL_OV518)
- reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02);
-
- return;
-}
-
-/* Matches the sensor's internal frame rate to the lighting frequency.
- * Valid frequencies are:
- * 50 - 50Hz, for European and Asian lighting
- * 60 - 60Hz, for American lighting
- *
- * Tested with: OV7610, OV7620, OV76BE, OV6620
- * Unsupported: KS0127, KS0127B, SAA7111A
- * Returns: 0 for success
- */
-static int
-sensor_set_light_freq(struct usb_ov511 *ov, int freq)
-{
- int sixty;
-
- PDEBUG(4, "%d Hz", freq);
-
- if (freq == 60)
- sixty = 1;
- else if (freq == 50)
- sixty = 0;
- else {
- err("Invalid light freq (%d Hz)", freq);
- return -EINVAL;
- }
-
- switch (ov->sensor) {
- case SEN_OV7610:
- i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
- i2c_w(ov, 0x2b, sixty?0x00:0xac);
- i2c_w_mask(ov, 0x13, 0x10, 0x10);
- i2c_w_mask(ov, 0x13, 0x00, 0x10);
- break;
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80);
- i2c_w(ov, 0x2b, sixty?0x00:0xac);
- i2c_w_mask(ov, 0x76, 0x01, 0x01);
- break;
- case SEN_OV6620:
- case SEN_OV6630:
- i2c_w(ov, 0x2b, sixty?0xa8:0x28);
- i2c_w(ov, 0x2a, sixty?0x84:0xa4);
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for set_light_freq");
- return -EINVAL;
- }
-
- ov->lightfreq = freq;
-
- return 0;
-}
-
-/* If enable is true, turn on the sensor's banding filter, otherwise turn it
- * off. This filter tries to reduce the pattern of horizontal light/dark bands
- * caused by some (usually fluorescent) lighting. The light frequency must be
- * set either before or after enabling it with ov51x_set_light_freq().
- *
- * Tested with: OV7610, OV7620, OV76BE, OV6620.
- * Unsupported: KS0127, KS0127B, SAA7111A
- * Returns: 0 for success
- */
-static int
-sensor_set_banding_filter(struct usb_ov511 *ov, int enable)
-{
- int rc;
-
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
- || ov->sensor == SEN_SAA7111A) {
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- }
-
- rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04);
- if (rc < 0)
- return rc;
-
- ov->bandfilt = enable;
-
- return 0;
-}
-
-/* If enable is true, turn on the sensor's auto brightness control, otherwise
- * turn it off.
- *
- * Unsupported: KS0127, KS0127B, SAA7111A
- * Returns: 0 for success
- */
-static int
-sensor_set_auto_brightness(struct usb_ov511 *ov, int enable)
-{
- int rc;
-
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B
- || ov->sensor == SEN_SAA7111A) {
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- }
-
- rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10);
- if (rc < 0)
- return rc;
-
- ov->auto_brt = enable;
-
- return 0;
-}
-
-/* If enable is true, turn on the sensor's auto exposure control, otherwise
- * turn it off.
- *
- * Unsupported: KS0127, KS0127B, SAA7111A
- * Returns: 0 for success
- */
-static int
-sensor_set_auto_exposure(struct usb_ov511 *ov, int enable)
-{
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- switch (ov->sensor) {
- case SEN_OV7610:
- i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80);
- break;
- case SEN_OV6620:
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01);
- break;
- case SEN_OV6630:
- i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10);
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for set_auto_exposure");
- return -EINVAL;
- }
-
- ov->auto_exp = enable;
-
- return 0;
-}
-
-/* Modifies the sensor's exposure algorithm to allow proper exposure of objects
- * that are illuminated from behind.
- *
- * Tested with: OV6620, OV7620
- * Unsupported: OV7610, OV76BE, KS0127, KS0127B, SAA7111A
- * Returns: 0 for success
- */
-static int
-sensor_set_backlight(struct usb_ov511 *ov, int enable)
-{
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- switch (ov->sensor) {
- case SEN_OV7620:
- case SEN_OV8600:
- i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0);
- i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
- i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
- break;
- case SEN_OV6620:
- i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0);
- i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
- i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80);
- break;
- case SEN_OV6630:
- i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0);
- i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08);
- i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02);
- break;
- case SEN_OV7610:
- case SEN_OV76BE:
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for set_backlight");
- return -EINVAL;
- }
-
- ov->backlight = enable;
-
- return 0;
-}
-
-static int
-sensor_set_mirror(struct usb_ov511 *ov, int enable)
-{
- PDEBUG(4, " (%s)", enable ? "turn on" : "turn off");
-
- switch (ov->sensor) {
- case SEN_OV6620:
- case SEN_OV6630:
- case SEN_OV7610:
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40);
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- case SEN_SAA7111A:
- PDEBUG(5, "Unsupported with this sensor");
- return -EPERM;
- default:
- err("Sensor not supported for set_mirror");
- return -EINVAL;
- }
-
- ov->mirror = enable;
-
- return 0;
-}
-
-/* Returns number of bits per pixel (regardless of where they are located;
- * planar or not), or zero for unsupported format.
- */
-static inline int
-get_depth(int palette)
-{
- switch (palette) {
- case VIDEO_PALETTE_GREY: return 8;
- case VIDEO_PALETTE_YUV420: return 12;
- case VIDEO_PALETTE_YUV420P: return 12; /* Planar */
- default: return 0; /* Invalid format */
- }
-}
-
-/* Bytes per frame. Used by read(). Return of 0 indicates error */
-static inline long int
-get_frame_length(struct ov511_frame *frame)
-{
- if (!frame)
- return 0;
- else
- return ((frame->width * frame->height
- * get_depth(frame->format)) >> 3);
-}
-
-static int
-mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height,
- int mode, int sub_flag, int qvga)
-{
- int clock;
-
- /******** Mode (VGA/QVGA) and sensor specific regs ********/
-
- switch (ov->sensor) {
- case SEN_OV7610:
- i2c_w(ov, 0x14, qvga?0x24:0x04);
-// FIXME: Does this improve the image quality or frame rate?
-#if 0
- i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
- i2c_w(ov, 0x24, 0x10);
- i2c_w(ov, 0x25, qvga?0x40:0x8a);
- i2c_w(ov, 0x2f, qvga?0x30:0xb0);
- i2c_w(ov, 0x35, qvga?0x1c:0x9c);
-#endif
- break;
- case SEN_OV7620:
-// i2c_w(ov, 0x2b, 0x00);
- i2c_w(ov, 0x14, qvga?0xa4:0x84);
- i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
- i2c_w(ov, 0x24, qvga?0x20:0x3a);
- i2c_w(ov, 0x25, qvga?0x30:0x60);
- i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
- i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0);
- i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
- break;
- case SEN_OV76BE:
-// i2c_w(ov, 0x2b, 0x00);
- i2c_w(ov, 0x14, qvga?0xa4:0x84);
-// FIXME: Enable this once 7620AE uses 7620 initial settings
-#if 0
- i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20);
- i2c_w(ov, 0x24, qvga?0x20:0x3a);
- i2c_w(ov, 0x25, qvga?0x30:0x60);
- i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40);
- i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0);
- i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20);
-#endif
- break;
- case SEN_OV6620:
- i2c_w(ov, 0x14, qvga?0x24:0x04);
- break;
- case SEN_OV6630:
- i2c_w(ov, 0x14, qvga?0xa0:0x80);
- break;
- default:
- err("Invalid sensor");
- return -EINVAL;
- }
-
- /******** Palette-specific regs ********/
-
- if (mode == VIDEO_PALETTE_GREY) {
- if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
- /* these aren't valid on the OV6620/OV7620/6630? */
- i2c_w_mask(ov, 0x0e, 0x40, 0x40);
- }
-
- if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
- && ov518_color) {
- i2c_w_mask(ov, 0x12, 0x00, 0x10);
- i2c_w_mask(ov, 0x13, 0x00, 0x20);
- } else {
- i2c_w_mask(ov, 0x13, 0x20, 0x20);
- }
- } else {
- if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
- /* not valid on the OV6620/OV7620/6630? */
- i2c_w_mask(ov, 0x0e, 0x00, 0x40);
- }
-
- /* The OV518 needs special treatment. Although both the OV518
- * and the OV6630 support a 16-bit video bus, only the 8 bit Y
- * bus is actually used. The UV bus is tied to ground.
- * Therefore, the OV6630 needs to be in 8-bit multiplexed
- * output mode */
-
- if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518
- && ov518_color) {
- i2c_w_mask(ov, 0x12, 0x10, 0x10);
- i2c_w_mask(ov, 0x13, 0x20, 0x20);
- } else {
- i2c_w_mask(ov, 0x13, 0x00, 0x20);
- }
- }
-
- /******** Clock programming ********/
-
- /* The OV6620 needs special handling. This prevents the
- * severe banding that normally occurs */
- if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630)
- {
- /* Clock down */
-
- i2c_w(ov, 0x2a, 0x04);
-
- if (ov->compress) {
-// clock = 0; /* This ensures the highest frame rate */
- clock = 3;
- } else if (clockdiv == -1) { /* If user didn't override it */
- clock = 3; /* Gives better exposure time */
- } else {
- clock = clockdiv;
- }
-
- PDEBUG(4, "Setting clock divisor to %d", clock);
-
- i2c_w(ov, 0x11, clock);
-
- i2c_w(ov, 0x2a, 0x84);
- /* This next setting is critical. It seems to improve
- * the gain or the contrast. The "reserved" bits seem
- * to have some effect in this case. */
- i2c_w(ov, 0x2d, 0x85);
- }
- else
- {
- if (ov->compress) {
- clock = 1; /* This ensures the highest frame rate */
- } else if (clockdiv == -1) { /* If user didn't override it */
- /* Calculate and set the clock divisor */
- clock = ((sub_flag ? ov->subw * ov->subh
- : width * height)
- * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2)
- / 66000;
- } else {
- clock = clockdiv;
- }
-
- PDEBUG(4, "Setting clock divisor to %d", clock);
-
- i2c_w(ov, 0x11, clock);
- }
-
- /******** Special Features ********/
-
- if (framedrop >= 0)
- i2c_w(ov, 0x16, framedrop);
-
- /* Test Pattern */
- i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02);
-
- /* Enable auto white balance */
- i2c_w_mask(ov, 0x12, 0x04, 0x04);
-
- // This will go away as soon as ov51x_mode_init_sensor_regs()
- // is fully tested.
- /* 7620/6620/6630? don't have register 0x35, so play it safe */
- if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) {
- if (width == 640 && height == 480)
- i2c_w(ov, 0x35, 0x9e);
- else
- i2c_w(ov, 0x35, 0x1e);
- }
-
- return 0;
-}
-
-static int
-set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode,
- int sub_flag)
-{
- int ret;
- int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize;
- int hoffset, voffset, hwscale = 0, vwscale = 0;
-
- /* The different sensor ICs handle setting up of window differently.
- * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV76BE:
- hwsbase = 0x38;
- hwebase = 0x3a;
- vwsbase = vwebase = 0x05;
- break;
- case SEN_OV6620:
- case SEN_OV6630:
- hwsbase = 0x38;
- hwebase = 0x3a;
- vwsbase = 0x05;
- vwebase = 0x06;
- break;
- case SEN_OV7620:
- hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */
- hwebase = 0x2f;
- vwsbase = vwebase = 0x05;
- break;
- default:
- err("Invalid sensor");
- return -EINVAL;
- }
-
- if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) {
- /* Note: OV518(+) does downsample on its own) */
- if ((width > 176 && height > 144)
- || ov->bclass == BCL_OV518) { /* CIF */
- ret = mode_init_ov_sensor_regs(ov, width, height,
- mode, sub_flag, 0);
- if (ret < 0)
- return ret;
- hwscale = 1;
- vwscale = 1; /* The datasheet says 0; it's wrong */
- hwsize = 352;
- vwsize = 288;
- } else if (width > 176 || height > 144) {
- err("Illegal dimensions");
- return -EINVAL;
- } else { /* QCIF */
- ret = mode_init_ov_sensor_regs(ov, width, height,
- mode, sub_flag, 1);
- if (ret < 0)
- return ret;
- hwsize = 176;
- vwsize = 144;
- }
- } else {
- if (width > 320 && height > 240) { /* VGA */
- ret = mode_init_ov_sensor_regs(ov, width, height,
- mode, sub_flag, 0);
- if (ret < 0)
- return ret;
- hwscale = 2;
- vwscale = 1;
- hwsize = 640;
- vwsize = 480;
- } else if (width > 320 || height > 240) {
- err("Illegal dimensions");
- return -EINVAL;
- } else { /* QVGA */
- ret = mode_init_ov_sensor_regs(ov, width, height,
- mode, sub_flag, 1);
- if (ret < 0)
- return ret;
- hwscale = 1;
- hwsize = 320;
- vwsize = 240;
- }
- }
-
- /* Center the window */
- hoffset = ((hwsize - width) / 2) >> hwscale;
- voffset = ((vwsize - height) / 2) >> vwscale;
-
- /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
- if (sub_flag) {
- i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale));
- i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale));
- i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale));
- i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale));
- } else {
- i2c_w(ov, 0x17, hwsbase + hoffset);
- i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale));
- i2c_w(ov, 0x19, vwsbase + voffset);
- i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale));
- }
-
-#ifdef OV511_DEBUG
- if (dump_sensor)
- dump_i2c_regs(ov);
-#endif
-
- return 0;
-}
-
-/* Set up the OV511/OV511+ with the given image parameters.
- *
- * Do not put any sensor-specific code in here (including I2C I/O functions)
- */
-static int
-ov511_mode_init_regs(struct usb_ov511 *ov,
- int width, int height, int mode, int sub_flag)
-{
- int hsegs, vsegs;
-
- if (sub_flag) {
- width = ov->subw;
- height = ov->subh;
- }
-
- PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
- width, height, mode, sub_flag);
-
- // FIXME: This should be moved to a 7111a-specific function once
- // subcapture is dealt with properly
- if (ov->sensor == SEN_SAA7111A) {
- if (width == 320 && height == 240) {
- /* No need to do anything special */
- } else if (width == 640 && height == 480) {
- /* Set the OV511 up as 320x480, but keep the
- * V4L resolution as 640x480 */
- width = 320;
- } else {
- err("SAA7111A only allows 320x240 or 640x480");
- return -EINVAL;
- }
- }
-
- /* Make sure width and height are a multiple of 8 */
- if (width % 8 || height % 8) {
- err("Invalid size (%d, %d) (mode = %d)", width, height, mode);
- return -EINVAL;
- }
-
- if (width < ov->minwidth || height < ov->minheight) {
- err("Requested dimensions are too small");
- return -EINVAL;
- }
-
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- if (mode == VIDEO_PALETTE_GREY) {
- reg_w(ov, R511_CAM_UV_EN, 0x00);
- reg_w(ov, R511_SNAP_UV_EN, 0x00);
- reg_w(ov, R511_SNAP_OPTS, 0x01);
- } else {
- reg_w(ov, R511_CAM_UV_EN, 0x01);
- reg_w(ov, R511_SNAP_UV_EN, 0x01);
- reg_w(ov, R511_SNAP_OPTS, 0x03);
- }
-
- /* Here I'm assuming that snapshot size == image size.
- * I hope that's always true. --claudio
- */
- hsegs = (width >> 3) - 1;
- vsegs = (height >> 3) - 1;
-
- reg_w(ov, R511_CAM_PXCNT, hsegs);
- reg_w(ov, R511_CAM_LNCNT, vsegs);
- reg_w(ov, R511_CAM_PXDIV, 0x00);
- reg_w(ov, R511_CAM_LNDIV, 0x00);
-
- /* YUV420, low pass filter on */
- reg_w(ov, R511_CAM_OPTS, 0x03);
-
- /* Snapshot additions */
- reg_w(ov, R511_SNAP_PXCNT, hsegs);
- reg_w(ov, R511_SNAP_LNCNT, vsegs);
- reg_w(ov, R511_SNAP_PXDIV, 0x00);
- reg_w(ov, R511_SNAP_LNDIV, 0x00);
-
- if (ov->compress) {
- /* Enable Y and UV quantization and compression */
- reg_w(ov, R511_COMP_EN, 0x07);
- reg_w(ov, R511_COMP_LUT_EN, 0x03);
- ov51x_reset(ov, OV511_RESET_OMNICE);
- }
-
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- return 0;
-}
-
-/* Sets up the OV518/OV518+ with the given image parameters
- *
- * OV518 needs a completely different approach, until we can figure out what
- * the individual registers do. Also, only 15 FPS is supported now.
- *
- * Do not put any sensor-specific code in here (including I2C I/O functions)
- */
-static int
-ov518_mode_init_regs(struct usb_ov511 *ov,
- int width, int height, int mode, int sub_flag)
-{
- int hsegs, vsegs, hi_res;
-
- if (sub_flag) {
- width = ov->subw;
- height = ov->subh;
- }
-
- PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
- width, height, mode, sub_flag);
-
- if (width % 16 || height % 8) {
- err("Invalid size (%d, %d)", width, height);
- return -EINVAL;
- }
-
- if (width < ov->minwidth || height < ov->minheight) {
- err("Requested dimensions are too small");
- return -EINVAL;
- }
-
- if (width >= 320 && height >= 240) {
- hi_res = 1;
- } else if (width >= 320 || height >= 240) {
- err("Invalid width/height combination (%d, %d)", width, height);
- return -EINVAL;
- } else {
- hi_res = 0;
- }
-
- if (ov51x_stop(ov) < 0)
- return -EIO;
-
- /******** Set the mode ********/
-
- reg_w(ov, 0x2b, 0);
- reg_w(ov, 0x2c, 0);
- reg_w(ov, 0x2d, 0);
- reg_w(ov, 0x2e, 0);
- reg_w(ov, 0x3b, 0);
- reg_w(ov, 0x3c, 0);
- reg_w(ov, 0x3d, 0);
- reg_w(ov, 0x3e, 0);
-
- if (ov->bridge == BRG_OV518 && ov518_color) {
- /* OV518 needs U and V swapped */
- i2c_w_mask(ov, 0x15, 0x00, 0x01);
-
- if (mode == VIDEO_PALETTE_GREY) {
- /* Set 16-bit input format (UV data are ignored) */
- reg_w_mask(ov, 0x20, 0x00, 0x08);
-
- /* Set 8-bit (4:0:0) output format */
- reg_w_mask(ov, 0x28, 0x00, 0xf0);
- reg_w_mask(ov, 0x38, 0x00, 0xf0);
- } else {
- /* Set 8-bit (YVYU) input format */
- reg_w_mask(ov, 0x20, 0x08, 0x08);
-
- /* Set 12-bit (4:2:0) output format */
- reg_w_mask(ov, 0x28, 0x80, 0xf0);
- reg_w_mask(ov, 0x38, 0x80, 0xf0);
- }
- } else {
- reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
- reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80);
- }
-
- hsegs = width / 16;
- vsegs = height / 4;
-
- reg_w(ov, 0x29, hsegs);
- reg_w(ov, 0x2a, vsegs);
-
- reg_w(ov, 0x39, hsegs);
- reg_w(ov, 0x3a, vsegs);
-
- /* Windows driver does this here; who knows why */
- reg_w(ov, 0x2f, 0x80);
-
- /******** Set the framerate (to 15 FPS) ********/
-
- /* Mode independent, but framerate dependent, regs */
- reg_w(ov, 0x51, 0x02); /* Clock divider; lower==faster */
- reg_w(ov, 0x22, 0x18);
- reg_w(ov, 0x23, 0xff);
-
- if (ov->bridge == BRG_OV518PLUS)
- reg_w(ov, 0x21, 0x19);
- else
- reg_w(ov, 0x71, 0x19); /* Compression-related? */
-
- // FIXME: Sensor-specific
- /* Bit 5 is what matters here. Of course, it is "reserved" */
- i2c_w(ov, 0x54, 0x23);
-
- reg_w(ov, 0x2f, 0x80);
-
- if (ov->bridge == BRG_OV518PLUS) {
- reg_w(ov, 0x24, 0x94);
- reg_w(ov, 0x25, 0x90);
- ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
- ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */
- ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */
- ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */
- ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
- ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
- ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */
- ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
- ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
- } else {
- reg_w(ov, 0x24, 0x9f);
- reg_w(ov, 0x25, 0x90);
- ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */
- ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */
- ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */
- ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */
- ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */
- ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */
- ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */
- ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */
- ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */
- }
-
- reg_w(ov, 0x2f, 0x80);
-
- if (ov51x_restart(ov) < 0)
- return -EIO;
-
- /* Reset it just for good measure */
- if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0)
- return -EIO;
-
- return 0;
-}
-
-/* This is a wrapper around the OV511, OV518, and sensor specific functions */
-static int
-mode_init_regs(struct usb_ov511 *ov,
- int width, int height, int mode, int sub_flag)
-{
- int rc = 0;
-
- if (!ov || !ov->dev)
- return -EFAULT;
-
- if (ov->bclass == BCL_OV518) {
- rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag);
- } else {
- rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag);
- }
-
- if (FATAL_ERROR(rc))
- return rc;
-
- switch (ov->sensor) {
- case SEN_OV7610:
- case SEN_OV7620:
- case SEN_OV76BE:
- case SEN_OV8600:
- case SEN_OV6620:
- case SEN_OV6630:
- rc = set_ov_sensor_window(ov, width, height, mode, sub_flag);
- break;
- case SEN_KS0127:
- case SEN_KS0127B:
- err("KS0127-series decoders not supported yet");
- rc = -EINVAL;
- break;
- case SEN_SAA7111A:
-// rc = mode_init_saa_sensor_regs(ov, width, height, mode,
-// sub_flag);
-
- PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f));
- break;
- default:
- err("Unknown sensor");
- rc = -EINVAL;
- }
-
- if (FATAL_ERROR(rc))
- return rc;
-
- /* Sensor-independent settings */
- rc = sensor_set_auto_brightness(ov, ov->auto_brt);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_auto_exposure(ov, ov->auto_exp);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_banding_filter(ov, bandingfilter);
- if (FATAL_ERROR(rc))
- return rc;
-
- if (ov->lightfreq) {
- rc = sensor_set_light_freq(ov, lightfreq);
- if (FATAL_ERROR(rc))
- return rc;
- }
-
- rc = sensor_set_backlight(ov, ov->backlight);
- if (FATAL_ERROR(rc))
- return rc;
-
- rc = sensor_set_mirror(ov, ov->mirror);
- if (FATAL_ERROR(rc))
- return rc;
-
- return 0;
-}
-
-/* This sets the default image parameters. This is useful for apps that use
- * read() and do not set these.
- */
-static int
-ov51x_set_default_params(struct usb_ov511 *ov)
-{
- int i;
-
- /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
- * (using read() instead). */
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].width = ov->maxwidth;
- ov->frame[i].height = ov->maxheight;
- ov->frame[i].bytes_read = 0;
- if (force_palette)
- ov->frame[i].format = force_palette;
- else
- ov->frame[i].format = VIDEO_PALETTE_YUV420;
-
- ov->frame[i].depth = get_depth(ov->frame[i].format);
- }
-
- PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight,
- symbolic(v4l1_plist, ov->frame[0].format));
-
- /* Initialize to max width/height, YUV420 or RGB24 (if supported) */
- if (mode_init_regs(ov, ov->maxwidth, ov->maxheight,
- ov->frame[0].format, 0) < 0)
- return -EINVAL;
-
- return 0;
-}
-
-/**********************************************************************
- *
- * Video decoder stuff
- *
- **********************************************************************/
-
-/* Set analog input port of decoder */
-static int
-decoder_set_input(struct usb_ov511 *ov, int input)
-{
- PDEBUG(4, "port %d", input);
-
- switch (ov->sensor) {
- case SEN_SAA7111A:
- {
- /* Select mode */
- i2c_w_mask(ov, 0x02, input, 0x07);
- /* Bypass chrominance trap for modes 4..7 */
- i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80);
- break;
- }
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* Get ASCII name of video input */
-static int
-decoder_get_input_name(struct usb_ov511 *ov, int input, char *name)
-{
- switch (ov->sensor) {
- case SEN_SAA7111A:
- {
- if (input < 0 || input > 7)
- return -EINVAL;
- else if (input < 4)
- sprintf(name, "CVBS-%d", input);
- else // if (input < 8)
- sprintf(name, "S-Video-%d", input - 4);
- break;
- }
- default:
- sprintf(name, "%s", "Camera");
- }
-
- return 0;
-}
-
-/* Set norm (NTSC, PAL, SECAM, AUTO) */
-static int
-decoder_set_norm(struct usb_ov511 *ov, int norm)
-{
- PDEBUG(4, "%d", norm);
-
- switch (ov->sensor) {
- case SEN_SAA7111A:
- {
- int reg_8, reg_e;
-
- if (norm == VIDEO_MODE_NTSC) {
- reg_8 = 0x40; /* 60 Hz */
- reg_e = 0x00; /* NTSC M / PAL BGHI */
- } else if (norm == VIDEO_MODE_PAL) {
- reg_8 = 0x00; /* 50 Hz */
- reg_e = 0x00; /* NTSC M / PAL BGHI */
- } else if (norm == VIDEO_MODE_AUTO) {
- reg_8 = 0x80; /* Auto field detect */
- reg_e = 0x00; /* NTSC M / PAL BGHI */
- } else if (norm == VIDEO_MODE_SECAM) {
- reg_8 = 0x00; /* 50 Hz */
- reg_e = 0x50; /* SECAM / PAL 4.43 */
- } else {
- return -EINVAL;
- }
-
- i2c_w_mask(ov, 0x08, reg_8, 0xc0);
- i2c_w_mask(ov, 0x0e, reg_e, 0x70);
- break;
- }
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/**********************************************************************
- *
- * Raw data parsing
- *
- **********************************************************************/
-
-/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the
- * image at pOut is specified by w.
- */
-static inline void
-make_8x8(unsigned char *pIn, unsigned char *pOut, int w)
-{
- unsigned char *pOut1 = pOut;
- int x, y;
-
- for (y = 0; y < 8; y++) {
- pOut1 = pOut;
- for (x = 0; x < 8; x++) {
- *pOut1++ = *pIn++;
- }
- pOut += w;
- }
-}
-
-/*
- * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments.
- * The segments represent 4 squares of 8x8 pixels as follows:
- *
- * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
- * 8 9 ... 15 72 73 ... 79 200 201 ... 207
- * ... ... ...
- * 56 57 ... 63 120 121 ... 127 248 249 ... 255
- *
- */
-static void
-yuv400raw_to_yuv400p(struct ov511_frame *frame,
- unsigned char *pIn0, unsigned char *pOut0)
-{
- int x, y;
- unsigned char *pIn, *pOut, *pOutLine;
-
- /* Copy Y */
- pIn = pIn0;
- pOutLine = pOut0;
- for (y = 0; y < frame->rawheight - 1; y += 8) {
- pOut = pOutLine;
- for (x = 0; x < frame->rawwidth - 1; x += 8) {
- make_8x8(pIn, pOut, frame->rawwidth);
- pIn += 64;
- pOut += 8;
- }
- pOutLine += 8 * frame->rawwidth;
- }
-}
-
-/*
- * For YUV 4:2:0 images, the data show up in 384 byte segments.
- * The first 64 bytes of each segment are U, the next 64 are V. The U and
- * V are arranged as follows:
- *
- * 0 1 ... 7
- * 8 9 ... 15
- * ...
- * 56 57 ... 63
- *
- * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
- *
- * The next 256 bytes are full resolution Y data and represent 4 squares
- * of 8x8 pixels as follows:
- *
- * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
- * 8 9 ... 15 72 73 ... 79 200 201 ... 207
- * ... ... ...
- * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255
- *
- * Note that the U and V data in one segment represent a 16 x 16 pixel
- * area, but the Y data represent a 32 x 8 pixel area. If the width is not an
- * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the
- * next horizontal stripe.
- *
- * If dumppix module param is set, _parse_data just dumps the incoming segments,
- * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
- * this puts the data on the standard output and can be analyzed with the
- * parseppm.c utility I wrote. That's a much faster way for figuring out how
- * these data are scrambled.
- */
-
-/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0.
- *
- * FIXME: Currently only handles width and height that are multiples of 16
- */
-static void
-yuv420raw_to_yuv420p(struct ov511_frame *frame,
- unsigned char *pIn0, unsigned char *pOut0)
-{
- int k, x, y;
- unsigned char *pIn, *pOut, *pOutLine;
- const unsigned int a = frame->rawwidth * frame->rawheight;
- const unsigned int w = frame->rawwidth / 2;
-
- /* Copy U and V */
- pIn = pIn0;
- pOutLine = pOut0 + a;
- for (y = 0; y < frame->rawheight - 1; y += 16) {
- pOut = pOutLine;
- for (x = 0; x < frame->rawwidth - 1; x += 16) {
- make_8x8(pIn, pOut, w);
- make_8x8(pIn + 64, pOut + a/4, w);
- pIn += 384;
- pOut += 8;
- }
- pOutLine += 8 * w;
- }
-
- /* Copy Y */
- pIn = pIn0 + 128;
- pOutLine = pOut0;
- k = 0;
- for (y = 0; y < frame->rawheight - 1; y += 8) {
- pOut = pOutLine;
- for (x = 0; x < frame->rawwidth - 1; x += 8) {
- make_8x8(pIn, pOut, frame->rawwidth);
- pIn += 64;
- pOut += 8;
- if ((++k) > 3) {
- k = 0;
- pIn += 128;
- }
- }
- pOutLine += 8 * frame->rawwidth;
- }
-}
-
-/**********************************************************************
- *
- * Decompression
- *
- **********************************************************************/
-
-static int
-request_decompressor(struct usb_ov511 *ov)
-{
- if (ov->bclass == BCL_OV511 || ov->bclass == BCL_OV518) {
- err("No decompressor available");
- } else {
- err("Unknown bridge");
- }
-
- return -ENOSYS;
-}
-
-static void
-decompress(struct usb_ov511 *ov, struct ov511_frame *frame,
- unsigned char *pIn0, unsigned char *pOut0)
-{
- if (!ov->decomp_ops)
- if (request_decompressor(ov))
- return;
-
-}
-
-/**********************************************************************
- *
- * Format conversion
- *
- **********************************************************************/
-
-/* Fuses even and odd fields together, and doubles width.
- * INPUT: an odd field followed by an even field at pIn0, in YUV planar format
- * OUTPUT: a normal YUV planar image, with correct aspect ratio
- */
-static void
-deinterlace(struct ov511_frame *frame, int rawformat,
- unsigned char *pIn0, unsigned char *pOut0)
-{
- const int fieldheight = frame->rawheight / 2;
- const int fieldpix = fieldheight * frame->rawwidth;
- const int w = frame->width;
- int x, y;
- unsigned char *pInEven, *pInOdd, *pOut;
-
- PDEBUG(5, "fieldheight=%d", fieldheight);
-
- if (frame->rawheight != frame->height) {
- err("invalid height");
- return;
- }
-
- if ((frame->rawwidth * 2) != frame->width) {
- err("invalid width");
- return;
- }
-
- /* Y */
- pInOdd = pIn0;
- pInEven = pInOdd + fieldpix;
- pOut = pOut0;
- for (y = 0; y < fieldheight; y++) {
- for (x = 0; x < frame->rawwidth; x++) {
- *pOut = *pInEven;
- *(pOut+1) = *pInEven++;
- *(pOut+w) = *pInOdd;
- *(pOut+w+1) = *pInOdd++;
- pOut += 2;
- }
- pOut += w;
- }
-
- if (rawformat == RAWFMT_YUV420) {
- /* U */
- pInOdd = pIn0 + fieldpix * 2;
- pInEven = pInOdd + fieldpix / 4;
- for (y = 0; y < fieldheight / 2; y++) {
- for (x = 0; x < frame->rawwidth / 2; x++) {
- *pOut = *pInEven;
- *(pOut+1) = *pInEven++;
- *(pOut+w/2) = *pInOdd;
- *(pOut+w/2+1) = *pInOdd++;
- pOut += 2;
- }
- pOut += w/2;
- }
- /* V */
- pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2;
- pInEven = pInOdd + fieldpix / 4;
- for (y = 0; y < fieldheight / 2; y++) {
- for (x = 0; x < frame->rawwidth / 2; x++) {
- *pOut = *pInEven;
- *(pOut+1) = *pInEven++;
- *(pOut+w/2) = *pInOdd;
- *(pOut+w/2+1) = *pInOdd++;
- pOut += 2;
- }
- pOut += w/2;
- }
- }
-}
-
-static void
-ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame)
-{
- /* Deinterlace frame, if necessary */
- if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
- if (frame->compressed)
- decompress(ov, frame, frame->rawdata,
- frame->tempdata);
- else
- yuv400raw_to_yuv400p(frame, frame->rawdata,
- frame->tempdata);
-
- deinterlace(frame, RAWFMT_YUV400, frame->tempdata,
- frame->data);
- } else {
- if (frame->compressed)
- decompress(ov, frame, frame->rawdata,
- frame->data);
- else
- yuv400raw_to_yuv400p(frame, frame->rawdata,
- frame->data);
- }
-}
-
-/* Process raw YUV420 data into standard YUV420P */
-static void
-ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame)
-{
- /* Deinterlace frame, if necessary */
- if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) {
- if (frame->compressed)
- decompress(ov, frame, frame->rawdata, frame->tempdata);
- else
- yuv420raw_to_yuv420p(frame, frame->rawdata,
- frame->tempdata);
-
- deinterlace(frame, RAWFMT_YUV420, frame->tempdata,
- frame->data);
- } else {
- if (frame->compressed)
- decompress(ov, frame, frame->rawdata, frame->data);
- else
- yuv420raw_to_yuv420p(frame, frame->rawdata,
- frame->data);
- }
-}
-
-/* Post-processes the specified frame. This consists of:
- * 1. Decompress frame, if necessary
- * 2. Deinterlace frame and scale to proper size, if necessary
- * 3. Convert from YUV planar to destination format, if necessary
- * 4. Fix the RGB offset, if necessary
- */
-static void
-ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame)
-{
- if (dumppix) {
- memset(frame->data, 0,
- MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
- PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd);
- memcpy(frame->data, frame->rawdata, frame->bytes_recvd);
- } else {
- switch (frame->format) {
- case VIDEO_PALETTE_GREY:
- ov51x_postprocess_grey(ov, frame);
- break;
- case VIDEO_PALETTE_YUV420:
- case VIDEO_PALETTE_YUV420P:
- ov51x_postprocess_yuv420(ov, frame);
- break;
- default:
- err("Cannot convert data to %s",
- symbolic(v4l1_plist, frame->format));
- }
- }
-}
-
-/**********************************************************************
- *
- * OV51x data transfer, IRQ handler
- *
- **********************************************************************/
-
-static inline void
-ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
-{
- int num, offset;
- int pnum = in[ov->packet_size - 1]; /* Get packet number */
- int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
- struct ov511_frame *frame = &ov->frame[ov->curframe];
- struct timeval *ts;
-
- /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
- * byte non-zero. The EOF packet has image width/height in the
- * 10th and 11th bytes. The 9th byte is given as follows:
- *
- * bit 7: EOF
- * 6: compression enabled
- * 5: 422/420/400 modes
- * 4: 422/420/400 modes
- * 3: 1
- * 2: snapshot button on
- * 1: snapshot frame
- * 0: even/odd field
- */
-
- if (printph) {
- dev_info(&ov->dev->dev,
- "ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",
- pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6],
- in[7], in[8], in[9], in[10], in[11]);
- }
-
- /* Check for SOF/EOF packet */
- if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) ||
- (~in[8] & 0x08))
- goto check_middle;
-
- /* Frame end */
- if (in[8] & 0x80) {
- ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
- do_gettimeofday(ts);
-
- /* Get the actual frame size from the EOF header */
- frame->rawwidth = ((int)(in[9]) + 1) * 8;
- frame->rawheight = ((int)(in[10]) + 1) * 8;
-
- PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d",
- ov->curframe, pnum, frame->rawwidth, frame->rawheight,
- frame->bytes_recvd);
-
- /* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov->minheight,
- ov->maxheight);
-
- /* Don't allow byte count to exceed buffer size */
- RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
-
- if (frame->scanstate == STATE_LINES) {
- int nextf;
-
- frame->grabstate = FRAME_DONE;
- wake_up_interruptible(&frame->wq);
-
- /* If next frame is ready or grabbing,
- * point to it */
- nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
- if (ov->frame[nextf].grabstate == FRAME_READY
- || ov->frame[nextf].grabstate == FRAME_GRABBING) {
- ov->curframe = nextf;
- ov->frame[nextf].scanstate = STATE_SCANNING;
- } else {
- if (frame->grabstate == FRAME_DONE) {
- PDEBUG(4, "** Frame done **");
- } else {
- PDEBUG(4, "Frame not ready? state = %d",
- ov->frame[nextf].grabstate);
- }
-
- ov->curframe = -1;
- }
- } else {
- PDEBUG(5, "Frame done, but not scanning");
- }
- /* Image corruption caused by misplaced frame->segment = 0
- * fixed by carlosf@conectiva.com.br
- */
- } else {
- /* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
-
- /* Check to see if it's a snapshot frame */
- /* FIXME?? Should the snapshot reset go here? Performance? */
- if (in[8] & 0x02) {
- frame->snapshot = 1;
- PDEBUG(3, "snapshot detected");
- }
-
- frame->scanstate = STATE_LINES;
- frame->bytes_recvd = 0;
- frame->compressed = in[8] & 0x40;
- }
-
-check_middle:
- /* Are we in a frame? */
- if (frame->scanstate != STATE_LINES) {
- PDEBUG(5, "Not in a frame; packet skipped");
- return;
- }
-
- /* If frame start, skip header */
- if (frame->bytes_recvd == 0)
- offset = 9;
- else
- offset = 0;
-
- num = n - offset - 1;
-
- /* Dump all data exactly as received */
- if (dumppix == 2) {
- frame->bytes_recvd += n - 1;
- if (frame->bytes_recvd <= max_raw)
- memcpy(frame->rawdata + frame->bytes_recvd - (n - 1),
- in, n - 1);
- else
- PDEBUG(3, "Raw data buffer overrun!! (%d)",
- frame->bytes_recvd - max_raw);
- } else if (!frame->compressed && !remove_zeros) {
- frame->bytes_recvd += num;
- if (frame->bytes_recvd <= max_raw)
- memcpy(frame->rawdata + frame->bytes_recvd - num,
- in + offset, num);
- else
- PDEBUG(3, "Raw data buffer overrun!! (%d)",
- frame->bytes_recvd - max_raw);
- } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */
- int b, read = 0, allzero, copied = 0;
- if (offset) {
- frame->bytes_recvd += 32 - offset; // Bytes out
- memcpy(frame->rawdata, in + offset, 32 - offset);
- read += 32;
- }
-
- while (read < n - 1) {
- allzero = 1;
- for (b = 0; b < 32; b++) {
- if (in[read + b]) {
- allzero = 0;
- break;
- }
- }
-
- if (allzero) {
- /* Don't copy it */
- } else {
- if (frame->bytes_recvd + copied + 32 <= max_raw)
- {
- memcpy(frame->rawdata
- + frame->bytes_recvd + copied,
- in + read, 32);
- copied += 32;
- } else {
- PDEBUG(3, "Raw data buffer overrun!!");
- }
- }
- read += 32;
- }
-
- frame->bytes_recvd += copied;
- }
-}
-
-static inline void
-ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n)
-{
- int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight);
- struct ov511_frame *frame = &ov->frame[ov->curframe];
- struct timeval *ts;
-
- /* Don't copy the packet number byte */
- if (ov->packet_numbering)
- --n;
-
- /* A false positive here is likely, until OVT gives me
- * the definitive SOF/EOF format */
- if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) {
- if (printph) {
- dev_info(&ov->dev->dev,
- "ph: %2x %2x %2x %2x %2x %2x %2x %2x\n",
- in[0], in[1], in[2], in[3], in[4], in[5],
- in[6], in[7]);
- }
-
- if (frame->scanstate == STATE_LINES) {
- PDEBUG(4, "Detected frame end/start");
- goto eof;
- } else { //scanstate == STATE_SCANNING
- /* Frame start */
- PDEBUG(4, "Frame start, framenum = %d", ov->curframe);
- goto sof;
- }
- } else {
- goto check_middle;
- }
-
-eof:
- ts = (struct timeval *)(frame->data
- + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight));
- do_gettimeofday(ts);
-
- PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d",
- ov->curframe,
- (int)(in[9]), (int)(in[10]), frame->bytes_recvd);
-
- // FIXME: Since we don't know the header formats yet,
- // there is no way to know what the actual image size is
- frame->rawwidth = frame->width;
- frame->rawheight = frame->height;
-
- /* Validate the header data */
- RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth);
- RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight);
-
- /* Don't allow byte count to exceed buffer size */
- RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw);
-
- if (frame->scanstate == STATE_LINES) {
- int nextf;
-
- frame->grabstate = FRAME_DONE;
- wake_up_interruptible(&frame->wq);
-
- /* If next frame is ready or grabbing,
- * point to it */
- nextf = (ov->curframe + 1) % OV511_NUMFRAMES;
- if (ov->frame[nextf].grabstate == FRAME_READY
- || ov->frame[nextf].grabstate == FRAME_GRABBING) {
- ov->curframe = nextf;
- ov->frame[nextf].scanstate = STATE_SCANNING;
- frame = &ov->frame[nextf];
- } else {
- if (frame->grabstate == FRAME_DONE) {
- PDEBUG(4, "** Frame done **");
- } else {
- PDEBUG(4, "Frame not ready? state = %d",
- ov->frame[nextf].grabstate);
- }
-
- ov->curframe = -1;
- PDEBUG(4, "SOF dropped (no active frame)");
- return; /* Nowhere to store this frame */
- }
- }
-sof:
- PDEBUG(4, "Starting capture on frame %d", frame->framenum);
-
-// Snapshot not reverse-engineered yet.
-#if 0
- /* Check to see if it's a snapshot frame */
- /* FIXME?? Should the snapshot reset go here? Performance? */
- if (in[8] & 0x02) {
- frame->snapshot = 1;
- PDEBUG(3, "snapshot detected");
- }
-#endif
- frame->scanstate = STATE_LINES;
- frame->bytes_recvd = 0;
- frame->compressed = 1;
-
-check_middle:
- /* Are we in a frame? */
- if (frame->scanstate != STATE_LINES) {
- PDEBUG(4, "scanstate: no SOF yet");
- return;
- }
-
- /* Dump all data exactly as received */
- if (dumppix == 2) {
- frame->bytes_recvd += n;
- if (frame->bytes_recvd <= max_raw)
- memcpy(frame->rawdata + frame->bytes_recvd - n, in, n);
- else
- PDEBUG(3, "Raw data buffer overrun!! (%d)",
- frame->bytes_recvd - max_raw);
- } else {
- /* All incoming data are divided into 8-byte segments. If the
- * segment contains all zero bytes, it must be skipped. These
- * zero-segments allow the OV518 to mainain a constant data rate
- * regardless of the effectiveness of the compression. Segments
- * are aligned relative to the beginning of each isochronous
- * packet. The first segment in each image is a header (the
- * decompressor skips it later).
- */
-
- int b, read = 0, allzero, copied = 0;
-
- while (read < n) {
- allzero = 1;
- for (b = 0; b < 8; b++) {
- if (in[read + b]) {
- allzero = 0;
- break;
- }
- }
-
- if (allzero) {
- /* Don't copy it */
- } else {
- if (frame->bytes_recvd + copied + 8 <= max_raw)
- {
- memcpy(frame->rawdata
- + frame->bytes_recvd + copied,
- in + read, 8);
- copied += 8;
- } else {
- PDEBUG(3, "Raw data buffer overrun!!");
- }
- }
- read += 8;
- }
- frame->bytes_recvd += copied;
- }
-}
-
-static void
-ov51x_isoc_irq(struct urb *urb)
-{
- int i;
- struct usb_ov511 *ov;
- struct ov511_sbuf *sbuf;
-
- if (!urb->context) {
- PDEBUG(4, "no context");
- return;
- }
-
- sbuf = urb->context;
- ov = sbuf->ov;
-
- if (!ov || !ov->dev || !ov->user) {
- PDEBUG(4, "no device, or not open");
- return;
- }
-
- if (!ov->streaming) {
- PDEBUG(4, "hmmm... not streaming, but got interrupt");
- return;
- }
-
- if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
- PDEBUG(4, "URB unlinked");
- return;
- }
-
- if (urb->status != -EINPROGRESS && urb->status != 0) {
- err("ERROR: urb->status=%d: %s", urb->status,
- symbolic(urb_errlist, urb->status));
- }
-
- /* Copy the data received into our frame buffer */
- PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n,
- urb->number_of_packets);
- for (i = 0; i < urb->number_of_packets; i++) {
- /* Warning: Don't call *_move_data() if no frame active! */
- if (ov->curframe >= 0) {
- int n = urb->iso_frame_desc[i].actual_length;
- int st = urb->iso_frame_desc[i].status;
- unsigned char *cdata;
-
- urb->iso_frame_desc[i].actual_length = 0;
- urb->iso_frame_desc[i].status = 0;
-
- cdata = urb->transfer_buffer
- + urb->iso_frame_desc[i].offset;
-
- if (!n) {
- PDEBUG(4, "Zero-length packet");
- continue;
- }
-
- if (st)
- PDEBUG(2, "data error: [%d] len=%d, status=%d",
- i, n, st);
-
- if (ov->bclass == BCL_OV511)
- ov511_move_data(ov, cdata, n);
- else if (ov->bclass == BCL_OV518)
- ov518_move_data(ov, cdata, n);
- else
- err("Unknown bridge device (%d)", ov->bridge);
-
- } else if (waitqueue_active(&ov->wq)) {
- wake_up_interruptible(&ov->wq);
- }
- }
-
- /* Resubmit this URB */
- urb->dev = ov->dev;
- if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0)
- err("usb_submit_urb() ret %d", i);
-
- return;
-}
-
-/****************************************************************************
- *
- * Stream initialization and termination
- *
- ***************************************************************************/
-
-static int
-ov51x_init_isoc(struct usb_ov511 *ov)
-{
- struct urb *urb;
- int fx, err, n, i, size;
-
- PDEBUG(3, "*** Initializing capture ***");
-
- ov->curframe = -1;
-
- if (ov->bridge == BRG_OV511) {
- if (cams == 1)
- size = 993;
- else if (cams == 2)
- size = 513;
- else if (cams == 3 || cams == 4)
- size = 257;
- else {
- err("\"cams\" parameter too high!");
- return -1;
- }
- } else if (ov->bridge == BRG_OV511PLUS) {
- if (cams == 1)
- size = 961;
- else if (cams == 2)
- size = 513;
- else if (cams == 3 || cams == 4)
- size = 257;
- else if (cams >= 5 && cams <= 8)
- size = 129;
- else if (cams >= 9 && cams <= 31)
- size = 33;
- else {
- err("\"cams\" parameter too high!");
- return -1;
- }
- } else if (ov->bclass == BCL_OV518) {
- if (cams == 1)
- size = 896;
- else if (cams == 2)
- size = 512;
- else if (cams == 3 || cams == 4)
- size = 256;
- else if (cams >= 5 && cams <= 8)
- size = 128;
- else {
- err("\"cams\" parameter too high!");
- return -1;
- }
- } else {
- err("invalid bridge type");
- return -1;
- }
-
- // FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now
- if (ov->bclass == BCL_OV518) {
- if (packetsize == -1) {
- ov518_set_packet_size(ov, 640);
- } else {
- dev_info(&ov->dev->dev, "Forcing packet size to %d\n",
- packetsize);
- ov518_set_packet_size(ov, packetsize);
- }
- } else {
- if (packetsize == -1) {
- ov511_set_packet_size(ov, size);
- } else {
- dev_info(&ov->dev->dev, "Forcing packet size to %d\n",
- packetsize);
- ov511_set_packet_size(ov, packetsize);
- }
- }
-
- for (n = 0; n < OV511_NUMSBUF; n++) {
- urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
- if (!urb) {
- err("init isoc: usb_alloc_urb ret. NULL");
- for (i = 0; i < n; i++)
- usb_free_urb(ov->sbuf[i].urb);
- return -ENOMEM;
- }
- ov->sbuf[n].urb = urb;
- urb->dev = ov->dev;
- urb->context = &ov->sbuf[n];
- urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = ov->sbuf[n].data;
- urb->complete = ov51x_isoc_irq;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC;
- urb->interval = 1;
- for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
- urb->iso_frame_desc[fx].offset = ov->packet_size * fx;
- urb->iso_frame_desc[fx].length = ov->packet_size;
- }
- }
-
- ov->streaming = 1;
-
- for (n = 0; n < OV511_NUMSBUF; n++) {
- ov->sbuf[n].urb->dev = ov->dev;
- err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL);
- if (err) {
- err("init isoc: usb_submit_urb(%d) ret %d", n, err);
- return err;
- }
- }
-
- return 0;
-}
-
-static void
-ov51x_unlink_isoc(struct usb_ov511 *ov)
-{
- int n;
-
- /* Unschedule all of the iso td's */
- for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
- if (ov->sbuf[n].urb) {
- usb_kill_urb(ov->sbuf[n].urb);
- usb_free_urb(ov->sbuf[n].urb);
- ov->sbuf[n].urb = NULL;
- }
- }
-}
-
-static void
-ov51x_stop_isoc(struct usb_ov511 *ov)
-{
- if (!ov->streaming || !ov->dev)
- return;
-
- PDEBUG(3, "*** Stopping capture ***");
-
- if (ov->bclass == BCL_OV518)
- ov518_set_packet_size(ov, 0);
- else
- ov511_set_packet_size(ov, 0);
-
- ov->streaming = 0;
-
- ov51x_unlink_isoc(ov);
-}
-
-static int
-ov51x_new_frame(struct usb_ov511 *ov, int framenum)
-{
- struct ov511_frame *frame;
- int newnum;
-
- PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum);
-
- if (!ov->dev)
- return -1;
-
- /* If we're not grabbing a frame right now and the other frame is */
- /* ready to be grabbed into, then use it instead */
- if (ov->curframe == -1) {
- newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
- if (ov->frame[newnum].grabstate == FRAME_READY)
- framenum = newnum;
- } else
- return 0;
-
- frame = &ov->frame[framenum];
-
- PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum,
- frame->width, frame->height);
-
- frame->grabstate = FRAME_GRABBING;
- frame->scanstate = STATE_SCANNING;
- frame->snapshot = 0;
-
- ov->curframe = framenum;
-
- /* Make sure it's not too big */
- if (frame->width > ov->maxwidth)
- frame->width = ov->maxwidth;
-
- frame->width &= ~7L; /* Multiple of 8 */
-
- if (frame->height > ov->maxheight)
- frame->height = ov->maxheight;
-
- frame->height &= ~3L; /* Multiple of 4 */
-
- return 0;
-}
-
-/****************************************************************************
- *
- * Buffer management
- *
- ***************************************************************************/
-
-/*
- * - You must acquire buf_lock before entering this function.
- * - Because this code will free any non-null pointer, you must be sure to null
- * them if you explicitly free them somewhere else!
- */
-static void
-ov51x_do_dealloc(struct usb_ov511 *ov)
-{
- int i;
- PDEBUG(4, "entered");
-
- if (ov->fbuf) {
- rvfree(ov->fbuf, OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight));
- ov->fbuf = NULL;
- }
-
- vfree(ov->rawfbuf);
- ov->rawfbuf = NULL;
-
- vfree(ov->tempfbuf);
- ov->tempfbuf = NULL;
-
- for (i = 0; i < OV511_NUMSBUF; i++) {
- kfree(ov->sbuf[i].data);
- ov->sbuf[i].data = NULL;
- }
-
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].data = NULL;
- ov->frame[i].rawdata = NULL;
- ov->frame[i].tempdata = NULL;
- if (ov->frame[i].compbuf) {
- free_page((unsigned long) ov->frame[i].compbuf);
- ov->frame[i].compbuf = NULL;
- }
- }
-
- PDEBUG(4, "buffer memory deallocated");
- ov->buf_state = BUF_NOT_ALLOCATED;
- PDEBUG(4, "leaving");
-}
-
-static int
-ov51x_alloc(struct usb_ov511 *ov)
-{
- int i;
- const int w = ov->maxwidth;
- const int h = ov->maxheight;
- const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h);
- const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h);
-
- PDEBUG(4, "entered");
- mutex_lock(&ov->buf_lock);
-
- if (ov->buf_state == BUF_ALLOCATED)
- goto out;
-
- ov->fbuf = rvmalloc(data_bufsize);
- if (!ov->fbuf)
- goto error;
-
- ov->rawfbuf = vmalloc(raw_bufsize);
- if (!ov->rawfbuf)
- goto error;
-
- memset(ov->rawfbuf, 0, raw_bufsize);
-
- ov->tempfbuf = vmalloc(raw_bufsize);
- if (!ov->tempfbuf)
- goto error;
-
- memset(ov->tempfbuf, 0, raw_bufsize);
-
- for (i = 0; i < OV511_NUMSBUF; i++) {
- ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
- MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
- if (!ov->sbuf[i].data)
- goto error;
-
- PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data);
- }
-
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h);
- ov->frame[i].rawdata = ov->rawfbuf
- + i * MAX_RAW_DATA_SIZE(w, h);
- ov->frame[i].tempdata = ov->tempfbuf
- + i * MAX_RAW_DATA_SIZE(w, h);
-
- ov->frame[i].compbuf =
- (unsigned char *) __get_free_page(GFP_KERNEL);
- if (!ov->frame[i].compbuf)
- goto error;
-
- PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data);
- }
-
- ov->buf_state = BUF_ALLOCATED;
-out:
- mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "leaving");
- return 0;
-error:
- ov51x_do_dealloc(ov);
- mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "errored");
- return -ENOMEM;
-}
-
-static void
-ov51x_dealloc(struct usb_ov511 *ov)
-{
- PDEBUG(4, "entered");
- mutex_lock(&ov->buf_lock);
- ov51x_do_dealloc(ov);
- mutex_unlock(&ov->buf_lock);
- PDEBUG(4, "leaving");
-}
-
-/****************************************************************************
- *
- * V4L 1 API
- *
- ***************************************************************************/
-
-static int
-ov51x_v4l1_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- int err, i;
-
- PDEBUG(4, "opening");
-
- mutex_lock(&ov->lock);
-
- err = -EBUSY;
- if (ov->user)
- goto out;
-
- ov->sub_flag = 0;
-
- /* In case app doesn't set them... */
- err = ov51x_set_default_params(ov);
- if (err < 0)
- goto out;
-
- /* Make sure frames are reset */
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].grabstate = FRAME_UNUSED;
- ov->frame[i].bytes_read = 0;
- }
-
- /* If compression is on, make sure now that a
- * decompressor can be loaded */
- if (ov->compress && !ov->decomp_ops) {
- err = request_decompressor(ov);
- if (err && !dumppix)
- goto out;
- }
-
- err = ov51x_alloc(ov);
- if (err < 0)
- goto out;
-
- err = ov51x_init_isoc(ov);
- if (err) {
- ov51x_dealloc(ov);
- goto out;
- }
-
- ov->user++;
- file->private_data = vdev;
-
- if (ov->led_policy == LED_AUTO)
- ov51x_led_control(ov, 1);
-
-out:
- mutex_unlock(&ov->lock);
- return err;
-}
-
-static int
-ov51x_v4l1_close(struct file *file)
-{
- struct video_device *vdev = file->private_data;
- struct usb_ov511 *ov = video_get_drvdata(vdev);
-
- PDEBUG(4, "ov511_close");
-
- mutex_lock(&ov->lock);
-
- ov->user--;
- ov51x_stop_isoc(ov);
-
- if (ov->led_policy == LED_AUTO)
- ov51x_led_control(ov, 0);
-
- if (ov->dev)
- ov51x_dealloc(ov);
-
- mutex_unlock(&ov->lock);
-
- /* Device unplugged while open. Only a minimum of unregistration is done
- * here; the disconnect callback already did the rest. */
- if (!ov->dev) {
- mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
- mutex_unlock(&ov->cbuf_lock);
-
- ov51x_dealloc(ov);
- kfree(ov);
- ov = NULL;
- }
-
- file->private_data = NULL;
- return 0;
-}
-
-/* Do not call this function directly! */
-static long
-ov51x_v4l1_ioctl_internal(struct file *file, unsigned int cmd, void *arg)
-{
- struct video_device *vdev = file->private_data;
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- PDEBUG(5, "IOCtl: 0x%X", cmd);
-
- if (!ov->dev)
- return -EIO;
-
- switch (cmd) {
- case VIDIOCGCAP:
- {
- struct video_capability *b = arg;
-
- PDEBUG(4, "VIDIOCGCAP");
-
- memset(b, 0, sizeof(struct video_capability));
- sprintf(b->name, "%s USB Camera",
- symbolic(brglist, ov->bridge));
- b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
- b->channels = ov->num_inputs;
- b->audios = 0;
- b->maxwidth = ov->maxwidth;
- b->maxheight = ov->maxheight;
- b->minwidth = ov->minwidth;
- b->minheight = ov->minheight;
-
- return 0;
- }
- case VIDIOCGCHAN:
- {
- struct video_channel *v = arg;
-
- PDEBUG(4, "VIDIOCGCHAN");
-
- if ((unsigned)(v->channel) >= ov->num_inputs) {
- err("Invalid channel (%d)", v->channel);
- return -EINVAL;
- }
-
- v->norm = ov->norm;
- v->type = VIDEO_TYPE_CAMERA;
- v->flags = 0;
-// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0;
- v->tuners = 0;
- decoder_get_input_name(ov, v->channel, v->name);
-
- return 0;
- }
- case VIDIOCSCHAN:
- {
- struct video_channel *v = arg;
- int err;
-
- PDEBUG(4, "VIDIOCSCHAN");
-
- /* Make sure it's not a camera */
- if (!ov->has_decoder) {
- if (v->channel == 0)
- return 0;
- else
- return -EINVAL;
- }
-
- if (v->norm != VIDEO_MODE_PAL &&
- v->norm != VIDEO_MODE_NTSC &&
- v->norm != VIDEO_MODE_SECAM &&
- v->norm != VIDEO_MODE_AUTO) {
- err("Invalid norm (%d)", v->norm);
- return -EINVAL;
- }
-
- if ((unsigned)(v->channel) >= ov->num_inputs) {
- err("Invalid channel (%d)", v->channel);
- return -EINVAL;
- }
-
- err = decoder_set_input(ov, v->channel);
- if (err)
- return err;
-
- err = decoder_set_norm(ov, v->norm);
- if (err)
- return err;
-
- return 0;
- }
- case VIDIOCGPICT:
- {
- struct video_picture *p = arg;
-
- PDEBUG(4, "VIDIOCGPICT");
-
- memset(p, 0, sizeof(struct video_picture));
- if (sensor_get_picture(ov, p))
- return -EIO;
-
- /* Can we get these from frame[0]? -claudio? */
- p->depth = ov->frame[0].depth;
- p->palette = ov->frame[0].format;
-
- return 0;
- }
- case VIDIOCSPICT:
- {
- struct video_picture *p = arg;
- int i, rc;
-
- PDEBUG(4, "VIDIOCSPICT");
-
- if (!get_depth(p->palette))
- return -EINVAL;
-
- if (sensor_set_picture(ov, p))
- return -EIO;
-
- if (force_palette && p->palette != force_palette) {
- dev_info(&ov->dev->dev, "Palette rejected (%s)\n",
- symbolic(v4l1_plist, p->palette));
- return -EINVAL;
- }
-
- // FIXME: Format should be independent of frames
- if (p->palette != ov->frame[0].format) {
- PDEBUG(4, "Detected format change");
-
- rc = ov51x_wait_frames_inactive(ov);
- if (rc)
- return rc;
-
- mode_init_regs(ov, ov->frame[0].width,
- ov->frame[0].height, p->palette, ov->sub_flag);
- }
-
- PDEBUG(4, "Setting depth=%d, palette=%s",
- p->depth, symbolic(v4l1_plist, p->palette));
-
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].depth = p->depth;
- ov->frame[i].format = p->palette;
- }
-
- return 0;
- }
- case VIDIOCGCAPTURE:
- {
- int *vf = arg;
-
- PDEBUG(4, "VIDIOCGCAPTURE");
-
- ov->sub_flag = *vf;
- return 0;
- }
- case VIDIOCSCAPTURE:
- {
- struct video_capture *vc = arg;
-
- PDEBUG(4, "VIDIOCSCAPTURE");
-
- if (vc->flags)
- return -EINVAL;
- if (vc->decimation)
- return -EINVAL;
-
- vc->x &= ~3L;
- vc->y &= ~1L;
- vc->y &= ~31L;
-
- if (vc->width == 0)
- vc->width = 32;
-
- vc->height /= 16;
- vc->height *= 16;
- if (vc->height == 0)
- vc->height = 16;
-
- ov->subx = vc->x;
- ov->suby = vc->y;
- ov->subw = vc->width;
- ov->subh = vc->height;
-
- return 0;
- }
- case VIDIOCSWIN:
- {
- struct video_window *vw = arg;
- int i, rc;
-
- PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height);
-
-#if 0
- if (vw->flags)
- return -EINVAL;
- if (vw->clipcount)
- return -EINVAL;
- if (vw->height != ov->maxheight)
- return -EINVAL;
- if (vw->width != ov->maxwidth)
- return -EINVAL;
-#endif
-
- rc = ov51x_wait_frames_inactive(ov);
- if (rc)
- return rc;
-
- rc = mode_init_regs(ov, vw->width, vw->height,
- ov->frame[0].format, ov->sub_flag);
- if (rc < 0)
- return rc;
-
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].width = vw->width;
- ov->frame[i].height = vw->height;
- }
-
- return 0;
- }
- case VIDIOCGWIN:
- {
- struct video_window *vw = arg;
-
- memset(vw, 0, sizeof(struct video_window));
- vw->x = 0; /* FIXME */
- vw->y = 0;
- vw->width = ov->frame[0].width;
- vw->height = ov->frame[0].height;
- vw->flags = 30;
-
- PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height);
-
- return 0;
- }
- case VIDIOCGMBUF:
- {
- struct video_mbuf *vm = arg;
- int i;
-
- PDEBUG(4, "VIDIOCGMBUF");
-
- memset(vm, 0, sizeof(struct video_mbuf));
- vm->size = OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
- vm->frames = OV511_NUMFRAMES;
-
- vm->offsets[0] = 0;
- for (i = 1; i < OV511_NUMFRAMES; i++) {
- vm->offsets[i] = vm->offsets[i-1]
- + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);
- }
-
- return 0;
- }
- case VIDIOCMCAPTURE:
- {
- struct video_mmap *vm = arg;
- int rc, depth;
- unsigned int f = vm->frame;
-
- PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width,
- vm->height, symbolic(v4l1_plist, vm->format));
-
- depth = get_depth(vm->format);
- if (!depth) {
- PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)",
- symbolic(v4l1_plist, vm->format));
- return -EINVAL;
- }
-
- if (f >= OV511_NUMFRAMES) {
- err("VIDIOCMCAPTURE: invalid frame (%d)", f);
- return -EINVAL;
- }
-
- if (vm->width > ov->maxwidth
- || vm->height > ov->maxheight) {
- err("VIDIOCMCAPTURE: requested dimensions too big");
- return -EINVAL;
- }
-
- if (ov->frame[f].grabstate == FRAME_GRABBING) {
- PDEBUG(4, "VIDIOCMCAPTURE: already grabbing");
- return -EBUSY;
- }
-
- if (force_palette && (vm->format != force_palette)) {
- PDEBUG(2, "palette rejected (%s)",
- symbolic(v4l1_plist, vm->format));
- return -EINVAL;
- }
-
- if ((ov->frame[f].width != vm->width) ||
- (ov->frame[f].height != vm->height) ||
- (ov->frame[f].format != vm->format) ||
- (ov->frame[f].sub_flag != ov->sub_flag) ||
- (ov->frame[f].depth != depth)) {
- PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters");
-
- rc = ov51x_wait_frames_inactive(ov);
- if (rc)
- return rc;
-
- rc = mode_init_regs(ov, vm->width, vm->height,
- vm->format, ov->sub_flag);
-#if 0
- if (rc < 0) {
- PDEBUG(1, "Got error while initializing regs ");
- return ret;
- }
-#endif
- ov->frame[f].width = vm->width;
- ov->frame[f].height = vm->height;
- ov->frame[f].format = vm->format;
- ov->frame[f].sub_flag = ov->sub_flag;
- ov->frame[f].depth = depth;
- }
-
- /* Mark it as ready */
- ov->frame[f].grabstate = FRAME_READY;
-
- PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f);
-
- return ov51x_new_frame(ov, f);
- }
- case VIDIOCSYNC:
- {
- unsigned int fnum = *((unsigned int *) arg);
- struct ov511_frame *frame;
- int rc;
-
- if (fnum >= OV511_NUMFRAMES) {
- err("VIDIOCSYNC: invalid frame (%d)", fnum);
- return -EINVAL;
- }
-
- frame = &ov->frame[fnum];
-
- PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,
- frame->grabstate);
-
- switch (frame->grabstate) {
- case FRAME_UNUSED:
- return -EINVAL;
- case FRAME_READY:
- case FRAME_GRABBING:
- case FRAME_ERROR:
-redo:
- if (!ov->dev)
- return -EIO;
-
- rc = wait_event_interruptible(frame->wq,
- (frame->grabstate == FRAME_DONE)
- || (frame->grabstate == FRAME_ERROR));
-
- if (rc)
- return rc;
-
- if (frame->grabstate == FRAME_ERROR) {
- if ((rc = ov51x_new_frame(ov, fnum)) < 0)
- return rc;
- goto redo;
- }
- /* Fall through */
- case FRAME_DONE:
- if (ov->snap_enabled && !frame->snapshot) {
- if ((rc = ov51x_new_frame(ov, fnum)) < 0)
- return rc;
- goto redo;
- }
-
- frame->grabstate = FRAME_UNUSED;
-
- /* Reset the hardware snapshot button */
- /* FIXME - Is this the best place for this? */
- if ((ov->snap_enabled) && (frame->snapshot)) {
- frame->snapshot = 0;
- ov51x_clear_snapshot(ov);
- }
-
- /* Decompression, format conversion, etc... */
- ov51x_postprocess(ov, frame);
-
- break;
- } /* end switch */
-
- return 0;
- }
- case VIDIOCGFBUF:
- {
- struct video_buffer *vb = arg;
-
- PDEBUG(4, "VIDIOCGFBUF");
-
- memset(vb, 0, sizeof(struct video_buffer));
-
- return 0;
- }
- case VIDIOCGUNIT:
- {
- struct video_unit *vu = arg;
-
- PDEBUG(4, "VIDIOCGUNIT");
-
- memset(vu, 0, sizeof(struct video_unit));
-
- vu->video = ov->vdev->minor;
- vu->vbi = VIDEO_NO_UNIT;
- vu->radio = VIDEO_NO_UNIT;
- vu->audio = VIDEO_NO_UNIT;
- vu->teletext = VIDEO_NO_UNIT;
-
- return 0;
- }
- case OV511IOC_WI2C:
- {
- struct ov511_i2c_struct *w = arg;
-
- return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask);
- }
- case OV511IOC_RI2C:
- {
- struct ov511_i2c_struct *r = arg;
- int rc;
-
- rc = i2c_r_slave(ov, r->slave, r->reg);
- if (rc < 0)
- return rc;
-
- r->value = rc;
- return 0;
- }
- default:
- PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);
- return -ENOIOCTLCMD;
- } /* end switch */
-
- return 0;
-}
-
-static long
-ov51x_v4l1_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct video_device *vdev = file->private_data;
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- int rc;
-
- if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- rc = video_usercopy(file, cmd, arg, ov51x_v4l1_ioctl_internal);
-
- mutex_unlock(&ov->lock);
- return rc;
-}
-
-static ssize_t
-ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos)
-{
- struct video_device *vdev = file->private_data;
- int noblock = file->f_flags&O_NONBLOCK;
- unsigned long count = cnt;
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- int i, rc = 0, frmx = -1;
- struct ov511_frame *frame;
-
- if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
-
- if (!vdev || !buf) {
- rc = -EFAULT;
- goto error;
- }
-
- if (!ov->dev) {
- rc = -EIO;
- goto error;
- }
-
-// FIXME: Only supports two frames
- /* See if a frame is completed, then use it. */
- if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
- frmx = 0;
- else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
- frmx = 1;
-
- /* If nonblocking we return immediately */
- if (noblock && (frmx == -1)) {
- rc = -EAGAIN;
- goto error;
- }
-
- /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
- /* See if a frame is in process (grabbing), then use it. */
- if (frmx == -1) {
- if (ov->frame[0].grabstate == FRAME_GRABBING)
- frmx = 0;
- else if (ov->frame[1].grabstate == FRAME_GRABBING)
- frmx = 1;
- }
-
- /* If no frame is active, start one. */
- if (frmx == -1) {
- if ((rc = ov51x_new_frame(ov, frmx = 0))) {
- err("read: ov51x_new_frame error");
- goto error;
- }
- }
-
- frame = &ov->frame[frmx];
-
-restart:
- if (!ov->dev) {
- rc = -EIO;
- goto error;
- }
-
- /* Wait while we're grabbing the image */
- PDEBUG(4, "Waiting image grabbing");
- rc = wait_event_interruptible(frame->wq,
- (frame->grabstate == FRAME_DONE)
- || (frame->grabstate == FRAME_ERROR));
-
- if (rc)
- goto error;
-
- PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate);
- PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd);
-
- if (frame->grabstate == FRAME_ERROR) {
- frame->bytes_read = 0;
- err("** ick! ** Errored frame %d", ov->curframe);
- if (ov51x_new_frame(ov, frmx)) {
- err("read: ov51x_new_frame error");
- goto error;
- }
- goto restart;
- }
-
-
- /* Repeat until we get a snapshot frame */
- if (ov->snap_enabled)
- PDEBUG(4, "Waiting snapshot frame");
- if (ov->snap_enabled && !frame->snapshot) {
- frame->bytes_read = 0;
- if ((rc = ov51x_new_frame(ov, frmx))) {
- err("read: ov51x_new_frame error");
- goto error;
- }
- goto restart;
- }
-
- /* Clear the snapshot */
- if (ov->snap_enabled && frame->snapshot) {
- frame->snapshot = 0;
- ov51x_clear_snapshot(ov);
- }
-
- /* Decompression, format conversion, etc... */
- ov51x_postprocess(ov, frame);
-
- PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx,
- frame->bytes_read,
- get_frame_length(frame));
-
- /* copy bytes to user space; we allow for partials reads */
-// if ((count + frame->bytes_read)
-// > get_frame_length((struct ov511_frame *)frame))
-// count = frame->scanlength - frame->bytes_read;
-
- /* FIXME - count hardwired to be one frame... */
- count = get_frame_length(frame);
-
- PDEBUG(4, "Copy to user space: %ld bytes", count);
- if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) {
- PDEBUG(4, "Copy failed! %d bytes not copied", i);
- rc = -EFAULT;
- goto error;
- }
-
- frame->bytes_read += count;
- PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
- count, frame->bytes_read);
-
- /* If all data have been read... */
- if (frame->bytes_read
- >= get_frame_length(frame)) {
- frame->bytes_read = 0;
-
-// FIXME: Only supports two frames
- /* Mark it as available to be used again. */
- ov->frame[frmx].grabstate = FRAME_UNUSED;
- if ((rc = ov51x_new_frame(ov, !frmx))) {
- err("ov51x_new_frame returned error");
- goto error;
- }
- }
-
- PDEBUG(4, "read finished, returning %ld (sweet)", count);
-
- mutex_unlock(&ov->lock);
- return count;
-
-error:
- mutex_unlock(&ov->lock);
- return rc;
-}
-
-static int
-ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *vdev = file->private_data;
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end - vma->vm_start;
- struct usb_ov511 *ov = video_get_drvdata(vdev);
- unsigned long page, pos;
-
- if (ov->dev == NULL)
- return -EIO;
-
- PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
-
- if (size > (((OV511_NUMFRAMES
- * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)
- + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))))
- return -EINVAL;
-
- if (mutex_lock_interruptible(&ov->lock))
- return -EINTR;
-
- pos = (unsigned long)ov->fbuf;
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- mutex_unlock(&ov->lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
-
- mutex_unlock(&ov->lock);
- return 0;
-}
-
-static const struct v4l2_file_operations ov511_fops = {
- .owner = THIS_MODULE,
- .open = ov51x_v4l1_open,
- .release = ov51x_v4l1_close,
- .read = ov51x_v4l1_read,
- .mmap = ov51x_v4l1_mmap,
- .ioctl = ov51x_v4l1_ioctl,
-};
-
-static struct video_device vdev_template = {
- .name = "OV511 USB Camera",
- .fops = &ov511_fops,
- .release = video_device_release,
-};
-
-/****************************************************************************
- *
- * OV511 and sensor configuration
- *
- ***************************************************************************/
-
-/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses
- * the same register settings as the OV7610, since they are very similar.
- */
-static int
-ov7xx0_configure(struct usb_ov511 *ov)
-{
- int i, success;
- int rc;
-
- /* Lawrence Glaister <lg@jfm.bc.ca> reports:
- *
- * Register 0x0f in the 7610 has the following effects:
- *
- * 0x85 (AEC method 1): Best overall, good contrast range
- * 0x45 (AEC method 2): Very overexposed
- * 0xa5 (spec sheet default): Ok, but the black level is
- * shifted resulting in loss of contrast
- * 0x05 (old driver setting): very overexposed, too much
- * contrast
- */
- static struct ov511_regvals aRegvalsNorm7610[] = {
- { OV511_I2C_BUS, 0x10, 0xff },
- { OV511_I2C_BUS, 0x16, 0x06 },
- { OV511_I2C_BUS, 0x28, 0x24 },
- { OV511_I2C_BUS, 0x2b, 0xac },
- { OV511_I2C_BUS, 0x12, 0x00 },
- { OV511_I2C_BUS, 0x38, 0x81 },
- { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */
- { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */
- { OV511_I2C_BUS, 0x15, 0x01 },
- { OV511_I2C_BUS, 0x20, 0x1c },
- { OV511_I2C_BUS, 0x23, 0x2a },
- { OV511_I2C_BUS, 0x24, 0x10 },
- { OV511_I2C_BUS, 0x25, 0x8a },
- { OV511_I2C_BUS, 0x26, 0xa2 },
- { OV511_I2C_BUS, 0x27, 0xc2 },
- { OV511_I2C_BUS, 0x2a, 0x04 },
- { OV511_I2C_BUS, 0x2c, 0xfe },
- { OV511_I2C_BUS, 0x2d, 0x93 },
- { OV511_I2C_BUS, 0x30, 0x71 },
- { OV511_I2C_BUS, 0x31, 0x60 },
- { OV511_I2C_BUS, 0x32, 0x26 },
- { OV511_I2C_BUS, 0x33, 0x20 },
- { OV511_I2C_BUS, 0x34, 0x48 },
- { OV511_I2C_BUS, 0x12, 0x24 },
- { OV511_I2C_BUS, 0x11, 0x01 },
- { OV511_I2C_BUS, 0x0c, 0x24 },
- { OV511_I2C_BUS, 0x0d, 0x24 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- static struct ov511_regvals aRegvalsNorm7620[] = {
- { OV511_I2C_BUS, 0x00, 0x00 },
- { OV511_I2C_BUS, 0x01, 0x80 },
- { OV511_I2C_BUS, 0x02, 0x80 },
- { OV511_I2C_BUS, 0x03, 0xc0 },
- { OV511_I2C_BUS, 0x06, 0x60 },
- { OV511_I2C_BUS, 0x07, 0x00 },
- { OV511_I2C_BUS, 0x0c, 0x24 },
- { OV511_I2C_BUS, 0x0c, 0x24 },
- { OV511_I2C_BUS, 0x0d, 0x24 },
- { OV511_I2C_BUS, 0x11, 0x01 },
- { OV511_I2C_BUS, 0x12, 0x24 },
- { OV511_I2C_BUS, 0x13, 0x01 },
- { OV511_I2C_BUS, 0x14, 0x84 },
- { OV511_I2C_BUS, 0x15, 0x01 },
- { OV511_I2C_BUS, 0x16, 0x03 },
- { OV511_I2C_BUS, 0x17, 0x2f },
- { OV511_I2C_BUS, 0x18, 0xcf },
- { OV511_I2C_BUS, 0x19, 0x06 },
- { OV511_I2C_BUS, 0x1a, 0xf5 },
- { OV511_I2C_BUS, 0x1b, 0x00 },
- { OV511_I2C_BUS, 0x20, 0x18 },
- { OV511_I2C_BUS, 0x21, 0x80 },
- { OV511_I2C_BUS, 0x22, 0x80 },
- { OV511_I2C_BUS, 0x23, 0x00 },
- { OV511_I2C_BUS, 0x26, 0xa2 },
- { OV511_I2C_BUS, 0x27, 0xea },
- { OV511_I2C_BUS, 0x28, 0x20 },
- { OV511_I2C_BUS, 0x29, 0x00 },
- { OV511_I2C_BUS, 0x2a, 0x10 },
- { OV511_I2C_BUS, 0x2b, 0x00 },
- { OV511_I2C_BUS, 0x2c, 0x88 },
- { OV511_I2C_BUS, 0x2d, 0x91 },
- { OV511_I2C_BUS, 0x2e, 0x80 },
- { OV511_I2C_BUS, 0x2f, 0x44 },
- { OV511_I2C_BUS, 0x60, 0x27 },
- { OV511_I2C_BUS, 0x61, 0x02 },
- { OV511_I2C_BUS, 0x62, 0x5f },
- { OV511_I2C_BUS, 0x63, 0xd5 },
- { OV511_I2C_BUS, 0x64, 0x57 },
- { OV511_I2C_BUS, 0x65, 0x83 },
- { OV511_I2C_BUS, 0x66, 0x55 },
- { OV511_I2C_BUS, 0x67, 0x92 },
- { OV511_I2C_BUS, 0x68, 0xcf },
- { OV511_I2C_BUS, 0x69, 0x76 },
- { OV511_I2C_BUS, 0x6a, 0x22 },
- { OV511_I2C_BUS, 0x6b, 0x00 },
- { OV511_I2C_BUS, 0x6c, 0x02 },
- { OV511_I2C_BUS, 0x6d, 0x44 },
- { OV511_I2C_BUS, 0x6e, 0x80 },
- { OV511_I2C_BUS, 0x6f, 0x1d },
- { OV511_I2C_BUS, 0x70, 0x8b },
- { OV511_I2C_BUS, 0x71, 0x00 },
- { OV511_I2C_BUS, 0x72, 0x14 },
- { OV511_I2C_BUS, 0x73, 0x54 },
- { OV511_I2C_BUS, 0x74, 0x00 },
- { OV511_I2C_BUS, 0x75, 0x8e },
- { OV511_I2C_BUS, 0x76, 0x00 },
- { OV511_I2C_BUS, 0x77, 0xff },
- { OV511_I2C_BUS, 0x78, 0x80 },
- { OV511_I2C_BUS, 0x79, 0x80 },
- { OV511_I2C_BUS, 0x7a, 0x80 },
- { OV511_I2C_BUS, 0x7b, 0xe2 },
- { OV511_I2C_BUS, 0x7c, 0x00 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- PDEBUG(4, "starting configuration");
-
- /* This looks redundant, but is necessary for WebCam 3 */
- ov->primary_i2c_slave = OV7xx0_SID;
- if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
- return -1;
-
- if (init_ov_sensor(ov) >= 0) {
- PDEBUG(1, "OV7xx0 sensor initalized (method 1)");
- } else {
- /* Reset the 76xx */
- if (i2c_w(ov, 0x12, 0x80) < 0)
- return -1;
-
- /* Wait for it to initialize */
- msleep(150);
-
- i = 0;
- success = 0;
- while (i <= i2c_detect_tries) {
- if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) &&
- (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) {
- success = 1;
- break;
- } else {
- i++;
- }
- }
-
-// Was (i == i2c_detect_tries) previously. This obviously used to always report
-// success. Whether anyone actually depended on that bug is unknown
- if ((i >= i2c_detect_tries) && (success == 0)) {
- err("Failed to read sensor ID. You might not have an");
- err("OV7610/20, or it may be not responding. Report");
- err("this to " EMAIL);
- err("This is only a warning. You can attempt to use");
- err("your camera anyway");
-// Only issue a warning for now
-// return -1;
- } else {
- PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1);
- }
- }
-
- /* Detect sensor (sub)type */
- rc = i2c_r(ov, OV7610_REG_COM_I);
-
- if (rc < 0) {
- err("Error detecting sensor type");
- return -1;
- } else if ((rc & 3) == 3) {
- dev_info(&ov->dev->dev, "Sensor is an OV7610\n");
- ov->sensor = SEN_OV7610;
- } else if ((rc & 3) == 1) {
- /* I don't know what's different about the 76BE yet. */
- if (i2c_r(ov, 0x15) & 1)
- dev_info(&ov->dev->dev, "Sensor is an OV7620AE\n");
- else
- dev_info(&ov->dev->dev, "Sensor is an OV76BE\n");
-
- /* OV511+ will return all zero isoc data unless we
- * configure the sensor as a 7620. Someone needs to
- * find the exact reg. setting that causes this. */
- if (ov->bridge == BRG_OV511PLUS) {
- dev_info(&ov->dev->dev,
- "Enabling 511+/7620AE workaround\n");
- ov->sensor = SEN_OV7620;
- } else {
- ov->sensor = SEN_OV76BE;
- }
- } else if ((rc & 3) == 0) {
- dev_info(&ov->dev->dev, "Sensor is an OV7620\n");
- ov->sensor = SEN_OV7620;
- } else {
- err("Unknown image sensor version: %d", rc & 3);
- return -1;
- }
-
- if (ov->sensor == SEN_OV7620) {
- PDEBUG(4, "Writing 7620 registers");
- if (write_regvals(ov, aRegvalsNorm7620))
- return -1;
- } else {
- PDEBUG(4, "Writing 7610 registers");
- if (write_regvals(ov, aRegvalsNorm7610))
- return -1;
- }
-
- /* Set sensor-specific vars */
- ov->maxwidth = 640;
- ov->maxheight = 480;
- ov->minwidth = 64;
- ov->minheight = 48;
-
- // FIXME: These do not match the actual settings yet
- ov->brightness = 0x80 << 8;
- ov->contrast = 0x80 << 8;
- ov->colour = 0x80 << 8;
- ov->hue = 0x80 << 8;
-
- return 0;
-}
-
-/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */
-static int
-ov6xx0_configure(struct usb_ov511 *ov)
-{
- int rc;
-
- static struct ov511_regvals aRegvalsNorm6x20[] = {
- { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
- { OV511_I2C_BUS, 0x11, 0x01 },
- { OV511_I2C_BUS, 0x03, 0x60 },
- { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
- { OV511_I2C_BUS, 0x07, 0xa8 },
- /* The ratio of 0x0c and 0x0d controls the white point */
- { OV511_I2C_BUS, 0x0c, 0x24 },
- { OV511_I2C_BUS, 0x0d, 0x24 },
- { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */
- { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */
- { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */
- { OV511_I2C_BUS, 0x14, 0x04 },
- /* 0x16: 0x06 helps frame stability with moving objects */
- { OV511_I2C_BUS, 0x16, 0x06 },
-// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
- { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
- /* 0x28: 0x05 Selects RGB format if RGB on */
- { OV511_I2C_BUS, 0x28, 0x05 },
- { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
-// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
- { OV511_I2C_BUS, 0x2d, 0x99 },
- { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */
- { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */
- { OV511_I2C_BUS, 0x38, 0x8b },
- { OV511_I2C_BUS, 0x39, 0x40 },
-
- { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
- { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
- { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
-
- { OV511_I2C_BUS, 0x3d, 0x80 },
- /* These next two registers (0x4a, 0x4b) are undocumented. They
- * control the color balance */
- { OV511_I2C_BUS, 0x4a, 0x80 },
- { OV511_I2C_BUS, 0x4b, 0x80 },
- { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */
- { OV511_I2C_BUS, 0x4e, 0xc1 },
- { OV511_I2C_BUS, 0x4f, 0x04 },
-// Do 50-53 have any effect?
-// Toggle 0x12[2] off and on here?
- { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
- };
-
- static struct ov511_regvals aRegvalsNorm6x30[] = {
- /*OK*/ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */
- { OV511_I2C_BUS, 0x11, 0x00 },
- /*OK*/ { OV511_I2C_BUS, 0x03, 0x60 },
- /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */
- { OV511_I2C_BUS, 0x07, 0xa8 },
- /* The ratio of 0x0c and 0x0d controls the white point */
- /*OK*/ { OV511_I2C_BUS, 0x0c, 0x24 },
- /*OK*/ { OV511_I2C_BUS, 0x0d, 0x24 },
- /*A*/ { OV511_I2C_BUS, 0x0e, 0x20 },
-// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 },
- { OV511_I2C_BUS, 0x16, 0x03 },
-// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */
- // 21 & 22? The suggested values look wrong. Go with default
- /*A*/ { OV511_I2C_BUS, 0x23, 0xc0 },
- /*A*/ { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default
-// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */
-
- /* 0x28: 0x05 Selects RGB format if RGB on */
-// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 },
-// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus
-
- /*OK*/ { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */
-// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */
- { OV511_I2C_BUS, 0x2d, 0x99 },
-// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620
-// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */
-// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 },
-// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7
-// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */
-// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */
-// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */
- { OV511_I2C_BUS, 0x3d, 0x80 },
-// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e },
-
- /* These next two registers (0x4a, 0x4b) are undocumented. They
- * control the color balance */
-// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these
-// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 },
- { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
- /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 },
-
- /* UV average mode, color killer: strongest */
- { OV511_I2C_BUS, 0x4f, 0x07 },
-
- { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */
- { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */
- { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */
- { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */
- { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */
-// { OV511_I2C_BUS, 0x5c, 0x10 },
- { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */
- };
-
- PDEBUG(4, "starting sensor configuration");
-
- if (init_ov_sensor(ov) < 0) {
- err("Failed to read sensor ID. You might not have an OV6xx0,");
- err("or it may be not responding. Report this to " EMAIL);
- return -1;
- } else {
- PDEBUG(1, "OV6xx0 sensor detected");
- }
-
- /* Detect sensor (sub)type */
- rc = i2c_r(ov, OV7610_REG_COM_I);
-
- if (rc < 0) {
- err("Error detecting sensor type");
- return -1;
- }
-
- if ((rc & 3) == 0) {
- ov->sensor = SEN_OV6630;
- dev_info(&ov->dev->dev, "Sensor is an OV6630\n");
- } else if ((rc & 3) == 1) {
- ov->sensor = SEN_OV6620;
- dev_info(&ov->dev->dev, "Sensor is an OV6620\n");
- } else if ((rc & 3) == 2) {
- ov->sensor = SEN_OV6630;
- dev_info(&ov->dev->dev, "Sensor is an OV6630AE\n");
- } else if ((rc & 3) == 3) {
- ov->sensor = SEN_OV6630;
- dev_info(&ov->dev->dev, "Sensor is an OV6630AF\n");
- }
-
- /* Set sensor-specific vars */
- ov->maxwidth = 352;
- ov->maxheight = 288;
- ov->minwidth = 64;
- ov->minheight = 48;
-
- // FIXME: These do not match the actual settings yet
- ov->brightness = 0x80 << 8;
- ov->contrast = 0x80 << 8;
- ov->colour = 0x80 << 8;
- ov->hue = 0x80 << 8;
-
- if (ov->sensor == SEN_OV6620) {
- PDEBUG(4, "Writing 6x20 registers");
- if (write_regvals(ov, aRegvalsNorm6x20))
- return -1;
- } else {
- PDEBUG(4, "Writing 6x30 registers");
- if (write_regvals(ov, aRegvalsNorm6x30))
- return -1;
- }
-
- return 0;
-}
-
-/* This initializes the KS0127 and KS0127B video decoders. */
-static int
-ks0127_configure(struct usb_ov511 *ov)
-{
- int rc;
-
-// FIXME: I don't know how to sync or reset it yet
-#if 0
- if (ov51x_init_ks_sensor(ov) < 0) {
- err("Failed to initialize the KS0127");
- return -1;
- } else {
- PDEBUG(1, "KS012x(B) sensor detected");
- }
-#endif
-
- /* Detect decoder subtype */
- rc = i2c_r(ov, 0x00);
- if (rc < 0) {
- err("Error detecting sensor type");
- return -1;
- } else if (rc & 0x08) {
- rc = i2c_r(ov, 0x3d);
- if (rc < 0) {
- err("Error detecting sensor type");
- return -1;
- } else if ((rc & 0x0f) == 0) {
- dev_info(&ov->dev->dev, "Sensor is a KS0127\n");
- ov->sensor = SEN_KS0127;
- } else if ((rc & 0x0f) == 9) {
- dev_info(&ov->dev->dev, "Sensor is a KS0127B Rev. A\n");
- ov->sensor = SEN_KS0127B;
- }
- } else {
- err("Error: Sensor is an unsupported KS0122");
- return -1;
- }
-
- /* Set sensor-specific vars */
- ov->maxwidth = 640;
- ov->maxheight = 480;
- ov->minwidth = 64;
- ov->minheight = 48;
-
- // FIXME: These do not match the actual settings yet
- ov->brightness = 0x80 << 8;
- ov->contrast = 0x80 << 8;
- ov->colour = 0x80 << 8;
- ov->hue = 0x80 << 8;
-
- /* This device is not supported yet. Bail out now... */
- err("This sensor is not supported yet.");
- return -1;
-
- return 0;
-}
-
-/* This initializes the SAA7111A video decoder. */
-static int
-saa7111a_configure(struct usb_ov511 *ov)
-{
- int rc;
-
- /* Since there is no register reset command, all registers must be
- * written, otherwise gives erratic results */
- static struct ov511_regvals aRegvalsNormSAA7111A[] = {
- { OV511_I2C_BUS, 0x06, 0xce },
- { OV511_I2C_BUS, 0x07, 0x00 },
- { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */
- { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */
- { OV511_I2C_BUS, 0x00, 0x00 },
- { OV511_I2C_BUS, 0x01, 0x00 },
- { OV511_I2C_BUS, 0x03, 0x23 },
- { OV511_I2C_BUS, 0x04, 0x00 },
- { OV511_I2C_BUS, 0x05, 0x00 },
- { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */
- { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */
- { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */
- { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */
- { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */
- { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */
- { OV511_I2C_BUS, 0x0f, 0x00 },
- { OV511_I2C_BUS, 0x11, 0x0c },
- { OV511_I2C_BUS, 0x12, 0x00 },
- { OV511_I2C_BUS, 0x13, 0x00 },
- { OV511_I2C_BUS, 0x14, 0x00 },
- { OV511_I2C_BUS, 0x15, 0x00 },
- { OV511_I2C_BUS, 0x16, 0x00 },
- { OV511_I2C_BUS, 0x17, 0x00 },
- { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
-// FIXME: I don't know how to sync or reset it yet
-#if 0
- if (ov51x_init_saa_sensor(ov) < 0) {
- err("Failed to initialize the SAA7111A");
- return -1;
- } else {
- PDEBUG(1, "SAA7111A sensor detected");
- }
-#endif
-
- /* 640x480 not supported with PAL */
- if (ov->pal) {
- ov->maxwidth = 320;
- ov->maxheight = 240; /* Even field only */
- } else {
- ov->maxwidth = 640;
- ov->maxheight = 480; /* Even/Odd fields */
- }
-
- ov->minwidth = 320;
- ov->minheight = 240; /* Even field only */
-
- ov->has_decoder = 1;
- ov->num_inputs = 8;
- ov->norm = VIDEO_MODE_AUTO;
- ov->stop_during_set = 0; /* Decoder guarantees stable image */
-
- /* Decoder doesn't change these values, so we use these instead of
- * acutally reading the registers (which doesn't work) */
- ov->brightness = 0x80 << 8;
- ov->contrast = 0x40 << 9;
- ov->colour = 0x40 << 9;
- ov->hue = 32768;
-
- PDEBUG(4, "Writing SAA7111A registers");
- if (write_regvals(ov, aRegvalsNormSAA7111A))
- return -1;
-
- /* Detect version of decoder. This must be done after writing the
- * initial regs or the decoder will lock up. */
- rc = i2c_r(ov, 0x00);
-
- if (rc < 0) {
- err("Error detecting sensor version");
- return -1;
- } else {
- dev_info(&ov->dev->dev,
- "Sensor is an SAA7111A (version 0x%x)\n", rc);
- ov->sensor = SEN_SAA7111A;
- }
-
- // FIXME: Fix this for OV518(+)
- /* Latch to negative edge of clock. Otherwise, we get incorrect
- * colors and jitter in the digital signal. */
- if (ov->bclass == BCL_OV511)
- reg_w(ov, 0x11, 0x00);
- else
- dev_warn(&ov->dev->dev,
- "SAA7111A not yet supported with OV518/OV518+\n");
-
- return 0;
-}
-
-/* This initializes the OV511/OV511+ and the sensor */
-static int
-ov511_configure(struct usb_ov511 *ov)
-{
- static struct ov511_regvals aRegvalsInit511[] = {
- { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
- { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
- { OV511_REG_BUS, R51x_SYS_RESET, 0x7f },
- { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
- { OV511_REG_BUS, R51x_SYS_RESET, 0x3f },
- { OV511_REG_BUS, R51x_SYS_INIT, 0x01 },
- { OV511_REG_BUS, R51x_SYS_RESET, 0x3d },
- { OV511_DONE_BUS, 0x0, 0x00},
- };
-
- static struct ov511_regvals aRegvalsNorm511[] = {
- { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
- { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f },
- { OV511_REG_BUS, R511_COMP_EN, 0x00 },
- { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- static struct ov511_regvals aRegvalsNorm511Plus[] = {
- { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 },
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 },
- { OV511_REG_BUS, R511_FIFO_OPTS, 0xff },
- { OV511_REG_BUS, R511_COMP_EN, 0x00 },
- { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- PDEBUG(4, "");
-
- ov->customid = reg_r(ov, R511_SYS_CUST_ID);
- if (ov->customid < 0) {
- err("Unable to read camera bridge registers");
- goto error;
- }
-
- PDEBUG (1, "CustomID = %d", ov->customid);
- ov->desc = symbolic(camlist, ov->customid);
- dev_info(&ov->dev->dev, "model: %s\n", ov->desc);
-
- if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) {
- err("Camera type (%d) not recognized", ov->customid);
- err("Please notify " EMAIL " of the name,");
- err("manufacturer, model, and this number of your camera.");
- err("Also include the output of the detection process.");
- }
-
- if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */
- ov->pal = 1;
-
- if (write_regvals(ov, aRegvalsInit511))
- goto error;
-
- if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
- ov51x_led_control(ov, 0);
-
- /* The OV511+ has undocumented bits in the flow control register.
- * Setting it to 0xff fixes the corruption with moving objects. */
- if (ov->bridge == BRG_OV511) {
- if (write_regvals(ov, aRegvalsNorm511))
- goto error;
- } else if (ov->bridge == BRG_OV511PLUS) {
- if (write_regvals(ov, aRegvalsNorm511Plus))
- goto error;
- } else {
- err("Invalid bridge");
- }
-
- if (ov511_init_compression(ov))
- goto error;
-
- ov->packet_numbering = 1;
- ov511_set_packet_size(ov, 0);
-
- ov->snap_enabled = snapshot;
-
- /* Test for 7xx0 */
- PDEBUG(3, "Testing for 0V7xx0");
- ov->primary_i2c_slave = OV7xx0_SID;
- if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
- goto error;
-
- if (i2c_w(ov, 0x12, 0x80) < 0) {
- /* Test for 6xx0 */
- PDEBUG(3, "Testing for 0V6xx0");
- ov->primary_i2c_slave = OV6xx0_SID;
- if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
- goto error;
-
- if (i2c_w(ov, 0x12, 0x80) < 0) {
- /* Test for 8xx0 */
- PDEBUG(3, "Testing for 0V8xx0");
- ov->primary_i2c_slave = OV8xx0_SID;
- if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
- goto error;
-
- if (i2c_w(ov, 0x12, 0x80) < 0) {
- /* Test for SAA7111A */
- PDEBUG(3, "Testing for SAA7111A");
- ov->primary_i2c_slave = SAA7111A_SID;
- if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0)
- goto error;
-
- if (i2c_w(ov, 0x0d, 0x00) < 0) {
- /* Test for KS0127 */
- PDEBUG(3, "Testing for KS0127");
- ov->primary_i2c_slave = KS0127_SID;
- if (ov51x_set_slave_ids(ov, KS0127_SID) < 0)
- goto error;
-
- if (i2c_w(ov, 0x10, 0x00) < 0) {
- err("Can't determine sensor slave IDs");
- goto error;
- } else {
- if (ks0127_configure(ov) < 0) {
- err("Failed to configure KS0127");
- goto error;
- }
- }
- } else {
- if (saa7111a_configure(ov) < 0) {
- err("Failed to configure SAA7111A");
- goto error;
- }
- }
- } else {
- err("Detected unsupported OV8xx0 sensor");
- goto error;
- }
- } else {
- if (ov6xx0_configure(ov) < 0) {
- err("Failed to configure OV6xx0");
- goto error;
- }
- }
- } else {
- if (ov7xx0_configure(ov) < 0) {
- err("Failed to configure OV7xx0");
- goto error;
- }
- }
-
- return 0;
-
-error:
- err("OV511 Config failed");
-
- return -EBUSY;
-}
-
-/* This initializes the OV518/OV518+ and the sensor */
-static int
-ov518_configure(struct usb_ov511 *ov)
-{
- /* For 518 and 518+ */
- static struct ov511_regvals aRegvalsInit518[] = {
- { OV511_REG_BUS, R51x_SYS_RESET, 0x40 },
- { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
- { OV511_REG_BUS, R51x_SYS_RESET, 0x3e },
- { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
- { OV511_REG_BUS, R51x_SYS_RESET, 0x00 },
- { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 },
- { OV511_REG_BUS, 0x46, 0x00 },
- { OV511_REG_BUS, 0x5d, 0x03 },
- { OV511_DONE_BUS, 0x0, 0x00},
- };
-
- static struct ov511_regvals aRegvalsNorm518[] = {
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
- { OV511_REG_BUS, 0x31, 0x0f },
- { OV511_REG_BUS, 0x5d, 0x03 },
- { OV511_REG_BUS, 0x24, 0x9f },
- { OV511_REG_BUS, 0x25, 0x90 },
- { OV511_REG_BUS, 0x20, 0x00 },
- { OV511_REG_BUS, 0x51, 0x04 },
- { OV511_REG_BUS, 0x71, 0x19 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- static struct ov511_regvals aRegvalsNorm518Plus[] = {
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */
- { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */
- { OV511_REG_BUS, 0x31, 0x0f },
- { OV511_REG_BUS, 0x5d, 0x03 },
- { OV511_REG_BUS, 0x24, 0x9f },
- { OV511_REG_BUS, 0x25, 0x90 },
- { OV511_REG_BUS, 0x20, 0x60 },
- { OV511_REG_BUS, 0x51, 0x02 },
- { OV511_REG_BUS, 0x71, 0x19 },
- { OV511_REG_BUS, 0x40, 0xff },
- { OV511_REG_BUS, 0x41, 0x42 },
- { OV511_REG_BUS, 0x46, 0x00 },
- { OV511_REG_BUS, 0x33, 0x04 },
- { OV511_REG_BUS, 0x21, 0x19 },
- { OV511_REG_BUS, 0x3f, 0x10 },
- { OV511_DONE_BUS, 0x0, 0x00 },
- };
-
- PDEBUG(4, "");
-
- /* First 5 bits of custom ID reg are a revision ID on OV518 */
- dev_info(&ov->dev->dev, "Device revision %d\n",
- 0x1F & reg_r(ov, R511_SYS_CUST_ID));
-
- /* Give it the default description */
- ov->desc = symbolic(camlist, 0);
-
- if (write_regvals(ov, aRegvalsInit518))
- goto error;
-
- /* Set LED GPIO pin to output mode */
- if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0)
- goto error;
-
- /* LED is off by default with OV518; have to explicitly turn it on */
- if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO)
- ov51x_led_control(ov, 0);
- else
- ov51x_led_control(ov, 1);
-
- /* Don't require compression if dumppix is enabled; otherwise it's
- * required. OV518 has no uncompressed mode, to save RAM. */
- if (!dumppix && !ov->compress) {
- ov->compress = 1;
- dev_warn(&ov->dev->dev,
- "Compression required with OV518...enabling\n");
- }
-
- if (ov->bridge == BRG_OV518) {
- if (write_regvals(ov, aRegvalsNorm518))
- goto error;
- } else if (ov->bridge == BRG_OV518PLUS) {
- if (write_regvals(ov, aRegvalsNorm518Plus))
- goto error;
- } else {
- err("Invalid bridge");
- }
-
- if (reg_w(ov, 0x2f, 0x80) < 0)
- goto error;
-
- if (ov518_init_compression(ov))
- goto error;
-
- if (ov->bridge == BRG_OV518)
- {
- struct usb_interface *ifp;
- struct usb_host_interface *alt;
- __u16 mxps = 0;
-
- ifp = usb_ifnum_to_if(ov->dev, 0);
- if (ifp) {
- alt = usb_altnum_to_altsetting(ifp, 7);
- if (alt)
- mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
- }
-
- /* Some OV518s have packet numbering by default, some don't */
- if (mxps == 897)
- ov->packet_numbering = 1;
- else
- ov->packet_numbering = 0;
- } else {
- /* OV518+ has packet numbering turned on by default */
- ov->packet_numbering = 1;
- }
-
- ov518_set_packet_size(ov, 0);
-
- ov->snap_enabled = snapshot;
-
- /* Test for 76xx */
- ov->primary_i2c_slave = OV7xx0_SID;
- if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0)
- goto error;
-
- /* The OV518 must be more aggressive about sensor detection since
- * I2C write will never fail if the sensor is not present. We have
- * to try to initialize the sensor to detect its presence */
-
- if (init_ov_sensor(ov) < 0) {
- /* Test for 6xx0 */
- ov->primary_i2c_slave = OV6xx0_SID;
- if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0)
- goto error;
-
- if (init_ov_sensor(ov) < 0) {
- /* Test for 8xx0 */
- ov->primary_i2c_slave = OV8xx0_SID;
- if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0)
- goto error;
-
- if (init_ov_sensor(ov) < 0) {
- err("Can't determine sensor slave IDs");
- goto error;
- } else {
- err("Detected unsupported OV8xx0 sensor");
- goto error;
- }
- } else {
- if (ov6xx0_configure(ov) < 0) {
- err("Failed to configure OV6xx0");
- goto error;
- }
- }
- } else {
- if (ov7xx0_configure(ov) < 0) {
- err("Failed to configure OV7xx0");
- goto error;
- }
- }
-
- ov->maxwidth = 352;
- ov->maxheight = 288;
-
- // The OV518 cannot go as low as the sensor can
- ov->minwidth = 160;
- ov->minheight = 120;
-
- return 0;
-
-error:
- err("OV518 Config failed");
-
- return -EBUSY;
-}
-
-/****************************************************************************
- * sysfs
- ***************************************************************************/
-
-static inline struct usb_ov511 *cd_to_ov(struct device *cd)
-{
- struct video_device *vdev = to_video_device(cd);
- return video_get_drvdata(vdev);
-}
-
-static ssize_t show_custom_id(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- return sprintf(buf, "%d\n", ov->customid);
-}
-static DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL);
-
-static ssize_t show_model(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- return sprintf(buf, "%s\n", ov->desc);
-}
-static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
-
-static ssize_t show_bridge(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge));
-}
-static DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL);
-
-static ssize_t show_sensor(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor));
-}
-static DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL);
-
-static ssize_t show_brightness(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- unsigned short x;
-
- if (!ov->dev)
- return -ENODEV;
- sensor_get_brightness(ov, &x);
- return sprintf(buf, "%d\n", x >> 8);
-}
-static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
-
-static ssize_t show_saturation(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- unsigned short x;
-
- if (!ov->dev)
- return -ENODEV;
- sensor_get_saturation(ov, &x);
- return sprintf(buf, "%d\n", x >> 8);
-}
-static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
-
-static ssize_t show_contrast(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- unsigned short x;
-
- if (!ov->dev)
- return -ENODEV;
- sensor_get_contrast(ov, &x);
- return sprintf(buf, "%d\n", x >> 8);
-}
-static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
-
-static ssize_t show_hue(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- unsigned short x;
-
- if (!ov->dev)
- return -ENODEV;
- sensor_get_hue(ov, &x);
- return sprintf(buf, "%d\n", x >> 8);
-}
-static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
-
-static ssize_t show_exposure(struct device *cd,
- struct device_attribute *attr, char *buf)
-{
- struct usb_ov511 *ov = cd_to_ov(cd);
- unsigned char exp = 0;
-
- if (!ov->dev)
- return -ENODEV;
- sensor_get_exposure(ov, &exp);
- return sprintf(buf, "%d\n", exp);
-}
-static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL);
-
-static int ov_create_sysfs(struct video_device *vdev)
-{
- int rc;
-
- rc = device_create_file(&vdev->dev, &dev_attr_custom_id);
- if (rc) goto err;
- rc = device_create_file(&vdev->dev, &dev_attr_model);
- if (rc) goto err_id;
- rc = device_create_file(&vdev->dev, &dev_attr_bridge);
- if (rc) goto err_model;
- rc = device_create_file(&vdev->dev, &dev_attr_sensor);
- if (rc) goto err_bridge;
- rc = device_create_file(&vdev->dev, &dev_attr_brightness);
- if (rc) goto err_sensor;
- rc = device_create_file(&vdev->dev, &dev_attr_saturation);
- if (rc) goto err_bright;
- rc = device_create_file(&vdev->dev, &dev_attr_contrast);
- if (rc) goto err_sat;
- rc = device_create_file(&vdev->dev, &dev_attr_hue);
- if (rc) goto err_contrast;
- rc = device_create_file(&vdev->dev, &dev_attr_exposure);
- if (rc) goto err_hue;
-
- return 0;
-
-err_hue:
- device_remove_file(&vdev->dev, &dev_attr_hue);
-err_contrast:
- device_remove_file(&vdev->dev, &dev_attr_contrast);
-err_sat:
- device_remove_file(&vdev->dev, &dev_attr_saturation);
-err_bright:
- device_remove_file(&vdev->dev, &dev_attr_brightness);
-err_sensor:
- device_remove_file(&vdev->dev, &dev_attr_sensor);
-err_bridge:
- device_remove_file(&vdev->dev, &dev_attr_bridge);
-err_model:
- device_remove_file(&vdev->dev, &dev_attr_model);
-err_id:
- device_remove_file(&vdev->dev, &dev_attr_custom_id);
-err:
- return rc;
-}
-
-/****************************************************************************
- * USB routines
- ***************************************************************************/
-
-static int
-ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_interface_descriptor *idesc;
- struct usb_ov511 *ov;
- int i, rc, nr;
-
- PDEBUG(1, "probing for device...");
-
- /* We don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- idesc = &intf->cur_altsetting->desc;
-
- if (idesc->bInterfaceClass != 0xFF)
- return -ENODEV;
- if (idesc->bInterfaceSubClass != 0x00)
- return -ENODEV;
-
- if ((ov = kzalloc(sizeof(*ov), GFP_KERNEL)) == NULL) {
- err("couldn't kmalloc ov struct");
- goto error_out;
- }
-
- ov->dev = dev;
- ov->iface = idesc->bInterfaceNumber;
- ov->led_policy = led;
- ov->compress = compress;
- ov->lightfreq = lightfreq;
- ov->num_inputs = 1; /* Video decoder init functs. change this */
- ov->stop_during_set = !fastset;
- ov->backlight = backlight;
- ov->mirror = mirror;
- ov->auto_brt = autobright;
- ov->auto_gain = autogain;
- ov->auto_exp = autoexp;
-
- switch (le16_to_cpu(dev->descriptor.idProduct)) {
- case PROD_OV511:
- ov->bridge = BRG_OV511;
- ov->bclass = BCL_OV511;
- break;
- case PROD_OV511PLUS:
- ov->bridge = BRG_OV511PLUS;
- ov->bclass = BCL_OV511;
- break;
- case PROD_OV518:
- ov->bridge = BRG_OV518;
- ov->bclass = BCL_OV518;
- break;
- case PROD_OV518PLUS:
- ov->bridge = BRG_OV518PLUS;
- ov->bclass = BCL_OV518;
- break;
- case PROD_ME2CAM:
- if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL)
- goto error;
- ov->bridge = BRG_OV511PLUS;
- ov->bclass = BCL_OV511;
- break;
- default:
- err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct));
- goto error;
- }
-
- dev_info(&intf->dev, "USB %s video device found\n",
- symbolic(brglist, ov->bridge));
-
- init_waitqueue_head(&ov->wq);
-
- mutex_init(&ov->lock); /* to 1 == available */
- mutex_init(&ov->buf_lock);
- mutex_init(&ov->i2c_lock);
- mutex_init(&ov->cbuf_lock);
-
- ov->buf_state = BUF_NOT_ALLOCATED;
-
- if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) {
- err("usb_make_path error");
- goto error;
- }
-
- /* Allocate control transfer buffer. */
- /* Must be kmalloc()'ed, for DMA compatibility */
- ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL);
- if (!ov->cbuf)
- goto error;
-
- if (ov->bclass == BCL_OV518) {
- if (ov518_configure(ov) < 0)
- goto error;
- } else {
- if (ov511_configure(ov) < 0)
- goto error;
- }
-
- for (i = 0; i < OV511_NUMFRAMES; i++) {
- ov->frame[i].framenum = i;
- init_waitqueue_head(&ov->frame[i].wq);
- }
-
- for (i = 0; i < OV511_NUMSBUF; i++) {
- ov->sbuf[i].ov = ov;
- spin_lock_init(&ov->sbuf[i].lock);
- ov->sbuf[i].n = i;
- }
-
- /* Unnecessary? (This is done on open(). Need to make sure variables
- * are properly initialized without this before removing it, though). */
- if (ov51x_set_default_params(ov) < 0)
- goto error;
-
-#ifdef OV511_DEBUG
- if (dump_bridge) {
- if (ov->bclass == BCL_OV511)
- ov511_dump_regs(ov);
- else
- ov518_dump_regs(ov);
- }
-#endif
-
- ov->vdev = video_device_alloc();
- if (!ov->vdev)
- goto error;
-
- memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev));
- ov->vdev->parent = &intf->dev;
- video_set_drvdata(ov->vdev, ov);
-
- mutex_lock(&ov->lock);
-
- /* Check to see next free device and mark as used */
- nr = find_first_zero_bit(&ov511_devused, OV511_MAX_UNIT_VIDEO);
-
- /* Registers device */
- if (unit_video[nr] != 0)
- rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER,
- unit_video[nr]);
- else
- rc = video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1);
-
- if (rc < 0) {
- err("video_register_device failed");
- mutex_unlock(&ov->lock);
- goto error;
- }
-
- /* Mark device as used */
- ov511_devused |= 1 << nr;
- ov->nr = nr;
-
- dev_info(&intf->dev, "Device at %s registered to %s\n",
- ov->usb_path, video_device_node_name(ov->vdev));
-
- usb_set_intfdata(intf, ov);
- if (ov_create_sysfs(ov->vdev)) {
- err("ov_create_sysfs failed");
- ov511_devused &= ~(1 << nr);
- mutex_unlock(&ov->lock);
- goto error;
- }
-
- mutex_unlock(&ov->lock);
-
- return 0;
-
-error:
- if (ov->vdev) {
- if (!video_is_registered(ov->vdev))
- video_device_release(ov->vdev);
- else
- video_unregister_device(ov->vdev);
- ov->vdev = NULL;
- }
-
- if (ov->cbuf) {
- mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
- mutex_unlock(&ov->cbuf_lock);
- }
-
- kfree(ov);
- ov = NULL;
-
-error_out:
- err("Camera initialization failed");
- return -EIO;
-}
-
-static void
-ov51x_disconnect(struct usb_interface *intf)
-{
- struct usb_ov511 *ov = usb_get_intfdata(intf);
- int n;
-
- PDEBUG(3, "");
-
- mutex_lock(&ov->lock);
- usb_set_intfdata (intf, NULL);
-
- /* Free device number */
- ov511_devused &= ~(1 << ov->nr);
-
- if (ov->vdev)
- video_unregister_device(ov->vdev);
-
- for (n = 0; n < OV511_NUMFRAMES; n++)
- ov->frame[n].grabstate = FRAME_ERROR;
-
- ov->curframe = -1;
-
- /* This will cause the process to request another frame */
- for (n = 0; n < OV511_NUMFRAMES; n++)
- wake_up_interruptible(&ov->frame[n].wq);
-
- wake_up_interruptible(&ov->wq);
-
- ov->streaming = 0;
- ov51x_unlink_isoc(ov);
- mutex_unlock(&ov->lock);
-
- ov->dev = NULL;
-
- /* Free the memory */
- if (!ov->user) {
- mutex_lock(&ov->cbuf_lock);
- kfree(ov->cbuf);
- ov->cbuf = NULL;
- mutex_unlock(&ov->cbuf_lock);
-
- ov51x_dealloc(ov);
- kfree(ov);
- ov = NULL;
- }
-
- PDEBUG(3, "Disconnect complete");
-}
-
-static struct usb_driver ov511_driver = {
- .name = "ov511",
- .id_table = device_table,
- .probe = ov51x_probe,
- .disconnect = ov51x_disconnect
-};
-
-/****************************************************************************
- *
- * Module routines
- *
- ***************************************************************************/
-
-static int __init
-usb_ov511_init(void)
-{
- int retval;
-
- retval = usb_register(&ov511_driver);
- if (retval)
- goto out;
-
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
-
-out:
- return retval;
-}
-
-static void __exit
-usb_ov511_exit(void)
-{
- usb_deregister(&ov511_driver);
- printk(KERN_INFO KBUILD_MODNAME ": driver deregistered\n");
-}
-
-module_init(usb_ov511_init);
-module_exit(usb_ov511_exit);
-
diff --git a/drivers/media/video/ov511.h b/drivers/media/video/ov511.h
deleted file mode 100644
index c450c92468da..000000000000
--- a/drivers/media/video/ov511.h
+++ /dev/null
@@ -1,573 +0,0 @@
-#ifndef __LINUX_OV511_H
-#define __LINUX_OV511_H
-
-#include <asm/uaccess.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-
-#define OV511_DEBUG /* Turn on debug messages */
-
-#ifdef OV511_DEBUG
- #define PDEBUG(level, fmt, args...) \
- if (debug >= (level)) \
- printk(KERN_INFO KBUILD_MODNAME "[%s:%d] \n" fmt, \
- __func__, __LINE__ , ## args)
-#else
- #define PDEBUG(level, fmt, args...) do {} while(0)
-#endif
-
-/* This macro restricts an int variable to an inclusive range */
-#define RESTRICT_TO_RANGE(v,mi,ma) { \
- if ((v) < (mi)) (v) = (mi); \
- else if ((v) > (ma)) (v) = (ma); \
-}
-
-/* --------------------------------- */
-/* DEFINES FOR OV511 AND OTHER CHIPS */
-/* --------------------------------- */
-
-/* USB IDs */
-#define VEND_OMNIVISION 0x05A9
-#define PROD_OV511 0x0511
-#define PROD_OV511PLUS 0xA511
-#define PROD_OV518 0x0518
-#define PROD_OV518PLUS 0xA518
-
-#define VEND_MATTEL 0x0813
-#define PROD_ME2CAM 0x0002
-
-/* --------------------------------- */
-/* OV51x REGISTER MNEMONICS */
-/* --------------------------------- */
-
-/* Camera interface register numbers */
-#define R511_CAM_DELAY 0x10
-#define R511_CAM_EDGE 0x11
-#define R511_CAM_PXCNT 0x12
-#define R511_CAM_LNCNT 0x13
-#define R511_CAM_PXDIV 0x14
-#define R511_CAM_LNDIV 0x15
-#define R511_CAM_UV_EN 0x16
-#define R511_CAM_LINE_MODE 0x17
-#define R511_CAM_OPTS 0x18
-
-/* Snapshot mode camera interface register numbers */
-#define R511_SNAP_FRAME 0x19
-#define R511_SNAP_PXCNT 0x1A
-#define R511_SNAP_LNCNT 0x1B
-#define R511_SNAP_PXDIV 0x1C
-#define R511_SNAP_LNDIV 0x1D
-#define R511_SNAP_UV_EN 0x1E
-#define R511_SNAP_OPTS 0x1F
-
-/* DRAM register numbers */
-#define R511_DRAM_FLOW_CTL 0x20
-#define R511_DRAM_ARCP 0x21
-#define R511_DRAM_MRC 0x22
-#define R511_DRAM_RFC 0x23
-
-/* ISO FIFO register numbers */
-#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */
-#define R511_FIFO_OPTS 0x31
-
-/* Parallel IO register numbers */
-#define R511_PIO_OPTS 0x38
-#define R511_PIO_DATA 0x39
-#define R511_PIO_BIST 0x3E
-#define R518_GPIO_IN 0x55 /* OV518(+) only */
-#define R518_GPIO_OUT 0x56 /* OV518(+) only */
-#define R518_GPIO_CTL 0x57 /* OV518(+) only */
-#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */
-#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */
-#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */
-#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */
-#define R518_GPIO_RESET 0x5c /* OV518(+) only */
-
-/* I2C registers */
-#define R511_I2C_CTL 0x40
-#define R518_I2C_CTL 0x47 /* OV518(+) only */
-#define R51x_I2C_W_SID 0x41
-#define R51x_I2C_SADDR_3 0x42
-#define R51x_I2C_SADDR_2 0x43
-#define R51x_I2C_R_SID 0x44
-#define R51x_I2C_DATA 0x45
-#define R51x_I2C_CLOCK 0x46
-#define R51x_I2C_TIMEOUT 0x47
-
-/* I2C snapshot registers */
-#define R511_SI2C_SADDR_3 0x48
-#define R511_SI2C_DATA 0x49
-
-/* System control registers */
-#define R51x_SYS_RESET 0x50
- /* Reset type definitions */
-#define OV511_RESET_UDC 0x01
-#define OV511_RESET_I2C 0x02
-#define OV511_RESET_FIFO 0x04
-#define OV511_RESET_OMNICE 0x08
-#define OV511_RESET_DRAM 0x10
-#define OV511_RESET_CAM_INT 0x20
-#define OV511_RESET_OV511 0x40
-#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */
-#define OV511_RESET_ALL 0x7F
-
-#define R511_SYS_CLOCK_DIV 0x51
-#define R51x_SYS_SNAP 0x52
-#define R51x_SYS_INIT 0x53
-#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */
-#define R511_SYS_LED_CTL 0x55 /* OV511+ only */
-#define R511_SYS_USER 0x5E
-#define R511_SYS_CUST_ID 0x5F
-
-/* OmniCE (compression) registers */
-#define R511_COMP_PHY 0x70
-#define R511_COMP_PHUV 0x71
-#define R511_COMP_PVY 0x72
-#define R511_COMP_PVUV 0x73
-#define R511_COMP_QHY 0x74
-#define R511_COMP_QHUV 0x75
-#define R511_COMP_QVY 0x76
-#define R511_COMP_QVUV 0x77
-#define R511_COMP_EN 0x78
-#define R511_COMP_LUT_EN 0x79
-#define R511_COMP_LUT_BEGIN 0x80
-
-/* --------------------------------- */
-/* ALTERNATE NUMBERS */
-/* --------------------------------- */
-
-/* Alternate numbers for various max packet sizes (OV511 only) */
-#define OV511_ALT_SIZE_992 0
-#define OV511_ALT_SIZE_993 1
-#define OV511_ALT_SIZE_768 2
-#define OV511_ALT_SIZE_769 3
-#define OV511_ALT_SIZE_512 4
-#define OV511_ALT_SIZE_513 5
-#define OV511_ALT_SIZE_257 6
-#define OV511_ALT_SIZE_0 7
-
-/* Alternate numbers for various max packet sizes (OV511+ only) */
-#define OV511PLUS_ALT_SIZE_0 0
-#define OV511PLUS_ALT_SIZE_33 1
-#define OV511PLUS_ALT_SIZE_129 2
-#define OV511PLUS_ALT_SIZE_257 3
-#define OV511PLUS_ALT_SIZE_385 4
-#define OV511PLUS_ALT_SIZE_513 5
-#define OV511PLUS_ALT_SIZE_769 6
-#define OV511PLUS_ALT_SIZE_961 7
-
-/* Alternate numbers for various max packet sizes (OV518(+) only) */
-#define OV518_ALT_SIZE_0 0
-#define OV518_ALT_SIZE_128 1
-#define OV518_ALT_SIZE_256 2
-#define OV518_ALT_SIZE_384 3
-#define OV518_ALT_SIZE_512 4
-#define OV518_ALT_SIZE_640 5
-#define OV518_ALT_SIZE_768 6
-#define OV518_ALT_SIZE_896 7
-
-/* --------------------------------- */
-/* OV7610 REGISTER MNEMONICS */
-/* --------------------------------- */
-
-/* OV7610 registers */
-#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */
-#define OV7610_REG_BLUE 0x01 /* blue channel balance */
-#define OV7610_REG_RED 0x02 /* red channel balance */
-#define OV7610_REG_SAT 0x03 /* saturation */
- /* 04 reserved */
-#define OV7610_REG_CNT 0x05 /* Y contrast */
-#define OV7610_REG_BRT 0x06 /* Y brightness */
- /* 08-0b reserved */
-#define OV7610_REG_BLUE_BIAS 0x0C /* blue channel bias (5:0) */
-#define OV7610_REG_RED_BIAS 0x0D /* read channel bias (5:0) */
-#define OV7610_REG_GAMMA_COEFF 0x0E /* gamma settings */
-#define OV7610_REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
-#define OV7610_REG_EXP 0x10 /* manual exposure setting */
-#define OV7610_REG_CLOCK 0x11 /* polarity/clock prescaler */
-#define OV7610_REG_COM_A 0x12 /* misc common regs */
-#define OV7610_REG_COM_B 0x13 /* misc common regs */
-#define OV7610_REG_COM_C 0x14 /* misc common regs */
-#define OV7610_REG_COM_D 0x15 /* misc common regs */
-#define OV7610_REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
-#define OV7610_REG_HWIN_START 0x17 /* horizontal window start */
-#define OV7610_REG_HWIN_END 0x18 /* horizontal window end */
-#define OV7610_REG_VWIN_START 0x19 /* vertical window start */
-#define OV7610_REG_VWIN_END 0x1A /* vertical window end */
-#define OV7610_REG_PIXEL_SHIFT 0x1B /* pixel shift */
-#define OV7610_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
-#define OV7610_REG_ID_LOW 0x1D /* manufacturer ID LSB */
- /* 0e-0f reserved */
-#define OV7610_REG_COM_E 0x20 /* misc common regs */
-#define OV7610_REG_YOFFSET 0x21 /* Y channel offset */
-#define OV7610_REG_UOFFSET 0x22 /* U channel offset */
- /* 23 reserved */
-#define OV7610_REG_ECW 0x24 /* Exposure white level for AEC */
-#define OV7610_REG_ECB 0x25 /* Exposure black level for AEC */
-#define OV7610_REG_COM_F 0x26 /* misc settings */
-#define OV7610_REG_COM_G 0x27 /* misc settings */
-#define OV7610_REG_COM_H 0x28 /* misc settings */
-#define OV7610_REG_COM_I 0x29 /* misc settings */
-#define OV7610_REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
-#define OV7610_REG_FRAMERATE_L 0x2B /* frame rate LSB */
-#define OV7610_REG_ALC 0x2C /* Auto Level Control settings */
-#define OV7610_REG_COM_J 0x2D /* misc settings */
-#define OV7610_REG_VOFFSET 0x2E /* V channel offset adjustment */
-#define OV7610_REG_ARRAY_BIAS 0x2F /* Array bias -- don't change */
- /* 30-32 reserved */
-#define OV7610_REG_YGAMMA 0x33 /* misc gamma settings (7:6) */
-#define OV7610_REG_BIAS_ADJUST 0x34 /* misc bias settings */
-#define OV7610_REG_COM_L 0x35 /* misc settings */
- /* 36-37 reserved */
-#define OV7610_REG_COM_K 0x38 /* misc registers */
-
-/* --------------------------------- */
-/* I2C ADDRESSES */
-/* --------------------------------- */
-
-#define OV7xx0_SID 0x42
-#define OV6xx0_SID 0xC0
-#define OV8xx0_SID 0xA0
-#define KS0127_SID 0xD8
-#define SAA7111A_SID 0x48
-
-/* --------------------------------- */
-/* MISCELLANEOUS DEFINES */
-/* --------------------------------- */
-
-#define I2C_CLOCK_PRESCALER 0x03
-
-#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */
-#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */
-#define PIXELS_PER_SEG 256 /* Pixels per segment */
-
-#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */
-
-#define OV511_NUMFRAMES 2
-#if OV511_NUMFRAMES > VIDEO_MAX_FRAME
- #error "OV511_NUMFRAMES is too high"
-#endif
-
-#define OV511_NUMSBUF 2
-
-/* Control transfers use up to 4 bytes */
-#define OV511_CBUF_SIZE 4
-
-/* Size of usb_make_path() buffer */
-#define OV511_USB_PATH_LEN 64
-
-/* Bridge types */
-enum {
- BRG_UNKNOWN,
- BRG_OV511,
- BRG_OV511PLUS,
- BRG_OV518,
- BRG_OV518PLUS,
-};
-
-/* Bridge classes */
-enum {
- BCL_UNKNOWN,
- BCL_OV511,
- BCL_OV518,
-};
-
-/* Sensor types */
-enum {
- SEN_UNKNOWN,
- SEN_OV76BE,
- SEN_OV7610,
- SEN_OV7620,
- SEN_OV7620AE,
- SEN_OV6620,
- SEN_OV6630,
- SEN_OV6630AE,
- SEN_OV6630AF,
- SEN_OV8600,
- SEN_KS0127,
- SEN_KS0127B,
- SEN_SAA7111A,
-};
-
-enum {
- STATE_SCANNING, /* Scanning for start */
- STATE_HEADER, /* Parsing header */
- STATE_LINES, /* Parsing lines */
-};
-
-/* Buffer states */
-enum {
- BUF_NOT_ALLOCATED,
- BUF_ALLOCATED,
-};
-
-/* --------- Definition of ioctl interface --------- */
-
-#define OV511_INTERFACE_VER 101
-
-/* LED options */
-enum {
- LED_OFF,
- LED_ON,
- LED_AUTO,
-};
-
-/* Raw frame formats */
-enum {
- RAWFMT_INVALID,
- RAWFMT_YUV400,
- RAWFMT_YUV420,
- RAWFMT_YUV422,
- RAWFMT_GBR422,
-};
-
-struct ov511_i2c_struct {
- unsigned char slave; /* Write slave ID (read ID - 1) */
- unsigned char reg; /* Index of register */
- unsigned char value; /* User sets this w/ write, driver does w/ read */
- unsigned char mask; /* Bits to be changed. Not used with read ops */
-};
-
-/* ioctls */
-#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \
- struct ov511_i2c_struct)
-#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \
- struct ov511_i2c_struct)
-/* ------------- End IOCTL interface -------------- */
-
-struct usb_ov511; /* Forward declaration */
-
-struct ov511_sbuf {
- struct usb_ov511 *ov;
- unsigned char *data;
- struct urb *urb;
- spinlock_t lock;
- int n;
-};
-
-enum {
- FRAME_UNUSED, /* Unused (no MCAPTURE) */
- FRAME_READY, /* Ready to start grabbing */
- FRAME_GRABBING, /* In the process of being grabbed into */
- FRAME_DONE, /* Finished grabbing, but not been synced yet */
- FRAME_ERROR, /* Something bad happened while processing */
-};
-
-struct ov511_regvals {
- enum {
- OV511_DONE_BUS,
- OV511_REG_BUS,
- OV511_I2C_BUS,
- } bus;
- unsigned char reg;
- unsigned char val;
-};
-
-struct ov511_frame {
- int framenum; /* Index of this frame */
- unsigned char *data; /* Frame buffer */
- unsigned char *tempdata; /* Temp buffer for multi-stage conversions */
- unsigned char *rawdata; /* Raw camera data buffer */
- unsigned char *compbuf; /* Temp buffer for decompressor */
-
- int depth; /* Bytes per pixel */
- int width; /* Width application is expecting */
- int height; /* Height application is expecting */
-
- int rawwidth; /* Actual width of frame sent from camera */
- int rawheight; /* Actual height of frame sent from camera */
-
- int sub_flag; /* Sub-capture mode for this frame? */
- unsigned int format; /* Format for this frame */
- int compressed; /* Is frame compressed? */
-
- volatile int grabstate; /* State of grabbing */
- int scanstate; /* State of scanning */
-
- int bytes_recvd; /* Number of image bytes received from camera */
-
- long bytes_read; /* Amount that has been read() */
-
- wait_queue_head_t wq; /* Processes waiting */
-
- int snapshot; /* True if frame was a snapshot */
-};
-
-#define DECOMP_INTERFACE_VER 4
-
-/* Compression module operations */
-struct ov51x_decomp_ops {
- int (*decomp_400)(unsigned char *, unsigned char *, unsigned char *,
- int, int, int);
- int (*decomp_420)(unsigned char *, unsigned char *, unsigned char *,
- int, int, int);
- int (*decomp_422)(unsigned char *, unsigned char *, unsigned char *,
- int, int, int);
- struct module *owner;
-};
-
-struct usb_ov511 {
- struct video_device *vdev;
- struct usb_device *dev;
-
- int customid;
- char *desc;
- unsigned char iface;
- char usb_path[OV511_USB_PATH_LEN];
-
- /* Determined by sensor type */
- int maxwidth;
- int maxheight;
- int minwidth;
- int minheight;
-
- int brightness;
- int colour;
- int contrast;
- int hue;
- int whiteness;
- int exposure;
- int auto_brt; /* Auto brightness enabled flag */
- int auto_gain; /* Auto gain control enabled flag */
- int auto_exp; /* Auto exposure enabled flag */
- int backlight; /* Backlight exposure algorithm flag */
- int mirror; /* Image is reversed horizontally */
-
- int led_policy; /* LED: off|on|auto; OV511+ only */
-
- struct mutex lock; /* Serializes user-accessible operations */
- int user; /* user count for exclusive use */
-
- int streaming; /* Are we streaming Isochronous? */
- int grabbing; /* Are we grabbing? */
-
- int compress; /* Should the next frame be compressed? */
- int compress_inited; /* Are compression params uploaded? */
-
- int lightfreq; /* Power (lighting) frequency */
- int bandfilt; /* Banding filter enabled flag */
-
- unsigned char *fbuf; /* Videodev buffer area */
- unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */
- unsigned char *rawfbuf; /* Raw camera data buffer area */
-
- int sub_flag; /* Pix Array subcapture on flag */
- int subx; /* Pix Array subcapture x offset */
- int suby; /* Pix Array subcapture y offset */
- int subw; /* Pix Array subcapture width */
- int subh; /* Pix Array subcapture height */
-
- int curframe; /* Current receiving sbuf */
- struct ov511_frame frame[OV511_NUMFRAMES];
-
- struct ov511_sbuf sbuf[OV511_NUMSBUF];
-
- wait_queue_head_t wq; /* Processes waiting */
-
- int snap_enabled; /* Snapshot mode enabled */
-
- int bridge; /* Type of bridge (BRG_*) */
- int bclass; /* Class of bridge (BCL_*) */
- int sensor; /* Type of image sensor chip (SEN_*) */
-
- int packet_size; /* Frame size per isoc desc */
- int packet_numbering; /* Is ISO frame numbering enabled? */
-
- /* Framebuffer/sbuf management */
- int buf_state;
- struct mutex buf_lock;
-
- struct ov51x_decomp_ops *decomp_ops;
-
- /* Stop streaming while changing picture settings */
- int stop_during_set;
-
- int stopped; /* Streaming is temporarily paused */
-
- /* Video decoder stuff */
- int input; /* Composite, S-VIDEO, etc... */
- int num_inputs; /* Number of inputs */
- int norm; /* NTSC / PAL / SECAM */
- int has_decoder; /* Device has a video decoder */
- int pal; /* Device is designed for PAL resolution */
-
- /* ov511 device number ID */
- int nr; /* Stores a device number */
-
- /* I2C interface */
- struct mutex i2c_lock; /* Protect I2C controller regs */
- unsigned char primary_i2c_slave; /* I2C write id of sensor */
-
- /* Control transaction stuff */
- unsigned char *cbuf; /* Buffer for payload */
- struct mutex cbuf_lock;
-};
-
-/* Used to represent a list of values and their respective symbolic names */
-struct symbolic_list {
- int num;
- char *name;
-};
-
-#define NOT_DEFINED_STR "Unknown"
-
-/* Returns the name of the matching element in the symbolic_list array. The
- * end of the list must be marked with an element that has a NULL name.
- */
-static inline char *
-symbolic(struct symbolic_list list[], int num)
-{
- int i;
-
- for (i = 0; list[i].name != NULL; i++)
- if (list[i].num == num)
- return (list[i].name);
-
- return (NOT_DEFINED_STR);
-}
-
-/* Compression stuff */
-
-#define OV511_QUANTABLESIZE 64
-#define OV518_QUANTABLESIZE 32
-
-#define OV511_YQUANTABLE { \
- 0, 1, 1, 2, 2, 3, 3, 4, \
- 1, 1, 1, 2, 2, 3, 4, 4, \
- 1, 1, 2, 2, 3, 4, 4, 4, \
- 2, 2, 2, 3, 4, 4, 4, 4, \
- 2, 2, 3, 4, 4, 5, 5, 5, \
- 3, 3, 4, 4, 5, 5, 5, 5, \
- 3, 4, 4, 4, 5, 5, 5, 5, \
- 4, 4, 4, 4, 5, 5, 5, 5 \
-}
-
-#define OV511_UVQUANTABLE { \
- 0, 2, 2, 3, 4, 4, 4, 4, \
- 2, 2, 2, 4, 4, 4, 4, 4, \
- 2, 2, 3, 4, 4, 4, 4, 4, \
- 3, 4, 4, 4, 4, 4, 4, 4, \
- 4, 4, 4, 4, 4, 4, 4, 4, \
- 4, 4, 4, 4, 4, 4, 4, 4, \
- 4, 4, 4, 4, 4, 4, 4, 4, \
- 4, 4, 4, 4, 4, 4, 4, 4 \
-}
-
-#define OV518_YQUANTABLE { \
- 5, 4, 5, 6, 6, 7, 7, 7, \
- 5, 5, 5, 5, 6, 7, 7, 7, \
- 6, 6, 6, 6, 7, 7, 7, 8, \
- 7, 7, 6, 7, 7, 7, 8, 8 \
-}
-
-#define OV518_UVQUANTABLE { \
- 6, 6, 6, 7, 7, 7, 7, 7, \
- 6, 6, 6, 7, 7, 7, 7, 7, \
- 6, 6, 6, 7, 7, 7, 7, 8, \
- 7, 7, 7, 7, 7, 7, 8, 8 \
-}
-
-#endif
diff --git a/drivers/media/video/ovcamchip/Makefile b/drivers/media/video/ovcamchip/Makefile
deleted file mode 100644
index cba4cdf20f49..000000000000
--- a/drivers/media/video/ovcamchip/Makefile
+++ /dev/null
@@ -1,4 +0,0 @@
-ovcamchip-objs := ovcamchip_core.o ov6x20.o ov6x30.o ov7x10.o ov7x20.o \
- ov76be.o
-
-obj-$(CONFIG_VIDEO_OVCAMCHIP) += ovcamchip.o
diff --git a/drivers/media/video/ovcamchip/ov6x20.c b/drivers/media/video/ovcamchip/ov6x20.c
deleted file mode 100644
index c04130dab127..000000000000
--- a/drivers/media/video/ovcamchip/ov6x20.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* OmniVision OV6620/OV6120 Camera Chip Support Code
- *
- * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/slab.h>
-#include "ovcamchip_priv.h"
-
-/* Registers */
-#define REG_GAIN 0x00 /* gain [5:0] */
-#define REG_BLUE 0x01 /* blue gain */
-#define REG_RED 0x02 /* red gain */
-#define REG_SAT 0x03 /* saturation */
-#define REG_CNT 0x05 /* Y contrast */
-#define REG_BRT 0x06 /* Y brightness */
-#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
-#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
-#define REG_EXP 0x10 /* exposure */
-
-/* Window parameters */
-#define HWSBASE 0x38
-#define HWEBASE 0x3A
-#define VWSBASE 0x05
-#define VWEBASE 0x06
-
-struct ov6x20 {
- int auto_brt;
- int auto_exp;
- int backlight;
- int bandfilt;
- int mirror;
-};
-
-/* Initial values for use with OV511/OV511+ cameras */
-static struct ovcamchip_regvals regvals_init_6x20_511[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x11, 0x01 },
- { 0x03, 0x60 },
- { 0x05, 0x7f }, /* For when autoadjust is off */
- { 0x07, 0xa8 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0x0f, 0x15 }, /* COMS */
- { 0x10, 0x75 }, /* AEC Exposure time */
- { 0x12, 0x24 }, /* Enable AGC and AWB */
- { 0x14, 0x04 },
- { 0x16, 0x03 },
- { 0x26, 0xb2 }, /* BLC enable */
- /* 0x28: 0x05 Selects RGB format if RGB on */
- { 0x28, 0x05 },
- { 0x2a, 0x04 }, /* Disable framerate adjust */
- { 0x2d, 0x99 },
- { 0x33, 0xa0 }, /* Color Processing Parameter */
- { 0x34, 0xd2 }, /* Max A/D range */
- { 0x38, 0x8b },
- { 0x39, 0x40 },
-
- { 0x3c, 0x39 }, /* Enable AEC mode changing */
- { 0x3c, 0x3c }, /* Change AEC mode */
- { 0x3c, 0x24 }, /* Disable AEC mode changing */
-
- { 0x3d, 0x80 },
- /* These next two registers (0x4a, 0x4b) are undocumented. They
- * control the color balance */
- { 0x4a, 0x80 },
- { 0x4b, 0x80 },
- { 0x4d, 0xd2 }, /* This reduces noise a bit */
- { 0x4e, 0xc1 },
- { 0x4f, 0x04 },
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* Initial values for use with OV518 cameras */
-static struct ovcamchip_regvals regvals_init_6x20_518[] = {
- { 0x12, 0x80 }, /* Do a reset */
- { 0x03, 0xc0 }, /* Saturation */
- { 0x05, 0x8a }, /* Contrast */
- { 0x0c, 0x24 }, /* AWB blue */
- { 0x0d, 0x24 }, /* AWB red */
- { 0x0e, 0x8d }, /* Additional 2x gain */
- { 0x0f, 0x25 }, /* Black expanding level = 1.3V */
- { 0x11, 0x01 }, /* Clock div. */
- { 0x12, 0x24 }, /* Enable AGC and AWB */
- { 0x13, 0x01 }, /* (default) */
- { 0x14, 0x80 }, /* Set reserved bit 7 */
- { 0x15, 0x01 }, /* (default) */
- { 0x16, 0x03 }, /* (default) */
- { 0x17, 0x38 }, /* (default) */
- { 0x18, 0xea }, /* (default) */
- { 0x19, 0x04 },
- { 0x1a, 0x93 },
- { 0x1b, 0x00 }, /* (default) */
- { 0x1e, 0xc4 }, /* (default) */
- { 0x1f, 0x04 }, /* (default) */
- { 0x20, 0x20 }, /* Enable 1st stage aperture correction */
- { 0x21, 0x10 }, /* Y offset */
- { 0x22, 0x88 }, /* U offset */
- { 0x23, 0xc0 }, /* Set XTAL power level */
- { 0x24, 0x53 }, /* AEC bright ratio */
- { 0x25, 0x7a }, /* AEC black ratio */
- { 0x26, 0xb2 }, /* BLC enable */
- { 0x27, 0xa2 }, /* Full output range */
- { 0x28, 0x01 }, /* (default) */
- { 0x29, 0x00 }, /* (default) */
- { 0x2a, 0x84 }, /* (default) */
- { 0x2b, 0xa8 }, /* Set custom frame rate */
- { 0x2c, 0xa0 }, /* (reserved) */
- { 0x2d, 0x95 }, /* Enable banding filter */
- { 0x2e, 0x88 }, /* V offset */
- { 0x33, 0x22 }, /* Luminance gamma on */
- { 0x34, 0xc7 }, /* A/D bias */
- { 0x36, 0x12 }, /* (reserved) */
- { 0x37, 0x63 }, /* (reserved) */
- { 0x38, 0x8b }, /* Quick AEC/AEB */
- { 0x39, 0x00 }, /* (default) */
- { 0x3a, 0x0f }, /* (default) */
- { 0x3b, 0x3c }, /* (default) */
- { 0x3c, 0x5c }, /* AEC controls */
- { 0x3d, 0x80 }, /* Drop 1 (bad) frame when AEC change */
- { 0x3e, 0x80 }, /* (default) */
- { 0x3f, 0x02 }, /* (default) */
- { 0x40, 0x10 }, /* (reserved) */
- { 0x41, 0x10 }, /* (reserved) */
- { 0x42, 0x00 }, /* (reserved) */
- { 0x43, 0x7f }, /* (reserved) */
- { 0x44, 0x80 }, /* (reserved) */
- { 0x45, 0x1c }, /* (reserved) */
- { 0x46, 0x1c }, /* (reserved) */
- { 0x47, 0x80 }, /* (reserved) */
- { 0x48, 0x5f }, /* (reserved) */
- { 0x49, 0x00 }, /* (reserved) */
- { 0x4a, 0x00 }, /* Color balance (undocumented) */
- { 0x4b, 0x80 }, /* Color balance (undocumented) */
- { 0x4c, 0x58 }, /* (reserved) */
- { 0x4d, 0xd2 }, /* U *= .938, V *= .838 */
- { 0x4e, 0xa0 }, /* (default) */
- { 0x4f, 0x04 }, /* UV 3-point average */
- { 0x50, 0xff }, /* (reserved) */
- { 0x51, 0x58 }, /* (reserved) */
- { 0x52, 0xc0 }, /* (reserved) */
- { 0x53, 0x42 }, /* (reserved) */
- { 0x27, 0xa6 }, /* Enable manual offset adj. (reg 21 & 22) */
- { 0x12, 0x20 },
- { 0x12, 0x24 },
-
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* This initializes the OV6x20 camera chip and relevant variables. */
-static int ov6x20_init(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x20 *s;
- int rc;
-
- DDEBUG(4, &c->dev, "entered");
-
- switch (c->adapter->id) {
- case I2C_HW_SMBUS_OV511:
- rc = ov_write_regvals(c, regvals_init_6x20_511);
- break;
- case I2C_HW_SMBUS_OV518:
- rc = ov_write_regvals(c, regvals_init_6x20_518);
- break;
- default:
- dev_err(&c->dev, "ov6x20: Unsupported adapter\n");
- rc = -ENODEV;
- }
-
- if (rc < 0)
- return rc;
-
- ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
- if (!s)
- return -ENOMEM;
-
- s->auto_brt = 1;
- s->auto_exp = 1;
-
- return rc;
-}
-
-static int ov6x20_free(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
-
- kfree(ov->spriv);
- return 0;
-}
-
-static int ov6x20_set_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x20 *s = ov->spriv;
- int rc;
- int v = ctl->value;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_write(c, REG_CNT, v >> 8);
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_write(c, REG_BRT, v >> 8);
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_write(c, REG_SAT, v >> 8);
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, REG_BLUE, v >> 8);
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_write(c, REG_EXP, v);
- break;
- case OVCAMCHIP_CID_FREQ:
- {
- int sixty = (v == 60);
-
- rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
- break;
- }
- case OVCAMCHIP_CID_BANDFILT:
- rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
- s->bandfilt = v;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
- s->auto_brt = v;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
- s->auto_exp = v;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- {
- rc = ov_write_mask(c, 0x4e, v?0xe0:0xc0, 0xe0);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x0e, v?0x80:0x00, 0x80);
- s->backlight = v;
- break;
- }
- case OVCAMCHIP_CID_MIRROR:
- rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
- s->mirror = v;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
-out:
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
- return rc;
-}
-
-static int ov6x20_get_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x20 *s = ov->spriv;
- int rc = 0;
- unsigned char val = 0;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_read(c, REG_CNT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_read(c, REG_BRT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_read(c, REG_SAT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_read(c, REG_BLUE, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_read(c, REG_EXP, &val);
- ctl->value = val;
- break;
- case OVCAMCHIP_CID_BANDFILT:
- ctl->value = s->bandfilt;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- ctl->value = s->auto_brt;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- ctl->value = s->auto_exp;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- ctl->value = s->backlight;
- break;
- case OVCAMCHIP_CID_MIRROR:
- ctl->value = s->mirror;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
- return rc;
-}
-
-static int ov6x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
-{
- /******** QCIF-specific regs ********/
-
- ov_write(c, 0x14, win->quarter?0x24:0x04);
-
- /******** Palette-specific regs ********/
-
- /* OV518 needs 8 bit multiplexed in color mode, and 16 bit in B&W */
- if (c->adapter->id == I2C_HW_SMBUS_OV518) {
- if (win->format == VIDEO_PALETTE_GREY)
- ov_write_mask(c, 0x13, 0x00, 0x20);
- else
- ov_write_mask(c, 0x13, 0x20, 0x20);
- } else {
- if (win->format == VIDEO_PALETTE_GREY)
- ov_write_mask(c, 0x13, 0x20, 0x20);
- else
- ov_write_mask(c, 0x13, 0x00, 0x20);
- }
-
- /******** Clock programming ********/
-
- /* The OV6620 needs special handling. This prevents the
- * severe banding that normally occurs */
-
- /* Clock down */
- ov_write(c, 0x2a, 0x04);
-
- ov_write(c, 0x11, win->clockdiv);
-
- ov_write(c, 0x2a, 0x84);
- /* This next setting is critical. It seems to improve
- * the gain or the contrast. The "reserved" bits seem
- * to have some effect in this case. */
- ov_write(c, 0x2d, 0x85); /* FIXME: This messes up banding filter */
-
- return 0;
-}
-
-static int ov6x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int ret, hwscale, vwscale;
-
- ret = ov6x20_mode_init(c, win);
- if (ret < 0)
- return ret;
-
- if (win->quarter) {
- hwscale = 0;
- vwscale = 0;
- } else {
- hwscale = 1;
- vwscale = 1; /* The datasheet says 0; it's wrong */
- }
-
- ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
- ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
- ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
- ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
-
- return 0;
-}
-
-static int ov6x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case OVCAMCHIP_CMD_S_CTRL:
- return ov6x20_set_control(c, arg);
- case OVCAMCHIP_CMD_G_CTRL:
- return ov6x20_get_control(c, arg);
- case OVCAMCHIP_CMD_S_MODE:
- return ov6x20_set_window(c, arg);
- default:
- DDEBUG(2, &c->dev, "command not supported: %d", cmd);
- return -ENOIOCTLCMD;
- }
-}
-
-struct ovcamchip_ops ov6x20_ops = {
- .init = ov6x20_init,
- .free = ov6x20_free,
- .command = ov6x20_command,
-};
diff --git a/drivers/media/video/ovcamchip/ov6x30.c b/drivers/media/video/ovcamchip/ov6x30.c
deleted file mode 100644
index 73b94f51a85a..000000000000
--- a/drivers/media/video/ovcamchip/ov6x30.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* OmniVision OV6630/OV6130 Camera Chip Support Code
- *
- * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/slab.h>
-#include "ovcamchip_priv.h"
-
-/* Registers */
-#define REG_GAIN 0x00 /* gain [5:0] */
-#define REG_BLUE 0x01 /* blue gain */
-#define REG_RED 0x02 /* red gain */
-#define REG_SAT 0x03 /* saturation [7:3] */
-#define REG_CNT 0x05 /* Y contrast [3:0] */
-#define REG_BRT 0x06 /* Y brightness */
-#define REG_SHARP 0x07 /* sharpness */
-#define REG_WB_BLUE 0x0C /* WB blue ratio [5:0] */
-#define REG_WB_RED 0x0D /* WB red ratio [5:0] */
-#define REG_EXP 0x10 /* exposure */
-
-/* Window parameters */
-#define HWSBASE 0x38
-#define HWEBASE 0x3A
-#define VWSBASE 0x05
-#define VWEBASE 0x06
-
-struct ov6x30 {
- int auto_brt;
- int auto_exp;
- int backlight;
- int bandfilt;
- int mirror;
-};
-
-static struct ovcamchip_regvals regvals_init_6x30[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x00, 0x1f }, /* Gain */
- { 0x01, 0x99 }, /* Blue gain */
- { 0x02, 0x7c }, /* Red gain */
- { 0x03, 0xc0 }, /* Saturation */
- { 0x05, 0x0a }, /* Contrast */
- { 0x06, 0x95 }, /* Brightness */
- { 0x07, 0x2d }, /* Sharpness */
- { 0x0c, 0x20 },
- { 0x0d, 0x20 },
- { 0x0e, 0x20 },
- { 0x0f, 0x05 },
- { 0x10, 0x9a }, /* "exposure check" */
- { 0x11, 0x00 }, /* Pixel clock = fastest */
- { 0x12, 0x24 }, /* Enable AGC and AWB */
- { 0x13, 0x21 },
- { 0x14, 0x80 },
- { 0x15, 0x01 },
- { 0x16, 0x03 },
- { 0x17, 0x38 },
- { 0x18, 0xea },
- { 0x19, 0x04 },
- { 0x1a, 0x93 },
- { 0x1b, 0x00 },
- { 0x1e, 0xc4 },
- { 0x1f, 0x04 },
- { 0x20, 0x20 },
- { 0x21, 0x10 },
- { 0x22, 0x88 },
- { 0x23, 0xc0 }, /* Crystal circuit power level */
- { 0x25, 0x9a }, /* Increase AEC black pixel ratio */
- { 0x26, 0xb2 }, /* BLC enable */
- { 0x27, 0xa2 },
- { 0x28, 0x00 },
- { 0x29, 0x00 },
- { 0x2a, 0x84 }, /* (keep) */
- { 0x2b, 0xa8 }, /* (keep) */
- { 0x2c, 0xa0 },
- { 0x2d, 0x95 }, /* Enable auto-brightness */
- { 0x2e, 0x88 },
- { 0x33, 0x26 },
- { 0x34, 0x03 },
- { 0x36, 0x8f },
- { 0x37, 0x80 },
- { 0x38, 0x83 },
- { 0x39, 0x80 },
- { 0x3a, 0x0f },
- { 0x3b, 0x3c },
- { 0x3c, 0x1a },
- { 0x3d, 0x80 },
- { 0x3e, 0x80 },
- { 0x3f, 0x0e },
- { 0x40, 0x00 }, /* White bal */
- { 0x41, 0x00 }, /* White bal */
- { 0x42, 0x80 },
- { 0x43, 0x3f }, /* White bal */
- { 0x44, 0x80 },
- { 0x45, 0x20 },
- { 0x46, 0x20 },
- { 0x47, 0x80 },
- { 0x48, 0x7f },
- { 0x49, 0x00 },
- { 0x4a, 0x00 },
- { 0x4b, 0x80 },
- { 0x4c, 0xd0 },
- { 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */
- { 0x4e, 0x40 },
- { 0x4f, 0x07 }, /* UV average mode, color killer: strongest */
- { 0x50, 0xff },
- { 0x54, 0x23 }, /* Max AGC gain: 18dB */
- { 0x55, 0xff },
- { 0x56, 0x12 },
- { 0x57, 0x81 }, /* (default) */
- { 0x58, 0x75 },
- { 0x59, 0x01 }, /* AGC dark current compensation: +1 */
- { 0x5a, 0x2c },
- { 0x5b, 0x0f }, /* AWB chrominance levels */
- { 0x5c, 0x10 },
- { 0x3d, 0x80 },
- { 0x27, 0xa6 },
- /* Toggle AWB off and on */
- { 0x12, 0x20 },
- { 0x12, 0x24 },
-
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* This initializes the OV6x30 camera chip and relevant variables. */
-static int ov6x30_init(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x30 *s;
- int rc;
-
- DDEBUG(4, &c->dev, "entered");
-
- rc = ov_write_regvals(c, regvals_init_6x30);
- if (rc < 0)
- return rc;
-
- ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
- if (!s)
- return -ENOMEM;
-
- s->auto_brt = 1;
- s->auto_exp = 1;
-
- return rc;
-}
-
-static int ov6x30_free(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
-
- kfree(ov->spriv);
- return 0;
-}
-
-static int ov6x30_set_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x30 *s = ov->spriv;
- int rc;
- int v = ctl->value;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_write_mask(c, REG_CNT, v >> 12, 0x0f);
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_write(c, REG_BRT, v >> 8);
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_write(c, REG_SAT, v >> 8);
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, REG_BLUE, v >> 8);
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_write(c, REG_EXP, v);
- break;
- case OVCAMCHIP_CID_FREQ:
- {
- int sixty = (v == 60);
-
- rc = ov_write(c, 0x2b, sixty?0xa8:0x28);
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, 0x2a, sixty?0x84:0xa4);
- break;
- }
- case OVCAMCHIP_CID_BANDFILT:
- rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
- s->bandfilt = v;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
- s->auto_brt = v;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- rc = ov_write_mask(c, 0x28, v?0x00:0x10, 0x10);
- s->auto_exp = v;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- {
- rc = ov_write_mask(c, 0x4e, v?0x80:0x60, 0xe0);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
- s->backlight = v;
- break;
- }
- case OVCAMCHIP_CID_MIRROR:
- rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
- s->mirror = v;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
-out:
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
- return rc;
-}
-
-static int ov6x30_get_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov6x30 *s = ov->spriv;
- int rc = 0;
- unsigned char val = 0;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_read(c, REG_CNT, &val);
- ctl->value = (val & 0x0f) << 12;
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_read(c, REG_BRT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_read(c, REG_SAT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_read(c, REG_BLUE, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_read(c, REG_EXP, &val);
- ctl->value = val;
- break;
- case OVCAMCHIP_CID_BANDFILT:
- ctl->value = s->bandfilt;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- ctl->value = s->auto_brt;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- ctl->value = s->auto_exp;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- ctl->value = s->backlight;
- break;
- case OVCAMCHIP_CID_MIRROR:
- ctl->value = s->mirror;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
- return rc;
-}
-
-static int ov6x30_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
-{
- /******** QCIF-specific regs ********/
-
- ov_write_mask(c, 0x14, win->quarter?0x20:0x00, 0x20);
-
- /******** Palette-specific regs ********/
-
- if (win->format == VIDEO_PALETTE_GREY) {
- if (c->adapter->id == I2C_HW_SMBUS_OV518) {
- /* Do nothing - we're already in 8-bit mode */
- } else {
- ov_write_mask(c, 0x13, 0x20, 0x20);
- }
- } else {
- /* The OV518 needs special treatment. Although both the OV518
- * and the OV6630 support a 16-bit video bus, only the 8 bit Y
- * bus is actually used. The UV bus is tied to ground.
- * Therefore, the OV6630 needs to be in 8-bit multiplexed
- * output mode */
-
- if (c->adapter->id == I2C_HW_SMBUS_OV518) {
- /* Do nothing - we want to stay in 8-bit mode */
- /* Warning: Messing with reg 0x13 breaks OV518 color */
- } else {
- ov_write_mask(c, 0x13, 0x00, 0x20);
- }
- }
-
- /******** Clock programming ********/
-
- ov_write(c, 0x11, win->clockdiv);
-
- return 0;
-}
-
-static int ov6x30_set_window(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int ret, hwscale, vwscale;
-
- ret = ov6x30_mode_init(c, win);
- if (ret < 0)
- return ret;
-
- if (win->quarter) {
- hwscale = 0;
- vwscale = 0;
- } else {
- hwscale = 1;
- vwscale = 1; /* The datasheet says 0; it's wrong */
- }
-
- ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
- ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
- ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
- ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
-
- return 0;
-}
-
-static int ov6x30_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case OVCAMCHIP_CMD_S_CTRL:
- return ov6x30_set_control(c, arg);
- case OVCAMCHIP_CMD_G_CTRL:
- return ov6x30_get_control(c, arg);
- case OVCAMCHIP_CMD_S_MODE:
- return ov6x30_set_window(c, arg);
- default:
- DDEBUG(2, &c->dev, "command not supported: %d", cmd);
- return -ENOIOCTLCMD;
- }
-}
-
-struct ovcamchip_ops ov6x30_ops = {
- .init = ov6x30_init,
- .free = ov6x30_free,
- .command = ov6x30_command,
-};
diff --git a/drivers/media/video/ovcamchip/ov76be.c b/drivers/media/video/ovcamchip/ov76be.c
deleted file mode 100644
index 11f6be924d8b..000000000000
--- a/drivers/media/video/ovcamchip/ov76be.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/* OmniVision OV76BE Camera Chip Support Code
- *
- * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/slab.h>
-#include "ovcamchip_priv.h"
-
-/* OV7610 registers: Since the OV76BE is undocumented, we'll settle for these
- * for now. */
-#define REG_GAIN 0x00 /* gain [5:0] */
-#define REG_BLUE 0x01 /* blue channel balance */
-#define REG_RED 0x02 /* red channel balance */
-#define REG_SAT 0x03 /* saturation */
-#define REG_CNT 0x05 /* Y contrast */
-#define REG_BRT 0x06 /* Y brightness */
-#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
-#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
-#define REG_GAMMA_COEFF 0x0E /* gamma settings */
-#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
-#define REG_EXP 0x10 /* manual exposure setting */
-#define REG_CLOCK 0x11 /* polarity/clock prescaler */
-#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
-#define REG_HWIN_START 0x17 /* horizontal window start */
-#define REG_HWIN_END 0x18 /* horizontal window end */
-#define REG_VWIN_START 0x19 /* vertical window start */
-#define REG_VWIN_END 0x1A /* vertical window end */
-#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
-#define REG_YOFFSET 0x21 /* Y channel offset */
-#define REG_UOFFSET 0x22 /* U channel offset */
-#define REG_ECW 0x24 /* exposure white level for AEC */
-#define REG_ECB 0x25 /* exposure black level for AEC */
-#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
-#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
-#define REG_ALC 0x2C /* Auto Level Control settings */
-#define REG_VOFFSET 0x2E /* V channel offset adjustment */
-#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
-#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
-#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
-
-/* Window parameters */
-#define HWSBASE 0x38
-#define HWEBASE 0x3a
-#define VWSBASE 0x05
-#define VWEBASE 0x05
-
-struct ov76be {
- int auto_brt;
- int auto_exp;
- int bandfilt;
- int mirror;
-};
-
-/* NOTE: These are the same as the 7x10 settings, but should eventually be
- * optimized for the OV76BE */
-static struct ovcamchip_regvals regvals_init_76be[] = {
- { 0x10, 0xff },
- { 0x16, 0x03 },
- { 0x28, 0x24 },
- { 0x2b, 0xac },
- { 0x12, 0x00 },
- { 0x38, 0x81 },
- { 0x28, 0x24 }, /* 0c */
- { 0x0f, 0x85 }, /* lg's setting */
- { 0x15, 0x01 },
- { 0x20, 0x1c },
- { 0x23, 0x2a },
- { 0x24, 0x10 },
- { 0x25, 0x8a },
- { 0x26, 0xa2 },
- { 0x27, 0xc2 },
- { 0x2a, 0x04 },
- { 0x2c, 0xfe },
- { 0x2d, 0x93 },
- { 0x30, 0x71 },
- { 0x31, 0x60 },
- { 0x32, 0x26 },
- { 0x33, 0x20 },
- { 0x34, 0x48 },
- { 0x12, 0x24 },
- { 0x11, 0x01 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* This initializes the OV76be camera chip and relevant variables. */
-static int ov76be_init(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov76be *s;
- int rc;
-
- DDEBUG(4, &c->dev, "entered");
-
- rc = ov_write_regvals(c, regvals_init_76be);
- if (rc < 0)
- return rc;
-
- ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
- if (!s)
- return -ENOMEM;
-
- s->auto_brt = 1;
- s->auto_exp = 1;
-
- return rc;
-}
-
-static int ov76be_free(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
-
- kfree(ov->spriv);
- return 0;
-}
-
-static int ov76be_set_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov76be *s = ov->spriv;
- int rc;
- int v = ctl->value;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_write(c, REG_BRT, v >> 8);
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_write(c, REG_SAT, v >> 8);
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_write(c, REG_EXP, v);
- break;
- case OVCAMCHIP_CID_FREQ:
- {
- int sixty = (v == 60);
-
- rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, 0x2b, sixty?0x00:0xac);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x76, 0x01, 0x01);
- break;
- }
- case OVCAMCHIP_CID_BANDFILT:
- rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
- s->bandfilt = v;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
- s->auto_brt = v;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
- s->auto_exp = v;
- break;
- case OVCAMCHIP_CID_MIRROR:
- rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
- s->mirror = v;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
-out:
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
- return rc;
-}
-
-static int ov76be_get_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov76be *s = ov->spriv;
- int rc = 0;
- unsigned char val = 0;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_read(c, REG_BRT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_read(c, REG_SAT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_read(c, REG_EXP, &val);
- ctl->value = val;
- break;
- case OVCAMCHIP_CID_BANDFILT:
- ctl->value = s->bandfilt;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- ctl->value = s->auto_brt;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- ctl->value = s->auto_exp;
- break;
- case OVCAMCHIP_CID_MIRROR:
- ctl->value = s->mirror;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
- return rc;
-}
-
-static int ov76be_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int qvga = win->quarter;
-
- /******** QVGA-specific regs ********/
-
- ov_write(c, 0x14, qvga?0xa4:0x84);
-
- /******** Palette-specific regs ********/
-
- if (win->format == VIDEO_PALETTE_GREY) {
- ov_write_mask(c, 0x0e, 0x40, 0x40);
- ov_write_mask(c, 0x13, 0x20, 0x20);
- } else {
- ov_write_mask(c, 0x0e, 0x00, 0x40);
- ov_write_mask(c, 0x13, 0x00, 0x20);
- }
-
- /******** Clock programming ********/
-
- ov_write(c, 0x11, win->clockdiv);
-
- /******** Resolution-specific ********/
-
- if (win->width == 640 && win->height == 480)
- ov_write(c, 0x35, 0x9e);
- else
- ov_write(c, 0x35, 0x1e);
-
- return 0;
-}
-
-static int ov76be_set_window(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int ret, hwscale, vwscale;
-
- ret = ov76be_mode_init(c, win);
- if (ret < 0)
- return ret;
-
- if (win->quarter) {
- hwscale = 1;
- vwscale = 0;
- } else {
- hwscale = 2;
- vwscale = 1;
- }
-
- ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
- ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
- ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
- ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
-
- return 0;
-}
-
-static int ov76be_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case OVCAMCHIP_CMD_S_CTRL:
- return ov76be_set_control(c, arg);
- case OVCAMCHIP_CMD_G_CTRL:
- return ov76be_get_control(c, arg);
- case OVCAMCHIP_CMD_S_MODE:
- return ov76be_set_window(c, arg);
- default:
- DDEBUG(2, &c->dev, "command not supported: %d", cmd);
- return -ENOIOCTLCMD;
- }
-}
-
-struct ovcamchip_ops ov76be_ops = {
- .init = ov76be_init,
- .free = ov76be_free,
- .command = ov76be_command,
-};
diff --git a/drivers/media/video/ovcamchip/ov7x10.c b/drivers/media/video/ovcamchip/ov7x10.c
deleted file mode 100644
index 5206e7913924..000000000000
--- a/drivers/media/video/ovcamchip/ov7x10.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/* OmniVision OV7610/OV7110 Camera Chip Support Code
- *
- * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/slab.h>
-#include "ovcamchip_priv.h"
-
-/* Registers */
-#define REG_GAIN 0x00 /* gain [5:0] */
-#define REG_BLUE 0x01 /* blue channel balance */
-#define REG_RED 0x02 /* red channel balance */
-#define REG_SAT 0x03 /* saturation */
-#define REG_CNT 0x05 /* Y contrast */
-#define REG_BRT 0x06 /* Y brightness */
-#define REG_BLUE_BIAS 0x0C /* blue channel bias [5:0] */
-#define REG_RED_BIAS 0x0D /* red channel bias [5:0] */
-#define REG_GAMMA_COEFF 0x0E /* gamma settings */
-#define REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */
-#define REG_EXP 0x10 /* manual exposure setting */
-#define REG_CLOCK 0x11 /* polarity/clock prescaler */
-#define REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */
-#define REG_HWIN_START 0x17 /* horizontal window start */
-#define REG_HWIN_END 0x18 /* horizontal window end */
-#define REG_VWIN_START 0x19 /* vertical window start */
-#define REG_VWIN_END 0x1A /* vertical window end */
-#define REG_PIXEL_SHIFT 0x1B /* pixel shift */
-#define REG_YOFFSET 0x21 /* Y channel offset */
-#define REG_UOFFSET 0x22 /* U channel offset */
-#define REG_ECW 0x24 /* exposure white level for AEC */
-#define REG_ECB 0x25 /* exposure black level for AEC */
-#define REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */
-#define REG_FRAMERATE_L 0x2B /* frame rate LSB */
-#define REG_ALC 0x2C /* Auto Level Control settings */
-#define REG_VOFFSET 0x2E /* V channel offset adjustment */
-#define REG_ARRAY_BIAS 0x2F /* array bias -- don't change */
-#define REG_YGAMMA 0x33 /* misc gamma settings [7:6] */
-#define REG_BIAS_ADJUST 0x34 /* misc bias settings */
-
-/* Window parameters */
-#define HWSBASE 0x38
-#define HWEBASE 0x3a
-#define VWSBASE 0x05
-#define VWEBASE 0x05
-
-struct ov7x10 {
- int auto_brt;
- int auto_exp;
- int bandfilt;
- int mirror;
-};
-
-/* Lawrence Glaister <lg@jfm.bc.ca> reports:
- *
- * Register 0x0f in the 7610 has the following effects:
- *
- * 0x85 (AEC method 1): Best overall, good contrast range
- * 0x45 (AEC method 2): Very overexposed
- * 0xa5 (spec sheet default): Ok, but the black level is
- * shifted resulting in loss of contrast
- * 0x05 (old driver setting): very overexposed, too much
- * contrast
- */
-static struct ovcamchip_regvals regvals_init_7x10[] = {
- { 0x10, 0xff },
- { 0x16, 0x03 },
- { 0x28, 0x24 },
- { 0x2b, 0xac },
- { 0x12, 0x00 },
- { 0x38, 0x81 },
- { 0x28, 0x24 }, /* 0c */
- { 0x0f, 0x85 }, /* lg's setting */
- { 0x15, 0x01 },
- { 0x20, 0x1c },
- { 0x23, 0x2a },
- { 0x24, 0x10 },
- { 0x25, 0x8a },
- { 0x26, 0xa2 },
- { 0x27, 0xc2 },
- { 0x2a, 0x04 },
- { 0x2c, 0xfe },
- { 0x2d, 0x93 },
- { 0x30, 0x71 },
- { 0x31, 0x60 },
- { 0x32, 0x26 },
- { 0x33, 0x20 },
- { 0x34, 0x48 },
- { 0x12, 0x24 },
- { 0x11, 0x01 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* This initializes the OV7x10 camera chip and relevant variables. */
-static int ov7x10_init(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x10 *s;
- int rc;
-
- DDEBUG(4, &c->dev, "entered");
-
- rc = ov_write_regvals(c, regvals_init_7x10);
- if (rc < 0)
- return rc;
-
- ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
- if (!s)
- return -ENOMEM;
-
- s->auto_brt = 1;
- s->auto_exp = 1;
-
- return rc;
-}
-
-static int ov7x10_free(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
-
- kfree(ov->spriv);
- return 0;
-}
-
-static int ov7x10_set_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x10 *s = ov->spriv;
- int rc;
- int v = ctl->value;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_write(c, REG_CNT, v >> 8);
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_write(c, REG_BRT, v >> 8);
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_write(c, REG_SAT, v >> 8);
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_write(c, REG_RED, 0xFF - (v >> 8));
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, REG_BLUE, v >> 8);
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_write(c, REG_EXP, v);
- break;
- case OVCAMCHIP_CID_FREQ:
- {
- int sixty = (v == 60);
-
- rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, 0x2b, sixty?0x00:0xac);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x13, 0x10, 0x10);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x13, 0x00, 0x10);
- break;
- }
- case OVCAMCHIP_CID_BANDFILT:
- rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
- s->bandfilt = v;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
- s->auto_brt = v;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- rc = ov_write_mask(c, 0x29, v?0x00:0x80, 0x80);
- s->auto_exp = v;
- break;
- case OVCAMCHIP_CID_MIRROR:
- rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
- s->mirror = v;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
-out:
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
- return rc;
-}
-
-static int ov7x10_get_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x10 *s = ov->spriv;
- int rc = 0;
- unsigned char val = 0;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_read(c, REG_CNT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_read(c, REG_BRT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_read(c, REG_SAT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_HUE:
- rc = ov_read(c, REG_BLUE, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_read(c, REG_EXP, &val);
- ctl->value = val;
- break;
- case OVCAMCHIP_CID_BANDFILT:
- ctl->value = s->bandfilt;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- ctl->value = s->auto_brt;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- ctl->value = s->auto_exp;
- break;
- case OVCAMCHIP_CID_MIRROR:
- ctl->value = s->mirror;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
- return rc;
-}
-
-static int ov7x10_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int qvga = win->quarter;
-
- /******** QVGA-specific regs ********/
-
- ov_write(c, 0x14, qvga?0x24:0x04);
-
- /******** Palette-specific regs ********/
-
- if (win->format == VIDEO_PALETTE_GREY) {
- ov_write_mask(c, 0x0e, 0x40, 0x40);
- ov_write_mask(c, 0x13, 0x20, 0x20);
- } else {
- ov_write_mask(c, 0x0e, 0x00, 0x40);
- ov_write_mask(c, 0x13, 0x00, 0x20);
- }
-
- /******** Clock programming ********/
-
- ov_write(c, 0x11, win->clockdiv);
-
- /******** Resolution-specific ********/
-
- if (win->width == 640 && win->height == 480)
- ov_write(c, 0x35, 0x9e);
- else
- ov_write(c, 0x35, 0x1e);
-
- return 0;
-}
-
-static int ov7x10_set_window(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int ret, hwscale, vwscale;
-
- ret = ov7x10_mode_init(c, win);
- if (ret < 0)
- return ret;
-
- if (win->quarter) {
- hwscale = 1;
- vwscale = 0;
- } else {
- hwscale = 2;
- vwscale = 1;
- }
-
- ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
- ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
- ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
- ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
-
- return 0;
-}
-
-static int ov7x10_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case OVCAMCHIP_CMD_S_CTRL:
- return ov7x10_set_control(c, arg);
- case OVCAMCHIP_CMD_G_CTRL:
- return ov7x10_get_control(c, arg);
- case OVCAMCHIP_CMD_S_MODE:
- return ov7x10_set_window(c, arg);
- default:
- DDEBUG(2, &c->dev, "command not supported: %d", cmd);
- return -ENOIOCTLCMD;
- }
-}
-
-struct ovcamchip_ops ov7x10_ops = {
- .init = ov7x10_init,
- .free = ov7x10_free,
- .command = ov7x10_command,
-};
diff --git a/drivers/media/video/ovcamchip/ov7x20.c b/drivers/media/video/ovcamchip/ov7x20.c
deleted file mode 100644
index 8e26ae338f31..000000000000
--- a/drivers/media/video/ovcamchip/ov7x20.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* OmniVision OV7620/OV7120 Camera Chip Support Code
- *
- * Copyright (c) 1999-2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * OV7620 fixes by Charl P. Botha <cpbotha@ieee.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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/slab.h>
-#include "ovcamchip_priv.h"
-
-/* Registers */
-#define REG_GAIN 0x00 /* gain [5:0] */
-#define REG_BLUE 0x01 /* blue gain */
-#define REG_RED 0x02 /* red gain */
-#define REG_SAT 0x03 /* saturation */
-#define REG_BRT 0x06 /* Y brightness */
-#define REG_SHARP 0x07 /* analog sharpness */
-#define REG_BLUE_BIAS 0x0C /* WB blue ratio [5:0] */
-#define REG_RED_BIAS 0x0D /* WB red ratio [5:0] */
-#define REG_EXP 0x10 /* exposure */
-
-/* Default control settings. Values are in terms of V4L2 controls. */
-#define OV7120_DFL_BRIGHT 0x60
-#define OV7620_DFL_BRIGHT 0x60
-#define OV7120_DFL_SAT 0xb0
-#define OV7620_DFL_SAT 0xc0
-#define DFL_AUTO_EXP 1
-#define DFL_AUTO_GAIN 1
-#define OV7120_DFL_GAIN 0x00
-#define OV7620_DFL_GAIN 0x00
-/* NOTE: Since autoexposure is the default, these aren't programmed into the
- * OV7x20 chip. They are just here because V4L2 expects a default */
-#define OV7120_DFL_EXP 0x7f
-#define OV7620_DFL_EXP 0x7f
-
-/* Window parameters */
-#define HWSBASE 0x2F /* From 7620.SET (spec is wrong) */
-#define HWEBASE 0x2F
-#define VWSBASE 0x05
-#define VWEBASE 0x05
-
-struct ov7x20 {
- int auto_brt;
- int auto_exp;
- int auto_gain;
- int backlight;
- int bandfilt;
- int mirror;
-};
-
-/* Contrast look-up table */
-static unsigned char ctab[] = {
- 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57,
- 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff
-};
-
-/* Settings for (Black & White) OV7120 camera chip */
-static struct ovcamchip_regvals regvals_init_7120[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x13, 0x00 }, /* Autoadjust off */
- { 0x12, 0x20 }, /* Disable AWB */
- { 0x13, DFL_AUTO_GAIN?0x01:0x00 }, /* Autoadjust on (if desired) */
- { 0x00, OV7120_DFL_GAIN },
- { 0x01, 0x80 },
- { 0x02, 0x80 },
- { 0x03, OV7120_DFL_SAT },
- { 0x06, OV7120_DFL_BRIGHT },
- { 0x07, 0x00 },
- { 0x0c, 0x20 },
- { 0x0d, 0x20 },
- { 0x11, 0x01 },
- { 0x14, 0x84 },
- { 0x15, 0x01 },
- { 0x16, 0x03 },
- { 0x17, 0x2f },
- { 0x18, 0xcf },
- { 0x19, 0x06 },
- { 0x1a, 0xf5 },
- { 0x1b, 0x00 },
- { 0x20, 0x08 },
- { 0x21, 0x80 },
- { 0x22, 0x80 },
- { 0x23, 0x00 },
- { 0x26, 0xa0 },
- { 0x27, 0xfa },
- { 0x28, 0x20 }, /* DON'T set bit 6. It is for the OV7620 only */
- { 0x29, DFL_AUTO_EXP?0x00:0x80 },
- { 0x2a, 0x10 },
- { 0x2b, 0x00 },
- { 0x2c, 0x88 },
- { 0x2d, 0x95 },
- { 0x2e, 0x80 },
- { 0x2f, 0x44 },
- { 0x60, 0x20 },
- { 0x61, 0x02 },
- { 0x62, 0x5f },
- { 0x63, 0xd5 },
- { 0x64, 0x57 },
- { 0x65, 0x83 }, /* OV says "don't change this value" */
- { 0x66, 0x55 },
- { 0x67, 0x92 },
- { 0x68, 0xcf },
- { 0x69, 0x76 },
- { 0x6a, 0x22 },
- { 0x6b, 0xe2 },
- { 0x6c, 0x40 },
- { 0x6d, 0x48 },
- { 0x6e, 0x80 },
- { 0x6f, 0x0d },
- { 0x70, 0x89 },
- { 0x71, 0x00 },
- { 0x72, 0x14 },
- { 0x73, 0x54 },
- { 0x74, 0xa0 },
- { 0x75, 0x8e },
- { 0x76, 0x00 },
- { 0x77, 0xff },
- { 0x78, 0x80 },
- { 0x79, 0x80 },
- { 0x7a, 0x80 },
- { 0x7b, 0xe6 },
- { 0x7c, 0x00 },
- { 0x24, 0x3a },
- { 0x25, 0x60 },
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* Settings for (color) OV7620 camera chip */
-static struct ovcamchip_regvals regvals_init_7620[] = {
- { 0x12, 0x80 }, /* reset */
- { 0x00, OV7620_DFL_GAIN },
- { 0x01, 0x80 },
- { 0x02, 0x80 },
- { 0x03, OV7620_DFL_SAT },
- { 0x06, OV7620_DFL_BRIGHT },
- { 0x07, 0x00 },
- { 0x0c, 0x24 },
- { 0x0c, 0x24 },
- { 0x0d, 0x24 },
- { 0x11, 0x01 },
- { 0x12, 0x24 },
- { 0x13, DFL_AUTO_GAIN?0x01:0x00 },
- { 0x14, 0x84 },
- { 0x15, 0x01 },
- { 0x16, 0x03 },
- { 0x17, 0x2f },
- { 0x18, 0xcf },
- { 0x19, 0x06 },
- { 0x1a, 0xf5 },
- { 0x1b, 0x00 },
- { 0x20, 0x18 },
- { 0x21, 0x80 },
- { 0x22, 0x80 },
- { 0x23, 0x00 },
- { 0x26, 0xa2 },
- { 0x27, 0xea },
- { 0x28, 0x20 },
- { 0x29, DFL_AUTO_EXP?0x00:0x80 },
- { 0x2a, 0x10 },
- { 0x2b, 0x00 },
- { 0x2c, 0x88 },
- { 0x2d, 0x91 },
- { 0x2e, 0x80 },
- { 0x2f, 0x44 },
- { 0x60, 0x27 },
- { 0x61, 0x02 },
- { 0x62, 0x5f },
- { 0x63, 0xd5 },
- { 0x64, 0x57 },
- { 0x65, 0x83 },
- { 0x66, 0x55 },
- { 0x67, 0x92 },
- { 0x68, 0xcf },
- { 0x69, 0x76 },
- { 0x6a, 0x22 },
- { 0x6b, 0x00 },
- { 0x6c, 0x02 },
- { 0x6d, 0x44 },
- { 0x6e, 0x80 },
- { 0x6f, 0x1d },
- { 0x70, 0x8b },
- { 0x71, 0x00 },
- { 0x72, 0x14 },
- { 0x73, 0x54 },
- { 0x74, 0x00 },
- { 0x75, 0x8e },
- { 0x76, 0x00 },
- { 0x77, 0xff },
- { 0x78, 0x80 },
- { 0x79, 0x80 },
- { 0x7a, 0x80 },
- { 0x7b, 0xe2 },
- { 0x7c, 0x00 },
- { 0xff, 0xff }, /* END MARKER */
-};
-
-/* Returns index into the specified look-up table, with 'n' elements, for which
- * the value is greater than or equal to "val". If a match isn't found, (n-1)
- * is returned. The entries in the table must be in ascending order. */
-static inline int ov7x20_lut_find(unsigned char lut[], int n, unsigned char val)
-{
- int i = 0;
-
- while (lut[i] < val && i < n)
- i++;
-
- return i;
-}
-
-/* This initializes the OV7x20 camera chip and relevant variables. */
-static int ov7x20_init(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x20 *s;
- int rc;
-
- DDEBUG(4, &c->dev, "entered");
-
- if (ov->mono)
- rc = ov_write_regvals(c, regvals_init_7120);
- else
- rc = ov_write_regvals(c, regvals_init_7620);
-
- if (rc < 0)
- return rc;
-
- ov->spriv = s = kzalloc(sizeof *s, GFP_KERNEL);
- if (!s)
- return -ENOMEM;
-
- s->auto_brt = 1;
- s->auto_exp = DFL_AUTO_EXP;
- s->auto_gain = DFL_AUTO_GAIN;
-
- return 0;
-}
-
-static int ov7x20_free(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
-
- kfree(ov->spriv);
- return 0;
-}
-
-static int ov7x20_set_v4l1_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x20 *s = ov->spriv;
- int rc;
- int v = ctl->value;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- {
- /* Use Y gamma control instead. Bit 0 enables it. */
- rc = ov_write(c, 0x64, ctab[v >> 12]);
- break;
- }
- case OVCAMCHIP_CID_BRIGHT:
- /* 7620 doesn't like manual changes when in auto mode */
- if (!s->auto_brt)
- rc = ov_write(c, REG_BRT, v >> 8);
- else
- rc = 0;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_write(c, REG_SAT, v >> 8);
- break;
- case OVCAMCHIP_CID_EXP:
- if (!s->auto_exp)
- rc = ov_write(c, REG_EXP, v);
- else
- rc = -EBUSY;
- break;
- case OVCAMCHIP_CID_FREQ:
- {
- int sixty = (v == 60);
-
- rc = ov_write_mask(c, 0x2a, sixty?0x00:0x80, 0x80);
- if (rc < 0)
- goto out;
-
- rc = ov_write(c, 0x2b, sixty?0x00:0xac);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x76, 0x01, 0x01);
- break;
- }
- case OVCAMCHIP_CID_BANDFILT:
- rc = ov_write_mask(c, 0x2d, v?0x04:0x00, 0x04);
- s->bandfilt = v;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- rc = ov_write_mask(c, 0x2d, v?0x10:0x00, 0x10);
- s->auto_brt = v;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- rc = ov_write_mask(c, 0x13, v?0x01:0x00, 0x01);
- s->auto_exp = v;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- {
- rc = ov_write_mask(c, 0x68, v?0xe0:0xc0, 0xe0);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x29, v?0x08:0x00, 0x08);
- if (rc < 0)
- goto out;
-
- rc = ov_write_mask(c, 0x28, v?0x02:0x00, 0x02);
- s->backlight = v;
- break;
- }
- case OVCAMCHIP_CID_MIRROR:
- rc = ov_write_mask(c, 0x12, v?0x40:0x00, 0x40);
- s->mirror = v;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
-out:
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, v, rc);
- return rc;
-}
-
-static int ov7x20_get_v4l1_control(struct i2c_client *c,
- struct ovcamchip_control *ctl)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- struct ov7x20 *s = ov->spriv;
- int rc = 0;
- unsigned char val = 0;
-
- switch (ctl->id) {
- case OVCAMCHIP_CID_CONT:
- rc = ov_read(c, 0x64, &val);
- ctl->value = ov7x20_lut_find(ctab, 16, val) << 12;
- break;
- case OVCAMCHIP_CID_BRIGHT:
- rc = ov_read(c, REG_BRT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_SAT:
- rc = ov_read(c, REG_SAT, &val);
- ctl->value = val << 8;
- break;
- case OVCAMCHIP_CID_EXP:
- rc = ov_read(c, REG_EXP, &val);
- ctl->value = val;
- break;
- case OVCAMCHIP_CID_BANDFILT:
- ctl->value = s->bandfilt;
- break;
- case OVCAMCHIP_CID_AUTOBRIGHT:
- ctl->value = s->auto_brt;
- break;
- case OVCAMCHIP_CID_AUTOEXP:
- ctl->value = s->auto_exp;
- break;
- case OVCAMCHIP_CID_BACKLIGHT:
- ctl->value = s->backlight;
- break;
- case OVCAMCHIP_CID_MIRROR:
- ctl->value = s->mirror;
- break;
- default:
- DDEBUG(2, &c->dev, "control not supported: %d", ctl->id);
- return -EPERM;
- }
-
- DDEBUG(3, &c->dev, "id=%d, arg=%d, rc=%d", ctl->id, ctl->value, rc);
- return rc;
-}
-
-static int ov7x20_mode_init(struct i2c_client *c, struct ovcamchip_window *win)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- int qvga = win->quarter;
-
- /******** QVGA-specific regs ********/
- ov_write_mask(c, 0x14, qvga?0x20:0x00, 0x20);
- ov_write_mask(c, 0x28, qvga?0x00:0x20, 0x20);
- ov_write(c, 0x24, qvga?0x20:0x3a);
- ov_write(c, 0x25, qvga?0x30:0x60);
- ov_write_mask(c, 0x2d, qvga?0x40:0x00, 0x40);
- if (!ov->mono)
- ov_write_mask(c, 0x67, qvga?0xf0:0x90, 0xf0);
- ov_write_mask(c, 0x74, qvga?0x20:0x00, 0x20);
-
- /******** Clock programming ********/
-
- ov_write(c, 0x11, win->clockdiv);
-
- return 0;
-}
-
-static int ov7x20_set_window(struct i2c_client *c, struct ovcamchip_window *win)
-{
- int ret, hwscale, vwscale;
-
- ret = ov7x20_mode_init(c, win);
- if (ret < 0)
- return ret;
-
- if (win->quarter) {
- hwscale = 1;
- vwscale = 0;
- } else {
- hwscale = 2;
- vwscale = 1;
- }
-
- ov_write(c, 0x17, HWSBASE + (win->x >> hwscale));
- ov_write(c, 0x18, HWEBASE + ((win->x + win->width) >> hwscale));
- ov_write(c, 0x19, VWSBASE + (win->y >> vwscale));
- ov_write(c, 0x1a, VWEBASE + ((win->y + win->height) >> vwscale));
-
- return 0;
-}
-
-static int ov7x20_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- switch (cmd) {
- case OVCAMCHIP_CMD_S_CTRL:
- return ov7x20_set_v4l1_control(c, arg);
- case OVCAMCHIP_CMD_G_CTRL:
- return ov7x20_get_v4l1_control(c, arg);
- case OVCAMCHIP_CMD_S_MODE:
- return ov7x20_set_window(c, arg);
- default:
- DDEBUG(2, &c->dev, "command not supported: %d", cmd);
- return -ENOIOCTLCMD;
- }
-}
-
-struct ovcamchip_ops ov7x20_ops = {
- .init = ov7x20_init,
- .free = ov7x20_free,
- .command = ov7x20_command,
-};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
deleted file mode 100644
index d573d8428998..000000000000
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ /dev/null
@@ -1,395 +0,0 @@
-/* Shared Code for OmniVision Camera Chip Drivers
- *
- * Copyright (c) 2004 Mark McClelland <mark@alpha.dyndns.org>
- * http://alpha.dyndns.org/ov511/
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- */
-
-#define DEBUG
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv.h>
-#include "ovcamchip_priv.h"
-
-#define DRIVER_VERSION "v2.27 for Linux 2.6"
-#define DRIVER_AUTHOR "Mark McClelland <mark@alpha.dyndns.org>"
-#define DRIVER_DESC "OV camera chip I2C driver"
-
-#define PINFO(fmt, args...) printk(KERN_INFO "ovcamchip: " fmt "\n" , ## args);
-#define PERROR(fmt, args...) printk(KERN_ERR "ovcamchip: " fmt "\n" , ## args);
-
-#ifdef DEBUG
-int ovcamchip_debug = 0;
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug,
- "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=all");
-#endif
-
-/* By default, let bridge driver tell us if chip is monochrome. mono=0
- * will ignore that and always treat chips as color. mono=1 will force
- * monochrome mode for all chips. */
-static int mono = -1;
-module_param(mono, int, 0);
-MODULE_PARM_DESC(mono,
- "1=chips are monochrome (OVx1xx), 0=force color, -1=autodetect (default)");
-
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
-
-
-/* Registers common to all chips, that are needed for detection */
-#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
-#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
-#define GENERIC_REG_COM_I 0x29 /* misc ID bits */
-
-static char *chip_names[NUM_CC_TYPES] = {
- [CC_UNKNOWN] = "Unknown chip",
- [CC_OV76BE] = "OV76BE",
- [CC_OV7610] = "OV7610",
- [CC_OV7620] = "OV7620",
- [CC_OV7620AE] = "OV7620AE",
- [CC_OV6620] = "OV6620",
- [CC_OV6630] = "OV6630",
- [CC_OV6630AE] = "OV6630AE",
- [CC_OV6630AF] = "OV6630AF",
-};
-
-/* ----------------------------------------------------------------------- */
-
-int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
-{
- int rc;
-
- while (rvals->reg != 0xff) {
- rc = ov_write(c, rvals->reg, rvals->val);
- if (rc < 0)
- return rc;
- rvals++;
- }
-
- return 0;
-}
-
-/* Writes bits at positions specified by mask to an I2C reg. Bits that are in
- * the same position as 1's in "mask" are cleared and set to "value". Bits
- * that are in the same position as 0's in "mask" are preserved, regardless
- * of their respective state in "value".
- */
-int ov_write_mask(struct i2c_client *c,
- unsigned char reg,
- unsigned char value,
- unsigned char mask)
-{
- int rc;
- unsigned char oldval, newval;
-
- if (mask == 0xff) {
- newval = value;
- } else {
- rc = ov_read(c, reg, &oldval);
- if (rc < 0)
- return rc;
-
- oldval &= (~mask); /* Clear the masked bits */
- value &= mask; /* Enforce mask on value */
- newval = oldval | value; /* Set the desired bits */
- }
-
- return ov_write(c, reg, newval);
-}
-
-/* ----------------------------------------------------------------------- */
-
-/* Reset the chip and ensure that I2C is synchronized. Returns <0 if failure.
- */
-static int init_camchip(struct i2c_client *c)
-{
- int i, success;
- unsigned char high, low;
-
- /* Reset the chip */
- ov_write(c, 0x12, 0x80);
-
- /* Wait for it to initialize */
- msleep(150);
-
- for (i = 0, success = 0; i < I2C_DETECT_RETRIES && !success; i++) {
- if (ov_read(c, GENERIC_REG_ID_HIGH, &high) >= 0) {
- if (ov_read(c, GENERIC_REG_ID_LOW, &low) >= 0) {
- if (high == 0x7F && low == 0xA2) {
- success = 1;
- continue;
- }
- }
- }
-
- /* Reset the chip */
- ov_write(c, 0x12, 0x80);
-
- /* Wait for it to initialize */
- msleep(150);
-
- /* Dummy read to sync I2C */
- ov_read(c, 0x00, &low);
- }
-
- if (!success)
- return -EIO;
-
- PDEBUG(1, "I2C synced in %d attempt(s)", i);
-
- return 0;
-}
-
-/* This detects the OV7610, OV7620, or OV76BE chip. */
-static int ov7xx0_detect(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- int rc;
- unsigned char val;
-
- PDEBUG(4, "");
-
- /* Detect chip (sub)type */
- rc = ov_read(c, GENERIC_REG_COM_I, &val);
- if (rc < 0) {
- PERROR("Error detecting ov7xx0 type");
- return rc;
- }
-
- if ((val & 3) == 3) {
- PINFO("Camera chip is an OV7610");
- ov->subtype = CC_OV7610;
- } else if ((val & 3) == 1) {
- rc = ov_read(c, 0x15, &val);
- if (rc < 0) {
- PERROR("Error detecting ov7xx0 type");
- return rc;
- }
-
- if (val & 1) {
- PINFO("Camera chip is an OV7620AE");
- /* OV7620 is a close enough match for now. There are
- * some definite differences though, so this should be
- * fixed */
- ov->subtype = CC_OV7620;
- } else {
- PINFO("Camera chip is an OV76BE");
- ov->subtype = CC_OV76BE;
- }
- } else if ((val & 3) == 0) {
- PINFO("Camera chip is an OV7620");
- ov->subtype = CC_OV7620;
- } else {
- PERROR("Unknown camera chip version: %d", val & 3);
- return -ENOSYS;
- }
-
- if (ov->subtype == CC_OV76BE)
- ov->sops = &ov76be_ops;
- else if (ov->subtype == CC_OV7620)
- ov->sops = &ov7x20_ops;
- else
- ov->sops = &ov7x10_ops;
-
- return 0;
-}
-
-/* This detects the OV6620, OV6630, OV6630AE, or OV6630AF chip. */
-static int ov6xx0_detect(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- int rc;
- unsigned char val;
-
- PDEBUG(4, "");
-
- /* Detect chip (sub)type */
- rc = ov_read(c, GENERIC_REG_COM_I, &val);
- if (rc < 0) {
- PERROR("Error detecting ov6xx0 type");
- return -1;
- }
-
- if ((val & 3) == 0) {
- ov->subtype = CC_OV6630;
- PINFO("Camera chip is an OV6630");
- } else if ((val & 3) == 1) {
- ov->subtype = CC_OV6620;
- PINFO("Camera chip is an OV6620");
- } else if ((val & 3) == 2) {
- ov->subtype = CC_OV6630;
- PINFO("Camera chip is an OV6630AE");
- } else if ((val & 3) == 3) {
- ov->subtype = CC_OV6630;
- PINFO("Camera chip is an OV6630AF");
- }
-
- if (ov->subtype == CC_OV6620)
- ov->sops = &ov6x20_ops;
- else
- ov->sops = &ov6x30_ops;
-
- return 0;
-}
-
-static int ovcamchip_detect(struct i2c_client *c)
-{
- /* Ideally we would just try a single register write and see if it NAKs.
- * That isn't possible since the OV518 can't report I2C transaction
- * failures. So, we have to try to initialize the chip (i.e. reset it
- * and check the ID registers) to detect its presence. */
-
- /* Test for 7xx0 */
- PDEBUG(3, "Testing for 0V7xx0");
- if (init_camchip(c) < 0)
- return -ENODEV;
- /* 7-bit addresses with bit 0 set are for the OV7xx0 */
- if (c->addr & 1) {
- if (ov7xx0_detect(c) < 0) {
- PERROR("Failed to init OV7xx0");
- return -EIO;
- }
- return 0;
- }
- /* Test for 6xx0 */
- PDEBUG(3, "Testing for 0V6xx0");
- if (ov6xx0_detect(c) < 0) {
- PERROR("Failed to init OV6xx0");
- return -EIO;
- }
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct ovcamchip *ov = to_ovcamchip(sd);
- struct i2c_client *c = v4l2_get_subdevdata(sd);
-
- if (!ov->initialized &&
- cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
- cmd != OVCAMCHIP_CMD_INITIALIZE) {
- v4l2_err(sd, "Camera chip not initialized yet!\n");
- return -EPERM;
- }
-
- switch (cmd) {
- case OVCAMCHIP_CMD_Q_SUBTYPE:
- {
- *(int *)arg = ov->subtype;
- return 0;
- }
- case OVCAMCHIP_CMD_INITIALIZE:
- {
- int rc;
-
- if (mono == -1)
- ov->mono = *(int *)arg;
- else
- ov->mono = mono;
-
- if (ov->mono) {
- if (ov->subtype != CC_OV7620)
- v4l2_warn(sd, "Monochrome not "
- "implemented for this chip\n");
- else
- v4l2_info(sd, "Initializing chip as "
- "monochrome\n");
- }
-
- rc = ov->sops->init(c);
- if (rc < 0)
- return rc;
-
- ov->initialized = 1;
- return 0;
- }
- default:
- return ov->sops->command(c, cmd, arg);
- }
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
- .ioctl = ovcamchip_ioctl,
-};
-
-static const struct v4l2_subdev_ops ovcamchip_ops = {
- .core = &ovcamchip_core_ops,
-};
-
-static int ovcamchip_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- struct ovcamchip *ov;
- struct v4l2_subdev *sd;
- int rc = 0;
-
- ov = kzalloc(sizeof *ov, GFP_KERNEL);
- if (!ov) {
- rc = -ENOMEM;
- goto no_ov;
- }
- sd = &ov->sd;
- v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);
-
- rc = ovcamchip_detect(client);
- if (rc < 0)
- goto error;
-
- v4l_info(client, "%s found @ 0x%02x (%s)\n",
- chip_names[ov->subtype], client->addr << 1, client->adapter->name);
-
- PDEBUG(1, "Camera chip detection complete");
-
- return rc;
-error:
- kfree(ov);
-no_ov:
- PDEBUG(1, "returning %d", rc);
- return rc;
-}
-
-static int ovcamchip_remove(struct i2c_client *client)
-{
- struct v4l2_subdev *sd = i2c_get_clientdata(client);
- struct ovcamchip *ov = to_ovcamchip(sd);
- int rc;
-
- v4l2_device_unregister_subdev(sd);
- rc = ov->sops->free(client);
- if (rc < 0)
- return rc;
-
- kfree(ov);
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id ovcamchip_id[] = {
- { "ovcamchip", 0 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
- .name = "ovcamchip",
- .probe = ovcamchip_probe,
- .remove = ovcamchip_remove,
- .id_table = ovcamchip_id,
-};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
deleted file mode 100644
index 4f07b78c88bc..000000000000
--- a/drivers/media/video/ovcamchip/ovcamchip_priv.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* OmniVision* camera chip driver private definitions for core code and
- * chip-specific code
- *
- * Copyright (c) 1999-2004 Mark McClelland
- *
- * 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. NO WARRANTY OF ANY KIND is expressed or implied.
- *
- * * OmniVision is a trademark of OmniVision Technologies, Inc. This driver
- * is not sponsored or developed by them.
- */
-
-#ifndef __LINUX_OVCAMCHIP_PRIV_H
-#define __LINUX_OVCAMCHIP_PRIV_H
-
-#include <linux/i2c.h>
-#include <media/v4l2-subdev.h>
-#include <media/ovcamchip.h>
-
-#ifdef DEBUG
-extern int ovcamchip_debug;
-#endif
-
-#define PDEBUG(level, fmt, args...) \
- if (ovcamchip_debug >= (level)) pr_debug("[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args)
-
-#define DDEBUG(level, dev, fmt, args...) \
- if (ovcamchip_debug >= (level)) dev_dbg(dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args)
-
-/* Number of times to retry chip detection. Increase this if you are getting
- * "Failed to init camera chip" */
-#define I2C_DETECT_RETRIES 10
-
-struct ovcamchip_regvals {
- unsigned char reg;
- unsigned char val;
-};
-
-struct ovcamchip_ops {
- int (*init)(struct i2c_client *);
- int (*free)(struct i2c_client *);
- int (*command)(struct i2c_client *, unsigned int, void *);
-};
-
-struct ovcamchip {
- struct v4l2_subdev sd;
- struct ovcamchip_ops *sops;
- void *spriv; /* Private data for OV7x10.c etc... */
- int subtype; /* = SEN_OV7610 etc... */
- int mono; /* Monochrome chip? (invalid until init) */
- int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
-};
-
-static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd)
-{
- return container_of(sd, struct ovcamchip, sd);
-}
-
-extern struct ovcamchip_ops ov6x20_ops;
-extern struct ovcamchip_ops ov6x30_ops;
-extern struct ovcamchip_ops ov7x10_ops;
-extern struct ovcamchip_ops ov7x20_ops;
-extern struct ovcamchip_ops ov76be_ops;
-
-/* --------------------------------- */
-/* I2C I/O */
-/* --------------------------------- */
-
-static inline int ov_read(struct i2c_client *c, unsigned char reg,
- unsigned char *value)
-{
- int rc;
-
- rc = i2c_smbus_read_byte_data(c, reg);
- *value = (unsigned char) rc;
- return rc;
-}
-
-static inline int ov_write(struct i2c_client *c, unsigned char reg,
- unsigned char value )
-{
- return i2c_smbus_write_byte_data(c, reg, value);
-}
-
-/* --------------------------------- */
-/* FUNCTION PROTOTYPES */
-/* --------------------------------- */
-
-/* Functions in ovcamchip_core.c */
-
-extern int ov_write_regvals(struct i2c_client *c,
- struct ovcamchip_regvals *rvals);
-
-extern int ov_write_mask(struct i2c_client *c, unsigned char reg,
- unsigned char value, unsigned char mask);
-
-#endif
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ioread.c b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
index b4824782d858..bba6115c9ae8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ioread.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ioread.c
@@ -223,7 +223,10 @@ int pvr2_ioread_setup(struct pvr2_ioread *cp,struct pvr2_stream *sp)
" pvr2_ioread_setup (setup) id=%p",cp);
pvr2_stream_kill(sp);
ret = pvr2_stream_set_buffer_count(sp,BUFFER_COUNT);
- if (ret < 0) return ret;
+ if (ret < 0) {
+ mutex_unlock(&cp->mutex);
+ return ret;
+ }
for (idx = 0; idx < BUFFER_COUNT; idx++) {
bp = pvr2_stream_get_buffer(sp,idx);
pvr2_buffer_set_buffer(bp,
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index fb242f6cfb1f..5835acf7fa7a 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -276,7 +276,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
* longer in STATE_QUEUED or STATE_ACTIVE
*/
videobuf_waiton(&buf->vb, 0, 0);
- videobuf_dma_unmap(vq, dma);
+ videobuf_dma_unmap(vq->dev, dma);
videobuf_dma_free(dma);
for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 3c7a79f3812a..8ec7c9a45a17 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -191,7 +191,6 @@ struct s2255_bufferi {
struct s2255_dmaqueue {
struct list_head active;
struct s2255_dev *dev;
- int channel;
};
/* for firmware loading, fw_state */
@@ -226,51 +225,60 @@ struct s2255_pipeinfo {
};
struct s2255_fmt; /*forward declaration */
+struct s2255_dev;
+
+struct s2255_channel {
+ struct video_device vdev;
+ int resources;
+ struct s2255_dmaqueue vidq;
+ struct s2255_bufferi buffer;
+ struct s2255_mode mode;
+ /* jpeg compression */
+ struct v4l2_jpegcompression jc;
+ /* capture parameters (for high quality mode full size) */
+ struct v4l2_captureparm cap_parm;
+ int cur_frame;
+ int last_frame;
+
+ int b_acquire;
+ /* allocated image size */
+ unsigned long req_image_size;
+ /* received packet size */
+ unsigned long pkt_size;
+ int bad_payload;
+ unsigned long frame_count;
+ /* if JPEG image */
+ int jpg_size;
+ /* if channel configured to default state */
+ int configured;
+ wait_queue_head_t wait_setmode;
+ int setmode_ready;
+ /* video status items */
+ int vidstatus;
+ wait_queue_head_t wait_vidstatus;
+ int vidstatus_ready;
+ unsigned int width;
+ unsigned int height;
+ const struct s2255_fmt *fmt;
+ int idx; /* channel number on device, 0-3 */
+};
+
struct s2255_dev {
- struct video_device vdev[MAX_CHANNELS];
+ struct s2255_channel channel[MAX_CHANNELS];
struct v4l2_device v4l2_dev;
- atomic_t channels; /* number of channels registered */
+ atomic_t num_channels;
int frames;
struct mutex lock;
struct mutex open_lock;
- int resources[MAX_CHANNELS];
struct usb_device *udev;
struct usb_interface *interface;
u8 read_endpoint;
-
- struct s2255_dmaqueue vidq[MAX_CHANNELS];
struct timer_list timer;
struct s2255_fw *fw_data;
struct s2255_pipeinfo pipe;
- struct s2255_bufferi buffer[MAX_CHANNELS];
- struct s2255_mode mode[MAX_CHANNELS];
- /* jpeg compression */
- struct v4l2_jpegcompression jc[MAX_CHANNELS];
- /* capture parameters (for high quality mode full size) */
- struct v4l2_captureparm cap_parm[MAX_CHANNELS];
- const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
- int cur_frame[MAX_CHANNELS];
- int last_frame[MAX_CHANNELS];
u32 cc; /* current channel */
- int b_acquire[MAX_CHANNELS];
- /* allocated image size */
- unsigned long req_image_size[MAX_CHANNELS];
- /* received packet size */
- unsigned long pkt_size[MAX_CHANNELS];
- int bad_payload[MAX_CHANNELS];
- unsigned long frame_count[MAX_CHANNELS];
int frame_ready;
- /* if JPEG image */
- int jpg_size[MAX_CHANNELS];
- /* if channel configured to default state */
- int chn_configured[MAX_CHANNELS];
- wait_queue_head_t wait_setmode[MAX_CHANNELS];
- int setmode_ready[MAX_CHANNELS];
- /* video status items */
- int vidstatus[MAX_CHANNELS];
- wait_queue_head_t wait_vidstatus[MAX_CHANNELS];
- int vidstatus_ready[MAX_CHANNELS];
int chn_ready;
spinlock_t slock;
/* dsp firmware version (f2255usb.bin) */
@@ -298,16 +306,10 @@ struct s2255_buffer {
struct s2255_fh {
struct s2255_dev *dev;
- const struct s2255_fmt *fmt;
- unsigned int width;
- unsigned int height;
struct videobuf_queue vb_vidq;
enum v4l2_buf_type type;
- int channel;
- /* mode below is the desired mode.
- mode in s2255_dev is the current mode that was last set */
- struct s2255_mode mode;
- int resources[MAX_CHANNELS];
+ struct s2255_channel *channel;
+ int resources;
};
/* current cypress EEPROM firmware version */
@@ -360,12 +362,11 @@ static int *s2255_debug = &debug;
static int s2255_start_readpipe(struct s2255_dev *dev);
static void s2255_stop_readpipe(struct s2255_dev *dev);
-static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn);
-static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn);
-static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
- int chn, int jpgsize);
-static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
- struct s2255_mode *mode);
+static int s2255_start_acquire(struct s2255_channel *channel);
+static int s2255_stop_acquire(struct s2255_channel *channel);
+static void s2255_fillbuff(struct s2255_channel *chn, struct s2255_buffer *buf,
+ int jpgsize);
+static int s2255_set_mode(struct s2255_channel *chan, struct s2255_mode *mode);
static int s2255_board_shutdown(struct s2255_dev *dev);
static void s2255_fwload_start(struct s2255_dev *dev, int reset);
static void s2255_destroy(struct s2255_dev *dev);
@@ -577,10 +578,11 @@ static void s2255_fwchunk_complete(struct urb *urb)
}
-static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
+static int s2255_got_frame(struct s2255_channel *channel, int jpgsize)
{
- struct s2255_dmaqueue *dma_q = &dev->vidq[chn];
+ struct s2255_dmaqueue *dma_q = &channel->vidq;
struct s2255_buffer *buf;
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
unsigned long flags = 0;
int rc = 0;
spin_lock_irqsave(&dev->slock, flags);
@@ -593,7 +595,7 @@ static int s2255_got_frame(struct s2255_dev *dev, int chn, int jpgsize)
struct s2255_buffer, vb.queue);
list_del(&buf->vb.queue);
do_gettimeofday(&buf->vb.ts);
- s2255_fillbuff(dev, buf, dma_q->channel, jpgsize);
+ s2255_fillbuff(channel, buf, jpgsize);
wake_up(&buf->vb.done);
dprintk(2, "%s: [buf/i] [%p/%d]\n", __func__, buf, buf->vb.i);
unlock:
@@ -621,8 +623,8 @@ static const struct s2255_fmt *format_by_fourcc(int fourcc)
* http://v4l.videotechnology.com/
*
*/
-static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
- int chn, int jpgsize)
+static void s2255_fillbuff(struct s2255_channel *channel,
+ struct s2255_buffer *buf, int jpgsize)
{
int pos = 0;
struct timeval ts;
@@ -633,12 +635,11 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
if (!vbuf)
return;
-
- last_frame = dev->last_frame[chn];
+ last_frame = channel->last_frame;
if (last_frame != -1) {
- frm = &dev->buffer[chn].frame[last_frame];
+ frm = &channel->buffer.frame[last_frame];
tmpbuf =
- (const char *)dev->buffer[chn].frame[last_frame].lpvbits;
+ (const char *)channel->buffer.frame[last_frame].lpvbits;
switch (buf->fmt->fourcc) {
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_UYVY:
@@ -661,7 +662,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
default:
printk(KERN_DEBUG "s2255: unknown format?\n");
}
- dev->last_frame[chn] = -1;
+ channel->last_frame = -1;
} else {
printk(KERN_ERR "s2255: =======no frame\n");
return;
@@ -671,7 +672,7 @@ static void s2255_fillbuff(struct s2255_dev *dev, struct s2255_buffer *buf,
(unsigned long)vbuf, pos);
/* tell v4l buffer was filled */
- buf->vb.field_count = dev->frame_count[chn] * 2;
+ buf->vb.field_count = channel->frame_count * 2;
do_gettimeofday(&ts);
buf->vb.ts = ts;
buf->vb.state = VIDEOBUF_DONE;
@@ -686,8 +687,8 @@ static int buffer_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
struct s2255_fh *fh = vq->priv_data;
-
- *size = fh->width * fh->height * (fh->fmt->depth >> 3);
+ struct s2255_channel *channel = fh->channel;
+ *size = channel->width * channel->height * (channel->fmt->depth >> 3);
if (0 == *count)
*count = S2255_DEF_BUFS;
@@ -710,30 +711,31 @@ static int buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
enum v4l2_field field)
{
struct s2255_fh *fh = vq->priv_data;
+ struct s2255_channel *channel = fh->channel;
struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
int rc;
+ int w = channel->width;
+ int h = channel->height;
dprintk(4, "%s, field=%d\n", __func__, field);
- if (fh->fmt == NULL)
+ if (channel->fmt == NULL)
return -EINVAL;
- if ((fh->width < norm_minw(&fh->dev->vdev[fh->channel])) ||
- (fh->width > norm_maxw(&fh->dev->vdev[fh->channel])) ||
- (fh->height < norm_minh(&fh->dev->vdev[fh->channel])) ||
- (fh->height > norm_maxh(&fh->dev->vdev[fh->channel]))) {
+ if ((w < norm_minw(&channel->vdev)) ||
+ (w > norm_maxw(&channel->vdev)) ||
+ (h < norm_minh(&channel->vdev)) ||
+ (h > norm_maxh(&channel->vdev))) {
dprintk(4, "invalid buffer prepare\n");
return -EINVAL;
}
-
- buf->vb.size = fh->width * fh->height * (fh->fmt->depth >> 3);
-
+ buf->vb.size = w * h * (channel->fmt->depth >> 3);
if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) {
dprintk(4, "invalid buffer prepare\n");
return -EINVAL;
}
- buf->fmt = fh->fmt;
- buf->vb.width = fh->width;
- buf->vb.height = fh->height;
+ buf->fmt = channel->fmt;
+ buf->vb.width = w;
+ buf->vb.height = h;
buf->vb.field = field;
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
@@ -753,8 +755,8 @@ static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
struct s2255_fh *fh = vq->priv_data;
- struct s2255_dev *dev = fh->dev;
- struct s2255_dmaqueue *vidq = &dev->vidq[fh->channel];
+ struct s2255_channel *channel = fh->channel;
+ struct s2255_dmaqueue *vidq = &channel->vidq;
dprintk(1, "%s\n", __func__);
buf->vb.state = VIDEOBUF_QUEUED;
list_add_tail(&buf->vb.queue, &vidq->active);
@@ -765,7 +767,7 @@ static void buffer_release(struct videobuf_queue *vq,
{
struct s2255_buffer *buf = container_of(vb, struct s2255_buffer, vb);
struct s2255_fh *fh = vq->priv_data;
- dprintk(4, "%s %d\n", __func__, fh->channel);
+ dprintk(4, "%s %d\n", __func__, fh->channel->idx);
free_buffer(vq, buf);
}
@@ -777,39 +779,43 @@ static struct videobuf_queue_ops s2255_video_qops = {
};
-static int res_get(struct s2255_dev *dev, struct s2255_fh *fh)
+static int res_get(struct s2255_fh *fh)
{
+ struct s2255_dev *dev = fh->dev;
/* is it free? */
+ struct s2255_channel *channel = fh->channel;
mutex_lock(&dev->lock);
- if (dev->resources[fh->channel]) {
+ if (channel->resources) {
/* no, someone else uses it */
mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
- dev->resources[fh->channel] = 1;
- fh->resources[fh->channel] = 1;
+ channel->resources = 1;
+ fh->resources = 1;
dprintk(1, "s2255: res: get\n");
mutex_unlock(&dev->lock);
return 1;
}
-static int res_locked(struct s2255_dev *dev, struct s2255_fh *fh)
+static int res_locked(struct s2255_fh *fh)
{
- return dev->resources[fh->channel];
+ return fh->channel->resources;
}
static int res_check(struct s2255_fh *fh)
{
- return fh->resources[fh->channel];
+ return fh->resources;
}
-static void res_free(struct s2255_dev *dev, struct s2255_fh *fh)
+static void res_free(struct s2255_fh *fh)
{
+ struct s2255_channel *channel = fh->channel;
+ struct s2255_dev *dev = fh->dev;
mutex_lock(&dev->lock);
- dev->resources[fh->channel] = 0;
- fh->resources[fh->channel] = 0;
+ channel->resources = 0;
+ fh->resources = 0;
mutex_unlock(&dev->lock);
dprintk(1, "res: put\n");
}
@@ -869,12 +875,13 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct s2255_fh *fh = priv;
+ struct s2255_channel *channel = fh->channel;
- f->fmt.pix.width = fh->width;
- f->fmt.pix.height = fh->height;
+ f->fmt.pix.width = channel->width;
+ f->fmt.pix.height = channel->height;
f->fmt.pix.field = fh->vb_vidq.field;
- f->fmt.pix.pixelformat = fh->fmt->fourcc;
- f->fmt.pix.bytesperline = f->fmt.pix.width * (fh->fmt->depth >> 3);
+ f->fmt.pix.pixelformat = channel->fmt->fourcc;
+ f->fmt.pix.bytesperline = f->fmt.pix.width * (channel->fmt->depth >> 3);
f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
return 0;
}
@@ -886,11 +893,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
enum v4l2_field field;
int b_any_field = 0;
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
+ struct s2255_channel *channel = fh->channel;
int is_ntsc;
-
is_ntsc =
- (dev->vdev[fh->channel].current_norm & V4L2_STD_NTSC) ? 1 : 0;
+ (channel->vdev.current_norm & V4L2_STD_NTSC) ? 1 : 0;
fmt = format_by_fourcc(f->fmt.pix.pixelformat);
@@ -982,8 +988,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_format *f)
{
struct s2255_fh *fh = priv;
+ struct s2255_channel *channel = fh->channel;
const struct s2255_fmt *fmt;
struct videobuf_queue *q = &fh->vb_vidq;
+ struct s2255_mode mode;
int ret;
int norm;
@@ -1005,54 +1013,61 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
goto out_s_fmt;
}
- if (res_locked(fh->dev, fh)) {
+ if (res_locked(fh)) {
dprintk(1, "%s: channel busy\n", __func__);
ret = -EBUSY;
goto out_s_fmt;
}
-
- fh->fmt = fmt;
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
+ mode = channel->mode;
+ channel->fmt = fmt;
+ channel->width = f->fmt.pix.width;
+ channel->height = f->fmt.pix.height;
fh->vb_vidq.field = f->fmt.pix.field;
fh->type = f->type;
- norm = norm_minw(&fh->dev->vdev[fh->channel]);
- if (fh->width > norm_minw(&fh->dev->vdev[fh->channel])) {
- if (fh->height > norm_minh(&fh->dev->vdev[fh->channel])) {
- if (fh->dev->cap_parm[fh->channel].capturemode &
+ norm = norm_minw(&channel->vdev);
+ if (channel->width > norm_minw(&channel->vdev)) {
+ if (channel->height > norm_minh(&channel->vdev)) {
+ if (channel->cap_parm.capturemode &
V4L2_MODE_HIGHQUALITY)
- fh->mode.scale = SCALE_4CIFSI;
+ mode.scale = SCALE_4CIFSI;
else
- fh->mode.scale = SCALE_4CIFS;
+ mode.scale = SCALE_4CIFS;
} else
- fh->mode.scale = SCALE_2CIFS;
+ mode.scale = SCALE_2CIFS;
} else {
- fh->mode.scale = SCALE_1CIFS;
+ mode.scale = SCALE_1CIFS;
}
-
/* color mode */
- switch (fh->fmt->fourcc) {
+ switch (channel->fmt->fourcc) {
case V4L2_PIX_FMT_GREY:
- fh->mode.color &= ~MASK_COLOR;
- fh->mode.color |= COLOR_Y8;
+ mode.color &= ~MASK_COLOR;
+ mode.color |= COLOR_Y8;
break;
case V4L2_PIX_FMT_JPEG:
- fh->mode.color &= ~MASK_COLOR;
- fh->mode.color |= COLOR_JPG;
- fh->mode.color |= (fh->dev->jc[fh->channel].quality << 8);
+ mode.color &= ~MASK_COLOR;
+ mode.color |= COLOR_JPG;
+ mode.color |= (channel->jc.quality << 8);
break;
case V4L2_PIX_FMT_YUV422P:
- fh->mode.color &= ~MASK_COLOR;
- fh->mode.color |= COLOR_YUVPL;
+ mode.color &= ~MASK_COLOR;
+ mode.color |= COLOR_YUVPL;
break;
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_UYVY:
default:
- fh->mode.color &= ~MASK_COLOR;
- fh->mode.color |= COLOR_YUVPK;
+ mode.color &= ~MASK_COLOR;
+ mode.color |= COLOR_YUVPK;
break;
}
+ if ((mode.color & MASK_COLOR) != (channel->mode.color & MASK_COLOR))
+ mode.restart = 1;
+ else if (mode.scale != channel->mode.scale)
+ mode.restart = 1;
+ else if (mode.format != channel->mode.format)
+ mode.restart = 1;
+ channel->mode = mode;
+ (void) s2255_set_mode(channel, &mode);
ret = 0;
out_s_fmt:
mutex_unlock(&q->vb_lock);
@@ -1197,26 +1212,27 @@ static void s2255_print_cfg(struct s2255_dev *sdev, struct s2255_mode *mode)
* When the restart parameter is set, we sleep for ONE frame to allow the
* DSP time to get the new frame
*/
-static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
+static int s2255_set_mode(struct s2255_channel *channel,
struct s2255_mode *mode)
{
int res;
__le32 *buffer;
unsigned long chn_rev;
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
mutex_lock(&dev->lock);
- chn_rev = G_chnmap[chn];
- dprintk(3, "%s channel %lu\n", __func__, chn);
+ chn_rev = G_chnmap[channel->idx];
+ dprintk(3, "%s channel: %d\n", __func__, channel->idx);
/* if JPEG, set the quality */
if ((mode->color & MASK_COLOR) == COLOR_JPG) {
mode->color &= ~MASK_COLOR;
mode->color |= COLOR_JPG;
mode->color &= ~MASK_JPG_QUALITY;
- mode->color |= (dev->jc[chn].quality << 8);
+ mode->color |= (channel->jc.quality << 8);
}
/* save the mode */
- dev->mode[chn] = *mode;
- dev->req_image_size[chn] = get_transfer_size(mode);
- dprintk(1, "%s: reqsize %ld\n", __func__, dev->req_image_size[chn]);
+ channel->mode = *mode;
+ channel->req_image_size = get_transfer_size(mode);
+ dprintk(1, "%s: reqsize %ld\n", __func__, channel->req_image_size);
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
@@ -1227,38 +1243,38 @@ static int s2255_set_mode(struct s2255_dev *dev, unsigned long chn,
buffer[0] = IN_DATA_TOKEN;
buffer[1] = (__le32) cpu_to_le32(chn_rev);
buffer[2] = CMD_SET_MODE;
- memcpy(&buffer[3], &dev->mode[chn], sizeof(struct s2255_mode));
- dev->setmode_ready[chn] = 0;
+ memcpy(&buffer[3], &channel->mode, sizeof(struct s2255_mode));
+ channel->setmode_ready = 0;
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
if (debug)
s2255_print_cfg(dev, mode);
kfree(buffer);
/* wait at least 3 frames before continuing */
if (mode->restart) {
- wait_event_timeout(dev->wait_setmode[chn],
- (dev->setmode_ready[chn] != 0),
+ wait_event_timeout(channel->wait_setmode,
+ (channel->setmode_ready != 0),
msecs_to_jiffies(S2255_SETMODE_TIMEOUT));
- if (dev->setmode_ready[chn] != 1) {
+ if (channel->setmode_ready != 1) {
printk(KERN_DEBUG "s2255: no set mode response\n");
res = -EFAULT;
}
}
/* clear the restart flag */
- dev->mode[chn].restart = 0;
+ channel->mode.restart = 0;
mutex_unlock(&dev->lock);
- dprintk(1, "%s chn %lu, result: %d\n", __func__, chn, res);
+ dprintk(1, "%s chn %d, result: %d\n", __func__, channel->idx, res);
return res;
}
-static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
- u32 *pstatus)
+static int s2255_cmd_status(struct s2255_channel *channel, u32 *pstatus)
{
int res;
__le32 *buffer;
u32 chn_rev;
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
mutex_lock(&dev->lock);
- chn_rev = G_chnmap[chn];
- dprintk(4, "%s chan %lu\n", __func__, chn);
+ chn_rev = G_chnmap[channel->idx];
+ dprintk(4, "%s chan %d\n", __func__, channel->idx);
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
@@ -1270,17 +1286,17 @@ static int s2255_cmd_status(struct s2255_dev *dev, unsigned long chn,
buffer[1] = (__le32) cpu_to_le32(chn_rev);
buffer[2] = CMD_STATUS;
*pstatus = 0;
- dev->vidstatus_ready[chn] = 0;
+ channel->vidstatus_ready = 0;
res = s2255_write_config(dev->udev, (unsigned char *)buffer, 512);
kfree(buffer);
- wait_event_timeout(dev->wait_vidstatus[chn],
- (dev->vidstatus_ready[chn] != 0),
+ wait_event_timeout(channel->wait_vidstatus,
+ (channel->vidstatus_ready != 0),
msecs_to_jiffies(S2255_VIDSTATUS_TIMEOUT));
- if (dev->vidstatus_ready[chn] != 1) {
+ if (channel->vidstatus_ready != 1) {
printk(KERN_DEBUG "s2255: no vidstatus response\n");
res = -EFAULT;
}
- *pstatus = dev->vidstatus[chn];
+ *pstatus = channel->vidstatus;
dprintk(4, "%s, vid status %d\n", __func__, *pstatus);
mutex_unlock(&dev->lock);
return res;
@@ -1291,9 +1307,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
int res;
struct s2255_fh *fh = priv;
struct s2255_dev *dev = fh->dev;
- struct s2255_mode *new_mode;
- struct s2255_mode *old_mode;
- int chn;
+ struct s2255_channel *channel = fh->channel;
int j;
dprintk(4, "%s\n", __func__);
if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
@@ -1305,51 +1319,32 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
return -EINVAL;
}
- if (!res_get(dev, fh)) {
+ if (!res_get(fh)) {
s2255_dev_err(&dev->udev->dev, "stream busy\n");
return -EBUSY;
}
-
- /* send a set mode command everytime with restart.
- in case we switch resolutions or other parameters */
- chn = fh->channel;
- new_mode = &fh->mode;
- old_mode = &fh->dev->mode[chn];
-
- if ((new_mode->color & MASK_COLOR) != (old_mode->color & MASK_COLOR))
- new_mode->restart = 1;
- else if (new_mode->scale != old_mode->scale)
- new_mode->restart = 1;
- else if (new_mode->format != old_mode->format)
- new_mode->restart = 1;
-
- s2255_set_mode(dev, chn, new_mode);
- new_mode->restart = 0;
- *old_mode = *new_mode;
- dev->cur_fmt[chn] = fh->fmt;
- dev->last_frame[chn] = -1;
- dev->bad_payload[chn] = 0;
- dev->cur_frame[chn] = 0;
- dev->frame_count[chn] = 0;
+ channel->last_frame = -1;
+ channel->bad_payload = 0;
+ channel->cur_frame = 0;
+ channel->frame_count = 0;
for (j = 0; j < SYS_FRAMES; j++) {
- dev->buffer[chn].frame[j].ulState = S2255_READ_IDLE;
- dev->buffer[chn].frame[j].cur_size = 0;
+ channel->buffer.frame[j].ulState = S2255_READ_IDLE;
+ channel->buffer.frame[j].cur_size = 0;
}
res = videobuf_streamon(&fh->vb_vidq);
if (res == 0) {
- s2255_start_acquire(dev, chn);
- dev->b_acquire[chn] = 1;
- } else {
- res_free(dev, fh);
- }
+ s2255_start_acquire(channel);
+ channel->b_acquire = 1;
+ } else
+ res_free(fh);
+
return res;
}
static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- dprintk(4, "%s\n, channel: %d", __func__, fh->channel);
+ dprintk(4, "%s\n, channel: %d", __func__, fh->channel->idx);
if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
printk(KERN_ERR "invalid fh type0\n");
return -EINVAL;
@@ -1358,16 +1353,16 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
printk(KERN_ERR "invalid type i\n");
return -EINVAL;
}
- s2255_stop_acquire(dev, fh->channel);
+ s2255_stop_acquire(fh->channel);
videobuf_streamoff(&fh->vb_vidq);
- res_free(dev, fh);
+ res_free(fh);
return 0;
}
static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
{
struct s2255_fh *fh = priv;
- struct s2255_mode *mode;
+ struct s2255_mode mode;
struct videobuf_queue *q = &fh->vb_vidq;
int ret = 0;
mutex_lock(&q->vb_lock);
@@ -1376,29 +1371,32 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
ret = -EBUSY;
goto out_s_std;
}
- if (res_locked(fh->dev, fh)) {
+ if (res_locked(fh)) {
dprintk(1, "can't change standard after started\n");
ret = -EBUSY;
goto out_s_std;
}
- mode = &fh->mode;
+ mode = fh->channel->mode;
if (*i & V4L2_STD_NTSC) {
dprintk(4, "%s NTSC\n", __func__);
/* if changing format, reset frame decimation/intervals */
- if (mode->format != FORMAT_NTSC) {
- mode->format = FORMAT_NTSC;
- mode->fdec = FDEC_1;
+ if (mode.format != FORMAT_NTSC) {
+ mode.restart = 1;
+ mode.format = FORMAT_NTSC;
+ mode.fdec = FDEC_1;
}
} else if (*i & V4L2_STD_PAL) {
dprintk(4, "%s PAL\n", __func__);
- mode->format = FORMAT_PAL;
- if (mode->format != FORMAT_PAL) {
- mode->format = FORMAT_PAL;
- mode->fdec = FDEC_1;
+ if (mode.format != FORMAT_PAL) {
+ mode.restart = 1;
+ mode.format = FORMAT_PAL;
+ mode.fdec = FDEC_1;
}
} else {
ret = -EINVAL;
}
+ if (mode.restart)
+ s2255_set_mode(fh->channel, &mode);
out_s_std:
mutex_unlock(&q->vb_lock);
return ret;
@@ -1416,6 +1414,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
{
struct s2255_fh *fh = priv;
struct s2255_dev *dev = fh->dev;
+ struct s2255_channel *channel = fh->channel;
u32 status = 0;
if (inp->index != 0)
return -EINVAL;
@@ -1424,7 +1423,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
inp->status = 0;
if (dev->dsp_fw_ver >= S2255_MIN_DSP_STATUS) {
int rc;
- rc = s2255_cmd_status(dev, fh->channel, &status);
+ rc = s2255_cmd_status(fh->channel, &status);
dprintk(4, "s2255_cmd_status rc: %d status %x\n", rc, status);
if (rc == 0)
inp->status = (status & 0x01) ? 0
@@ -1436,7 +1435,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
strlcpy(inp->name, "Composite", sizeof(inp->name));
break;
case 0x2257:
- strlcpy(inp->name, (fh->channel < 2) ? "Composite" : "S-Video",
+ strlcpy(inp->name, (channel->idx < 2) ? "Composite" : "S-Video",
sizeof(inp->name));
break;
}
@@ -1460,6 +1459,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
struct s2255_fh *fh = priv;
+ struct s2255_channel *channel = fh->channel;
struct s2255_dev *dev = fh->dev;
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
@@ -1477,7 +1477,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
case V4L2_CID_PRIVATE_COLORFILTER:
if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
return -EINVAL;
- if ((dev->pid == 0x2257) && (fh->channel > 1))
+ if ((dev->pid == 0x2257) && (channel->idx > 1))
return -EINVAL;
strlcpy(qc->name, "Color Filter", sizeof(qc->name));
qc->type = V4L2_CTRL_TYPE_MENU;
@@ -1499,25 +1499,26 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
{
struct s2255_fh *fh = priv;
struct s2255_dev *dev = fh->dev;
+ struct s2255_channel *channel = fh->channel;
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- ctrl->value = fh->mode.bright;
+ ctrl->value = channel->mode.bright;
break;
case V4L2_CID_CONTRAST:
- ctrl->value = fh->mode.contrast;
+ ctrl->value = channel->mode.contrast;
break;
case V4L2_CID_SATURATION:
- ctrl->value = fh->mode.saturation;
+ ctrl->value = channel->mode.saturation;
break;
case V4L2_CID_HUE:
- ctrl->value = fh->mode.hue;
+ ctrl->value = channel->mode.hue;
break;
case V4L2_CID_PRIVATE_COLORFILTER:
if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
return -EINVAL;
- if ((dev->pid == 0x2257) && (fh->channel > 1))
+ if ((dev->pid == 0x2257) && (channel->idx > 1))
return -EINVAL;
- ctrl->value = !((fh->mode.color & MASK_INPUT_TYPE) >> 16);
+ ctrl->value = !((channel->mode.color & MASK_INPUT_TYPE) >> 16);
break;
default:
return -EINVAL;
@@ -1530,41 +1531,42 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- struct s2255_mode *mode;
- mode = &fh->mode;
+ struct s2255_channel *channel = fh->channel;
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
+ struct s2255_mode mode;
+ mode = channel->mode;
dprintk(4, "%s\n", __func__);
/* update the mode to the corresponding value */
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- mode->bright = ctrl->value;
+ mode.bright = ctrl->value;
break;
case V4L2_CID_CONTRAST:
- mode->contrast = ctrl->value;
+ mode.contrast = ctrl->value;
break;
case V4L2_CID_HUE:
- mode->hue = ctrl->value;
+ mode.hue = ctrl->value;
break;
case V4L2_CID_SATURATION:
- mode->saturation = ctrl->value;
+ mode.saturation = ctrl->value;
break;
case V4L2_CID_PRIVATE_COLORFILTER:
if (dev->dsp_fw_ver < S2255_MIN_DSP_COLORFILTER)
return -EINVAL;
- if ((dev->pid == 0x2257) && (fh->channel > 1))
+ if ((dev->pid == 0x2257) && (channel->idx > 1))
return -EINVAL;
- mode->color &= ~MASK_INPUT_TYPE;
- mode->color |= ((ctrl->value ? 0 : 1) << 16);
+ mode.color &= ~MASK_INPUT_TYPE;
+ mode.color |= ((ctrl->value ? 0 : 1) << 16);
break;
default:
return -EINVAL;
}
- mode->restart = 0;
+ mode.restart = 0;
/* set mode here. Note: stream does not need restarted.
some V4L programs restart stream unnecessarily
after a s_crtl.
*/
- s2255_set_mode(dev, fh->channel, mode);
+ s2255_set_mode(fh->channel, &mode);
return 0;
}
@@ -1572,8 +1574,8 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
struct v4l2_jpegcompression *jc)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
- *jc = dev->jc[fh->channel];
+ struct s2255_channel *channel = fh->channel;
+ *jc = channel->jc;
dprintk(2, "%s: quality %d\n", __func__, jc->quality);
return 0;
}
@@ -1582,10 +1584,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
struct v4l2_jpegcompression *jc)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
+ struct s2255_channel *channel = fh->channel;
if (jc->quality < 0 || jc->quality > 100)
return -EINVAL;
- dev->jc[fh->channel].quality = jc->quality;
+ channel->jc.quality = jc->quality;
dprintk(2, "%s: quality %d\n", __func__, jc->quality);
return 0;
}
@@ -1594,17 +1596,17 @@ static int vidioc_g_parm(struct file *file, void *priv,
struct v4l2_streamparm *sp)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
__u32 def_num, def_dem;
+ struct s2255_channel *channel = fh->channel;
if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
memset(sp, 0, sizeof(struct v4l2_streamparm));
sp->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
- def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
- def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
+ sp->parm.capture.capturemode = channel->cap_parm.capturemode;
+ def_num = (channel->mode.format == FORMAT_NTSC) ? 1001 : 1000;
+ def_dem = (channel->mode.format == FORMAT_NTSC) ? 30000 : 25000;
sp->parm.capture.timeperframe.denominator = def_dem;
- switch (fh->mode.fdec) {
+ switch (channel->mode.fdec) {
default:
case FDEC_1:
sp->parm.capture.timeperframe.numerator = def_num;
@@ -1630,17 +1632,19 @@ static int vidioc_s_parm(struct file *file, void *priv,
struct v4l2_streamparm *sp)
{
struct s2255_fh *fh = priv;
- struct s2255_dev *dev = fh->dev;
+ struct s2255_channel *channel = fh->channel;
+ struct s2255_mode mode;
int fdec = FDEC_1;
__u32 def_num, def_dem;
if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
+ mode = channel->mode;
/* high quality capture mode requires a stream restart */
- if (dev->cap_parm[fh->channel].capturemode
- != sp->parm.capture.capturemode && res_locked(fh->dev, fh))
+ if (channel->cap_parm.capturemode
+ != sp->parm.capture.capturemode && res_locked(fh))
return -EBUSY;
- def_num = (fh->mode.format == FORMAT_NTSC) ? 1001 : 1000;
- def_dem = (fh->mode.format == FORMAT_NTSC) ? 30000 : 25000;
+ def_num = (mode.format == FORMAT_NTSC) ? 1001 : 1000;
+ def_dem = (mode.format == FORMAT_NTSC) ? 30000 : 25000;
if (def_dem != sp->parm.capture.timeperframe.denominator)
sp->parm.capture.timeperframe.numerator = def_num;
else if (sp->parm.capture.timeperframe.numerator <= def_num)
@@ -1655,9 +1659,9 @@ static int vidioc_s_parm(struct file *file, void *priv,
sp->parm.capture.timeperframe.numerator = def_num * 5;
fdec = FDEC_5;
}
- fh->mode.fdec = fdec;
+ mode.fdec = fdec;
sp->parm.capture.timeperframe.denominator = def_dem;
- s2255_set_mode(dev, fh->channel, &fh->mode);
+ s2255_set_mode(channel, &mode);
dprintk(4, "%s capture mode, %d timeperframe %d/%d, fdec %d\n",
__func__,
sp->parm.capture.capturemode,
@@ -1707,24 +1711,13 @@ static int vidioc_enum_frameintervals(struct file *file, void *priv,
static int s2255_open(struct file *file)
{
struct video_device *vdev = video_devdata(file);
- struct s2255_dev *dev = video_drvdata(file);
+ struct s2255_channel *channel = video_drvdata(file);
+ struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
struct s2255_fh *fh;
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- int i = 0;
- int cur_channel = -1;
int state;
dprintk(1, "s2255: open called (dev=%s)\n",
video_device_node_name(vdev));
-
- for (i = 0; i < MAX_CHANNELS; i++) {
- if (&dev->vdev[i] == vdev) {
- cur_channel = i;
- break;
- }
- }
- if (i == MAX_CHANNELS)
- return -ENODEV;
-
/*
* open lock necessary to prevent multiple instances
* of v4l-conf (or other programs) from simultaneously
@@ -1806,24 +1799,20 @@ static int s2255_open(struct file *file)
file->private_data = fh;
fh->dev = dev;
fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fh->mode = dev->mode[cur_channel];
- fh->fmt = dev->cur_fmt[cur_channel];
- /* default 4CIF NTSC */
- fh->width = LINE_SZ_4CIFS_NTSC;
- fh->height = NUM_LINES_4CIFS_NTSC * 2;
- fh->channel = cur_channel;
- /* configure channel to default state */
- if (!dev->chn_configured[cur_channel]) {
- s2255_set_mode(dev, cur_channel, &fh->mode);
- dev->chn_configured[cur_channel] = 1;
+ fh->channel = channel;
+ if (!channel->configured) {
+ /* configure channel to default state */
+ channel->fmt = &formats[0];
+ s2255_set_mode(channel, &channel->mode);
+ channel->configured = 1;
}
dprintk(1, "%s: dev=%s type=%s\n", __func__,
video_device_node_name(vdev), v4l2_type_names[type]);
dprintk(2, "%s: fh=0x%08lx, dev=0x%08lx, vidq=0x%08lx\n", __func__,
(unsigned long)fh, (unsigned long)dev,
- (unsigned long)&dev->vidq[cur_channel]);
+ (unsigned long)&channel->vidq);
dprintk(4, "%s: list_empty active=%d\n", __func__,
- list_empty(&dev->vidq[cur_channel].active));
+ list_empty(&channel->vidq.active));
videobuf_queue_vmalloc_init(&fh->vb_vidq, &s2255_video_qops,
NULL, &dev->slock,
fh->type,
@@ -1865,6 +1854,7 @@ static void s2255_destroy(struct s2255_dev *dev)
mutex_destroy(&dev->open_lock);
mutex_destroy(&dev->lock);
usb_put_dev(dev->udev);
+ v4l2_device_unregister(&dev->v4l2_dev);
dprintk(1, "%s", __func__);
kfree(dev);
}
@@ -1874,14 +1864,15 @@ static int s2255_release(struct file *file)
struct s2255_fh *fh = file->private_data;
struct s2255_dev *dev = fh->dev;
struct video_device *vdev = video_devdata(file);
+ struct s2255_channel *channel = fh->channel;
if (!dev)
return -ENODEV;
/* turn off stream */
if (res_check(fh)) {
- if (dev->b_acquire[fh->channel])
- s2255_stop_acquire(dev, fh->channel);
+ if (channel->b_acquire)
+ s2255_stop_acquire(fh->channel);
videobuf_streamoff(&fh->vb_vidq);
- res_free(dev, fh);
+ res_free(fh);
}
videobuf_mmap_free(&fh->vb_vidq);
dprintk(1, "%s (dev=%s)\n", __func__, video_device_node_name(vdev));
@@ -1945,9 +1936,10 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
static void s2255_video_device_release(struct video_device *vdev)
{
- struct s2255_dev *dev = video_get_drvdata(vdev);
- dprintk(4, "%s, chnls: %d \n", __func__, atomic_read(&dev->channels));
- if (atomic_dec_and_test(&dev->channels))
+ struct s2255_dev *dev = to_s2255_dev(vdev->v4l2_dev);
+ dprintk(4, "%s, chnls: %d \n", __func__,
+ atomic_read(&dev->num_channels));
+ if (atomic_dec_and_test(&dev->num_channels))
s2255_destroy(dev);
return;
}
@@ -1966,47 +1958,48 @@ static int s2255_probe_v4l(struct s2255_dev *dev)
int ret;
int i;
int cur_nr = video_nr;
+ struct s2255_channel *channel;
ret = v4l2_device_register(&dev->interface->dev, &dev->v4l2_dev);
if (ret)
return ret;
/* initialize all video 4 linux */
/* register 4 video devices */
for (i = 0; i < MAX_CHANNELS; i++) {
- INIT_LIST_HEAD(&dev->vidq[i].active);
- dev->vidq[i].dev = dev;
- dev->vidq[i].channel = i;
+ channel = &dev->channel[i];
+ INIT_LIST_HEAD(&channel->vidq.active);
+ channel->vidq.dev = dev;
/* register 4 video devices */
- memcpy(&dev->vdev[i], &template, sizeof(struct video_device));
- dev->vdev[i].v4l2_dev = &dev->v4l2_dev;
- video_set_drvdata(&dev->vdev[i], dev);
+ channel->vdev = template;
+ channel->vdev.v4l2_dev = &dev->v4l2_dev;
+ video_set_drvdata(&channel->vdev, channel);
if (video_nr == -1)
- ret = video_register_device(&dev->vdev[i],
+ ret = video_register_device(&channel->vdev,
VFL_TYPE_GRABBER,
video_nr);
else
- ret = video_register_device(&dev->vdev[i],
+ ret = video_register_device(&channel->vdev,
VFL_TYPE_GRABBER,
cur_nr + i);
+
if (ret) {
dev_err(&dev->udev->dev,
"failed to register video device!\n");
break;
}
- atomic_inc(&dev->channels);
+ atomic_inc(&dev->num_channels);
v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
- video_device_node_name(&dev->vdev[i]));
+ video_device_node_name(&channel->vdev));
}
-
printk(KERN_INFO "Sensoray 2255 V4L driver Revision: %d.%d\n",
S2255_MAJOR_VERSION,
S2255_MINOR_VERSION);
/* if no channels registered, return error and probe will fail*/
- if (atomic_read(&dev->channels) == 0) {
+ if (atomic_read(&dev->num_channels) == 0) {
v4l2_device_unregister(&dev->v4l2_dev);
return ret;
}
- if (atomic_read(&dev->channels) != MAX_CHANNELS)
+ if (atomic_read(&dev->num_channels) != MAX_CHANNELS)
printk(KERN_WARNING "s2255: Not all channels available.\n");
return 0;
}
@@ -2033,12 +2026,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
s32 idx = -1;
struct s2255_framei *frm;
unsigned char *pdata;
-
+ struct s2255_channel *channel;
dprintk(100, "buffer to user\n");
-
- idx = dev->cur_frame[dev->cc];
- frm = &dev->buffer[dev->cc].frame[idx];
-
+ channel = &dev->channel[dev->cc];
+ idx = channel->cur_frame;
+ frm = &channel->buffer.frame[idx];
if (frm->ulState == S2255_READ_IDLE) {
int jj;
unsigned int cc;
@@ -2063,16 +2055,18 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
}
/* reverse it */
dev->cc = G_chnmap[cc];
+ channel = &dev->channel[dev->cc];
payload = pdword[3];
- if (payload > dev->req_image_size[dev->cc]) {
- dev->bad_payload[dev->cc]++;
+ if (payload > channel->req_image_size) {
+ channel->bad_payload++;
/* discard the bad frame */
return -EINVAL;
}
- dev->pkt_size[dev->cc] = payload;
- dev->jpg_size[dev->cc] = pdword[4];
+ channel->pkt_size = payload;
+ channel->jpg_size = pdword[4];
break;
case S2255_MARKER_RESPONSE:
+
pdata += DEF_USB_BLOCK;
jj += DEF_USB_BLOCK;
if (pdword[1] >= MAX_CHANNELS)
@@ -2080,12 +2074,13 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
cc = G_chnmap[pdword[1]];
if (cc >= MAX_CHANNELS)
break;
+ channel = &dev->channel[cc];
switch (pdword[2]) {
case S2255_RESPONSE_SETMODE:
/* check if channel valid */
/* set mode ready */
- dev->setmode_ready[cc] = 1;
- wake_up(&dev->wait_setmode[cc]);
+ channel->setmode_ready = 1;
+ wake_up(&channel->wait_setmode);
dprintk(5, "setmode ready %d\n", cc);
break;
case S2255_RESPONSE_FW:
@@ -2099,9 +2094,9 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
wake_up(&dev->fw_data->wait_fw);
break;
case S2255_RESPONSE_STATUS:
- dev->vidstatus[cc] = pdword[3];
- dev->vidstatus_ready[cc] = 1;
- wake_up(&dev->wait_vidstatus[cc]);
+ channel->vidstatus = pdword[3];
+ channel->vidstatus_ready = 1;
+ wake_up(&channel->wait_vidstatus);
dprintk(5, "got vidstatus %x chan %d\n",
pdword[3], cc);
break;
@@ -2118,13 +2113,11 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
if (!bframe)
return -EINVAL;
}
-
-
- idx = dev->cur_frame[dev->cc];
- frm = &dev->buffer[dev->cc].frame[idx];
-
+ channel = &dev->channel[dev->cc];
+ idx = channel->cur_frame;
+ frm = &channel->buffer.frame[idx];
/* search done. now find out if should be acquiring on this channel */
- if (!dev->b_acquire[dev->cc]) {
+ if (!channel->b_acquire) {
/* we found a frame, but this channel is turned off */
frm->ulState = S2255_READ_IDLE;
return -EINVAL;
@@ -2149,30 +2142,28 @@ static int save_frame(struct s2255_dev *dev, struct s2255_pipeinfo *pipe_info)
copy_size = (pipe_info->cur_transfer_size - offset);
- size = dev->pkt_size[dev->cc] - PREFIX_SIZE;
+ size = channel->pkt_size - PREFIX_SIZE;
/* sanity check on pdest */
- if ((copy_size + frm->cur_size) < dev->req_image_size[dev->cc])
+ if ((copy_size + frm->cur_size) < channel->req_image_size)
memcpy(pdest, psrc, copy_size);
frm->cur_size += copy_size;
dprintk(4, "cur_size size %lu size %lu \n", frm->cur_size, size);
if (frm->cur_size >= size) {
-
- u32 cc = dev->cc;
dprintk(2, "****************[%d]Buffer[%d]full*************\n",
- cc, idx);
- dev->last_frame[cc] = dev->cur_frame[cc];
- dev->cur_frame[cc]++;
+ dev->cc, idx);
+ channel->last_frame = channel->cur_frame;
+ channel->cur_frame++;
/* end of system frame ring buffer, start at zero */
- if ((dev->cur_frame[cc] == SYS_FRAMES) ||
- (dev->cur_frame[cc] == dev->buffer[cc].dwFrames))
- dev->cur_frame[cc] = 0;
+ if ((channel->cur_frame == SYS_FRAMES) ||
+ (channel->cur_frame == channel->buffer.dwFrames))
+ channel->cur_frame = 0;
/* frame ready */
- if (dev->b_acquire[cc])
- s2255_got_frame(dev, cc, dev->jpg_size[cc]);
- dev->frame_count[cc]++;
+ if (channel->b_acquire)
+ s2255_got_frame(channel, channel->jpg_size);
+ channel->frame_count++;
frm->ulState = S2255_READ_IDLE;
frm->cur_size = 0;
@@ -2245,16 +2236,12 @@ static int s2255_get_fx2fw(struct s2255_dev *dev)
* Create the system ring buffer to copy frames into from the
* usb read pipe.
*/
-static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
+static int s2255_create_sys_buffers(struct s2255_channel *channel)
{
unsigned long i;
unsigned long reqsize;
dprintk(1, "create sys buffers\n");
- if (chn >= MAX_CHANNELS)
- return -1;
-
- dev->buffer[chn].dwFrames = SYS_FRAMES;
-
+ channel->buffer.dwFrames = SYS_FRAMES;
/* always allocate maximum size(PAL) for system buffers */
reqsize = SYS_FRAMES_MAXSIZE;
@@ -2263,42 +2250,40 @@ static int s2255_create_sys_buffers(struct s2255_dev *dev, unsigned long chn)
for (i = 0; i < SYS_FRAMES; i++) {
/* allocate the frames */
- dev->buffer[chn].frame[i].lpvbits = vmalloc(reqsize);
-
- dprintk(1, "valloc %p chan %lu, idx %lu, pdata %p\n",
- &dev->buffer[chn].frame[i], chn, i,
- dev->buffer[chn].frame[i].lpvbits);
- dev->buffer[chn].frame[i].size = reqsize;
- if (dev->buffer[chn].frame[i].lpvbits == NULL) {
+ channel->buffer.frame[i].lpvbits = vmalloc(reqsize);
+ dprintk(1, "valloc %p chan %d, idx %lu, pdata %p\n",
+ &channel->buffer.frame[i], channel->idx, i,
+ channel->buffer.frame[i].lpvbits);
+ channel->buffer.frame[i].size = reqsize;
+ if (channel->buffer.frame[i].lpvbits == NULL) {
printk(KERN_INFO "out of memory. using less frames\n");
- dev->buffer[chn].dwFrames = i;
+ channel->buffer.dwFrames = i;
break;
}
}
/* make sure internal states are set */
for (i = 0; i < SYS_FRAMES; i++) {
- dev->buffer[chn].frame[i].ulState = 0;
- dev->buffer[chn].frame[i].cur_size = 0;
+ channel->buffer.frame[i].ulState = 0;
+ channel->buffer.frame[i].cur_size = 0;
}
- dev->cur_frame[chn] = 0;
- dev->last_frame[chn] = -1;
+ channel->cur_frame = 0;
+ channel->last_frame = -1;
return 0;
}
-static int s2255_release_sys_buffers(struct s2255_dev *dev,
- unsigned long channel)
+static int s2255_release_sys_buffers(struct s2255_channel *channel)
{
unsigned long i;
dprintk(1, "release sys buffers\n");
for (i = 0; i < SYS_FRAMES; i++) {
- if (dev->buffer[channel].frame[i].lpvbits) {
+ if (channel->buffer.frame[i].lpvbits) {
dprintk(1, "vfree %p\n",
- dev->buffer[channel].frame[i].lpvbits);
- vfree(dev->buffer[channel].frame[i].lpvbits);
+ channel->buffer.frame[i].lpvbits);
+ vfree(channel->buffer.frame[i].lpvbits);
}
- dev->buffer[channel].frame[i].lpvbits = NULL;
+ channel->buffer.frame[i].lpvbits = NULL;
}
return 0;
}
@@ -2335,17 +2320,20 @@ static int s2255_board_init(struct s2255_dev *dev)
fw_ver & 0xff);
for (j = 0; j < MAX_CHANNELS; j++) {
- dev->b_acquire[j] = 0;
- dev->mode[j] = mode_def;
+ struct s2255_channel *channel = &dev->channel[j];
+ channel->b_acquire = 0;
+ channel->mode = mode_def;
if (dev->pid == 0x2257 && j > 1)
- dev->mode[j].color |= (1 << 16);
- dev->jc[j].quality = S2255_DEF_JPEG_QUAL;
- dev->cur_fmt[j] = &formats[0];
- dev->mode[j].restart = 1;
- dev->req_image_size[j] = get_transfer_size(&mode_def);
- dev->frame_count[j] = 0;
+ channel->mode.color |= (1 << 16);
+ channel->jc.quality = S2255_DEF_JPEG_QUAL;
+ channel->width = LINE_SZ_4CIFS_NTSC;
+ channel->height = NUM_LINES_4CIFS_NTSC * 2;
+ channel->fmt = &formats[0];
+ channel->mode.restart = 1;
+ channel->req_image_size = get_transfer_size(&mode_def);
+ channel->frame_count = 0;
/* create the system buffers */
- s2255_create_sys_buffers(dev, j);
+ s2255_create_sys_buffers(channel);
}
/* start read pipe */
s2255_start_readpipe(dev);
@@ -2359,14 +2347,12 @@ static int s2255_board_shutdown(struct s2255_dev *dev)
dprintk(1, "%s: dev: %p", __func__, dev);
for (i = 0; i < MAX_CHANNELS; i++) {
- if (dev->b_acquire[i])
- s2255_stop_acquire(dev, i);
+ if (dev->channel[i].b_acquire)
+ s2255_stop_acquire(&dev->channel[i]);
}
-
s2255_stop_readpipe(dev);
-
for (i = 0; i < MAX_CHANNELS; i++)
- s2255_release_sys_buffers(dev, i);
+ s2255_release_sys_buffers(&dev->channel[i]);
/* release transfer buffer */
kfree(dev->pipe.transfer_buffer);
return 0;
@@ -2459,29 +2445,26 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
}
/* starts acquisition process */
-static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
+static int s2255_start_acquire(struct s2255_channel *channel)
{
unsigned char *buffer;
int res;
unsigned long chn_rev;
int j;
- if (chn >= MAX_CHANNELS) {
- dprintk(2, "start acquire failed, bad channel %lu\n", chn);
- return -1;
- }
- chn_rev = G_chnmap[chn];
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
+ chn_rev = G_chnmap[channel->idx];
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
return -ENOMEM;
}
- dev->last_frame[chn] = -1;
- dev->bad_payload[chn] = 0;
- dev->cur_frame[chn] = 0;
+ channel->last_frame = -1;
+ channel->bad_payload = 0;
+ channel->cur_frame = 0;
for (j = 0; j < SYS_FRAMES; j++) {
- dev->buffer[chn].frame[j].ulState = 0;
- dev->buffer[chn].frame[j].cur_size = 0;
+ channel->buffer.frame[j].ulState = 0;
+ channel->buffer.frame[j].cur_size = 0;
}
/* send the start command */
@@ -2492,21 +2475,18 @@ static int s2255_start_acquire(struct s2255_dev *dev, unsigned long chn)
if (res != 0)
dev_err(&dev->udev->dev, "CMD_START error\n");
- dprintk(2, "start acquire exit[%lu] %d \n", chn, res);
+ dprintk(2, "start acquire exit[%d] %d \n", channel->idx, res);
kfree(buffer);
return 0;
}
-static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
+static int s2255_stop_acquire(struct s2255_channel *channel)
{
unsigned char *buffer;
int res;
unsigned long chn_rev;
- if (chn >= MAX_CHANNELS) {
- dprintk(2, "stop acquire failed, bad channel %lu\n", chn);
- return -1;
- }
- chn_rev = G_chnmap[chn];
+ struct s2255_dev *dev = to_s2255_dev(channel->vdev.v4l2_dev);
+ chn_rev = G_chnmap[channel->idx];
buffer = kzalloc(512, GFP_KERNEL);
if (buffer == NULL) {
dev_err(&dev->udev->dev, "out of mem\n");
@@ -2520,8 +2500,8 @@ static int s2255_stop_acquire(struct s2255_dev *dev, unsigned long chn)
if (res != 0)
dev_err(&dev->udev->dev, "CMD_STOP error\n");
kfree(buffer);
- dev->b_acquire[chn] = 0;
- dprintk(4, "%s: chn %lu, res %d\n", __func__, chn, res);
+ channel->b_acquire = 0;
+ dprintk(4, "%s: chn %d, res %d\n", __func__, channel->idx, res);
return res;
}
@@ -2575,7 +2555,7 @@ static int s2255_probe(struct usb_interface *interface,
s2255_dev_err(&interface->dev, "out of memory\n");
return -ENOMEM;
}
- atomic_set(&dev->channels, 0);
+ atomic_set(&dev->num_channels, 0);
dev->pid = id->idProduct;
dev->fw_data = kzalloc(sizeof(struct s2255_fw), GFP_KERNEL);
if (!dev->fw_data)
@@ -2612,8 +2592,10 @@ static int s2255_probe(struct usb_interface *interface,
dev->timer.data = (unsigned long)dev->fw_data;
init_waitqueue_head(&dev->fw_data->wait_fw);
for (i = 0; i < MAX_CHANNELS; i++) {
- init_waitqueue_head(&dev->wait_setmode[i]);
- init_waitqueue_head(&dev->wait_vidstatus[i]);
+ struct s2255_channel *channel = &dev->channel[i];
+ dev->channel[i].idx = i;
+ init_waitqueue_head(&channel->wait_setmode);
+ init_waitqueue_head(&channel->wait_vidstatus);
}
dev->fw_data->fw_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -2651,7 +2633,7 @@ static int s2255_probe(struct usb_interface *interface,
printk(KERN_INFO "s2255: f2255usb.bin out of date.\n");
if (dev->pid == 0x2257 && *pRel < S2255_MIN_DSP_COLORFILTER)
printk(KERN_WARNING "s2255: 2257 requires firmware %d"
- "or above.\n", S2255_MIN_DSP_COLORFILTER);
+ " or above.\n", S2255_MIN_DSP_COLORFILTER);
}
usb_reset_device(dev->udev);
/* load 2255 board specific */
@@ -2693,25 +2675,23 @@ static void s2255_disconnect(struct usb_interface *interface)
{
struct s2255_dev *dev = to_s2255_dev(usb_get_intfdata(interface));
int i;
- int channels = atomic_read(&dev->channels);
- v4l2_device_unregister(&dev->v4l2_dev);
+ int channels = atomic_read(&dev->num_channels);
+ v4l2_device_disconnect(&dev->v4l2_dev);
/*see comments in the uvc_driver.c usb disconnect function */
- atomic_inc(&dev->channels);
+ atomic_inc(&dev->num_channels);
/* unregister each video device. */
- for (i = 0; i < channels; i++) {
- if (video_is_registered(&dev->vdev[i]))
- video_unregister_device(&dev->vdev[i]);
- }
+ for (i = 0; i < channels; i++)
+ video_unregister_device(&dev->channel[i].vdev);
/* wake up any of our timers */
atomic_set(&dev->fw_data->fw_state, S2255_FW_DISCONNECTING);
wake_up(&dev->fw_data->wait_fw);
for (i = 0; i < MAX_CHANNELS; i++) {
- dev->setmode_ready[i] = 1;
- wake_up(&dev->wait_setmode[i]);
- dev->vidstatus_ready[i] = 1;
- wake_up(&dev->wait_vidstatus[i]);
+ dev->channel[i].setmode_ready = 1;
+ wake_up(&dev->channel[i].wait_setmode);
+ dev->channel[i].vidstatus_ready = 1;
+ wake_up(&dev->channel[i].wait_vidstatus);
}
- if (atomic_dec_and_test(&dev->channels))
+ if (atomic_dec_and_test(&dev->num_channels))
s2255_destroy(dev);
dev_info(&interface->dev, "%s\n", __func__);
}
diff --git a/drivers/media/video/saa7134/saa7134-alsa.c b/drivers/media/video/saa7134/saa7134-alsa.c
index d3bd82ad010a..68b7e8d10ded 100644
--- a/drivers/media/video/saa7134/saa7134-alsa.c
+++ b/drivers/media/video/saa7134/saa7134-alsa.c
@@ -630,7 +630,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
/* release the old buffer */
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}
@@ -646,12 +646,12 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
return err;
}
- if (0 != (err = videobuf_sg_dma_map(&dev->pci->dev, &dev->dmasound.dma))) {
+ if (0 != (err = videobuf_dma_map(&dev->pci->dev, &dev->dmasound.dma))) {
dsp_buffer_free(dev);
return err;
}
if (0 != (err = saa7134_pgtable_alloc(dev->pci,&dev->dmasound.pt))) {
- videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
dsp_buffer_free(dev);
return err;
}
@@ -660,7 +660,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
dev->dmasound.dma.sglen,
0))) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
dsp_buffer_free(dev);
return err;
}
@@ -669,7 +669,7 @@ static int snd_card_saa7134_hw_params(struct snd_pcm_substream * substream,
byte, but it doesn't work. So I allocate the DMA using the
V4L functions, and force ALSA to use that as the DMA area */
- substream->runtime->dma_area = dev->dmasound.dma.vmalloc;
+ substream->runtime->dma_area = dev->dmasound.dma.vaddr;
substream->runtime->dma_bytes = dev->dmasound.bufsize;
substream->runtime->dma_addr = 0;
@@ -696,7 +696,7 @@ static int snd_card_saa7134_hw_free(struct snd_pcm_substream * substream)
if (substream->runtime->dma_area) {
saa7134_pgtable_free(dev->pci, &dev->dmasound.pt);
- videobuf_sg_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
+ videobuf_dma_unmap(&dev->pci->dev, &dev->dmasound.dma);
dsp_buffer_free(dev);
substream->runtime->dma_area = NULL;
}
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 07f6bb8ef9d9..ec697fcd406e 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -5462,6 +5462,30 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
},
},
+ [SAA7134_BOARD_TECHNOTREND_BUDGET_T3000] = {
+ .name = "TechoTrend TT-budget T-3000",
+ .tuner_type = TUNER_PHILIPS_TD1316,
+ .audio_clock = 0x00187de7,
+ .radio_type = UNSET,
+ .tuner_addr = 0x63,
+ .radio_addr = ADDR_UNSET,
+ .tda9887_conf = TDA9887_PRESENT | TDA9887_PORT1_ACTIVE,
+ .mpeg = SAA7134_MPEG_DVB,
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 3,
+ .amux = TV,
+ .tv = 1,
+ }, {
+ .name = name_comp1,
+ .vmux = 0,
+ .amux = LINE2,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE2,
+ } },
+ },
};
@@ -6631,6 +6655,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
.subdevice = 0x6655,
.driver_data = SAA7134_BOARD_LEADTEK_WINFAST_DTV1000S,
}, {
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x13c2,
+ .subdevice = 0x2804,
+ .driver_data = SAA7134_BOARD_TECHNOTREND_BUDGET_T3000,
+ }, {
/* --- boards without eeprom + subsystem ID --- */
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -7320,6 +7350,7 @@ int saa7134_board_init2(struct saa7134_dev *dev)
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
case SAA7134_BOARD_ASUS_EUROPA_HYBRID:
+ case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
{
/* The Philips EUROPA based hybrid boards have the tuner
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 90f231881297..40bc635e8a3f 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -256,7 +256,7 @@ void saa7134_dma_free(struct videobuf_queue *q,struct saa7134_buf *buf)
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb,0,0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 31e82be1b7e7..f26fe7661a1d 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -481,6 +481,17 @@ static struct tda1004x_config medion_cardbus = {
.request_firmware = philips_tda1004x_request_firmware
};
+static struct tda1004x_config technotrend_budget_t3000_config = {
+ .demod_address = 0x8,
+ .invert = 1,
+ .invert_oclk = 0,
+ .xtal_freq = TDA10046_XTAL_4M,
+ .agc_config = TDA10046_AGC_DEFAULT,
+ .if_freq = TDA10046_FREQ_3617,
+ .tuner_address = 0x63,
+ .request_firmware = philips_tda1004x_request_firmware
+};
+
/* ------------------------------------------------------------------
* tda 1004x based cards with philips silicon tuner
*/
@@ -1168,6 +1179,18 @@ static int dvb_init(struct saa7134_dev *dev)
fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
}
break;
+ case SAA7134_BOARD_TECHNOTREND_BUDGET_T3000:
+ fe0->dvb.frontend = dvb_attach(tda10046_attach,
+ &technotrend_budget_t3000_config,
+ &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ dev->original_demod_sleep = fe0->dvb.frontend->ops.sleep;
+ fe0->dvb.frontend->ops.sleep = philips_europa_demod_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.init = philips_europa_tuner_init;
+ fe0->dvb.frontend->ops.tuner_ops.sleep = philips_europa_tuner_sleep;
+ fe0->dvb.frontend->ops.tuner_ops.set_params = philips_td1316_tuner_set_params;
+ }
+ break;
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
fe0->dvb.frontend = dvb_attach(tda10046_attach,
&philips_tu1216_61_config,
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 756a1ca8833d..c040a1808542 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -304,6 +304,7 @@ struct saa7134_format {
#define SAA7134_BOARD_BEHOLD_H7 178
#define SAA7134_BOARD_BEHOLD_A7 179
#define SAA7134_BOARD_AVERMEDIA_M733A 180
+#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/stv680.c b/drivers/media/video/stv680.c
deleted file mode 100644
index 5938ad8702ef..000000000000
--- a/drivers/media/video/stv680.c
+++ /dev/null
@@ -1,1565 +0,0 @@
-/*
- * STV0680 USB Camera Driver, by Kevin Sisson (kjsisson@bellsouth.net)
- *
- * Thanks to STMicroelectronics for information on the usb commands, and
- * to Steve Miller at STM for his help and encouragement while I was
- * writing this driver.
- *
- * This driver is based heavily on the
- * Endpoints (formerly known as AOX) se401 USB Camera Driver
- * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
- *
- * Still somewhat based on the Linux ov511 driver.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * History:
- * ver 0.1 October, 2001. Initial attempt.
- *
- * ver 0.2 November, 2001. Fixed asbility to resize, added brightness
- * function, made more stable (?)
- *
- * ver 0.21 Nov, 2001. Added gamma correction and white balance,
- * due to Alexander Schwartz. Still trying to
- * improve stablility. Moved stuff into stv680.h
- *
- * ver 0.22 Nov, 2001. Added sharpen function (by Michael Sweet,
- * mike@easysw.com) from GIMP, also used in pencam.
- * Simple, fast, good integer math routine.
- *
- * ver 0.23 Dec, 2001 (gkh)
- * Took out sharpen function, ran code through
- * Lindent, and did other minor tweaks to get
- * things to work properly with 2.5.1
- *
- * ver 0.24 Jan, 2002 (kjs)
- * Fixed the problem with webcam crashing after
- * two pictures. Changed the way pic is halved to
- * improve quality. Got rid of green line around
- * frame. Fix brightness reset when changing size
- * bug. Adjusted gamma filters slightly.
- *
- * ver 0.25 Jan, 2002 (kjs)
- * Fixed a bug in which the driver sometimes attempted
- * to set to a non-supported size. This allowed
- * gnomemeeting to work.
- * Fixed proc entry removal bug.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/smp_lock.h>
-#include <linux/pagemap.h>
-#include <linux/errno.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/usb.h>
-#include <linux/mutex.h>
-
-#include "stv680.h"
-
-static int video_nr = -1;
-
-static int swapRGB; /* 0 = default for auto select */
-
-/* 0 = default to allow auto select; -1 = swap never, +1 = swap always */
-static int swapRGB_on;
-
-static unsigned int debug;
-
-#define PDEBUG(level, fmt, args...) \
- do { \
- if (debug >= level) \
- printk(KERN_INFO KBUILD_MODNAME " [%s:%d] \n" fmt, \
- __func__, __LINE__ , ## args); \
- } while (0)
-
-
-/*
- * Version Information
- */
-#define DRIVER_VERSION "v0.25"
-#define DRIVER_AUTHOR "Kevin Sisson <kjsisson@bellsouth.net>"
-#define DRIVER_DESC "STV0680 USB Camera Driver"
-
-MODULE_AUTHOR (DRIVER_AUTHOR);
-MODULE_DESCRIPTION (DRIVER_DESC);
-MODULE_LICENSE ("GPL");
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC (debug, "Debug enabled or not");
-module_param(swapRGB_on, int, 0);
-MODULE_PARM_DESC (swapRGB_on, "Red/blue swap: 1=always, 0=auto, -1=never");
-module_param(video_nr, int, 0);
-
-/********************************************************************
- *
- * Memory management
- *
- * This is a shameless copy from the USB-cpia driver (linux kernel
- * version 2.3.29 or so, I have no idea what this code actually does ;).
- * Actually it seems to be a copy of a shameless copy of the bttv-driver.
- * Or that is a copy of a shameless copy of ... (To the powers: is there
- * no generic kernel-function to do this sort of stuff?)
- *
- * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
- * there will be one, but apparentely not yet -jerdfelt
- *
- * So I copied it again for the ov511 driver -claudio
- *
- * Same for the se401 driver -Jeroen
- *
- * And the STV0680 driver - Kevin
- ********************************************************************/
-static void *rvmalloc (unsigned long size)
-{
- void *mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32 (size);
- if (!mem)
- return NULL;
-
- memset (mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- return mem;
-}
-
-static void rvfree (void *mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree (mem);
-}
-
-
-/*********************************************************************
- * pencam read/write functions
- ********************************************************************/
-
-static int stv_sndctrl (int set, struct usb_stv *stv680, unsigned short req, unsigned short value, unsigned char *buffer, int size)
-{
- int ret = -1;
-
- switch (set) {
- case 0: /* 0xc1 */
- ret = usb_control_msg (stv680->udev,
- usb_rcvctrlpipe (stv680->udev, 0),
- req,
- (USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
- value, 0, buffer, size, PENCAM_TIMEOUT);
- break;
-
- case 1: /* 0x41 */
- ret = usb_control_msg (stv680->udev,
- usb_sndctrlpipe (stv680->udev, 0),
- req,
- (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT),
- value, 0, buffer, size, PENCAM_TIMEOUT);
- break;
-
- case 2: /* 0x80 */
- ret = usb_control_msg (stv680->udev,
- usb_rcvctrlpipe (stv680->udev, 0),
- req,
- (USB_DIR_IN | USB_RECIP_DEVICE),
- value, 0, buffer, size, PENCAM_TIMEOUT);
- break;
-
- case 3: /* 0x40 */
- ret = usb_control_msg (stv680->udev,
- usb_sndctrlpipe (stv680->udev, 0),
- req,
- (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE),
- value, 0, buffer, size, PENCAM_TIMEOUT);
- break;
-
- }
- if ((ret < 0) && (req != 0x0a)) {
- PDEBUG (1, "STV(e): usb_control_msg error %i, request = 0x%x, error = %i", set, req, ret);
- }
- return ret;
-}
-
-static int stv_set_config (struct usb_stv *dev, int configuration, int interface, int alternate)
-{
-
- if (configuration != dev->udev->actconfig->desc.bConfigurationValue
- || usb_reset_configuration (dev->udev) < 0) {
- PDEBUG (1, "STV(e): FAILED to reset configuration %i", configuration);
- return -1;
- }
- if (usb_set_interface (dev->udev, interface, alternate) < 0) {
- PDEBUG (1, "STV(e): FAILED to set alternate interface %i", alternate);
- return -1;
- }
- return 0;
-}
-
-static int stv_stop_video (struct usb_stv *dev)
-{
- int i;
- unsigned char *buf;
-
- buf = kmalloc (40, GFP_KERNEL);
- if (buf == NULL) {
- PDEBUG (0, "STV(e): Out of (small buf) memory");
- return -1;
- }
-
- /* this is a high priority command; it stops all lower order commands */
- if ((i = stv_sndctrl (1, dev, 0x04, 0x0000, buf, 0x0)) < 0) {
- i = stv_sndctrl (0, dev, 0x80, 0, buf, 0x02); /* Get Last Error; 2 = busy */
- PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buf[0], buf[1]);
- } else {
- PDEBUG (1, "STV(i): Camera reset to idle mode.");
- }
-
- if ((i = stv_set_config (dev, 1, 0, 0)) < 0)
- PDEBUG (1, "STV(e): Reset config during exit failed");
-
- /* get current mode */
- buf[0] = 0xf0;
- if ((i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08)) != 0x08) /* get mode */
- PDEBUG (0, "STV(e): Stop_video: problem setting original mode");
- if (dev->origMode != buf[0]) {
- memset (buf, 0, 8);
- buf[0] = (unsigned char) dev->origMode;
- if ((i = stv_sndctrl (3, dev, 0x07, 0x0100, buf, 0x08)) != 0x08) {
- PDEBUG (0, "STV(e): Stop_video: Set_Camera_Mode failed");
- i = -1;
- }
- buf[0] = 0xf0;
- i = stv_sndctrl (0, dev, 0x87, 0, buf, 0x08);
- if ((i != 0x08) || (buf[0] != dev->origMode)) {
- PDEBUG (0, "STV(e): camera NOT set to original resolution.");
- i = -1;
- } else
- PDEBUG (0, "STV(i): Camera set to original resolution");
- }
- /* origMode */
- kfree(buf);
- return i;
-}
-
-static int stv_set_video_mode (struct usb_stv *dev)
-{
- int i, stop_video = 1;
- unsigned char *buf;
-
- buf = kmalloc (40, GFP_KERNEL);
- if (buf == NULL) {
- PDEBUG (0, "STV(e): Out of (small buf) memory");
- return -1;
- }
-
- if ((i = stv_set_config (dev, 1, 0, 0)) < 0) {
- kfree(buf);
- return i;
- }
-
- i = stv_sndctrl (2, dev, 0x06, 0x0100, buf, 0x12);
- if (!(i > 0) && (buf[8] == 0x53) && (buf[9] == 0x05)) {
- PDEBUG (1, "STV(e): Could not get descriptor 0100.");
- goto error;
- }
-
- /* set alternate interface 1 */
- if ((i = stv_set_config (dev, 1, 0, 1)) < 0)
- goto error;
-
- if ((i = stv_sndctrl (0, dev, 0x85, 0, buf, 0x10)) != 0x10)
- goto error;
- PDEBUG (1, "STV(i): Setting video mode.");
- /* Switch to Video mode: 0x0100 = VGA (640x480), 0x0000 = CIF (352x288) 0x0300 = QVGA (320x240) */
- if ((i = stv_sndctrl (1, dev, 0x09, dev->VideoMode, buf, 0x0)) < 0) {
- stop_video = 0;
- goto error;
- }
- goto exit;
-
-error:
- kfree(buf);
- if (stop_video == 1)
- stv_stop_video (dev);
- return -1;
-
-exit:
- kfree(buf);
- return 0;
-}
-
-static int stv_init (struct usb_stv *stv680)
-{
- int i = 0;
- unsigned char *buffer;
- unsigned long int bufsize;
-
- buffer = kzalloc (40, GFP_KERNEL);
- if (buffer == NULL) {
- PDEBUG (0, "STV(e): Out of (small buf) memory");
- return -1;
- }
- udelay (100);
-
- /* set config 1, interface 0, alternate 0 */
- if ((i = stv_set_config (stv680, 1, 0, 0)) < 0) {
- kfree(buffer);
- PDEBUG (0, "STV(e): set config 1,0,0 failed");
- return -1;
- }
- /* ping camera to be sure STV0680 is present */
- if ((i = stv_sndctrl (0, stv680, 0x88, 0x5678, buffer, 0x02)) != 0x02)
- goto error;
- if ((buffer[0] != 0x56) || (buffer[1] != 0x78)) {
- PDEBUG (1, "STV(e): camera ping failed!!");
- goto error;
- }
-
- /* get camera descriptor */
- if ((i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x09)) != 0x09)
- goto error;
- i = stv_sndctrl (2, stv680, 0x06, 0x0200, buffer, 0x22);
- if (!(i >= 0) && (buffer[7] == 0xa0) && (buffer[8] == 0x23)) {
- PDEBUG (1, "STV(e): Could not get descriptor 0200.");
- goto error;
- }
- if ((i = stv_sndctrl (0, stv680, 0x8a, 0, buffer, 0x02)) != 0x02)
- goto error;
- if ((i = stv_sndctrl (0, stv680, 0x8b, 0, buffer, 0x24)) != 0x24)
- goto error;
- if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
- goto error;
-
- stv680->SupportedModes = buffer[7];
- i = stv680->SupportedModes;
- stv680->CIF = 0;
- stv680->VGA = 0;
- stv680->QVGA = 0;
- if (i & 1)
- stv680->CIF = 1;
- if (i & 2)
- stv680->VGA = 1;
- if (i & 8)
- stv680->QVGA = 1;
- if (stv680->SupportedModes == 0) {
- PDEBUG (0, "STV(e): There are NO supported STV680 modes!!");
- i = -1;
- goto error;
- } else {
- if (stv680->CIF)
- PDEBUG (0, "STV(i): CIF is supported");
- if (stv680->QVGA)
- PDEBUG (0, "STV(i): QVGA is supported");
- }
- /* FW rev, ASIC rev, sensor ID */
- PDEBUG (1, "STV(i): Firmware rev is %i.%i", buffer[0], buffer[1]);
- PDEBUG (1, "STV(i): ASIC rev is %i.%i", buffer[2], buffer[3]);
- PDEBUG (1, "STV(i): Sensor ID is %i", (buffer[4]*16) + (buffer[5]>>4));
-
- /* set alternate interface 1 */
- if ((i = stv_set_config (stv680, 1, 0, 1)) < 0)
- goto error;
-
- if ((i = stv_sndctrl (0, stv680, 0x85, 0, buffer, 0x10)) != 0x10)
- goto error;
- if ((i = stv_sndctrl (0, stv680, 0x8d, 0, buffer, 0x08)) != 0x08)
- goto error;
- i = buffer[3];
- PDEBUG (0, "STV(i): Camera has %i pictures.", i);
-
- /* get current mode */
- if ((i = stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08)) != 0x08)
- goto error;
- stv680->origMode = buffer[0]; /* 01 = VGA, 03 = QVGA, 00 = CIF */
-
- /* This will attemp CIF mode, if supported. If not, set to QVGA */
- memset (buffer, 0, 8);
- if (stv680->CIF)
- buffer[0] = 0x00;
- else if (stv680->QVGA)
- buffer[0] = 0x03;
- if ((i = stv_sndctrl (3, stv680, 0x07, 0x0100, buffer, 0x08)) != 0x08) {
- PDEBUG (0, "STV(i): Set_Camera_Mode failed");
- i = -1;
- goto error;
- }
- buffer[0] = 0xf0;
- stv_sndctrl (0, stv680, 0x87, 0, buffer, 0x08);
- if (((stv680->CIF == 1) && (buffer[0] != 0x00)) || ((stv680->QVGA == 1) && (buffer[0] != 0x03))) {
- PDEBUG (0, "STV(e): Error setting camera video mode!");
- i = -1;
- goto error;
- } else {
- if (buffer[0] == 0) {
- stv680->VideoMode = 0x0000;
- PDEBUG (0, "STV(i): Video Mode set to CIF");
- }
- if (buffer[0] == 0x03) {
- stv680->VideoMode = 0x0300;
- PDEBUG (0, "STV(i): Video Mode set to QVGA");
- }
- }
- if ((i = stv_sndctrl (0, stv680, 0x8f, 0, buffer, 0x10)) != 0x10)
- goto error;
- bufsize = (buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | (buffer[3]);
- stv680->cwidth = (buffer[4] << 8) | (buffer[5]); /* ->camera = 322, 356, 644 */
- stv680->cheight = (buffer[6] << 8) | (buffer[7]); /* ->camera = 242, 292, 484 */
- stv680->origGain = buffer[12];
-
- goto exit;
-
-error:
- i = stv_sndctrl (0, stv680, 0x80, 0, buffer, 0x02); /* Get Last Error */
- PDEBUG (1, "STV(i): last error: %i, command = 0x%x", buffer[0], buffer[1]);
- kfree(buffer);
- return -1;
-
-exit:
- kfree(buffer);
-
- /* video = 320x240, 352x288 */
- if (stv680->CIF == 1) {
- stv680->maxwidth = 352;
- stv680->maxheight = 288;
- stv680->vwidth = 352;
- stv680->vheight = 288;
- }
- if (stv680->QVGA == 1) {
- stv680->maxwidth = 320;
- stv680->maxheight = 240;
- stv680->vwidth = 320;
- stv680->vheight = 240;
- }
-
- stv680->rawbufsize = bufsize; /* must be ./. by 8 */
- stv680->maxframesize = bufsize * 3; /* RGB size */
- PDEBUG (2, "STV(i): cwidth = %i, cheight = %i", stv680->cwidth, stv680->cheight);
- PDEBUG (1, "STV(i): width = %i, height = %i, rawbufsize = %li", stv680->vwidth, stv680->vheight, stv680->rawbufsize);
-
- /* some default values */
- stv680->bulk_in_endpointAddr = 0x82;
- stv680->dropped = 0;
- stv680->error = 0;
- stv680->framecount = 0;
- stv680->readcount = 0;
- stv680->streaming = 0;
- /* bright, white, colour, hue, contrast are set by software, not in stv0680 */
- stv680->brightness = 32767;
- stv680->chgbright = 0;
- stv680->whiteness = 0; /* only for greyscale */
- stv680->colour = 32767;
- stv680->contrast = 32767;
- stv680->hue = 32767;
- stv680->palette = STV_VIDEO_PALETTE;
- stv680->depth = 24; /* rgb24 bits */
- if ((swapRGB_on == 0) && (swapRGB == 0))
- PDEBUG (1, "STV(i): swapRGB is (auto) OFF");
- else if ((swapRGB_on == 0) && (swapRGB == 1))
- PDEBUG (1, "STV(i): swapRGB is (auto) ON");
- else if (swapRGB_on == 1)
- PDEBUG (1, "STV(i): swapRGB is (forced) ON");
- else if (swapRGB_on == -1)
- PDEBUG (1, "STV(i): swapRGB is (forced) OFF");
-
- if (stv_set_video_mode (stv680) < 0) {
- PDEBUG (0, "STV(e): Could not set video mode in stv_init");
- return -1;
- }
-
- return 0;
-}
-
-/***************** last of pencam routines *******************/
-
-/****************************************************************************
- * sysfs
- ***************************************************************************/
-#define stv680_file(name, variable, field) \
-static ssize_t show_##name(struct device *class_dev, \
- struct device_attribute *attr, char *buf) \
-{ \
- struct video_device *vdev = to_video_device(class_dev); \
- struct usb_stv *stv = video_get_drvdata(vdev); \
- return sprintf(buf, field, stv->variable); \
-} \
-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
-
-stv680_file(model, camera_name, "%s\n");
-stv680_file(in_use, user, "%d\n");
-stv680_file(streaming, streaming, "%d\n");
-stv680_file(palette, palette, "%i\n");
-stv680_file(frames_total, readcount, "%d\n");
-stv680_file(frames_read, framecount, "%d\n");
-stv680_file(packets_dropped, dropped, "%d\n");
-stv680_file(decoding_errors, error, "%d\n");
-
-static int stv680_create_sysfs_files(struct video_device *vdev)
-{
- int rc;
-
- rc = device_create_file(&vdev->dev, &dev_attr_model);
- if (rc) goto err;
- rc = device_create_file(&vdev->dev, &dev_attr_in_use);
- if (rc) goto err_model;
- rc = device_create_file(&vdev->dev, &dev_attr_streaming);
- if (rc) goto err_inuse;
- rc = device_create_file(&vdev->dev, &dev_attr_palette);
- if (rc) goto err_stream;
- rc = device_create_file(&vdev->dev, &dev_attr_frames_total);
- if (rc) goto err_pal;
- rc = device_create_file(&vdev->dev, &dev_attr_frames_read);
- if (rc) goto err_framtot;
- rc = device_create_file(&vdev->dev, &dev_attr_packets_dropped);
- if (rc) goto err_framread;
- rc = device_create_file(&vdev->dev, &dev_attr_decoding_errors);
- if (rc) goto err_dropped;
-
- return 0;
-
-err_dropped:
- device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
-err_framread:
- device_remove_file(&vdev->dev, &dev_attr_frames_read);
-err_framtot:
- device_remove_file(&vdev->dev, &dev_attr_frames_total);
-err_pal:
- device_remove_file(&vdev->dev, &dev_attr_palette);
-err_stream:
- device_remove_file(&vdev->dev, &dev_attr_streaming);
-err_inuse:
- device_remove_file(&vdev->dev, &dev_attr_in_use);
-err_model:
- device_remove_file(&vdev->dev, &dev_attr_model);
-err:
- PDEBUG(0, "STV(e): Could not create sysfs files");
- return rc;
-}
-
-static void stv680_remove_sysfs_files(struct video_device *vdev)
-{
- device_remove_file(&vdev->dev, &dev_attr_model);
- device_remove_file(&vdev->dev, &dev_attr_in_use);
- device_remove_file(&vdev->dev, &dev_attr_streaming);
- device_remove_file(&vdev->dev, &dev_attr_palette);
- device_remove_file(&vdev->dev, &dev_attr_frames_total);
- device_remove_file(&vdev->dev, &dev_attr_frames_read);
- device_remove_file(&vdev->dev, &dev_attr_packets_dropped);
- device_remove_file(&vdev->dev, &dev_attr_decoding_errors);
-}
-
-/********************************************************************
- * Camera control
- *******************************************************************/
-
-static int stv680_get_pict (struct usb_stv *stv680, struct video_picture *p)
-{
- /* This sets values for v4l interface. max/min = 65535/0 */
-
- p->brightness = stv680->brightness;
- p->whiteness = stv680->whiteness; /* greyscale */
- p->colour = stv680->colour;
- p->contrast = stv680->contrast;
- p->hue = stv680->hue;
- p->palette = stv680->palette;
- p->depth = stv680->depth;
- return 0;
-}
-
-static int stv680_set_pict (struct usb_stv *stv680, struct video_picture *p)
-{
- /* See above stv680_get_pict */
-
- if (p->palette != STV_VIDEO_PALETTE) {
- PDEBUG (2, "STV(e): Palette set error in _set_pic");
- return 1;
- }
-
- if (stv680->brightness != p->brightness) {
- stv680->chgbright = 1;
- stv680->brightness = p->brightness;
- }
-
- stv680->whiteness = p->whiteness; /* greyscale */
- stv680->colour = p->colour;
- stv680->contrast = p->contrast;
- stv680->hue = p->hue;
- stv680->palette = p->palette;
- stv680->depth = p->depth;
-
- return 0;
-}
-
-static void stv680_video_irq (struct urb *urb)
-{
- struct usb_stv *stv680 = urb->context;
- int length = urb->actual_length;
-
- if (length < stv680->rawbufsize)
- PDEBUG (2, "STV(i): Lost data in transfer: exp %li, got %i", stv680->rawbufsize, length);
-
- /* ohoh... */
- if (!stv680->streaming)
- return;
-
- if (!stv680->udev) {
- PDEBUG (0, "STV(e): device vapourished in video_irq");
- return;
- }
-
- /* 0 sized packets happen if we are to fast, but sometimes the camera
- keeps sending them forever...
- */
- if (length && !urb->status) {
- stv680->nullpackets = 0;
- switch (stv680->scratch[stv680->scratch_next].state) {
- case BUFFER_READY:
- case BUFFER_BUSY:
- stv680->dropped++;
- break;
-
- case BUFFER_UNUSED:
- memcpy (stv680->scratch[stv680->scratch_next].data,
- (unsigned char *) urb->transfer_buffer, length);
- stv680->scratch[stv680->scratch_next].state = BUFFER_READY;
- stv680->scratch[stv680->scratch_next].length = length;
- if (waitqueue_active (&stv680->wq)) {
- wake_up_interruptible (&stv680->wq);
- }
- stv680->scratch_overflow = 0;
- stv680->scratch_next++;
- if (stv680->scratch_next >= STV680_NUMSCRATCH)
- stv680->scratch_next = 0;
- break;
- } /* switch */
- } else {
- stv680->nullpackets++;
- if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
- if (waitqueue_active (&stv680->wq)) {
- wake_up_interruptible (&stv680->wq);
- }
- }
- } /* if - else */
-
- /* Resubmit urb for new data */
- urb->status = 0;
- urb->dev = stv680->udev;
- if (usb_submit_urb (urb, GFP_ATOMIC))
- PDEBUG (0, "STV(e): urb burned down in video irq");
- return;
-} /* _video_irq */
-
-static int stv680_start_stream (struct usb_stv *stv680)
-{
- struct urb *urb;
- int err = 0, i;
-
- stv680->streaming = 1;
-
- /* Do some memory allocation */
- for (i = 0; i < STV680_NUMFRAMES; i++) {
- stv680->frame[i].data = stv680->fbuf + i * stv680->maxframesize;
- stv680->frame[i].curpix = 0;
- }
- /* packet size = 4096 */
- for (i = 0; i < STV680_NUMSBUF; i++) {
- stv680->sbuf[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
- if (stv680->sbuf[i].data == NULL) {
- PDEBUG (0, "STV(e): Could not kmalloc raw data buffer %i", i);
- goto nomem_err;
- }
- }
-
- stv680->scratch_next = 0;
- stv680->scratch_use = 0;
- stv680->scratch_overflow = 0;
- for (i = 0; i < STV680_NUMSCRATCH; i++) {
- stv680->scratch[i].data = kmalloc (stv680->rawbufsize, GFP_KERNEL);
- if (stv680->scratch[i].data == NULL) {
- PDEBUG (0, "STV(e): Could not kmalloc raw scratch buffer %i", i);
- goto nomem_err;
- }
- stv680->scratch[i].state = BUFFER_UNUSED;
- }
-
- for (i = 0; i < STV680_NUMSBUF; i++) {
- urb = usb_alloc_urb (0, GFP_KERNEL);
- if (!urb)
- goto nomem_err;
-
- /* sbuf is urb->transfer_buffer, later gets memcpyed to scratch */
- usb_fill_bulk_urb (urb, stv680->udev,
- usb_rcvbulkpipe (stv680->udev, stv680->bulk_in_endpointAddr),
- stv680->sbuf[i].data, stv680->rawbufsize,
- stv680_video_irq, stv680);
- stv680->urb[i] = urb;
- err = usb_submit_urb (stv680->urb[i], GFP_KERNEL);
- if (err) {
- PDEBUG (0, "STV(e): urb burned down with err "
- "%d in start stream %d", err, i);
- goto nomem_err;
- }
- } /* i STV680_NUMSBUF */
-
- stv680->framecount = 0;
- return 0;
-
- nomem_err:
- for (i = 0; i < STV680_NUMSBUF; i++) {
- usb_kill_urb(stv680->urb[i]);
- usb_free_urb(stv680->urb[i]);
- stv680->urb[i] = NULL;
- kfree(stv680->sbuf[i].data);
- stv680->sbuf[i].data = NULL;
- }
- /* used in irq, free only as all URBs are dead */
- for (i = 0; i < STV680_NUMSCRATCH; i++) {
- kfree(stv680->scratch[i].data);
- stv680->scratch[i].data = NULL;
- }
- return -ENOMEM;
-
-}
-
-static int stv680_stop_stream (struct usb_stv *stv680)
-{
- int i;
-
- if (!stv680->streaming || !stv680->udev)
- return 1;
-
- stv680->streaming = 0;
-
- for (i = 0; i < STV680_NUMSBUF; i++)
- if (stv680->urb[i]) {
- usb_kill_urb (stv680->urb[i]);
- usb_free_urb (stv680->urb[i]);
- stv680->urb[i] = NULL;
- kfree(stv680->sbuf[i].data);
- }
- for (i = 0; i < STV680_NUMSCRATCH; i++) {
- kfree(stv680->scratch[i].data);
- stv680->scratch[i].data = NULL;
- }
-
- return 0;
-}
-
-static int stv680_set_size (struct usb_stv *stv680, int width, int height)
-{
- int wasstreaming = stv680->streaming;
-
- /* Check to see if we need to change */
- if ((stv680->vwidth == width) && (stv680->vheight == height))
- return 0;
-
- PDEBUG (1, "STV(i): size request for %i x %i", width, height);
- /* Check for a valid mode */
- if ((!width || !height) || ((width & 1) || (height & 1))) {
- PDEBUG (1, "STV(e): set_size error: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
- return 1;
- }
-
- if ((width < (stv680->maxwidth / 2)) || (height < (stv680->maxheight / 2))) {
- width = stv680->maxwidth / 2;
- height = stv680->maxheight / 2;
- } else if ((width >= 158) && (width <= 166) && (stv680->QVGA == 1)) {
- width = 160;
- height = 120;
- } else if ((width >= 172) && (width <= 180) && (stv680->CIF == 1)) {
- width = 176;
- height = 144;
- } else if ((width >= 318) && (width <= 350) && (stv680->QVGA == 1)) {
- width = 320;
- height = 240;
- } else if ((width >= 350) && (width <= 358) && (stv680->CIF == 1)) {
- width = 352;
- height = 288;
- } else {
- PDEBUG (1, "STV(e): request for non-supported size: request: v.width = %i, v.height = %i actual: stv.width = %i, stv.height = %i", width, height, stv680->vwidth, stv680->vheight);
- return 1;
- }
-
- /* Stop a current stream and start it again at the new size */
- if (wasstreaming)
- stv680_stop_stream (stv680);
- stv680->vwidth = width;
- stv680->vheight = height;
- PDEBUG (1, "STV(i): size set to %i x %i", stv680->vwidth, stv680->vheight);
- if (wasstreaming)
- stv680_start_stream (stv680);
-
- return 0;
-}
-
-/**********************************************************************
- * Video Decoding
- **********************************************************************/
-
-/******* routines from the pencam program; hey, they work! ********/
-
-/*
- * STV0680 Vision Camera Chipset Driver
- * Copyright (C) 2000 Adam Harrison <adam@antispin.org>
-*/
-
-#define RED 0
-#define GREEN 1
-#define BLUE 2
-#define AD(x, y, w) (((y)*(w)+(x))*3)
-
-static void bayer_unshuffle (struct usb_stv *stv680, struct stv680_scratch *buffer)
-{
- int x, y, i;
- int w = stv680->cwidth;
- int vw = stv680->cwidth, vh = stv680->cheight;
- unsigned int p = 0;
- int colour = 0, bayer = 0;
- unsigned char *raw = buffer->data;
- struct stv680_frame *frame = &stv680->frame[stv680->curframe];
- unsigned char *output = frame->data;
- unsigned char *temp = frame->data;
- int offset = buffer->offset;
-
- if (frame->curpix == 0) {
- if (frame->grabstate == FRAME_READY) {
- frame->grabstate = FRAME_GRABBING;
- }
- }
- if (offset != frame->curpix) { /* Regard frame as lost :( */
- frame->curpix = 0;
- stv680->error++;
- return;
- }
-
- if ((stv680->vwidth == 320) || (stv680->vwidth == 160)) {
- vw = 320;
- vh = 240;
- }
- if ((stv680->vwidth == 352) || (stv680->vwidth == 176)) {
- vw = 352;
- vh = 288;
- }
-
- memset (output, 0, 3 * vw * vh); /* clear output matrix. */
-
- for (y = 0; y < vh; y++) {
- for (x = 0; x < vw; x++) {
- if (x & 1)
- p = *(raw + y * w + (x >> 1));
- else
- p = *(raw + y * w + (x >> 1) + (w >> 1));
-
- if (y & 1)
- bayer = 2;
- else
- bayer = 0;
- if (x & 1)
- bayer++;
-
- switch (bayer) {
- case 0:
- case 3:
- colour = 1;
- break;
- case 1:
- colour = 0;
- break;
- case 2:
- colour = 2;
- break;
- }
- i = (y * vw + x) * 3;
- *(output + i + colour) = (unsigned char) p;
- } /* for x */
-
- } /* for y */
-
- /****** gamma correction plus hardcoded white balance */
- /* Thanks to Alexander Schwartx <alexander.schwartx@gmx.net> for this code.
- Correction values red[], green[], blue[], are generated by
- (pow(i/256.0, GAMMA)*255.0)*white balanceRGB where GAMMA=0.55, 1<i<255.
- White balance (RGB)= 1.0, 1.17, 1.48. Values are calculated as double float and
- converted to unsigned char. Values are in stv680.h */
-
- for (y = 0; y < vh; y++) {
- for (x = 0; x < vw; x++) {
- i = (y * vw + x) * 3;
- *(output + i) = red[*(output + i)];
- *(output + i + 1) = green[*(output + i + 1)];
- *(output + i + 2) = blue[*(output + i + 2)];
- }
- }
-
- /****** bayer demosaic ******/
- for (y = 1; y < (vh - 1); y++) {
- for (x = 1; x < (vw - 1); x++) { /* work out pixel type */
- if (y & 1)
- bayer = 0;
- else
- bayer = 2;
- if (!(x & 1))
- bayer++;
-
- switch (bayer) {
- case 0: /* green. blue lr, red tb */
- *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y, vw) + BLUE) + (int) *(output + AD (x + 1, y, vw) + BLUE)) >> 1;
- *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x, y - 1, vw) + RED) + (int) *(output + AD (x, y + 1, vw) + RED)) >> 1;
- break;
-
- case 1: /* blue. green lrtb, red diagonals */
- *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
- *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y - 1, vw) + RED) + (int) *(output + AD (x - 1, y + 1, vw) + RED) + (int) *(output + AD (x + 1, y - 1, vw) + RED) + (int) *(output + AD (x + 1, y + 1, vw) + RED)) >> 2;
- break;
-
- case 2: /* red. green lrtb, blue diagonals */
- *(output + AD (x, y, vw) + GREEN) = ((int) *(output + AD (x - 1, y, vw) + GREEN) + (int) *(output + AD (x + 1, y, vw) + GREEN) + (int) *(output + AD (x, y - 1, vw) + GREEN) + (int) *(output + AD (x, y + 1, vw) + GREEN)) >> 2;
- *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x - 1, y - 1, vw) + BLUE) + (int) *(output + AD (x + 1, y - 1, vw) + BLUE) + (int) *(output + AD (x - 1, y + 1, vw) + BLUE) + (int) *(output + AD (x + 1, y + 1, vw) + BLUE)) >> 2;
- break;
-
- case 3: /* green. red lr, blue tb */
- *(output + AD (x, y, vw) + RED) = ((int) *(output + AD (x - 1, y, vw) + RED) + (int) *(output + AD (x + 1, y, vw) + RED)) >> 1;
- *(output + AD (x, y, vw) + BLUE) = ((int) *(output + AD (x, y - 1, vw) + BLUE) + (int) *(output + AD (x, y + 1, vw) + BLUE)) >> 1;
- break;
- } /* switch */
- } /* for x */
- } /* for y - end demosaic */
-
- /* fix top and bottom row, left and right side */
- i = vw * 3;
- memcpy (output, (output + i), i);
- memcpy ((output + (vh * i)), (output + ((vh - 1) * i)), i);
- for (y = 0; y < vh; y++) {
- i = y * vw * 3;
- memcpy ((output + i), (output + i + 3), 3);
- memcpy ((output + i + (vw * 3)), (output + i + (vw - 1) * 3), 3);
- }
-
- /* process all raw data, then trim to size if necessary */
- if ((stv680->vwidth == 160) || (stv680->vwidth == 176)) {
- i = 0;
- for (y = 0; y < vh; y++) {
- if (!(y & 1)) {
- for (x = 0; x < vw; x++) {
- p = (y * vw + x) * 3;
- if (!(x & 1)) {
- *(output + i) = *(output + p);
- *(output + i + 1) = *(output + p + 1);
- *(output + i + 2) = *(output + p + 2);
- i += 3;
- }
- } /* for x */
- }
- } /* for y */
- }
- /* reset to proper width */
- if ((stv680->vwidth == 160)) {
- vw = 160;
- vh = 120;
- }
- if ((stv680->vwidth == 176)) {
- vw = 176;
- vh = 144;
- }
-
- /* output is RGB; some programs want BGR */
- /* swapRGB_on=0 -> program decides; swapRGB_on=1, always swap */
- /* swapRGB_on=-1, never swap */
- if (((swapRGB == 1) && (swapRGB_on != -1)) || (swapRGB_on == 1)) {
- for (y = 0; y < vh; y++) {
- for (x = 0; x < vw; x++) {
- i = (y * vw + x) * 3;
- *(temp) = *(output + i);
- *(output + i) = *(output + i + 2);
- *(output + i + 2) = *(temp);
- }
- }
- }
- /* brightness */
- if (stv680->chgbright == 1) {
- if (stv680->brightness >= 32767) {
- p = (stv680->brightness - 32767) / 256;
- for (x = 0; x < (vw * vh * 3); x++) {
- if ((*(output + x) + (unsigned char) p) > 255)
- *(output + x) = 255;
- else
- *(output + x) += (unsigned char) p;
- } /* for */
- } else {
- p = (32767 - stv680->brightness) / 256;
- for (x = 0; x < (vw * vh * 3); x++) {
- if ((unsigned char) p > *(output + x))
- *(output + x) = 0;
- else
- *(output + x) -= (unsigned char) p;
- } /* for */
- } /* else */
- }
- /* if */
- frame->curpix = 0;
- frame->curlinepix = 0;
- frame->grabstate = FRAME_DONE;
- stv680->framecount++;
- stv680->readcount++;
- if (stv680->frame[(stv680->curframe + 1) & (STV680_NUMFRAMES - 1)].grabstate == FRAME_READY) {
- stv680->curframe = (stv680->curframe + 1) & (STV680_NUMFRAMES - 1);
- }
-
-} /* bayer_unshuffle */
-
-/******* end routines from the pencam program *********/
-
-static int stv680_newframe (struct usb_stv *stv680, int framenr)
-{
- int errors = 0;
-
- while (stv680->streaming && (stv680->frame[framenr].grabstate == FRAME_READY || stv680->frame[framenr].grabstate == FRAME_GRABBING)) {
- if (!stv680->frame[framenr].curpix) {
- errors++;
- }
- wait_event_interruptible (stv680->wq, (stv680->scratch[stv680->scratch_use].state == BUFFER_READY));
-
- if (stv680->nullpackets > STV680_MAX_NULLPACKETS) {
- stv680->nullpackets = 0;
- PDEBUG (2, "STV(i): too many null length packets, restarting capture");
- stv680_stop_stream (stv680);
- stv680_start_stream (stv680);
- } else {
- if (stv680->scratch[stv680->scratch_use].state != BUFFER_READY) {
- stv680->frame[framenr].grabstate = FRAME_ERROR;
- PDEBUG (2, "STV(e): FRAME_ERROR in _newframe");
- return -EIO;
- }
- stv680->scratch[stv680->scratch_use].state = BUFFER_BUSY;
-
- bayer_unshuffle (stv680, &stv680->scratch[stv680->scratch_use]);
-
- stv680->scratch[stv680->scratch_use].state = BUFFER_UNUSED;
- stv680->scratch_use++;
- if (stv680->scratch_use >= STV680_NUMSCRATCH)
- stv680->scratch_use = 0;
- if (errors > STV680_MAX_ERRORS) {
- errors = 0;
- PDEBUG (2, "STV(i): too many errors, restarting capture");
- stv680_stop_stream (stv680);
- stv680_start_stream (stv680);
- }
- } /* else */
- } /* while */
- return 0;
-}
-
-/*********************************************************************
- * Video4Linux
- *********************************************************************/
-
-static int stv_open(struct file *file)
-{
- struct video_device *dev = video_devdata(file);
- struct usb_stv *stv680 = video_get_drvdata(dev);
- int err = 0;
-
- /* we are called with the BKL held */
- lock_kernel();
- stv680->user = 1;
- err = stv_init (stv680); /* main initialization routine for camera */
-
- if (err >= 0) {
- stv680->fbuf = rvmalloc (stv680->maxframesize * STV680_NUMFRAMES);
- if (!stv680->fbuf) {
- PDEBUG (0, "STV(e): Could not rvmalloc frame bufer");
- err = -ENOMEM;
- }
- file->private_data = dev;
- }
- if (err)
- stv680->user = 0;
- unlock_kernel();
-
- return err;
-}
-
-static int stv_close(struct file *file)
-{
- struct video_device *dev = file->private_data;
- struct usb_stv *stv680 = video_get_drvdata(dev);
- int i;
-
- for (i = 0; i < STV680_NUMFRAMES; i++)
- stv680->frame[i].grabstate = FRAME_UNUSED;
- if (stv680->streaming)
- stv680_stop_stream (stv680);
-
- if ((i = stv_stop_video (stv680)) < 0)
- PDEBUG (1, "STV(e): stop_video failed in stv_close");
-
- rvfree (stv680->fbuf, stv680->maxframesize * STV680_NUMFRAMES);
- stv680->user = 0;
-
- if (stv680->removed) {
- kfree(stv680);
- stv680 = NULL;
- PDEBUG (0, "STV(i): device unregistered");
- }
- file->private_data = NULL;
- return 0;
-}
-
-static long stv680_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct video_device *vdev = file->private_data;
- struct usb_stv *stv680 = video_get_drvdata(vdev);
-
- if (!stv680->udev)
- return -EIO;
-
- switch (cmd) {
- case VIDIOCGCAP:{
- struct video_capability *b = arg;
-
- strcpy (b->name, stv680->camera_name);
- b->type = VID_TYPE_CAPTURE;
- b->channels = 1;
- b->audios = 0;
- b->maxwidth = stv680->maxwidth;
- b->maxheight = stv680->maxheight;
- b->minwidth = stv680->maxwidth / 2;
- b->minheight = stv680->maxheight / 2;
- return 0;
- }
- case VIDIOCGCHAN:{
- struct video_channel *v = arg;
-
- if (v->channel != 0)
- return -EINVAL;
- v->flags = 0;
- v->tuners = 0;
- v->type = VIDEO_TYPE_CAMERA;
- strcpy (v->name, "STV Camera");
- return 0;
- }
- case VIDIOCSCHAN:{
- struct video_channel *v = arg;
- if (v->channel != 0)
- return -EINVAL;
- return 0;
- }
- case VIDIOCGPICT:{
- struct video_picture *p = arg;
-
- stv680_get_pict (stv680, p);
- return 0;
- }
- case VIDIOCSPICT:{
- struct video_picture *p = arg;
-
- if (stv680_set_pict (stv680, p))
- return -EINVAL;
- return 0;
- }
- case VIDIOCSWIN:{
- struct video_window *vw = arg;
-
- if (vw->flags)
- return -EINVAL;
- if (vw->clipcount)
- return -EINVAL;
- if (vw->width != stv680->vwidth) {
- if (stv680_set_size (stv680, vw->width, vw->height)) {
- PDEBUG (2, "STV(e): failed (from user) set size in VIDIOCSWIN");
- return -EINVAL;
- }
- }
- return 0;
- }
- case VIDIOCGWIN:{
- struct video_window *vw = arg;
-
- vw->x = 0; /* FIXME */
- vw->y = 0;
- vw->chromakey = 0;
- vw->flags = 0;
- vw->clipcount = 0;
- vw->width = stv680->vwidth;
- vw->height = stv680->vheight;
- return 0;
- }
- case VIDIOCGMBUF:{
- struct video_mbuf *vm = arg;
- int i;
-
- memset (vm, 0, sizeof (*vm));
- vm->size = STV680_NUMFRAMES * stv680->maxframesize;
- vm->frames = STV680_NUMFRAMES;
- for (i = 0; i < STV680_NUMFRAMES; i++)
- vm->offsets[i] = stv680->maxframesize * i;
- return 0;
- }
- case VIDIOCMCAPTURE:{
- struct video_mmap *vm = arg;
-
- if (vm->format != STV_VIDEO_PALETTE) {
- PDEBUG (2, "STV(i): VIDIOCMCAPTURE vm.format (%i) != VIDEO_PALETTE (%i)",
- vm->format, STV_VIDEO_PALETTE);
- if ((vm->format == 3) && (swapRGB_on == 0)) {
- PDEBUG (2, "STV(i): VIDIOCMCAPTURE swapRGB is (auto) ON");
- /* this may fix those apps (e.g., xawtv) that want BGR */
- swapRGB = 1;
- }
- return -EINVAL;
- }
- if (vm->frame >= STV680_NUMFRAMES) {
- PDEBUG (2, "STV(e): VIDIOCMCAPTURE vm.frame > NUMFRAMES");
- return -EINVAL;
- }
- if ((stv680->frame[vm->frame].grabstate == FRAME_ERROR)
- || (stv680->frame[vm->frame].grabstate == FRAME_GRABBING)) {
- PDEBUG (2, "STV(e): VIDIOCMCAPTURE grabstate (%i) error",
- stv680->frame[vm->frame].grabstate);
- return -EBUSY;
- }
- /* Is this according to the v4l spec??? */
- if (stv680->vwidth != vm->width) {
- if (stv680_set_size (stv680, vm->width, vm->height)) {
- PDEBUG (2, "STV(e): VIDIOCMCAPTURE set_size failed");
- return -EINVAL;
- }
- }
- stv680->frame[vm->frame].grabstate = FRAME_READY;
-
- if (!stv680->streaming)
- stv680_start_stream (stv680);
-
- return 0;
- }
- case VIDIOCSYNC:{
- int *frame = arg;
- int ret = 0;
-
- if (*frame < 0 || *frame >= STV680_NUMFRAMES) {
- PDEBUG (2, "STV(e): Bad frame # in VIDIOCSYNC");
- return -EINVAL;
- }
- ret = stv680_newframe (stv680, *frame);
- stv680->frame[*frame].grabstate = FRAME_UNUSED;
- return ret;
- }
- case VIDIOCGFBUF:{
- struct video_buffer *vb = arg;
-
- memset (vb, 0, sizeof (*vb));
- return 0;
- }
- case VIDIOCKEY:
- return 0;
- case VIDIOCCAPTURE:
- {
- PDEBUG (2, "STV(e): VIDIOCCAPTURE failed");
- return -EINVAL;
- }
- case VIDIOCSFBUF:
- case VIDIOCGTUNER:
- case VIDIOCSTUNER:
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- return -EINVAL;
- default:
- return -ENOIOCTLCMD;
- } /* end switch */
-
- return 0;
-}
-
-static long stv680_ioctl(struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, stv680_do_ioctl);
-}
-
-static int stv680_mmap (struct file *file, struct vm_area_struct *vma)
-{
- struct video_device *dev = file->private_data;
- struct usb_stv *stv680 = video_get_drvdata(dev);
- unsigned long start = vma->vm_start;
- unsigned long size = vma->vm_end-vma->vm_start;
- unsigned long page, pos;
-
- mutex_lock(&stv680->lock);
-
- if (stv680->udev == NULL) {
- mutex_unlock(&stv680->lock);
- return -EIO;
- }
- if (size > (((STV680_NUMFRAMES * stv680->maxframesize) + PAGE_SIZE - 1)
- & ~(PAGE_SIZE - 1))) {
- mutex_unlock(&stv680->lock);
- return -EINVAL;
- }
- pos = (unsigned long) stv680->fbuf;
- while (size > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
- mutex_unlock(&stv680->lock);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- if (size > PAGE_SIZE)
- size -= PAGE_SIZE;
- else
- size = 0;
- }
- mutex_unlock(&stv680->lock);
-
- return 0;
-}
-
-static ssize_t stv680_read (struct file *file, char __user *buf,
- size_t count, loff_t *ppos)
-{
- struct video_device *dev = file->private_data;
- unsigned long int realcount = count;
- int ret = 0;
- struct usb_stv *stv680 = video_get_drvdata(dev);
- unsigned long int i;
-
- if (STV680_NUMFRAMES != 2) {
- PDEBUG (0, "STV(e): STV680_NUMFRAMES needs to be 2!");
- return -1;
- }
- if (stv680->udev == NULL)
- return -EIO;
- if (realcount > (stv680->vwidth * stv680->vheight * 3))
- realcount = stv680->vwidth * stv680->vheight * 3;
-
- /* Shouldn't happen: */
- if (stv680->frame[0].grabstate == FRAME_GRABBING) {
- PDEBUG (2, "STV(e): FRAME_GRABBING in stv680_read");
- return -EBUSY;
- }
- stv680->frame[0].grabstate = FRAME_READY;
- stv680->frame[1].grabstate = FRAME_UNUSED;
- stv680->curframe = 0;
-
- if (!stv680->streaming)
- stv680_start_stream (stv680);
-
- if (!stv680->streaming) {
- ret = stv680_newframe (stv680, 0); /* ret should = 0 */
- }
-
- ret = stv680_newframe (stv680, 0);
-
- if (!ret) {
- if ((i = copy_to_user (buf, stv680->frame[0].data, realcount)) != 0) {
- PDEBUG (2, "STV(e): copy_to_user frame 0 failed, ret count = %li", i);
- return -EFAULT;
- }
- } else {
- realcount = ret;
- }
- stv680->frame[0].grabstate = FRAME_UNUSED;
- return realcount;
-} /* stv680_read */
-
-static const struct v4l2_file_operations stv680_fops = {
- .owner = THIS_MODULE,
- .open = stv_open,
- .release = stv_close,
- .read = stv680_read,
- .mmap = stv680_mmap,
- .ioctl = stv680_ioctl,
-};
-static struct video_device stv680_template = {
- .name = "STV0680 USB camera",
- .fops = &stv680_fops,
- .release = video_device_release,
-};
-
-static int stv680_probe (struct usb_interface *intf, const struct usb_device_id *id)
-{
- struct usb_device *dev = interface_to_usbdev(intf);
- struct usb_host_interface *interface;
- struct usb_stv *stv680 = NULL;
- char *camera_name = NULL;
- int retval = 0;
-
- /* We don't handle multi-config cameras */
- if (dev->descriptor.bNumConfigurations != 1) {
- PDEBUG (0, "STV(e): Number of Configurations != 1");
- return -ENODEV;
- }
-
- interface = &intf->altsetting[0];
- /* Is it a STV680? */
- if ((le16_to_cpu(dev->descriptor.idVendor) == USB_PENCAM_VENDOR_ID) &&
- (le16_to_cpu(dev->descriptor.idProduct) == USB_PENCAM_PRODUCT_ID)) {
- camera_name = "STV0680";
- PDEBUG (0, "STV(i): STV0680 camera found.");
- } else if ((le16_to_cpu(dev->descriptor.idVendor) == USB_CREATIVEGOMINI_VENDOR_ID) &&
- (le16_to_cpu(dev->descriptor.idProduct) == USB_CREATIVEGOMINI_PRODUCT_ID)) {
- camera_name = "Creative WebCam Go Mini";
- PDEBUG (0, "STV(i): Creative WebCam Go Mini found.");
- } else {
- PDEBUG (0, "STV(e): Vendor/Product ID do not match STV0680 or Creative WebCam Go Mini values.");
- PDEBUG (0, "STV(e): Check that the STV0680 or Creative WebCam Go Mini camera is connected to the computer.");
- retval = -ENODEV;
- goto error;
- }
- /* We found one */
- if ((stv680 = kzalloc (sizeof (*stv680), GFP_KERNEL)) == NULL) {
- PDEBUG (0, "STV(e): couldn't kmalloc stv680 struct.");
- retval = -ENOMEM;
- goto error;
- }
-
- stv680->udev = dev;
- stv680->camera_name = camera_name;
-
- stv680->vdev = video_device_alloc();
- if (!stv680->vdev) {
- retval = -ENOMEM;
- goto error;
- }
- memcpy(stv680->vdev, &stv680_template, sizeof(stv680_template));
- stv680->vdev->parent = &intf->dev;
- video_set_drvdata(stv680->vdev, stv680);
-
- memcpy (stv680->vdev->name, stv680->camera_name, strlen (stv680->camera_name));
- init_waitqueue_head (&stv680->wq);
- mutex_init (&stv680->lock);
- wmb ();
-
- if (video_register_device(stv680->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
- PDEBUG (0, "STV(e): video_register_device failed");
- retval = -EIO;
- goto error_vdev;
- }
- PDEBUG(0, "STV(i): registered new video device: %s",
- video_device_node_name(stv680->vdev));
-
- usb_set_intfdata (intf, stv680);
- retval = stv680_create_sysfs_files(stv680->vdev);
- if (retval)
- goto error_unreg;
- return 0;
-
-error_unreg:
- video_unregister_device(stv680->vdev);
-error_vdev:
- video_device_release(stv680->vdev);
-error:
- kfree(stv680);
- return retval;
-}
-
-static inline void usb_stv680_remove_disconnected (struct usb_stv *stv680)
-{
- int i;
-
- stv680->udev = NULL;
- stv680->frame[0].grabstate = FRAME_ERROR;
- stv680->frame[1].grabstate = FRAME_ERROR;
- stv680->streaming = 0;
-
- wake_up_interruptible (&stv680->wq);
-
- for (i = 0; i < STV680_NUMSBUF; i++)
- if (stv680->urb[i]) {
- usb_kill_urb (stv680->urb[i]);
- usb_free_urb (stv680->urb[i]);
- stv680->urb[i] = NULL;
- kfree(stv680->sbuf[i].data);
- }
- for (i = 0; i < STV680_NUMSCRATCH; i++)
- kfree(stv680->scratch[i].data);
- PDEBUG (0, "STV(i): %s disconnected", stv680->camera_name);
-
- /* Free the memory */
- kfree(stv680);
-}
-
-static void stv680_disconnect (struct usb_interface *intf)
-{
- struct usb_stv *stv680 = usb_get_intfdata (intf);
-
- usb_set_intfdata (intf, NULL);
-
- if (stv680) {
- /* We don't want people trying to open up the device */
- if (stv680->vdev) {
- stv680_remove_sysfs_files(stv680->vdev);
- video_unregister_device(stv680->vdev);
- stv680->vdev = NULL;
- }
- if (!stv680->user) {
- usb_stv680_remove_disconnected (stv680);
- } else {
- stv680->removed = 1;
- }
- }
-}
-
-static struct usb_driver stv680_driver = {
- .name = "stv680",
- .probe = stv680_probe,
- .disconnect = stv680_disconnect,
- .id_table = device_table
-};
-
-/********************************************************************
- * Module routines
- ********************************************************************/
-
-static int __init usb_stv680_init (void)
-{
- if (usb_register (&stv680_driver) < 0) {
- PDEBUG (0, "STV(e): Could not setup STV0680 driver");
- return -1;
- }
- PDEBUG (0, "STV(i): usb camera driver version %s registering", DRIVER_VERSION);
-
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
- return 0;
-}
-
-static void __exit usb_stv680_exit (void)
-{
- usb_deregister (&stv680_driver);
- PDEBUG (0, "STV(i): driver deregistered");
-}
-
-module_init (usb_stv680_init);
-module_exit (usb_stv680_exit);
diff --git a/drivers/media/video/stv680.h b/drivers/media/video/stv680.h
deleted file mode 100644
index a08f1b08a4b0..000000000000
--- a/drivers/media/video/stv680.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/****************************************************************************
- *
- * Filename: stv680.h
- *
- * Description:
- * This is a USB driver for STV0680 based usb video cameras.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- ****************************************************************************/
-
-/* size of usb transfers */
-#define STV680_PACKETSIZE 4096
-
-/* number of queued bulk transfers to use, may have problems if > 1 */
-#define STV680_NUMSBUF 1
-
-/* number of frames supported by the v4l part */
-#define STV680_NUMFRAMES 2
-
-/* scratch buffers for passing data to the decoders: 2 or 4 are good */
-#define STV680_NUMSCRATCH 2
-
-/* number of nul sized packets to receive before kicking the camera */
-#define STV680_MAX_NULLPACKETS 200
-
-/* number of decoding errors before kicking the camera */
-#define STV680_MAX_ERRORS 100
-
-#define USB_PENCAM_VENDOR_ID 0x0553
-#define USB_PENCAM_PRODUCT_ID 0x0202
-
-#define USB_CREATIVEGOMINI_VENDOR_ID 0x041e
-#define USB_CREATIVEGOMINI_PRODUCT_ID 0x4007
-
-#define PENCAM_TIMEOUT 1000
-/* fmt 4 */
-#define STV_VIDEO_PALETTE VIDEO_PALETTE_RGB24
-
-static struct usb_device_id device_table[] = {
- {USB_DEVICE (USB_PENCAM_VENDOR_ID, USB_PENCAM_PRODUCT_ID)},
- {USB_DEVICE (USB_CREATIVEGOMINI_VENDOR_ID, USB_CREATIVEGOMINI_PRODUCT_ID)},
- {}
-};
-MODULE_DEVICE_TABLE (usb, device_table);
-
-struct stv680_sbuf {
- unsigned char *data;
-};
-
-enum {
- FRAME_UNUSED, /* Unused (no MCAPTURE) */
- FRAME_READY, /* Ready to start grabbing */
- FRAME_GRABBING, /* In the process of being grabbed into */
- FRAME_DONE, /* Finished grabbing, but not been synced yet */
- FRAME_ERROR, /* Something bad happened while processing */
-};
-
-enum {
- BUFFER_UNUSED,
- BUFFER_READY,
- BUFFER_BUSY,
- BUFFER_DONE,
-};
-
-/* raw camera data <- sbuf (urb transfer buf) */
-struct stv680_scratch {
- unsigned char *data;
- volatile int state;
- int offset;
- int length;
-};
-
-/* processed data for display ends up here, after bayer */
-struct stv680_frame {
- unsigned char *data; /* Frame buffer */
- volatile int grabstate; /* State of grabbing */
- unsigned char *curline;
- int curlinepix;
- int curpix;
-};
-
-/* this is almost the video structure uvd_t, with extra parameters for stv */
-struct usb_stv {
- struct video_device *vdev;
-
- struct usb_device *udev;
-
- unsigned char bulk_in_endpointAddr; /* __u8 the address of the bulk in endpoint */
- char *camera_name;
-
- unsigned int VideoMode; /* 0x0100 = VGA, 0x0000 = CIF, 0x0300 = QVGA */
- int SupportedModes;
- int CIF;
- int VGA;
- int QVGA;
- int cwidth; /* camera width */
- int cheight; /* camera height */
- int maxwidth; /* max video width */
- int maxheight; /* max video height */
- int vwidth; /* current width for video window */
- int vheight; /* current height for video window */
- unsigned long int rawbufsize;
- unsigned long int maxframesize; /* rawbufsize * 3 for RGB */
-
- int origGain;
- int origMode; /* original camera mode */
-
- struct mutex lock; /* to lock the structure */
- int user; /* user count for exclusive use */
- int removed; /* device disconnected */
- int streaming; /* Are we streaming video? */
- char *fbuf; /* Videodev buffer area */
- struct urb *urb[STV680_NUMSBUF]; /* # of queued bulk transfers */
- int curframe; /* Current receiving frame */
- struct stv680_frame frame[STV680_NUMFRAMES]; /* # frames supported by v4l part */
- int readcount;
- int framecount;
- int error;
- int dropped;
- int scratch_next;
- int scratch_use;
- int scratch_overflow;
- struct stv680_scratch scratch[STV680_NUMSCRATCH]; /* for decoders */
- struct stv680_sbuf sbuf[STV680_NUMSBUF];
-
- unsigned int brightness;
- unsigned int chgbright;
- unsigned int whiteness;
- unsigned int colour;
- unsigned int contrast;
- unsigned int hue;
- unsigned int palette;
- unsigned int depth; /* rgb24 in bits */
-
- wait_queue_head_t wq; /* Processes waiting */
-
- int nullpackets;
-};
-
-
-static const unsigned char red[256] = {
- 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
- 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42,
- 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69,
- 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87,
- 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101,
- 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
- 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124,
- 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134,
- 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143,
- 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151,
- 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159,
- 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166,
- 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173,
- 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179,
- 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186,
- 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192,
- 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197,
- 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204,
- 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209,
- 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215,
- 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219,
- 220, 220, 221, 221
-};
-
-static const unsigned char green[256] = {
- 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
- 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47,
- 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77,
- 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97,
- 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113,
- 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126,
- 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
- 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149,
- 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159,
- 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168,
- 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177,
- 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185,
- 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193,
- 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200,
- 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207,
- 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214,
- 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220,
- 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
- 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
- 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239,
- 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244,
- 245, 245, 246, 246
-};
-
-static const unsigned char blue[256] = {
- 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
- 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51,
- 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84,
- 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106,
- 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124,
- 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138,
- 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151,
- 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163,
- 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174,
- 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184,
- 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194,
- 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203,
- 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212,
- 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220,
- 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227,
- 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235,
- 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242,
- 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249,
- 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255
-};
diff --git a/drivers/media/video/tlg2300/pd-main.c b/drivers/media/video/tlg2300/pd-main.c
index 256cc558ba13..4555f4a5f4c8 100644
--- a/drivers/media/video/tlg2300/pd-main.c
+++ b/drivers/media/video/tlg2300/pd-main.c
@@ -227,12 +227,11 @@ static int firmware_download(struct usb_device *udev)
fwlength = fw->size;
- fwbuf = kzalloc(fwlength, GFP_KERNEL);
+ fwbuf = kmemdup(fw->data, fwlength, GFP_KERNEL);
if (!fwbuf) {
ret = -ENOMEM;
goto out;
}
- memcpy(fwbuf, fw->data, fwlength);
max_packet_size = udev->ep_out[0x1]->desc.wMaxPacketSize;
log("\t\t download size : %d", (int)max_packet_size);
diff --git a/drivers/media/video/usbvideo/Kconfig b/drivers/media/video/usbvideo/Kconfig
index adb1c044ad7d..d6e16959f78b 100644
--- a/drivers/media/video/usbvideo/Kconfig
+++ b/drivers/media/video/usbvideo/Kconfig
@@ -37,17 +37,3 @@ config USB_KONICAWC
To compile this driver as a module, choose M here: the
module will be called konicawc.
-config USB_QUICKCAM_MESSENGER
- tristate "USB Logitech Quickcam Messenger (DEPRECATED)"
- depends on VIDEO_V4L1
- select VIDEO_USBVIDEO
- ---help---
- This driver is DEPRECATED please use the gspca stv06xx module
- instead.
-
- Say Y or M here to enable support for the USB Logitech Quickcam
- Messenger webcam.
-
- To compile this driver as a module, choose M here: the
- module will be called quickcam_messenger.
-
diff --git a/drivers/media/video/usbvideo/Makefile b/drivers/media/video/usbvideo/Makefile
index 4a1b144bee4d..bb52eb8dc2f9 100644
--- a/drivers/media/video/usbvideo/Makefile
+++ b/drivers/media/video/usbvideo/Makefile
@@ -2,4 +2,3 @@ obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
obj-$(CONFIG_USB_IBMCAM) += ibmcam.o ultracam.o
obj-$(CONFIG_USB_KONICAWC) += konicawc.o
obj-$(CONFIG_USB_VICAM) += vicam.o
-obj-$(CONFIG_USB_QUICKCAM_MESSENGER) += quickcam_messenger.o
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.c b/drivers/media/video/usbvideo/quickcam_messenger.c
deleted file mode 100644
index fbd665fa1979..000000000000
--- a/drivers/media/video/usbvideo/quickcam_messenger.c
+++ /dev/null
@@ -1,1126 +0,0 @@
-/*
- * Driver for Logitech Quickcam Messenger usb video camera
- * Copyright (C) Jaya Kumar
- *
- * This work was sponsored by CIS(M) Sdn Bhd.
- * History:
- * 05/08/2006 - Jaya Kumar
- * I wrote this based on the konicawc by Simon Evans.
- * -
- * Full credit for reverse engineering and creating an initial
- * working linux driver for the VV6422 goes to the qce-ga project by
- * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
- * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
- * others.
- * ---
- * 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/init.h>
-#include <linux/input.h>
-#include <linux/usb/input.h>
-#include <linux/slab.h>
-
-#include "usbvideo.h"
-#include "quickcam_messenger.h"
-
-/*
- * Version Information
- */
-
-#ifdef CONFIG_USB_DEBUG
-static int debug;
-#define DEBUG(n, format, arg...) \
- if (n <= debug) { \
- printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
- }
-#else
-#define DEBUG(n, arg...)
-static const int debug;
-#endif
-
-#define DRIVER_VERSION "v0.01"
-#define DRIVER_DESC "Logitech Quickcam Messenger USB"
-
-#define USB_LOGITECH_VENDOR_ID 0x046D
-#define USB_QCM_PRODUCT_ID 0x08F0
-
-#define MAX_CAMERAS 1
-
-#define MAX_COLOUR 32768
-#define MAX_HUE 32768
-#define MAX_BRIGHTNESS 32768
-#define MAX_CONTRAST 32768
-#define MAX_WHITENESS 32768
-
-static int size = SIZE_320X240;
-static int colour = MAX_COLOUR;
-static int hue = MAX_HUE;
-static int brightness = MAX_BRIGHTNESS;
-static int contrast = MAX_CONTRAST;
-static int whiteness = MAX_WHITENESS;
-
-static struct usbvideo *cams;
-
-static struct usb_device_id qcm_table [] = {
- { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
- { }
-};
-MODULE_DEVICE_TABLE(usb, qcm_table);
-
-#ifdef CONFIG_INPUT
-static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
-{
- struct input_dev *input_dev;
- int error;
-
- usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
- strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
-
- cam->input = input_dev = input_allocate_device();
- if (!input_dev) {
- dev_warn(&dev->dev, "insufficient mem for cam input device\n");
- return;
- }
-
- input_dev->name = "QCM button";
- input_dev->phys = cam->input_physname;
- usb_to_input_id(dev, &input_dev->id);
- input_dev->dev.parent = &dev->dev;
-
- input_dev->evbit[0] = BIT_MASK(EV_KEY);
- input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
-
- error = input_register_device(cam->input);
- if (error) {
- dev_warn(&dev->dev,
- "Failed to register camera's input device, err: %d\n",
- error);
- input_free_device(cam->input);
- cam->input = NULL;
- }
-}
-
-static void qcm_unregister_input(struct qcm *cam)
-{
- if (cam->input) {
- input_unregister_device(cam->input);
- cam->input = NULL;
- }
-}
-
-static void qcm_report_buttonstat(struct qcm *cam)
-{
- if (cam->input) {
- input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
- input_sync(cam->input);
- }
-}
-
-static void qcm_int_irq(struct urb *urb)
-{
- int ret;
- struct uvd *uvd = urb->context;
- struct qcm *cam;
-
- if (!CAMERA_IS_OPERATIONAL(uvd))
- return;
-
- if (!uvd->streaming)
- return;
-
- uvd->stats.urb_count++;
-
- if (urb->status < 0)
- uvd->stats.iso_err_count++;
- else {
- if (urb->actual_length > 0 ) {
- cam = (struct qcm *) uvd->user_data;
- if (cam->button_sts_buf == 0x88)
- cam->button_sts = 0x0;
- else if (cam->button_sts_buf == 0x80)
- cam->button_sts = 0x1;
- qcm_report_buttonstat(cam);
- }
- }
-
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret < 0)
- err("usb_submit_urb error (%d)", ret);
-}
-
-static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
-{
- int errflag;
- usb_fill_int_urb(cam->button_urb, uvd->dev,
- usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
- &cam->button_sts_buf,
- 1,
- qcm_int_irq,
- uvd, 16);
-
- errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
- if (errflag)
- err ("usb_submit_int ret %d", errflag);
- return errflag;
-}
-
-static void qcm_stop_int_data(struct qcm *cam)
-{
- usb_kill_urb(cam->button_urb);
-}
-
-static int qcm_alloc_int_urb(struct qcm *cam)
-{
- cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
-
- if (!cam->button_urb)
- return -ENOMEM;
-
- return 0;
-}
-
-static void qcm_free_int(struct qcm *cam)
-{
- usb_free_urb(cam->button_urb);
-}
-#endif /* CONFIG_INPUT */
-
-static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
-{
- int ret;
-
- /* we'll wait up to 3 slices but no more */
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- reg, 0, &val, 1, 3*HZ);
- return ret;
-}
-
-static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
-{
- int ret;
-
- /* we'll wait up to 3 slices but no more */
- ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- reg, 0, &val, 2, 3*HZ);
- return ret;
-}
-
-static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
- __le16 *val)
-{
- int ret;
-
- /* we'll wait up to 3 slices but no more */
- ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
- reg, 0, val, 2, 3*HZ);
- return ret;
-}
-
-static int qcm_camera_on(struct uvd *uvd)
-{
- int ret;
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
- return 0;
-}
-
-static int qcm_camera_off(struct uvd *uvd)
-{
- int ret;
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
- return 0;
-}
-
-static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
-{
- unsigned int segment, valsat;
- signed int h = (signed int) hue;
- unsigned int s = (sat - 32768) * 2; /* rescale */
- unsigned int v = val;
- unsigned int p;
-
- /*
- the registers controlling gain are 8 bit of which
- we affect only the last 4 bits with our gain.
- we know that if saturation is 0, (unsaturated) then
- we're grayscale (center axis of the colour cone) so
- we set rgb=value. we use a formula obtained from
- wikipedia to map the cone to the RGB plane. it's
- as follows for the human value case of h=0..360,
- s=0..1, v=0..1
- h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
- q = v(1 - f*s) , t = v(1 - (1-f)s)
- h_i==0 => r=v , g=t, b=p
- h_i==1 => r=q , g=v, b=p
- h_i==2 => r=p , g=v, b=t
- h_i==3 => r=p , g=q, b=v
- h_i==4 => r=t , g=p, b=v
- h_i==5 => r=v , g=p, b=q
- the bottom side (the point) and the stuff just up
- of that is black so we simplify those two cases.
- */
- if (sat < 32768) {
- /* anything less than this is unsaturated */
- *r = val;
- *g = val;
- *b = val;
- return;
- }
- if (val <= (0xFFFF/8)) {
- /* anything less than this is black */
- *r = 0;
- *g = 0;
- *b = 0;
- return;
- }
-
- /* the rest of this code is copying tukkat's
- implementation of the hsv2rgb conversion as taken
- from qc-usb-messenger code. the 10923 is 0xFFFF/6
- to divide the cone into 6 sectors. */
-
- segment = (h + 10923) & 0xFFFF;
- segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
- hue -= segment * 21845; /* -10923..10923 */
- h = hue;
- h *= 3;
- valsat = v*s >> 16; /* 0..65534 */
- p = v - valsat;
- if (h >= 0) {
- unsigned int t = v - (valsat * (32769 - h) >> 15);
- switch (segment) {
- case 0: /* R-> */
- *r = v;
- *g = t;
- *b = p;
- break;
- case 1: /* G-> */
- *r = p;
- *g = v;
- *b = t;
- break;
- case 2: /* B-> */
- *r = t;
- *g = p;
- *b = v;
- break;
- }
- } else {
- unsigned int q = v - (valsat * (32769 + h) >> 15);
- switch (segment) {
- case 0: /* ->R */
- *r = v;
- *g = p;
- *b = q;
- break;
- case 1: /* ->G */
- *r = q;
- *g = v;
- *b = p;
- break;
- case 2: /* ->B */
- *r = p;
- *g = q;
- *b = v;
- break;
- }
- }
-}
-
-static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
- u16 saturation, u16 value)
-{
- int ret;
- u16 r=0,g=0,b=0;
-
- /* this code is based on qc-usb-messenger */
- qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
-
- r >>= 12;
- g >>= 12;
- b >>= 12;
-
- /* min val is 8 */
- r = max((u16) 8, r);
- g = max((u16) 8, g);
- b = max((u16) 8, b);
-
- r |= 0x30;
- g |= 0x30;
- b |= 0x30;
-
- /* set the r,g,b gain registers */
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
-
- /* doing as qc-usb did */
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
-
- return 0;
-}
-
-static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
-{
- int ret;
- int formedval;
-
- /* calculation was from qc-usb-messenger driver */
- formedval = ( exposure >> 12 );
-
- /* max value for formedval is 14 */
- formedval = min(formedval, 14);
-
- CHECK_RET(ret, qcm_stv_setb(uvd->dev,
- 0x143A, 0xF0 | formedval));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
- return 0;
-}
-
-static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
- int hue, int colour)
-{
- int ret;
- /* brightness is exposure, contrast is gain, colour is saturation */
- CHECK_RET(ret,
- qcm_sensor_set_exposure(uvd, brightness));
- CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
-
- return 0;
-}
-
-static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
-{
- int ret;
-
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
- return 0;
-}
-
-static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
-{
- int ret;
- /* some rescaling as done by the qc-usb-messenger code */
- if (whiteness > 0xC000)
- whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
-
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
- (whiteness >> 8) & 0xFF));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
- (whiteness >> 16) & 0x03));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
-
- return 0;
-}
-
-static int qcm_sensor_init(struct uvd *uvd)
-{
- struct qcm *cam = (struct qcm *) uvd->user_data;
- int ret;
- int i;
-
- for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
- CHECK_RET(ret, qcm_stv_setb(uvd->dev,
- regval_table[i].reg,
- regval_table[i].val));
- }
-
- CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
- cpu_to_le16(ISOC_PACKET_SIZE)));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
-
- CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
-
- CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
-
- CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
- uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
-
- CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
- CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
-
- return 0;
-}
-
-static int qcm_set_camera_size(struct uvd *uvd)
-{
- int ret;
- struct qcm *cam = (struct qcm *) uvd->user_data;
-
- CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
- cam->width = camera_sizes[cam->size].width;
- cam->height = camera_sizes[cam->size].height;
- uvd->videosize = VIDEOSIZE(cam->width, cam->height);
-
- return 0;
-}
-
-static int qcm_setup_on_open(struct uvd *uvd)
-{
- int ret;
-
- CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
- uvd->vpic.colour, uvd->vpic.contrast));
- CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
- CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
- CHECK_RET(ret, qcm_set_camera_size(uvd));
- CHECK_RET(ret, qcm_camera_on(uvd));
- return 0;
-}
-
-static void qcm_adjust_picture(struct uvd *uvd)
-{
- int ret;
- struct qcm *cam = (struct qcm *) uvd->user_data;
-
- ret = qcm_camera_off(uvd);
- if (ret) {
- err("can't turn camera off. abandoning pic adjustment");
- return;
- }
-
- /* if there's been a change in contrast, hue, or
- colour then we need to recalculate hsv in order
- to update gains */
- if ((cam->contrast != uvd->vpic.contrast) ||
- (cam->hue != uvd->vpic.hue) ||
- (cam->colour != uvd->vpic.colour)) {
- cam->contrast = uvd->vpic.contrast;
- cam->hue = uvd->vpic.hue;
- cam->colour = uvd->vpic.colour;
- ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
- cam->contrast);
- if (ret) {
- err("can't set gains. abandoning pic adjustment");
- return;
- }
- }
-
- if (cam->brightness != uvd->vpic.brightness) {
- cam->brightness = uvd->vpic.brightness;
- ret = qcm_sensor_set_exposure(uvd, cam->brightness);
- if (ret) {
- err("can't set exposure. abandoning pic adjustment");
- return;
- }
- }
-
- if (cam->whiteness != uvd->vpic.whiteness) {
- cam->whiteness = uvd->vpic.whiteness;
- qcm_sensor_set_shutter(uvd, cam->whiteness);
- if (ret) {
- err("can't set shutter. abandoning pic adjustment");
- return;
- }
- }
-
- ret = qcm_camera_on(uvd);
- if (ret) {
- err("can't reenable camera. pic adjustment failed");
- return;
- }
-}
-
-static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
-{
- int datalen;
- int totaldata;
- struct framehdr {
- __be16 id;
- __be16 len;
- };
- struct framehdr *fhdr;
-
- totaldata = 0;
- while (framelen) {
- fhdr = (struct framehdr *) cdata;
- datalen = be16_to_cpu(fhdr->len);
- framelen -= 4;
- cdata += 4;
-
- if ((fhdr->id) == cpu_to_be16(0x8001)) {
- RingQueue_Enqueue(&uvd->dp, marker, 4);
- totaldata += 4;
- continue;
- }
- if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
- RingQueue_Enqueue(&uvd->dp, cdata, datalen);
- totaldata += datalen;
- }
- framelen -= datalen;
- cdata += datalen;
- }
- return totaldata;
-}
-
-static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
-{
- int totlen;
- int i;
- unsigned char *cdata;
-
- totlen=0;
- for (i = 0; i < dataurb->number_of_packets; i++) {
- int n = dataurb->iso_frame_desc[i].actual_length;
- int st = dataurb->iso_frame_desc[i].status;
-
- cdata = dataurb->transfer_buffer +
- dataurb->iso_frame_desc[i].offset;
-
- if (st < 0) {
- dev_warn(&uvd->dev->dev,
- "Data error: packet=%d. len=%d. status=%d.\n",
- i, n, st);
- uvd->stats.iso_err_count++;
- continue;
- }
- if (!n)
- continue;
-
- totlen += qcm_process_frame(uvd, cdata, n);
- }
- return totlen;
-}
-
-static void resubmit_urb(struct uvd *uvd, struct urb *urb)
-{
- int ret;
-
- urb->dev = uvd->dev;
- ret = usb_submit_urb(urb, GFP_ATOMIC);
- if (ret)
- err("usb_submit_urb error (%d)", ret);
-}
-
-static void qcm_isoc_irq(struct urb *urb)
-{
- int len;
- struct uvd *uvd = urb->context;
-
- if (!CAMERA_IS_OPERATIONAL(uvd))
- return;
-
- if (!uvd->streaming)
- return;
-
- uvd->stats.urb_count++;
-
- if (!urb->actual_length) {
- resubmit_urb(uvd, urb);
- return;
- }
-
- len = qcm_compress_iso(uvd, urb);
- resubmit_urb(uvd, urb);
- uvd->stats.urb_length = len;
- uvd->stats.data_count += len;
- if (len)
- RingQueue_WakeUpInterruptible(&uvd->dp);
-}
-
-static int qcm_start_data(struct uvd *uvd)
-{
- struct qcm *cam = (struct qcm *) uvd->user_data;
- int i;
- int errflag;
- int pktsz;
- int err;
-
- pktsz = uvd->iso_packet_len;
- if (!CAMERA_IS_OPERATIONAL(uvd)) {
- err("Camera is not operational");
- return -EFAULT;
- }
-
- err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
- if (err < 0) {
- err("usb_set_interface error");
- uvd->last_error = err;
- return -EBUSY;
- }
-
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- int j, k;
- struct urb *urb = uvd->sbuf[i].urb;
- urb->dev = uvd->dev;
- urb->context = uvd;
- urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
- urb->interval = 1;
- urb->transfer_flags = URB_ISO_ASAP;
- urb->transfer_buffer = uvd->sbuf[i].data;
- urb->complete = qcm_isoc_irq;
- urb->number_of_packets = FRAMES_PER_DESC;
- urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
- for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
- urb->iso_frame_desc[j].offset = k;
- urb->iso_frame_desc[j].length = pktsz;
- }
- }
-
- uvd->streaming = 1;
- uvd->curframe = -1;
- for (i=0; i < USBVIDEO_NUMSBUF; i++) {
- errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
- if (errflag)
- err ("usb_submit_isoc(%d) ret %d", i, errflag);
- }
-
- CHECK_RET(err, qcm_setup_input_int(cam, uvd));
- CHECK_RET(err, qcm_camera_on(uvd));
- return 0;
-}
-
-static void qcm_stop_data(struct uvd *uvd)
-{
- struct qcm *cam;
- int i, j;
- int ret;
-
- if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
- return;
- cam = (struct qcm *) uvd->user_data;
-
- ret = qcm_camera_off(uvd);
- if (ret)
- dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
-
- uvd->streaming = 0;
-
- /* Unschedule all of the iso td's */
- for (i=0; i < USBVIDEO_NUMSBUF; i++)
- usb_kill_urb(uvd->sbuf[i].urb);
-
- qcm_stop_int_data(cam);
-
- if (!uvd->remove_pending) {
- /* Set packet size to 0 */
- j = usb_set_interface(uvd->dev, uvd->iface,
- uvd->ifaceAltInactive);
- if (j < 0) {
- err("usb_set_interface() error %d.", j);
- uvd->last_error = j;
- }
- }
-}
-
-static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
-{
- struct qcm *cam = (struct qcm *) uvd->user_data;
- int x;
- struct rgb *rgbL0;
- struct rgb *rgbL1;
- struct bayL0 *bayL0;
- struct bayL1 *bayL1;
- int hor,ver,hordel,verdel;
- assert(frame != NULL);
-
- switch (cam->size) {
- case SIZE_160X120:
- hor = 162; ver = 124; hordel = 1; verdel = 2;
- break;
- case SIZE_320X240:
- default:
- hor = 324; ver = 248; hordel = 2; verdel = 4;
- break;
- }
-
- if (frame->scanstate == ScanState_Scanning) {
- while (RingQueue_GetLength(&uvd->dp) >=
- 4 + (hor*verdel + hordel)) {
- if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
- (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
- (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
- frame->curline = 0;
- frame->scanstate = ScanState_Lines;
- frame->frameState = FrameState_Grabbing;
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
- /*
- * if we're starting, we need to discard the first
- * 4 lines of y bayer data
- * and the first 2 gr elements of x bayer data
- */
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
- (hor*verdel + hordel));
- break;
- }
- RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
- }
- }
-
- if (frame->scanstate == ScanState_Scanning)
- return;
-
- /* now we can start processing bayer data so long as we have at least
- * 2 lines worth of data. this is the simplest demosaicing method that
- * I could think of. I use each 2x2 bayer element without interpolation
- * to generate 4 rgb pixels.
- */
- while ( frame->curline < cam->height &&
- (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
- /* get 2 lines of bayer for demosaicing
- * into 2 lines of RGB */
- RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
- bayL0 = (struct bayL0 *) cam->scratch;
- bayL1 = (struct bayL1 *) (cam->scratch + hor);
- /* frame->curline is the rgb y line */
- rgbL0 = (struct rgb *)
- ( frame->data + (cam->width*3*frame->curline));
- /* w/2 because we're already doing 2 pixels */
- rgbL1 = rgbL0 + (cam->width/2);
-
- for (x=0; x < cam->width; x+=2) {
- rgbL0->r = bayL0->r;
- rgbL0->g = bayL0->g;
- rgbL0->b = bayL1->b;
-
- rgbL0->r2 = bayL0->r;
- rgbL0->g2 = bayL1->g;
- rgbL0->b2 = bayL1->b;
-
- rgbL1->r = bayL0->r;
- rgbL1->g = bayL1->g;
- rgbL1->b = bayL1->b;
-
- rgbL1->r2 = bayL0->r;
- rgbL1->g2 = bayL1->g;
- rgbL1->b2 = bayL1->b;
-
- rgbL0++;
- rgbL1++;
-
- bayL0++;
- bayL1++;
- }
-
- frame->seqRead_Length += cam->width*3*2;
- frame->curline += 2;
- }
- /* See if we filled the frame */
- if (frame->curline == cam->height) {
- frame->frameState = FrameState_Done_Hold;
- frame->curline = 0;
- uvd->curframe = -1;
- uvd->stats.frame_num++;
- }
-}
-
-/* taken from konicawc */
-static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
-{
- int ret;
- int newsize;
- int oldsize;
- int x = vw->width;
- int y = vw->height;
- struct qcm *cam = (struct qcm *) uvd->user_data;
-
- if (x > 0 && y > 0) {
- DEBUG(2, "trying to find size %d,%d", x, y);
- for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
- if ((camera_sizes[newsize].width == x) &&
- (camera_sizes[newsize].height == y))
- break;
- }
- } else
- newsize = cam->size;
-
- if (newsize > MAX_FRAME_SIZE) {
- DEBUG(1, "couldn't find size %d,%d", x, y);
- return -EINVAL;
- }
-
- if (newsize == cam->size) {
- DEBUG(1, "Nothing to do");
- return 0;
- }
-
- qcm_stop_data(uvd);
-
- if (cam->size != newsize) {
- oldsize = cam->size;
- cam->size = newsize;
- ret = qcm_set_camera_size(uvd);
- if (ret) {
- err("Couldn't set camera size, err=%d",ret);
- /* restore the original size */
- cam->size = oldsize;
- return ret;
- }
- }
-
- /* Flush the input queue and clear any current frame in progress */
-
- RingQueue_Flush(&uvd->dp);
- if (uvd->curframe != -1) {
- uvd->frame[uvd->curframe].curline = 0;
- uvd->frame[uvd->curframe].seqRead_Length = 0;
- uvd->frame[uvd->curframe].seqRead_Index = 0;
- }
-
- CHECK_RET(ret, qcm_start_data(uvd));
- return 0;
-}
-
-static int qcm_configure_video(struct uvd *uvd)
-{
- int ret;
- memset(&uvd->vpic, 0, sizeof(uvd->vpic));
- memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
-
- uvd->vpic.colour = colour;
- uvd->vpic.hue = hue;
- uvd->vpic.brightness = brightness;
- uvd->vpic.contrast = contrast;
- uvd->vpic.whiteness = whiteness;
- uvd->vpic.depth = 24;
- uvd->vpic.palette = VIDEO_PALETTE_RGB24;
-
- memset(&uvd->vcap, 0, sizeof(uvd->vcap));
- strcpy(uvd->vcap.name, "QCM USB Camera");
- uvd->vcap.type = VID_TYPE_CAPTURE;
- uvd->vcap.channels = 1;
- uvd->vcap.audios = 0;
-
- uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
- uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
- uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
- uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
-
- memset(&uvd->vchan, 0, sizeof(uvd->vchan));
- uvd->vchan.flags = 0 ;
- uvd->vchan.tuners = 0;
- uvd->vchan.channel = 0;
- uvd->vchan.type = VIDEO_TYPE_CAMERA;
- strcpy(uvd->vchan.name, "Camera");
-
- CHECK_RET(ret, qcm_sensor_init(uvd));
- return 0;
-}
-
-static int qcm_probe(struct usb_interface *intf,
- const struct usb_device_id *devid)
-{
- int err;
- struct uvd *uvd;
- struct usb_device *dev = interface_to_usbdev(intf);
- struct qcm *cam;
- size_t buffer_size;
- unsigned char video_ep;
- struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
- int i,j;
- unsigned int ifacenum, ifacenum_inact=0;
- __le16 sensor_id;
-
- /* we don't support multiconfig cams */
- if (dev->descriptor.bNumConfigurations != 1)
- return -ENODEV;
-
- /* first check for the video interface and not
- * the audio interface */
- interface = &intf->cur_altsetting[0];
- if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
- || (interface->desc.bInterfaceSubClass !=
- USB_CLASS_VENDOR_SPEC))
- return -ENODEV;
-
- /*
- walk through each endpoint in each setting in the interface
- stop when we find the one that's an isochronous IN endpoint.
- */
- for (i=0; i < intf->num_altsetting; i++) {
- interface = &intf->cur_altsetting[i];
- ifacenum = interface->desc.bAlternateSetting;
- /* walk the end points */
- for (j=0; j < interface->desc.bNumEndpoints; j++) {
- endpoint = &interface->endpoint[j].desc;
-
- if (usb_endpoint_dir_out(endpoint))
- continue; /* not input then not good */
-
- buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
- if (!buffer_size) {
- ifacenum_inact = ifacenum;
- continue; /* 0 pkt size is not what we want */
- }
-
- if (usb_endpoint_xfer_isoc(endpoint)) {
- video_ep = endpoint->bEndpointAddress;
- /* break out of the search */
- goto good_videoep;
- }
- }
- }
- /* failed out since nothing useful was found */
- err("No suitable endpoint was found\n");
- return -ENODEV;
-
-good_videoep:
- /* disable isochronous stream before doing anything else */
- err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
- if (err < 0) {
- err("Failed to disable sensor stream");
- return -EIO;
- }
-
- /*
- Check that this is the same unknown sensor that is known to work. This
- sensor is suspected to be the ST VV6422C001. I'll check the same value
- that the qc-usb driver checks. This value is probably not even the
- sensor ID since it matches the USB dev ID. Oh well. If it doesn't
- match, it's probably a diff sensor so exit and apologize.
- */
- err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
- if (err < 0) {
- err("Couldn't read sensor values. Err %d\n",err);
- return err;
- }
- if (sensor_id != cpu_to_le16(0x08F0)) {
- err("Sensor ID %x != %x. Unsupported. Sorry\n",
- le16_to_cpu(sensor_id), (0x08F0));
- return -ENODEV;
- }
-
- uvd = usbvideo_AllocateDevice(cams);
- if (!uvd)
- return -ENOMEM;
-
- cam = (struct qcm *) uvd->user_data;
-
- /* buf for doing demosaicing */
- cam->scratch = kmalloc(324*2, GFP_KERNEL);
- if (!cam->scratch) /* uvd freed in dereg */
- return -ENOMEM;
-
- /* yes, if we fail after here, cam->scratch gets freed
- by qcm_free_uvd */
-
- err = qcm_alloc_int_urb(cam);
- if (err < 0)
- return err;
-
- /* yes, if we fail after here, int urb gets freed
- by qcm_free_uvd */
-
- RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
- cam->width = camera_sizes[size].width;
- cam->height = camera_sizes[size].height;
- cam->size = size;
-
- uvd->debug = debug;
- uvd->flags = 0;
- uvd->dev = dev;
- uvd->iface = intf->altsetting->desc.bInterfaceNumber;
- uvd->ifaceAltActive = ifacenum;
- uvd->ifaceAltInactive = ifacenum_inact;
- uvd->video_endp = video_ep;
- uvd->iso_packet_len = buffer_size;
- uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
- uvd->defaultPalette = VIDEO_PALETTE_RGB24;
- uvd->canvas = VIDEOSIZE(320, 240);
- uvd->videosize = VIDEOSIZE(cam->width, cam->height);
- err = qcm_configure_video(uvd);
- if (err) {
- err("failed to configure video settings");
- return err;
- }
-
- err = usbvideo_RegisterVideoDevice(uvd);
- if (err) { /* the uvd gets freed in Deregister */
- err("usbvideo_RegisterVideoDevice() failed.");
- return err;
- }
-
- uvd->max_frame_size = (320 * 240 * 3);
- qcm_register_input(cam, dev);
- usb_set_intfdata(intf, uvd);
- return 0;
-}
-
-static void qcm_free_uvd(struct uvd *uvd)
-{
- struct qcm *cam = (struct qcm *) uvd->user_data;
-
- kfree(cam->scratch);
- qcm_unregister_input(cam);
- qcm_free_int(cam);
-}
-
-static struct usbvideo_cb qcm_driver = {
- .probe = qcm_probe,
- .setupOnOpen = qcm_setup_on_open,
- .processData = qcm_process_isoc,
- .setVideoMode = qcm_set_video_mode,
- .startDataPump = qcm_start_data,
- .stopDataPump = qcm_stop_data,
- .adjustPicture = qcm_adjust_picture,
- .userFree = qcm_free_uvd
-};
-
-static int __init qcm_init(void)
-{
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
- DRIVER_DESC "\n");
-
- return usbvideo_register(
- &cams,
- MAX_CAMERAS,
- sizeof(struct qcm),
- "QCM",
- &qcm_driver,
- THIS_MODULE,
- qcm_table);
-}
-
-static void __exit qcm_exit(void)
-{
- usbvideo_Deregister(&cams);
-}
-
-module_param(size, int, 0);
-MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
-module_param(colour, int, 0);
-MODULE_PARM_DESC(colour, "Initial colour");
-module_param(hue, int, 0);
-MODULE_PARM_DESC(hue, "Initial hue");
-module_param(brightness, int, 0);
-MODULE_PARM_DESC(brightness, "Initial brightness");
-module_param(contrast, int, 0);
-MODULE_PARM_DESC(contrast, "Initial contrast");
-module_param(whiteness, int, 0);
-MODULE_PARM_DESC(whiteness, "Initial whiteness");
-
-#ifdef CONFIG_USB_DEBUG
-module_param(debug, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
-#endif
-
-module_init(qcm_init);
-module_exit(qcm_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Jaya Kumar");
-MODULE_DESCRIPTION("QCM USB Camera");
-MODULE_SUPPORTED_DEVICE("QCM USB Camera");
diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h
deleted file mode 100644
index 17ace394d981..000000000000
--- a/drivers/media/video/usbvideo/quickcam_messenger.h
+++ /dev/null
@@ -1,112 +0,0 @@
-#ifndef quickcam_messenger_h
-#define quickcam_messenger_h
-
-#ifndef CONFIG_INPUT
-/* if we're not using input we dummy out these functions */
-#define qcm_register_input(...)
-#define qcm_unregister_input(...)
-#define qcm_report_buttonstat(...)
-#define qcm_setup_input_int(...) 0
-#define qcm_stop_int_data(...)
-#define qcm_alloc_int_urb(...) 0
-#define qcm_free_int(...)
-#endif
-
-
-#define CHECK_RET(ret, expr) \
- if ((ret = expr) < 0) return ret
-
-/* Control Registers for the STVV6422 ASIC
- * - this define is taken from the qc-usb-messenger code
- */
-#define STV_ISO_ENABLE 0x1440
-#define ISOC_PACKET_SIZE 1023
-
-/* Chip identification number including revision indicator */
-#define CMOS_SENSOR_IDREV 0xE00A
-
-struct rgb {
- u8 b;
- u8 g;
- u8 r;
- u8 b2;
- u8 g2;
- u8 r2;
-};
-
-struct bayL0 {
- u8 g;
- u8 r;
-};
-
-struct bayL1 {
- u8 b;
- u8 g;
-};
-
-struct cam_size {
- u16 width;
- u16 height;
- u8 cmd;
-};
-
-static const struct cam_size camera_sizes[] = {
- { 160, 120, 0xf },
- { 320, 240, 0x2 },
-};
-
-enum frame_sizes {
- SIZE_160X120 = 0,
- SIZE_320X240 = 1,
-};
-
-#define MAX_FRAME_SIZE SIZE_320X240
-
-struct qcm {
- u16 colour;
- u16 hue;
- u16 brightness;
- u16 contrast;
- u16 whiteness;
-
- u8 size;
- int height;
- int width;
- u8 *scratch;
- struct urb *button_urb;
- u8 button_sts;
- u8 button_sts_buf;
-
-#ifdef CONFIG_INPUT
- struct input_dev *input;
- char input_physname[64];
-#endif
-};
-
-struct regval {
- u16 reg;
- u8 val;
-};
-/* this table is derived from the
-qc-usb-messenger code */
-static const struct regval regval_table[] = {
- { STV_ISO_ENABLE, 0x00 },
- { 0x1436, 0x00 }, { 0x1432, 0x03 },
- { 0x143a, 0xF9 }, { 0x0509, 0x38 },
- { 0x050a, 0x38 }, { 0x050b, 0x38 },
- { 0x050c, 0x2A }, { 0x050d, 0x01 },
- { 0x1431, 0x00 }, { 0x1433, 0x34 },
- { 0x1438, 0x18 }, { 0x1439, 0x00 },
- { 0x143b, 0x05 }, { 0x143c, 0x00 },
- { 0x143e, 0x01 }, { 0x143d, 0x00 },
- { 0x1442, 0xe2 }, { 0x1500, 0xd0 },
- { 0x1500, 0xd0 }, { 0x1500, 0x50 },
- { 0x1501, 0xaf }, { 0x1502, 0xc2 },
- { 0x1503, 0x45 }, { 0x1505, 0x02 },
- { 0x150e, 0x8e }, { 0x150f, 0x37 },
- { 0x15c0, 0x00 },
-};
-
-static const unsigned char marker[] = { 0x00, 0xff, 0x00, 0xFF };
-
-#endif /* quickcam_messenger_h */
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 27a79f087b15..a350fad0db43 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -606,6 +606,26 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
.set = uvc_ctrl_set_zoom,
},
{
+ .id = V4L2_CID_PAN_ABSOLUTE,
+ .name = "Pan (Absolute)",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
+ .size = 32,
+ .offset = 0,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
+ .id = V4L2_CID_TILT_ABSOLUTE,
+ .name = "Tilt (Absolute)",
+ .entity = UVC_GUID_UVC_CAMERA,
+ .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL,
+ .size = 32,
+ .offset = 32,
+ .v4l2_type = V4L2_CTRL_TYPE_INTEGER,
+ .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED,
+ },
+ {
.id = V4L2_CID_PRIVACY,
.name = "Privacy",
.entity = UVC_GUID_UVC_CAMERA,
@@ -623,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
{
- return ctrl->data + id * ctrl->info->size;
+ return ctrl->uvc_data + id * ctrl->info->size;
}
static inline int uvc_test_bit(const __u8 *data, int bit)
@@ -678,6 +698,14 @@ static void uvc_set_le_value(struct uvc_control_mapping *mapping,
int offset = mapping->offset;
__u8 mask;
+ /* According to the v4l2 spec, writing any value to a button control
+ * should result in the action belonging to the button control being
+ * triggered. UVC devices however want to see a 1 written -> override
+ * value.
+ */
+ if (mapping->v4l2_type == V4L2_CTRL_TYPE_BUTTON)
+ value = -1;
+
data += offset / 8;
offset &= 7;
@@ -1265,13 +1293,15 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
* Control and mapping handling
*/
-static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
+static int uvc_ctrl_add_ctrl(struct uvc_device *dev,
struct uvc_control_info *info)
{
struct uvc_entity *entity;
struct uvc_control *ctrl = NULL;
- int ret, found = 0;
+ int ret = 0, found = 0;
unsigned int i;
+ u8 *uvc_info;
+ u8 *uvc_data;
list_for_each_entry(entity, &dev->entities, list) {
if (!uvc_entity_match_guid(entity, info->entity))
@@ -1290,56 +1320,69 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
}
if (!found)
- return;
+ return 0;
+
+ uvc_data = kmalloc(info->size * UVC_CTRL_DATA_LAST + 1, GFP_KERNEL);
+ if (uvc_data == NULL)
+ return -ENOMEM;
+
+ uvc_info = uvc_data + info->size * UVC_CTRL_DATA_LAST;
if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
/* Check if the device control information and length match
* the user supplied information.
*/
- __u32 flags;
- __le16 size;
- __u8 inf;
-
ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
- dev->intfnum, info->selector, (__u8 *)&size, 2);
+ dev->intfnum, info->selector, uvc_data, 2);
if (ret < 0) {
uvc_trace(UVC_TRACE_CONTROL,
"GET_LEN failed on control %pUl/%u (%d).\n",
info->entity, info->selector, ret);
- return;
+ goto done;
}
- if (info->size != le16_to_cpu(size)) {
+ if (info->size != le16_to_cpu(*(__le16 *)uvc_data)) {
uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size "
"doesn't match user supplied value.\n",
info->entity, info->selector);
- return;
+ ret = -EINVAL;
+ goto done;
}
ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
- dev->intfnum, info->selector, &inf, 1);
+ dev->intfnum, info->selector, uvc_info, 1);
if (ret < 0) {
uvc_trace(UVC_TRACE_CONTROL,
"GET_INFO failed on control %pUl/%u (%d).\n",
info->entity, info->selector, ret);
- return;
+ goto done;
}
- flags = info->flags;
- if (((flags & UVC_CONTROL_GET_CUR) && !(inf & (1 << 0))) ||
- ((flags & UVC_CONTROL_SET_CUR) && !(inf & (1 << 1)))) {
+ if (((info->flags & UVC_CONTROL_GET_CUR) &&
+ !(*uvc_info & UVC_CONTROL_CAP_GET)) ||
+ ((info->flags & UVC_CONTROL_SET_CUR) &&
+ !(*uvc_info & UVC_CONTROL_CAP_SET))) {
uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags "
"don't match supported operations.\n",
info->entity, info->selector);
- return;
+ ret = -EINVAL;
+ goto done;
}
}
ctrl->info = info;
- ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL);
+ ctrl->uvc_data = uvc_data;
+ ctrl->uvc_info = uvc_info;
+
uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
"entity %u\n", ctrl->info->entity, ctrl->info->selector,
dev->udev->devpath, entity->id);
+
+done:
+ if (ret < 0)
+ kfree(uvc_data);
+
+ return ret;
}
/*
@@ -1572,12 +1615,34 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev)
list_for_each_entry(entity, &dev->entities, list) {
for (i = 0; i < entity->ncontrols; ++i)
- kfree(entity->controls[i].data);
+ kfree(entity->controls[i].uvc_data);
kfree(entity->controls);
}
}
+void uvc_ctrl_cleanup(void)
+{
+ struct uvc_control_info *info;
+ struct uvc_control_info *ni;
+ struct uvc_control_mapping *mapping;
+ struct uvc_control_mapping *nm;
+
+ list_for_each_entry_safe(info, ni, &uvc_driver.controls, list) {
+ if (!(info->flags & UVC_CONTROL_EXTENSION))
+ continue;
+
+ list_for_each_entry_safe(mapping, nm, &info->mappings, list) {
+ list_del(&mapping->list);
+ kfree(mapping->menu_info);
+ kfree(mapping);
+ }
+
+ list_del(&info->list);
+ kfree(info);
+ }
+}
+
void uvc_ctrl_init(void)
{
struct uvc_control_info *ctrl = uvc_ctrls;
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 838b56f097cf..7eaf99b22a48 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -637,14 +637,13 @@ static int uvc_parse_streaming(struct uvc_device *dev,
}
streaming->header.bControlSize = n;
- streaming->header.bmaControls = kmalloc(p*n, GFP_KERNEL);
+ streaming->header.bmaControls = kmemdup(&buffer[size], p * n,
+ GFP_KERNEL);
if (streaming->header.bmaControls == NULL) {
ret = -ENOMEM;
goto error;
}
- memcpy(streaming->header.bmaControls, &buffer[size], p*n);
-
buflen -= buffer[0];
buffer += buffer[0];
@@ -2174,6 +2173,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
+ /* Manta MM-353 Plako */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x18ec,
+ .idProduct = 0x3188,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* FSC WebCam V30S */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2261,6 +2269,7 @@ static int __init uvc_init(void)
static void __exit uvc_cleanup(void)
{
usb_deregister(&uvc_driver.driver);
+ uvc_ctrl_cleanup();
}
module_init(uvc_init);
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 7c9ab2933496..369ce06be035 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -29,6 +29,71 @@
#include "uvcvideo.h"
/* ------------------------------------------------------------------------
+ * UVC ioctls
+ */
+static int uvc_ioctl_ctrl_map(struct uvc_xu_control_mapping *xmap, int old)
+{
+ struct uvc_control_mapping *map;
+ unsigned int size;
+ int ret;
+
+ map = kzalloc(sizeof *map, GFP_KERNEL);
+ if (map == NULL)
+ return -ENOMEM;
+
+ map->id = xmap->id;
+ memcpy(map->name, xmap->name, sizeof map->name);
+ memcpy(map->entity, xmap->entity, sizeof map->entity);
+ map->selector = xmap->selector;
+ map->size = xmap->size;
+ map->offset = xmap->offset;
+ map->v4l2_type = xmap->v4l2_type;
+ map->data_type = xmap->data_type;
+
+ switch (xmap->v4l2_type) {
+ case V4L2_CTRL_TYPE_INTEGER:
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_BUTTON:
+ break;
+
+ case V4L2_CTRL_TYPE_MENU:
+ if (old) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ size = xmap->menu_count * sizeof(*map->menu_info);
+ map->menu_info = kmalloc(size, GFP_KERNEL);
+ if (map->menu_info == NULL) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ if (copy_from_user(map->menu_info, xmap->menu_info, size)) {
+ ret = -EFAULT;
+ goto done;
+ }
+
+ map->menu_count = xmap->menu_count;
+ break;
+
+ default:
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = uvc_ctrl_add_mapping(map);
+
+done:
+ if (ret < 0) {
+ kfree(map->menu_info);
+ kfree(map);
+ }
+
+ return ret;
+}
+
+/* ------------------------------------------------------------------------
* V4L2 interface
*/
@@ -963,6 +1028,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ if (xinfo->size == 0)
+ return -EINVAL;
+
info = kzalloc(sizeof *info, GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
@@ -974,7 +1042,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
info->flags = xinfo->flags;
info->flags |= UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
- UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF;
+ UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF |
+ UVC_CONTROL_EXTENSION;
ret = uvc_ctrl_add_info(info);
if (ret < 0)
@@ -982,32 +1051,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
break;
}
+ case UVCIOC_CTRL_MAP_OLD:
case UVCIOC_CTRL_MAP:
- {
- struct uvc_xu_control_mapping *xmap = arg;
- struct uvc_control_mapping *map;
-
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- map = kzalloc(sizeof *map, GFP_KERNEL);
- if (map == NULL)
- return -ENOMEM;
-
- map->id = xmap->id;
- memcpy(map->name, xmap->name, sizeof map->name);
- memcpy(map->entity, xmap->entity, sizeof map->entity);
- map->selector = xmap->selector;
- map->size = xmap->size;
- map->offset = xmap->offset;
- map->v4l2_type = xmap->v4l2_type;
- map->data_type = xmap->data_type;
-
- ret = uvc_ctrl_add_mapping(map);
- if (ret < 0)
- kfree(map);
- break;
- }
+ return uvc_ioctl_ctrl_map(arg, cmd == UVCIOC_CTRL_MAP_OLD);
case UVCIOC_CTRL_GET:
return uvc_xu_ctrl_query(chain, arg, 0);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index d1f88406a5e7..47b20e7e3786 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -27,6 +27,8 @@
#define UVC_CONTROL_RESTORE (1 << 6)
/* Control can be updated by the camera. */
#define UVC_CONTROL_AUTO_UPDATE (1 << 7)
+/* Control is an extension unit control. */
+#define UVC_CONTROL_EXTENSION (1 << 8)
#define UVC_CONTROL_GET_RANGE (UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
@@ -40,6 +42,15 @@ struct uvc_xu_control_info {
__u32 flags;
};
+struct uvc_menu_info {
+ __u32 value;
+ __u8 name[32];
+};
+
+struct uvc_xu_control_mapping_old {
+ __u8 reserved[64];
+};
+
struct uvc_xu_control_mapping {
__u32 id;
__u8 name[32];
@@ -50,6 +61,11 @@ struct uvc_xu_control_mapping {
__u8 offset;
enum v4l2_ctrl_type v4l2_type;
__u32 data_type;
+
+ struct uvc_menu_info __user *menu_info;
+ __u32 menu_count;
+
+ __u32 reserved[4];
};
struct uvc_xu_control {
@@ -60,6 +76,7 @@ struct uvc_xu_control {
};
#define UVCIOC_CTRL_ADD _IOW('U', 1, struct uvc_xu_control_info)
+#define UVCIOC_CTRL_MAP_OLD _IOWR('U', 2, struct uvc_xu_control_mapping_old)
#define UVCIOC_CTRL_MAP _IOWR('U', 2, struct uvc_xu_control_mapping)
#define UVCIOC_CTRL_GET _IOWR('U', 3, struct uvc_xu_control)
#define UVCIOC_CTRL_SET _IOW('U', 4, struct uvc_xu_control)
@@ -198,11 +215,6 @@ struct uvc_streaming_control {
__u8 bMaxVersion;
};
-struct uvc_menu_info {
- __u32 value;
- __u8 name[32];
-};
-
struct uvc_control_info {
struct list_head list;
struct list_head mappings;
@@ -250,7 +262,8 @@ struct uvc_control {
modified : 1,
cached : 1;
- __u8 *data;
+ __u8 *uvc_data;
+ __u8 *uvc_info;
};
struct uvc_format_desc {
@@ -625,6 +638,7 @@ extern int uvc_ctrl_init_device(struct uvc_device *dev);
extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
extern int uvc_ctrl_resume_device(struct uvc_device *dev);
extern void uvc_ctrl_init(void);
+extern void uvc_ctrl_cleanup(void);
extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback);
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 4e53b0b3339c..861ff50e569c 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -850,7 +850,8 @@ struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
/* Create the i2c client */
if (info->addr == 0 && probe_addrs)
- client = i2c_new_probed_device(adapter, info, probe_addrs);
+ client = i2c_new_probed_device(adapter, info, probe_addrs,
+ NULL);
else
client = i2c_new_device(adapter, info);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 0ca7ec9ca902..9e89bf617790 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -410,7 +410,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
int minor_offset = 0;
int minor_cnt = VIDEO_NUM_DEVICES;
const char *name_base;
- void *priv = video_get_drvdata(vdev);
+ void *priv = vdev->dev.p;
/* A minor value of -1 marks this video device as never
having been registered */
@@ -536,9 +536,9 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
/* Part 4: register the device with sysfs */
memset(&vdev->dev, 0, sizeof(vdev->dev));
- /* The memset above cleared the device's drvdata, so
+ /* The memset above cleared the device's device_private, so
put back the copy we made earlier. */
- video_set_drvdata(vdev, priv);
+ vdev->dev.p = priv;
vdev->dev.class = &video_class;
vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
if (vdev->parent)
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index 7d3378437ded..ce1595bef629 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -52,18 +52,18 @@ MODULE_LICENSE("GPL");
#define CALL(q, f, arg...) \
((q->int_ops->f) ? q->int_ops->f(arg) : 0)
-struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q)
+struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q)
{
struct videobuf_buffer *vb;
BUG_ON(q->msize < sizeof(*vb));
- if (!q->int_ops || !q->int_ops->alloc) {
+ if (!q->int_ops || !q->int_ops->alloc_vb) {
printk(KERN_ERR "No specific ops defined!\n");
BUG();
}
- vb = q->int_ops->alloc(q->msize);
+ vb = q->int_ops->alloc_vb(q->msize);
if (NULL != vb) {
init_waitqueue_head(&vb->done);
vb->magic = MAGIC_BUFFER;
@@ -71,7 +71,7 @@ struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q)
return vb;
}
-EXPORT_SYMBOL_GPL(videobuf_alloc);
+EXPORT_SYMBOL_GPL(videobuf_alloc_vb);
#define WAITON_CONDITION (vb->state != VIDEOBUF_ACTIVE &&\
vb->state != VIDEOBUF_QUEUED)
@@ -195,6 +195,45 @@ int videobuf_queue_is_busy(struct videobuf_queue *q)
}
EXPORT_SYMBOL_GPL(videobuf_queue_is_busy);
+/**
+ * __videobuf_free() - free all the buffers and their control structures
+ *
+ * This function can only be called if streaming/reading is off, i.e. no buffers
+ * are under control of the driver.
+ */
+/* Locking: Caller holds q->vb_lock */
+static int __videobuf_free(struct videobuf_queue *q)
+{
+ int i;
+
+ dprintk(1, "%s\n", __func__);
+ if (!q)
+ return 0;
+
+ if (q->streaming || q->reading) {
+ dprintk(1, "Cannot free buffers when streaming or reading\n");
+ return -EBUSY;
+ }
+
+ MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+
+ for (i = 0; i < VIDEO_MAX_FRAME; i++)
+ if (q->bufs[i] && q->bufs[i]->map) {
+ dprintk(1, "Cannot free mmapped buffers\n");
+ return -EBUSY;
+ }
+
+ for (i = 0; i < VIDEO_MAX_FRAME; i++) {
+ if (NULL == q->bufs[i])
+ continue;
+ q->ops->buf_release(q, q->bufs[i]);
+ kfree(q->bufs[i]);
+ q->bufs[i] = NULL;
+ }
+
+ return 0;
+}
+
/* Locking: Caller holds q->vb_lock */
void videobuf_queue_cancel(struct videobuf_queue *q)
{
@@ -308,36 +347,11 @@ static void videobuf_status(struct videobuf_queue *q, struct v4l2_buffer *b,
b->sequence = vb->field_count >> 1;
}
-/* Locking: Caller holds q->vb_lock */
-static int __videobuf_mmap_free(struct videobuf_queue *q)
-{
- int i;
-
- if (!q)
- return 0;
-
- MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++)
- if (q->bufs[i] && q->bufs[i]->map)
- return -EBUSY;
-
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- if (NULL == q->bufs[i])
- continue;
- q->ops->buf_release(q, q->bufs[i]);
- kfree(q->bufs[i]);
- q->bufs[i] = NULL;
- }
-
- return 0;
-}
-
int videobuf_mmap_free(struct videobuf_queue *q)
{
int ret;
mutex_lock(&q->vb_lock);
- ret = __videobuf_mmap_free(q);
+ ret = __videobuf_free(q);
mutex_unlock(&q->vb_lock);
return ret;
}
@@ -353,13 +367,13 @@ int __videobuf_mmap_setup(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
- err = __videobuf_mmap_free(q);
+ err = __videobuf_free(q);
if (0 != err)
return err;
/* Allocate and initialize buffers */
for (i = 0; i < bcount; i++) {
- q->bufs[i] = videobuf_alloc(q);
+ q->bufs[i] = videobuf_alloc_vb(q);
if (NULL == q->bufs[i])
break;
@@ -766,7 +780,7 @@ static ssize_t videobuf_read_zerocopy(struct videobuf_queue *q,
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
/* setup stuff */
- q->read_buf = videobuf_alloc(q);
+ q->read_buf = videobuf_alloc_vb(q);
if (NULL == q->read_buf)
return -ENOMEM;
@@ -871,7 +885,7 @@ ssize_t videobuf_read_one(struct videobuf_queue *q,
if (NULL == q->read_buf) {
/* need to capture a new frame */
retval = -ENOMEM;
- q->read_buf = videobuf_alloc(q);
+ q->read_buf = videobuf_alloc_vb(q);
dprintk(1, "video alloc=0x%p\n", q->read_buf);
if (NULL == q->read_buf)
@@ -970,7 +984,7 @@ static void __videobuf_read_stop(struct videobuf_queue *q)
int i;
videobuf_queue_cancel(q);
- __videobuf_mmap_free(q);
+ __videobuf_free(q);
INIT_LIST_HEAD(&q->stream);
for (i = 0; i < VIDEO_MAX_FRAME; i++) {
if (NULL == q->bufs[i])
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 74730c624cfc..372b87efcd05 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -190,7 +190,7 @@ static int videobuf_dma_contig_user_get(struct videobuf_dma_contig_memory *mem,
return ret;
}
-static struct videobuf_buffer *__videobuf_alloc(size_t size)
+static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
{
struct videobuf_dma_contig_memory *mem;
struct videobuf_buffer *vb;
@@ -280,8 +280,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
return -ENOMEM;
buf->map = map;
- map->start = vma->vm_start;
- map->end = vma->vm_end;
map->q = q;
buf->baddr = vma->vm_start;
@@ -338,7 +336,7 @@ error:
static struct videobuf_qtype_ops qops = {
.magic = MAGIC_QTYPE_OPS,
- .alloc = __videobuf_alloc,
+ .alloc_vb = __videobuf_alloc_vb,
.iolock = __videobuf_iolock,
.mmap_mapper = __videobuf_mmap_mapper,
.vaddr = __videobuf_to_vaddr,
diff --git a/drivers/media/video/videobuf-dma-sg.c b/drivers/media/video/videobuf-dma-sg.c
index 8359e6badd36..06f9a9c2a39a 100644
--- a/drivers/media/video/videobuf-dma-sg.c
+++ b/drivers/media/video/videobuf-dma-sg.c
@@ -57,7 +57,13 @@ MODULE_LICENSE("GPL");
/* --------------------------------------------------------------------- */
-struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
+/*
+ * Return a scatterlist for some page-aligned vmalloc()'ed memory
+ * block (NULL on errors). Memory for the scatterlist is allocated
+ * using kmalloc. The caller must free the memory.
+ */
+static struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt,
+ int nr_pages)
{
struct scatterlist *sglist;
struct page *pg;
@@ -81,10 +87,14 @@ err:
vfree(sglist);
return NULL;
}
-EXPORT_SYMBOL_GPL(videobuf_vmalloc_to_sg);
-struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages,
- int offset)
+/*
+ * Return a scatterlist for a an array of userpages (NULL on errors).
+ * Memory for the scatterlist is allocated using kmalloc. The caller
+ * must free the memory.
+ */
+static struct scatterlist *videobuf_pages_to_sg(struct page **pages,
+ int nr_pages, int offset)
{
struct scatterlist *sglist;
int i;
@@ -201,17 +211,17 @@ int videobuf_dma_init_kernel(struct videobuf_dmabuf *dma, int direction,
dprintk(1, "init kernel [%d pages]\n", nr_pages);
dma->direction = direction;
- dma->vmalloc = vmalloc_32(nr_pages << PAGE_SHIFT);
- if (NULL == dma->vmalloc) {
+ dma->vaddr = vmalloc_32(nr_pages << PAGE_SHIFT);
+ if (NULL == dma->vaddr) {
dprintk(1, "vmalloc_32(%d pages) failed\n", nr_pages);
return -ENOMEM;
}
dprintk(1, "vmalloc is at addr 0x%08lx, size=%d\n",
- (unsigned long)dma->vmalloc,
+ (unsigned long)dma->vaddr,
nr_pages << PAGE_SHIFT);
- memset(dma->vmalloc, 0, nr_pages << PAGE_SHIFT);
+ memset(dma->vaddr, 0, nr_pages << PAGE_SHIFT);
dma->nr_pages = nr_pages;
return 0;
@@ -235,7 +245,7 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
}
EXPORT_SYMBOL_GPL(videobuf_dma_init_overlay);
-int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
+int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
{
MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
BUG_ON(0 == dma->nr_pages);
@@ -244,8 +254,8 @@ int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
dma->sglist = videobuf_pages_to_sg(dma->pages, dma->nr_pages,
dma->offset);
}
- if (dma->vmalloc) {
- dma->sglist = videobuf_vmalloc_to_sg(dma->vmalloc,
+ if (dma->vaddr) {
+ dma->sglist = videobuf_vmalloc_to_sg(dma->vaddr,
dma->nr_pages);
}
if (dma->bus_addr) {
@@ -263,7 +273,7 @@ int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
return -ENOMEM;
}
if (!dma->bus_addr) {
- dma->sglen = dma_map_sg(q->dev, dma->sglist,
+ dma->sglen = dma_map_sg(dev, dma->sglist,
dma->nr_pages, dma->direction);
if (0 == dma->sglen) {
printk(KERN_WARNING
@@ -279,14 +289,14 @@ int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
}
EXPORT_SYMBOL_GPL(videobuf_dma_map);
-int videobuf_dma_unmap(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
+int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma)
{
MAGIC_CHECK(dma->magic, MAGIC_DMABUF);
if (!dma->sglen)
return 0;
- dma_unmap_sg(q->dev, dma->sglist, dma->sglen, dma->direction);
+ dma_unmap_sg(dev, dma->sglist, dma->sglen, dma->direction);
vfree(dma->sglist);
dma->sglist = NULL;
@@ -309,8 +319,8 @@ int videobuf_dma_free(struct videobuf_dmabuf *dma)
dma->pages = NULL;
}
- vfree(dma->vmalloc);
- dma->vmalloc = NULL;
+ vfree(dma->vaddr);
+ dma->vaddr = NULL;
if (dma->bus_addr)
dma->bus_addr = 0;
@@ -322,28 +332,6 @@ EXPORT_SYMBOL_GPL(videobuf_dma_free);
/* --------------------------------------------------------------------- */
-int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma)
-{
- struct videobuf_queue q;
-
- q.dev = dev;
-
- return videobuf_dma_map(&q, dma);
-}
-EXPORT_SYMBOL_GPL(videobuf_sg_dma_map);
-
-int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma)
-{
- struct videobuf_queue q;
-
- q.dev = dev;
-
- return videobuf_dma_unmap(&q, dma);
-}
-EXPORT_SYMBOL_GPL(videobuf_sg_dma_unmap);
-
-/* --------------------------------------------------------------------- */
-
static void videobuf_vm_open(struct vm_area_struct *vma)
{
struct videobuf_mapping *map = vma->vm_private_data;
@@ -428,7 +416,7 @@ static const struct vm_operations_struct videobuf_vm_ops = {
struct videobuf_dma_sg_memory
*/
-static struct videobuf_buffer *__videobuf_alloc(size_t size)
+static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
{
struct videobuf_dma_sg_memory *mem;
struct videobuf_buffer *vb;
@@ -456,7 +444,7 @@ static void *__videobuf_to_vaddr(struct videobuf_buffer *buf)
MAGIC_CHECK(mem->magic, MAGIC_SG_MEM);
- return mem->dma.vmalloc;
+ return mem->dma.vaddr;
}
static int __videobuf_iolock(struct videobuf_queue *q,
@@ -520,7 +508,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
default:
BUG();
}
- err = videobuf_dma_map(q, &mem->dma);
+ err = videobuf_dma_map(q->dev, &mem->dma);
if (0 != err)
return err;
@@ -620,8 +608,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
}
map->count = 1;
- map->start = vma->vm_start;
- map->end = vma->vm_end;
map->q = q;
vma->vm_ops = &videobuf_vm_ops;
vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
@@ -638,7 +624,7 @@ done:
static struct videobuf_qtype_ops sg_ops = {
.magic = MAGIC_QTYPE_OPS,
- .alloc = __videobuf_alloc,
+ .alloc_vb = __videobuf_alloc_vb,
.iolock = __videobuf_iolock,
.sync = __videobuf_sync,
.mmap_mapper = __videobuf_mmap_mapper,
@@ -654,7 +640,7 @@ void *videobuf_sg_alloc(size_t size)
q.msize = size;
- return videobuf_alloc(&q);
+ return videobuf_alloc_vb(&q);
}
EXPORT_SYMBOL_GPL(videobuf_sg_alloc);
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index 583728f4c221..e7fe31d54f07 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -102,10 +102,10 @@ static void videobuf_vm_close(struct vm_area_struct *vma)
called with IRQ's disabled
*/
dprintk(1, "%s: buf[%d] freeing (%p)\n",
- __func__, i, mem->vmalloc);
+ __func__, i, mem->vaddr);
- vfree(mem->vmalloc);
- mem->vmalloc = NULL;
+ vfree(mem->vaddr);
+ mem->vaddr = NULL;
}
q->bufs[i]->map = NULL;
@@ -135,7 +135,7 @@ static const struct vm_operations_struct videobuf_vm_ops = {
struct videobuf_dma_sg_memory
*/
-static struct videobuf_buffer *__videobuf_alloc(size_t size)
+static struct videobuf_buffer *__videobuf_alloc_vb(size_t size)
{
struct videobuf_vmalloc_memory *mem;
struct videobuf_buffer *vb;
@@ -170,7 +170,7 @@ static int __videobuf_iolock(struct videobuf_queue *q,
dprintk(1, "%s memory method MMAP\n", __func__);
/* All handling should be done by __videobuf_mmap_mapper() */
- if (!mem->vmalloc) {
+ if (!mem->vaddr) {
printk(KERN_ERR "memory is not alloced/mmapped.\n");
return -EINVAL;
}
@@ -189,13 +189,13 @@ static int __videobuf_iolock(struct videobuf_queue *q,
* read() method.
*/
- mem->vmalloc = vmalloc_user(pages);
- if (!mem->vmalloc) {
+ mem->vaddr = vmalloc_user(pages);
+ if (!mem->vaddr) {
printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
return -ENOMEM;
}
dprintk(1, "vmalloc is at addr %p (%d pages)\n",
- mem->vmalloc, pages);
+ mem->vaddr, pages);
#if 0
int rc;
@@ -245,8 +245,6 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
return -ENOMEM;
buf->map = map;
- map->start = vma->vm_start;
- map->end = vma->vm_end;
map->q = q;
buf->baddr = vma->vm_start;
@@ -256,18 +254,18 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
pages = PAGE_ALIGN(vma->vm_end - vma->vm_start);
- mem->vmalloc = vmalloc_user(pages);
- if (!mem->vmalloc) {
+ mem->vaddr = vmalloc_user(pages);
+ if (!mem->vaddr) {
printk(KERN_ERR "vmalloc (%d pages) failed\n", pages);
goto error;
}
- dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vmalloc, pages);
+ dprintk(1, "vmalloc is at addr %p (%d pages)\n", mem->vaddr, pages);
/* Try to remap memory */
- retval = remap_vmalloc_range(vma, mem->vmalloc, 0);
+ retval = remap_vmalloc_range(vma, mem->vaddr, 0);
if (retval < 0) {
printk(KERN_ERR "mmap: remap failed with error %d. ", retval);
- vfree(mem->vmalloc);
+ vfree(mem->vaddr);
goto error;
}
@@ -293,7 +291,7 @@ error:
static struct videobuf_qtype_ops qops = {
.magic = MAGIC_QTYPE_OPS,
- .alloc = __videobuf_alloc,
+ .alloc_vb = __videobuf_alloc_vb,
.iolock = __videobuf_iolock,
.mmap_mapper = __videobuf_mmap_mapper,
.vaddr = videobuf_to_vmalloc,
@@ -319,7 +317,7 @@ void *videobuf_to_vmalloc(struct videobuf_buffer *buf)
BUG_ON(!mem);
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
- return mem->vmalloc;
+ return mem->vaddr;
}
EXPORT_SYMBOL_GPL(videobuf_to_vmalloc);
@@ -341,8 +339,8 @@ void videobuf_vmalloc_free(struct videobuf_buffer *buf)
MAGIC_CHECK(mem->magic, MAGIC_VMAL_MEM);
- vfree(mem->vmalloc);
- mem->vmalloc = NULL;
+ vfree(mem->vaddr);
+ mem->vaddr = NULL;
return;
}
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
deleted file mode 100644
index d807eea91757..000000000000
--- a/drivers/media/video/w9968cf.c
+++ /dev/null
@@ -1,3620 +0,0 @@
-/***************************************************************************
- * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
- * *
- * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * - Memory management code from bttv driver by Ralph Metzler, *
- * Marcus Metzler and Gerd Knorr. *
- * - I2C interface to kernel, high-level image sensor control routines and *
- * some symbolic names from OV511 driver by Mark W. McClelland. *
- * - Low-level I2C fast write function by Piotr Czerczak. *
- * - Low-level I2C read function by Frederic Jouault. *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/kmod.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/vmalloc.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/ioctl.h>
-#include <linux/delay.h>
-#include <linux/stddef.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-#include <linux/page-flags.h>
-#include <linux/videodev.h>
-#include <media/v4l2-ioctl.h>
-
-#include "w9968cf.h"
-#include "w9968cf_decoder.h"
-
-static struct w9968cf_vpp_t* w9968cf_vpp;
-static DECLARE_WAIT_QUEUE_HEAD(w9968cf_vppmod_wait);
-
-static LIST_HEAD(w9968cf_dev_list); /* head of V4L registered cameras list */
-static DEFINE_MUTEX(w9968cf_devlist_mutex); /* semaphore for list traversal */
-
-static DECLARE_RWSEM(w9968cf_disconnect); /* prevent races with open() */
-
-
-/****************************************************************************
- * Module macros and parameters *
- ****************************************************************************/
-
-MODULE_DEVICE_TABLE(usb, winbond_id_table);
-
-MODULE_AUTHOR(W9968CF_MODULE_AUTHOR" "W9968CF_AUTHOR_EMAIL);
-MODULE_DESCRIPTION(W9968CF_MODULE_NAME);
-MODULE_VERSION(W9968CF_MODULE_VERSION);
-MODULE_LICENSE(W9968CF_MODULE_LICENSE);
-MODULE_SUPPORTED_DEVICE("Video");
-
-static unsigned short simcams = W9968CF_SIMCAMS;
-static short video_nr[]={[0 ... W9968CF_MAX_DEVICES-1] = -1}; /*-1=first free*/
-static unsigned int packet_size[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_PACKET_SIZE};
-static unsigned short max_buffers[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_BUFFERS};
-static int double_buffer[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_DOUBLE_BUFFER};
-static int clamping[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLAMPING};
-static unsigned short filter_type[]= {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_FILTER_TYPE};
-static int largeview[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_LARGEVIEW};
-static unsigned short decompression[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_DECOMPRESSION};
-static int upscaling[]= {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_UPSCALING};
-static unsigned short force_palette[] = {[0 ... W9968CF_MAX_DEVICES-1] = 0};
-static int force_rgb[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_FORCE_RGB};
-static int autobright[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOBRIGHT};
-static int autoexp[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_AUTOEXP};
-static unsigned short lightfreq[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_LIGHTFREQ};
-static int bandingfilter[] = {[0 ... W9968CF_MAX_DEVICES-1]=
- W9968CF_BANDINGFILTER};
-static short clockdiv[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_CLOCKDIV};
-static int backlight[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_BACKLIGHT};
-static int mirror[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_MIRROR};
-static int monochrome[] = {[0 ... W9968CF_MAX_DEVICES-1]=W9968CF_MONOCHROME};
-static unsigned int brightness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_BRIGHTNESS};
-static unsigned int hue[] = {[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_HUE};
-static unsigned int colour[]={[0 ... W9968CF_MAX_DEVICES-1] = W9968CF_COLOUR};
-static unsigned int contrast[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_CONTRAST};
-static unsigned int whiteness[] = {[0 ... W9968CF_MAX_DEVICES-1] =
- W9968CF_WHITENESS};
-#ifdef W9968CF_DEBUG
-static unsigned short debug = W9968CF_DEBUG_LEVEL;
-static int specific_debug = W9968CF_SPECIFIC_DEBUG;
-#endif
-
-static unsigned int param_nv[24]; /* number of values per parameter */
-
-module_param(simcams, ushort, 0644);
-module_param_array(video_nr, short, &param_nv[0], 0444);
-module_param_array(packet_size, uint, &param_nv[1], 0444);
-module_param_array(max_buffers, ushort, &param_nv[2], 0444);
-module_param_array(double_buffer, bool, &param_nv[3], 0444);
-module_param_array(clamping, bool, &param_nv[4], 0444);
-module_param_array(filter_type, ushort, &param_nv[5], 0444);
-module_param_array(largeview, bool, &param_nv[6], 0444);
-module_param_array(decompression, ushort, &param_nv[7], 0444);
-module_param_array(upscaling, bool, &param_nv[8], 0444);
-module_param_array(force_palette, ushort, &param_nv[9], 0444);
-module_param_array(force_rgb, ushort, &param_nv[10], 0444);
-module_param_array(autobright, bool, &param_nv[11], 0444);
-module_param_array(autoexp, bool, &param_nv[12], 0444);
-module_param_array(lightfreq, ushort, &param_nv[13], 0444);
-module_param_array(bandingfilter, bool, &param_nv[14], 0444);
-module_param_array(clockdiv, short, &param_nv[15], 0444);
-module_param_array(backlight, bool, &param_nv[16], 0444);
-module_param_array(mirror, bool, &param_nv[17], 0444);
-module_param_array(monochrome, bool, &param_nv[18], 0444);
-module_param_array(brightness, uint, &param_nv[19], 0444);
-module_param_array(hue, uint, &param_nv[20], 0444);
-module_param_array(colour, uint, &param_nv[21], 0444);
-module_param_array(contrast, uint, &param_nv[22], 0444);
-module_param_array(whiteness, uint, &param_nv[23], 0444);
-#ifdef W9968CF_DEBUG
-module_param(debug, ushort, 0644);
-module_param(specific_debug, bool, 0644);
-#endif
-
-MODULE_PARM_DESC(simcams,
- "\n<n> Number of cameras allowed to stream simultaneously."
- "\nn may vary from 0 to "
- __MODULE_STRING(W9968CF_MAX_DEVICES)"."
- "\nDefault value is "__MODULE_STRING(W9968CF_SIMCAMS)"."
- "\n");
-MODULE_PARM_DESC(video_nr,
- "\n<-1|n[,...]> Specify V4L minor mode number."
- "\n -1 = use next available (default)"
- "\n n = use minor number n (integer >= 0)"
- "\nYou can specify up to "__MODULE_STRING(W9968CF_MAX_DEVICES)
- " cameras this way."
- "\nFor example:"
- "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
- "\nthe second camera and use auto for the first"
- "\none and for every other camera."
- "\n");
-MODULE_PARM_DESC(packet_size,
- "\n<n[,...]> Specify the maximum data payload"
- "\nsize in bytes for alternate settings, for each device."
- "\nn is scaled between 63 and 1023 "
- "(default is "__MODULE_STRING(W9968CF_PACKET_SIZE)")."
- "\n");
-MODULE_PARM_DESC(max_buffers,
- "\n<n[,...]> For advanced users."
- "\nSpecify the maximum number of video frame buffers"
- "\nto allocate for each device, from 2 to "
- __MODULE_STRING(W9968CF_MAX_BUFFERS)
- ". (default is "__MODULE_STRING(W9968CF_BUFFERS)")."
- "\n");
-MODULE_PARM_DESC(double_buffer,
- "\n<0|1[,...]> "
- "Hardware double buffering: 0 disabled, 1 enabled."
- "\nIt should be enabled if you want smooth video output: if"
- "\nyou obtain out of sync. video, disable it, or try to"
- "\ndecrease the 'clockdiv' module parameter value."
- "\nDefault value is "__MODULE_STRING(W9968CF_DOUBLE_BUFFER)
- " for every device."
- "\n");
-MODULE_PARM_DESC(clamping,
- "\n<0|1[,...]> Video data clamping: 0 disabled, 1 enabled."
- "\nDefault value is "__MODULE_STRING(W9968CF_CLAMPING)
- " for every device."
- "\n");
-MODULE_PARM_DESC(filter_type,
- "\n<0|1|2[,...]> Video filter type."
- "\n0 none, 1 (1-2-1) 3-tap filter, "
- "2 (2-3-6-3-2) 5-tap filter."
- "\nDefault value is "__MODULE_STRING(W9968CF_FILTER_TYPE)
- " for every device."
- "\nThe filter is used to reduce noise and aliasing artifacts"
- "\nproduced by the CCD or CMOS image sensor, and the scaling"
- " process."
- "\n");
-MODULE_PARM_DESC(largeview,
- "\n<0|1[,...]> Large view: 0 disabled, 1 enabled."
- "\nDefault value is "__MODULE_STRING(W9968CF_LARGEVIEW)
- " for every device."
- "\n");
-MODULE_PARM_DESC(upscaling,
- "\n<0|1[,...]> Software scaling (for non-compressed video):"
- "\n0 disabled, 1 enabled."
- "\nDisable it if you have a slow CPU or you don't have"
- " enough memory."
- "\nDefault value is "__MODULE_STRING(W9968CF_UPSCALING)
- " for every device."
- "\nIf 'w9968cf-vpp' is not present, this parameter is"
- " set to 0."
- "\n");
-MODULE_PARM_DESC(decompression,
- "\n<0|1|2[,...]> Software video decompression:"
- "\n- 0 disables decompression (doesn't allow formats needing"
- " decompression)"
- "\n- 1 forces decompression (allows formats needing"
- " decompression only);"
- "\n- 2 allows any permitted formats."
- "\nFormats supporting compressed video are YUV422P and"
- " YUV420P/YUV420 "
- "\nin any resolutions where both width and height are "
- "a multiple of 16."
- "\nDefault value is "__MODULE_STRING(W9968CF_DECOMPRESSION)
- " for every device."
- "\nIf 'w9968cf-vpp' is not present, forcing decompression is "
- "\nnot allowed; in this case this parameter is set to 2."
- "\n");
-MODULE_PARM_DESC(force_palette,
- "\n<0"
- "|" __MODULE_STRING(VIDEO_PALETTE_UYVY)
- "|" __MODULE_STRING(VIDEO_PALETTE_YUV420)
- "|" __MODULE_STRING(VIDEO_PALETTE_YUV422P)
- "|" __MODULE_STRING(VIDEO_PALETTE_YUV420P)
- "|" __MODULE_STRING(VIDEO_PALETTE_YUYV)
- "|" __MODULE_STRING(VIDEO_PALETTE_YUV422)
- "|" __MODULE_STRING(VIDEO_PALETTE_GREY)
- "|" __MODULE_STRING(VIDEO_PALETTE_RGB555)
- "|" __MODULE_STRING(VIDEO_PALETTE_RGB565)
- "|" __MODULE_STRING(VIDEO_PALETTE_RGB24)
- "|" __MODULE_STRING(VIDEO_PALETTE_RGB32)
- "[,...]>"
- " Force picture palette."
- "\nIn order:"
- "\n- 0 allows any of the following formats:"
- "\n- UYVY 16 bpp - Original video, compression disabled"
- "\n- YUV420 12 bpp - Original video, compression enabled"
- "\n- YUV422P 16 bpp - Original video, compression enabled"
- "\n- YUV420P 12 bpp - Original video, compression enabled"
- "\n- YUVY 16 bpp - Software conversion from UYVY"
- "\n- YUV422 16 bpp - Software conversion from UYVY"
- "\n- GREY 8 bpp - Software conversion from UYVY"
- "\n- RGB555 16 bpp - Software conversion from UYVY"
- "\n- RGB565 16 bpp - Software conversion from UYVY"
- "\n- RGB24 24 bpp - Software conversion from UYVY"
- "\n- RGB32 32 bpp - Software conversion from UYVY"
- "\nWhen not 0, this parameter will override 'decompression'."
- "\nDefault value is 0 for every device."
- "\nInitial palette is "
- __MODULE_STRING(W9968CF_PALETTE_DECOMP_ON)"."
- "\nIf 'w9968cf-vpp' is not present, this parameter is"
- " set to 9 (UYVY)."
- "\n");
-MODULE_PARM_DESC(force_rgb,
- "\n<0|1[,...]> Read RGB video data instead of BGR:"
- "\n 1 = use RGB component ordering."
- "\n 0 = use BGR component ordering."
- "\nThis parameter has effect when using RGBX palettes only."
- "\nDefault value is "__MODULE_STRING(W9968CF_FORCE_RGB)
- " for every device."
- "\n");
-MODULE_PARM_DESC(autobright,
- "\n<0|1[,...]> Image sensor automatically changes brightness:"
- "\n 0 = no, 1 = yes"
- "\nDefault value is "__MODULE_STRING(W9968CF_AUTOBRIGHT)
- " for every device."
- "\n");
-MODULE_PARM_DESC(autoexp,
- "\n<0|1[,...]> Image sensor automatically changes exposure:"
- "\n 0 = no, 1 = yes"
- "\nDefault value is "__MODULE_STRING(W9968CF_AUTOEXP)
- " for every device."
- "\n");
-MODULE_PARM_DESC(lightfreq,
- "\n<50|60[,...]> Light frequency in Hz:"
- "\n 50 for European and Asian lighting,"
- " 60 for American lighting."
- "\nDefault value is "__MODULE_STRING(W9968CF_LIGHTFREQ)
- " for every device."
- "\n");
-MODULE_PARM_DESC(bandingfilter,
- "\n<0|1[,...]> Banding filter to reduce effects of"
- " fluorescent lighting:"
- "\n 0 disabled, 1 enabled."
- "\nThis filter tries to reduce the pattern of horizontal"
- "\nlight/dark bands caused by some (usually fluorescent)"
- " lighting."
- "\nDefault value is "__MODULE_STRING(W9968CF_BANDINGFILTER)
- " for every device."
- "\n");
-MODULE_PARM_DESC(clockdiv,
- "\n<-1|n[,...]> "
- "Force pixel clock divisor to a specific value (for experts):"
- "\n n may vary from 0 to 127."
- "\n -1 for automatic value."
- "\nSee also the 'double_buffer' module parameter."
- "\nDefault value is "__MODULE_STRING(W9968CF_CLOCKDIV)
- " for every device."
- "\n");
-MODULE_PARM_DESC(backlight,
- "\n<0|1[,...]> Objects are lit from behind:"
- "\n 0 = no, 1 = yes"
- "\nDefault value is "__MODULE_STRING(W9968CF_BACKLIGHT)
- " for every device."
- "\n");
-MODULE_PARM_DESC(mirror,
- "\n<0|1[,...]> Reverse image horizontally:"
- "\n 0 = no, 1 = yes"
- "\nDefault value is "__MODULE_STRING(W9968CF_MIRROR)
- " for every device."
- "\n");
-MODULE_PARM_DESC(monochrome,
- "\n<0|1[,...]> Use image sensor as monochrome sensor:"
- "\n 0 = no, 1 = yes"
- "\nNot all the sensors support monochrome color."
- "\nDefault value is "__MODULE_STRING(W9968CF_MONOCHROME)
- " for every device."
- "\n");
-MODULE_PARM_DESC(brightness,
- "\n<n[,...]> Set picture brightness (0-65535)."
- "\nDefault value is "__MODULE_STRING(W9968CF_BRIGHTNESS)
- " for every device."
- "\nThis parameter has no effect if 'autobright' is enabled."
- "\n");
-MODULE_PARM_DESC(hue,
- "\n<n[,...]> Set picture hue (0-65535)."
- "\nDefault value is "__MODULE_STRING(W9968CF_HUE)
- " for every device."
- "\n");
-MODULE_PARM_DESC(colour,
- "\n<n[,...]> Set picture saturation (0-65535)."
- "\nDefault value is "__MODULE_STRING(W9968CF_COLOUR)
- " for every device."
- "\n");
-MODULE_PARM_DESC(contrast,
- "\n<n[,...]> Set picture contrast (0-65535)."
- "\nDefault value is "__MODULE_STRING(W9968CF_CONTRAST)
- " for every device."
- "\n");
-MODULE_PARM_DESC(whiteness,
- "\n<n[,...]> Set picture whiteness (0-65535)."
- "\nDefault value is "__MODULE_STRING(W9968CF_WHITENESS)
- " for every device."
- "\n");
-#ifdef W9968CF_DEBUG
-MODULE_PARM_DESC(debug,
- "\n<n> Debugging information level, from 0 to 6:"
- "\n0 = none (use carefully)"
- "\n1 = critical errors"
- "\n2 = significant informations"
- "\n3 = configuration or general messages"
- "\n4 = warnings"
- "\n5 = called functions"
- "\n6 = function internals"
- "\nLevel 5 and 6 are useful for testing only, when only "
- "one device is used."
- "\nDefault value is "__MODULE_STRING(W9968CF_DEBUG_LEVEL)"."
- "\n");
-MODULE_PARM_DESC(specific_debug,
- "\n<0|1> Enable or disable specific debugging messages:"
- "\n0 = print messages concerning every level"
- " <= 'debug' level."
- "\n1 = print messages concerning the level"
- " indicated by 'debug'."
- "\nDefault value is "
- __MODULE_STRING(W9968CF_SPECIFIC_DEBUG)"."
- "\n");
-#endif /* W9968CF_DEBUG */
-
-
-
-/****************************************************************************
- * Some prototypes *
- ****************************************************************************/
-
-/* Video4linux interface */
-static const struct v4l2_file_operations w9968cf_fops;
-static int w9968cf_open(struct file *);
-static int w9968cf_release(struct file *);
-static int w9968cf_mmap(struct file *, struct vm_area_struct *);
-static long w9968cf_ioctl(struct file *, unsigned, unsigned long);
-static ssize_t w9968cf_read(struct file *, char __user *, size_t, loff_t *);
-static long w9968cf_v4l_ioctl(struct file *, unsigned int,
- void __user *);
-
-/* USB-specific */
-static int w9968cf_start_transfer(struct w9968cf_device*);
-static int w9968cf_stop_transfer(struct w9968cf_device*);
-static int w9968cf_write_reg(struct w9968cf_device*, u16 value, u16 index);
-static int w9968cf_read_reg(struct w9968cf_device*, u16 index);
-static int w9968cf_write_fsb(struct w9968cf_device*, u16* data);
-static int w9968cf_write_sb(struct w9968cf_device*, u16 value);
-static int w9968cf_read_sb(struct w9968cf_device*);
-static int w9968cf_upload_quantizationtables(struct w9968cf_device*);
-static void w9968cf_urb_complete(struct urb *urb);
-
-/* Low-level I2C (SMBus) I/O */
-static int w9968cf_smbus_start(struct w9968cf_device*);
-static int w9968cf_smbus_stop(struct w9968cf_device*);
-static int w9968cf_smbus_write_byte(struct w9968cf_device*, u8 v);
-static int w9968cf_smbus_read_byte(struct w9968cf_device*, u8* v);
-static int w9968cf_smbus_write_ack(struct w9968cf_device*);
-static int w9968cf_smbus_read_ack(struct w9968cf_device*);
-static int w9968cf_smbus_refresh_bus(struct w9968cf_device*);
-static int w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
- u16 address, u8* value);
-static int w9968cf_i2c_adap_read_byte_data(struct w9968cf_device*, u16 address,
- u8 subaddress, u8* value);
-static int w9968cf_i2c_adap_write_byte(struct w9968cf_device*,
- u16 address, u8 subaddress);
-static int w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device*,
- u16 address, u8 subaddress,
- u8 value);
-
-/* I2C interface to kernel */
-static int w9968cf_i2c_init(struct w9968cf_device*);
-static int w9968cf_i2c_smbus_xfer(struct i2c_adapter*, u16 addr,
- unsigned short flags, char read_write,
- u8 command, int size, union i2c_smbus_data*);
-static u32 w9968cf_i2c_func(struct i2c_adapter*);
-
-/* Memory management */
-static void* rvmalloc(unsigned long size);
-static void rvfree(void *mem, unsigned long size);
-static void w9968cf_deallocate_memory(struct w9968cf_device*);
-static int w9968cf_allocate_memory(struct w9968cf_device*);
-
-/* High-level image sensor control functions */
-static int w9968cf_sensor_set_control(struct w9968cf_device*,int cid,int val);
-static int w9968cf_sensor_get_control(struct w9968cf_device*,int cid,int *val);
-static int w9968cf_sensor_cmd(struct w9968cf_device*,
- unsigned int cmd, void *arg);
-static int w9968cf_sensor_init(struct w9968cf_device*);
-static int w9968cf_sensor_update_settings(struct w9968cf_device*);
-static int w9968cf_sensor_get_picture(struct w9968cf_device*);
-static int w9968cf_sensor_update_picture(struct w9968cf_device*,
- struct video_picture pict);
-
-/* Other helper functions */
-static void w9968cf_configure_camera(struct w9968cf_device*,struct usb_device*,
- enum w9968cf_model_id,
- const unsigned short dev_nr);
-static void w9968cf_adjust_configuration(struct w9968cf_device*);
-static int w9968cf_turn_on_led(struct w9968cf_device*);
-static int w9968cf_init_chip(struct w9968cf_device*);
-static inline u16 w9968cf_valid_palette(u16 palette);
-static inline u16 w9968cf_valid_depth(u16 palette);
-static inline u8 w9968cf_need_decompression(u16 palette);
-static int w9968cf_set_picture(struct w9968cf_device*, struct video_picture);
-static int w9968cf_set_window(struct w9968cf_device*, struct video_window);
-static int w9968cf_postprocess_frame(struct w9968cf_device*,
- struct w9968cf_frame_t*);
-static int w9968cf_adjust_window_size(struct w9968cf_device*, u32 *w, u32 *h);
-static void w9968cf_init_framelist(struct w9968cf_device*);
-static void w9968cf_push_frame(struct w9968cf_device*, u8 f_num);
-static void w9968cf_pop_frame(struct w9968cf_device*,struct w9968cf_frame_t**);
-static void w9968cf_release_resources(struct w9968cf_device*);
-
-
-
-/****************************************************************************
- * Symbolic names *
- ****************************************************************************/
-
-/* Used to represent a list of values and their respective symbolic names */
-struct w9968cf_symbolic_list {
- const int num;
- const char *name;
-};
-
-/*--------------------------------------------------------------------------
- Returns the name of the matching element in the symbolic_list array. The
- end of the list must be marked with an element that has a NULL name.
- --------------------------------------------------------------------------*/
-static inline const char *
-symbolic(struct w9968cf_symbolic_list list[], const int num)
-{
- int i;
-
- for (i = 0; list[i].name != NULL; i++)
- if (list[i].num == num)
- return (list[i].name);
-
- return "Unknown";
-}
-
-static struct w9968cf_symbolic_list camlist[] = {
- { W9968CF_MOD_GENERIC, "W996[87]CF JPEG USB Dual Mode Camera" },
- { W9968CF_MOD_CLVBWGP, "Creative Labs Video Blaster WebCam Go Plus" },
-
- /* Other cameras (having the same descriptors as Generic W996[87]CF) */
- { W9968CF_MOD_ADPVDMA, "Aroma Digi Pen VGA Dual Mode ADG-5000" },
- { W9986CF_MOD_AAU, "AVerMedia AVerTV USB" },
- { W9968CF_MOD_CLVBWG, "Creative Labs Video Blaster WebCam Go" },
- { W9968CF_MOD_LL, "Lebon LDC-035A" },
- { W9968CF_MOD_EEEMC, "Ezonics EZ-802 EZMega Cam" },
- { W9968CF_MOD_OOE, "OmniVision OV8610-EDE" },
- { W9968CF_MOD_ODPVDMPC, "OPCOM Digi Pen VGA Dual Mode Pen Camera" },
- { W9968CF_MOD_PDPII, "Pretec Digi Pen-II" },
- { W9968CF_MOD_PDP480, "Pretec DigiPen-480" },
-
- { -1, NULL }
-};
-
-static struct w9968cf_symbolic_list senlist[] = {
- { CC_OV76BE, "OV76BE" },
- { CC_OV7610, "OV7610" },
- { CC_OV7620, "OV7620" },
- { CC_OV7620AE, "OV7620AE" },
- { CC_OV6620, "OV6620" },
- { CC_OV6630, "OV6630" },
- { CC_OV6630AE, "OV6630AE" },
- { CC_OV6630AF, "OV6630AF" },
- { -1, NULL }
-};
-
-/* Video4Linux1 palettes */
-static struct w9968cf_symbolic_list v4l1_plist[] = {
- { VIDEO_PALETTE_GREY, "GREY" },
- { VIDEO_PALETTE_HI240, "HI240" },
- { VIDEO_PALETTE_RGB565, "RGB565" },
- { VIDEO_PALETTE_RGB24, "RGB24" },
- { VIDEO_PALETTE_RGB32, "RGB32" },
- { VIDEO_PALETTE_RGB555, "RGB555" },
- { VIDEO_PALETTE_YUV422, "YUV422" },
- { VIDEO_PALETTE_YUYV, "YUYV" },
- { VIDEO_PALETTE_UYVY, "UYVY" },
- { VIDEO_PALETTE_YUV420, "YUV420" },
- { VIDEO_PALETTE_YUV411, "YUV411" },
- { VIDEO_PALETTE_RAW, "RAW" },
- { VIDEO_PALETTE_YUV422P, "YUV422P" },
- { VIDEO_PALETTE_YUV411P, "YUV411P" },
- { VIDEO_PALETTE_YUV420P, "YUV420P" },
- { VIDEO_PALETTE_YUV410P, "YUV410P" },
- { -1, NULL }
-};
-
-/* Decoder error codes: */
-static struct w9968cf_symbolic_list decoder_errlist[] = {
- { W9968CF_DEC_ERR_CORRUPTED_DATA, "Corrupted data" },
- { W9968CF_DEC_ERR_BUF_OVERFLOW, "Buffer overflow" },
- { W9968CF_DEC_ERR_NO_SOI, "SOI marker not found" },
- { W9968CF_DEC_ERR_NO_SOF0, "SOF0 marker not found" },
- { W9968CF_DEC_ERR_NO_SOS, "SOS marker not found" },
- { W9968CF_DEC_ERR_NO_EOI, "EOI marker not found" },
- { -1, NULL }
-};
-
-/* URB error codes: */
-static struct w9968cf_symbolic_list urb_errlist[] = {
- { -ENOMEM, "No memory for allocation of internal structures" },
- { -ENOSPC, "The host controller's bandwidth is already consumed" },
- { -ENOENT, "URB was canceled by unlink_urb" },
- { -EXDEV, "ISO transfer only partially completed" },
- { -EAGAIN, "Too match scheduled for the future" },
- { -ENXIO, "URB already queued" },
- { -EFBIG, "Too much ISO frames requested" },
- { -ENOSR, "Buffer error (overrun)" },
- { -EPIPE, "Specified endpoint is stalled (device not responding)"},
- { -EOVERFLOW, "Babble (too much data)" },
- { -EPROTO, "Bit-stuff error (bad cable?)" },
- { -EILSEQ, "CRC/Timeout" },
- { -ETIME, "Device does not respond to token" },
- { -ETIMEDOUT, "Device does not respond to command" },
- { -1, NULL }
-};
-
-/****************************************************************************
- * Memory management functions *
- ****************************************************************************/
-static void* rvmalloc(unsigned long size)
-{
- void* mem;
- unsigned long adr;
-
- size = PAGE_ALIGN(size);
- mem = vmalloc_32(size);
- if (!mem)
- return NULL;
-
- memset(mem, 0, size); /* Clear the ram out, no junk to the user */
- adr = (unsigned long) mem;
- while (size > 0) {
- SetPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- return mem;
-}
-
-
-static void rvfree(void* mem, unsigned long size)
-{
- unsigned long adr;
-
- if (!mem)
- return;
-
- adr = (unsigned long) mem;
- while ((long) size > 0) {
- ClearPageReserved(vmalloc_to_page((void *)adr));
- adr += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
- vfree(mem);
-}
-
-
-/*--------------------------------------------------------------------------
- Deallocate previously allocated memory.
- --------------------------------------------------------------------------*/
-static void w9968cf_deallocate_memory(struct w9968cf_device* cam)
-{
- u8 i;
-
- /* Free the isochronous transfer buffers */
- for (i = 0; i < W9968CF_URBS; i++) {
- kfree(cam->transfer_buffer[i]);
- cam->transfer_buffer[i] = NULL;
- }
-
- /* Free temporary frame buffer */
- if (cam->frame_tmp.buffer) {
- rvfree(cam->frame_tmp.buffer, cam->frame_tmp.size);
- cam->frame_tmp.buffer = NULL;
- }
-
- /* Free helper buffer */
- if (cam->frame_vpp.buffer) {
- rvfree(cam->frame_vpp.buffer, cam->frame_vpp.size);
- cam->frame_vpp.buffer = NULL;
- }
-
- /* Free video frame buffers */
- if (cam->frame[0].buffer) {
- rvfree(cam->frame[0].buffer, cam->nbuffers*cam->frame[0].size);
- cam->frame[0].buffer = NULL;
- }
-
- cam->nbuffers = 0;
-
- DBG(5, "Memory successfully deallocated")
-}
-
-
-/*--------------------------------------------------------------------------
- Allocate memory buffers for USB transfers and video frames.
- This function is called by open() only.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_allocate_memory(struct w9968cf_device* cam)
-{
- const u16 p_size = wMaxPacketSize[cam->altsetting-1];
- void* buff = NULL;
- unsigned long hw_bufsize, vpp_bufsize;
- u8 i, bpp;
-
- /* NOTE: Deallocation is done elsewhere in case of error */
-
- /* Calculate the max amount of raw data per frame from the device */
- hw_bufsize = cam->maxwidth*cam->maxheight*2;
-
- /* Calculate the max buf. size needed for post-processing routines */
- bpp = (w9968cf_vpp) ? 4 : 2;
- if (cam->upscaling)
- vpp_bufsize = max(W9968CF_MAX_WIDTH*W9968CF_MAX_HEIGHT*bpp,
- cam->maxwidth*cam->maxheight*bpp);
- else
- vpp_bufsize = cam->maxwidth*cam->maxheight*bpp;
-
- /* Allocate memory for the isochronous transfer buffers */
- for (i = 0; i < W9968CF_URBS; i++) {
- if (!(cam->transfer_buffer[i] =
- kzalloc(W9968CF_ISO_PACKETS*p_size, GFP_KERNEL))) {
- DBG(1, "Couldn't allocate memory for the isochronous "
- "transfer buffers (%u bytes)",
- p_size * W9968CF_ISO_PACKETS)
- return -ENOMEM;
- }
- }
-
- /* Allocate memory for the temporary frame buffer */
- if (!(cam->frame_tmp.buffer = rvmalloc(hw_bufsize))) {
- DBG(1, "Couldn't allocate memory for the temporary "
- "video frame buffer (%lu bytes)", hw_bufsize)
- return -ENOMEM;
- }
- cam->frame_tmp.size = hw_bufsize;
- cam->frame_tmp.number = -1;
-
- /* Allocate memory for the helper buffer */
- if (w9968cf_vpp) {
- if (!(cam->frame_vpp.buffer = rvmalloc(vpp_bufsize))) {
- DBG(1, "Couldn't allocate memory for the helper buffer"
- " (%lu bytes)", vpp_bufsize)
- return -ENOMEM;
- }
- cam->frame_vpp.size = vpp_bufsize;
- } else
- cam->frame_vpp.buffer = NULL;
-
- /* Allocate memory for video frame buffers */
- cam->nbuffers = cam->max_buffers;
- while (cam->nbuffers >= 2) {
- if ((buff = rvmalloc(cam->nbuffers * vpp_bufsize)))
- break;
- else
- cam->nbuffers--;
- }
-
- if (!buff) {
- DBG(1, "Couldn't allocate memory for the video frame buffers")
- cam->nbuffers = 0;
- return -ENOMEM;
- }
-
- if (cam->nbuffers != cam->max_buffers)
- DBG(2, "Couldn't allocate memory for %u video frame buffers. "
- "Only memory for %u buffers has been allocated",
- cam->max_buffers, cam->nbuffers)
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->frame[i].buffer = buff + i*vpp_bufsize;
- cam->frame[i].size = vpp_bufsize;
- cam->frame[i].number = i;
- /* Circular list */
- if (i != cam->nbuffers-1)
- cam->frame[i].next = &cam->frame[i+1];
- else
- cam->frame[i].next = &cam->frame[0];
- cam->frame[i].status = F_UNUSED;
- }
-
- DBG(5, "Memory successfully allocated")
- return 0;
-}
-
-
-
-/****************************************************************************
- * USB-specific functions *
- ****************************************************************************/
-
-/*--------------------------------------------------------------------------
- This is an handler function which is called after the URBs are completed.
- It collects multiple data packets coming from the camera by putting them
- into frame buffers: one or more zero data length data packets are used to
- mark the end of a video frame; the first non-zero data packet is the start
- of the next video frame; if an error is encountered in a packet, the entire
- video frame is discarded and grabbed again.
- If there are no requested frames in the FIFO list, packets are collected into
- a temporary buffer.
- --------------------------------------------------------------------------*/
-static void w9968cf_urb_complete(struct urb *urb)
-{
- struct w9968cf_device* cam = (struct w9968cf_device*)urb->context;
- struct w9968cf_frame_t** f;
- unsigned int len, status;
- void* pos;
- u8 i;
- int err = 0;
-
- if ((!cam->streaming) || cam->disconnected) {
- DBG(4, "Got interrupt, but not streaming")
- return;
- }
-
- /* "(*f)" will be used instead of "cam->frame_current" */
- f = &cam->frame_current;
-
- /* If a frame has been requested and we are grabbing into
- the temporary frame, we'll switch to that requested frame */
- if ((*f) == &cam->frame_tmp && *cam->requested_frame) {
- if (cam->frame_tmp.status == F_GRABBING) {
- w9968cf_pop_frame(cam, &cam->frame_current);
- (*f)->status = F_GRABBING;
- (*f)->length = cam->frame_tmp.length;
- memcpy((*f)->buffer, cam->frame_tmp.buffer,
- (*f)->length);
- DBG(6, "Switched from temp. frame to frame #%d",
- (*f)->number)
- }
- }
-
- for (i = 0; i < urb->number_of_packets; i++) {
- len = urb->iso_frame_desc[i].actual_length;
- status = urb->iso_frame_desc[i].status;
- pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-
- if (status && len != 0) {
- DBG(4, "URB failed, error in data packet "
- "(error #%u, %s)",
- status, symbolic(urb_errlist, status))
- (*f)->status = F_ERROR;
- continue;
- }
-
- if (len) { /* start of frame */
-
- if ((*f)->status == F_UNUSED) {
- (*f)->status = F_GRABBING;
- (*f)->length = 0;
- }
-
- /* Buffer overflows shouldn't happen, however...*/
- if ((*f)->length + len > (*f)->size) {
- DBG(4, "Buffer overflow: bad data packets")
- (*f)->status = F_ERROR;
- }
-
- if ((*f)->status == F_GRABBING) {
- memcpy((*f)->buffer + (*f)->length, pos, len);
- (*f)->length += len;
- }
-
- } else if ((*f)->status == F_GRABBING) { /* end of frame */
-
- DBG(6, "Frame #%d successfully grabbed", (*f)->number)
-
- if (cam->vpp_flag & VPP_DECOMPRESSION) {
- err = w9968cf_vpp->check_headers((*f)->buffer,
- (*f)->length);
- if (err) {
- DBG(4, "Skip corrupted frame: %s",
- symbolic(decoder_errlist, err))
- (*f)->status = F_UNUSED;
- continue; /* grab this frame again */
- }
- }
-
- (*f)->status = F_READY;
- (*f)->queued = 0;
-
- /* Take a pointer to the new frame from the FIFO list.
- If the list is empty,we'll use the temporary frame*/
- if (*cam->requested_frame)
- w9968cf_pop_frame(cam, &cam->frame_current);
- else {
- cam->frame_current = &cam->frame_tmp;
- (*f)->status = F_UNUSED;
- }
-
- } else if ((*f)->status == F_ERROR)
- (*f)->status = F_UNUSED; /* grab it again */
-
- PDBGG("Frame length %lu | pack.#%u | pack.len. %u | state %d",
- (unsigned long)(*f)->length, i, len, (*f)->status)
-
- } /* end for */
-
- /* Resubmit this URB */
- urb->dev = cam->usbdev;
- urb->status = 0;
- spin_lock(&cam->urb_lock);
- if (cam->streaming)
- if ((err = usb_submit_urb(urb, GFP_ATOMIC))) {
- cam->misconfigured = 1;
- DBG(1, "Couldn't resubmit the URB: error %d, %s",
- err, symbolic(urb_errlist, err))
- }
- spin_unlock(&cam->urb_lock);
-
- /* Wake up the user process */
- wake_up_interruptible(&cam->wait_queue);
-}
-
-
-/*---------------------------------------------------------------------------
- Setup the URB structures for the isochronous transfer.
- Submit the URBs so that the data transfer begins.
- Return 0 on success, a negative number otherwise.
- ---------------------------------------------------------------------------*/
-static int w9968cf_start_transfer(struct w9968cf_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- struct urb* urb;
- const u16 p_size = wMaxPacketSize[cam->altsetting-1];
- u16 w, h, d;
- int vidcapt;
- u32 t_size;
- int err = 0;
- s8 i, j;
-
- for (i = 0; i < W9968CF_URBS; i++) {
- urb = usb_alloc_urb(W9968CF_ISO_PACKETS, GFP_KERNEL);
- if (!urb) {
- for (j = 0; j < i; j++)
- usb_free_urb(cam->urb[j]);
- DBG(1, "Couldn't allocate the URB structures")
- return -ENOMEM;
- }
-
- cam->urb[i] = urb;
- urb->dev = udev;
- urb->context = (void*)cam;
- urb->pipe = usb_rcvisocpipe(udev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = W9968CF_ISO_PACKETS;
- urb->complete = w9968cf_urb_complete;
- urb->transfer_buffer = cam->transfer_buffer[i];
- urb->transfer_buffer_length = p_size*W9968CF_ISO_PACKETS;
- urb->interval = 1;
- for (j = 0; j < W9968CF_ISO_PACKETS; j++) {
- urb->iso_frame_desc[j].offset = p_size*j;
- urb->iso_frame_desc[j].length = p_size;
- }
- }
-
- /* Transfer size per frame, in WORD ! */
- d = cam->hw_depth;
- w = cam->hw_width;
- h = cam->hw_height;
-
- t_size = (w*h*d)/16;
-
- err = w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
- err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
-
- /* Transfer size */
- err += w9968cf_write_reg(cam, t_size & 0xffff, 0x3d); /* low bits */
- err += w9968cf_write_reg(cam, t_size >> 16, 0x3e); /* high bits */
-
- if (cam->vpp_flag & VPP_DECOMPRESSION)
- err += w9968cf_upload_quantizationtables(cam);
-
- vidcapt = w9968cf_read_reg(cam, 0x16); /* read picture settings */
- err += w9968cf_write_reg(cam, vidcapt|0x8000, 0x16); /* capt. enable */
-
- err += usb_set_interface(udev, 0, cam->altsetting);
- err += w9968cf_write_reg(cam, 0x8a05, 0x3c); /* USB FIFO enable */
-
- if (err || (vidcapt < 0)) {
- for (i = 0; i < W9968CF_URBS; i++)
- usb_free_urb(cam->urb[i]);
- DBG(1, "Couldn't tell the camera to start the data transfer")
- return err;
- }
-
- w9968cf_init_framelist(cam);
-
- /* Begin to grab into the temporary buffer */
- cam->frame_tmp.status = F_UNUSED;
- cam->frame_tmp.queued = 0;
- cam->frame_current = &cam->frame_tmp;
-
- if (!(cam->vpp_flag & VPP_DECOMPRESSION))
- DBG(5, "Isochronous transfer size: %lu bytes/frame",
- (unsigned long)t_size*2)
-
- DBG(5, "Starting the isochronous transfer...")
-
- cam->streaming = 1;
-
- /* Submit the URBs */
- for (i = 0; i < W9968CF_URBS; i++) {
- err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
- if (err) {
- cam->streaming = 0;
- for (j = i-1; j >= 0; j--) {
- usb_kill_urb(cam->urb[j]);
- usb_free_urb(cam->urb[j]);
- }
- DBG(1, "Couldn't send a transfer request to the "
- "USB core (error #%d, %s)", err,
- symbolic(urb_errlist, err))
- return err;
- }
- }
-
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Stop the isochronous transfer and set alternate setting to 0 (0Mb/s).
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_stop_transfer(struct w9968cf_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- unsigned long lock_flags;
- int err = 0;
- s8 i;
-
- if (!cam->streaming)
- return 0;
-
- /* This avoids race conditions with usb_submit_urb()
- in the URB completition handler */
- spin_lock_irqsave(&cam->urb_lock, lock_flags);
- cam->streaming = 0;
- spin_unlock_irqrestore(&cam->urb_lock, lock_flags);
-
- for (i = W9968CF_URBS-1; i >= 0; i--)
- if (cam->urb[i]) {
- usb_kill_urb(cam->urb[i]);
- usb_free_urb(cam->urb[i]);
- cam->urb[i] = NULL;
- }
-
- if (cam->disconnected)
- goto exit;
-
- err = w9968cf_write_reg(cam, 0x0a05, 0x3c); /* stop USB transfer */
- err += usb_set_interface(udev, 0, 0); /* 0 Mb/s */
- err += w9968cf_write_reg(cam, 0x0000, 0x39); /* disable JPEG encoder */
- err += w9968cf_write_reg(cam, 0x0000, 0x16); /* stop video capture */
-
- if (err) {
- DBG(2, "Failed to tell the camera to stop the isochronous "
- "transfer. However this is not a critical error.")
- return -EIO;
- }
-
-exit:
- DBG(5, "Isochronous transfer stopped")
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Write a W9968CF register.
- Return 0 on success, -1 otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_write_reg(struct w9968cf_device* cam, u16 value, u16 index)
-{
- struct usb_device* udev = cam->usbdev;
- int res;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- value, index, NULL, 0, W9968CF_USB_CTRL_TIMEOUT);
-
- if (res < 0)
- DBG(4, "Failed to write a register "
- "(value 0x%04X, index 0x%02X, error #%d, %s)",
- value, index, res, symbolic(urb_errlist, res))
-
- return (res >= 0) ? 0 : -1;
-}
-
-
-/*--------------------------------------------------------------------------
- Read a W9968CF register.
- Return the register value on success, -1 otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_read_reg(struct w9968cf_device* cam, u16 index)
-{
- struct usb_device* udev = cam->usbdev;
- u16* buff = cam->control_buffer;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0, index, buff, 2, W9968CF_USB_CTRL_TIMEOUT);
-
- if (res < 0)
- DBG(4, "Failed to read a register "
- "(index 0x%02X, error #%d, %s)",
- index, res, symbolic(urb_errlist, res))
-
- return (res >= 0) ? (int)(*buff) : -1;
-}
-
-
-/*--------------------------------------------------------------------------
- Write 64-bit data to the fast serial bus registers.
- Return 0 on success, -1 otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_write_fsb(struct w9968cf_device* cam, u16* data)
-{
- struct usb_device* udev = cam->usbdev;
- u16 value;
- int res;
-
- value = *data++;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
- USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
- value, 0x06, data, 6, W9968CF_USB_CTRL_TIMEOUT);
-
- if (res < 0)
- DBG(4, "Failed to write the FSB registers "
- "(error #%d, %s)", res, symbolic(urb_errlist, res))
-
- return (res >= 0) ? 0 : -1;
-}
-
-
-/*--------------------------------------------------------------------------
- Write data to the serial bus control register.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_write_sb(struct w9968cf_device* cam, u16 value)
-{
- int err = 0;
-
- err = w9968cf_write_reg(cam, value, 0x01);
- udelay(W9968CF_I2C_BUS_DELAY);
-
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Read data from the serial bus control register.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_read_sb(struct w9968cf_device* cam)
-{
- int v = 0;
-
- v = w9968cf_read_reg(cam, 0x01);
- udelay(W9968CF_I2C_BUS_DELAY);
-
- return v;
-}
-
-
-/*--------------------------------------------------------------------------
- Upload quantization tables for the JPEG compression.
- This function is called by w9968cf_start_transfer().
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_upload_quantizationtables(struct w9968cf_device* cam)
-{
- u16 a, b;
- int err = 0, i, j;
-
- err += w9968cf_write_reg(cam, 0x0010, 0x39); /* JPEG clock enable */
-
- for (i = 0, j = 0; i < 32; i++, j += 2) {
- a = Y_QUANTABLE[j] | ((unsigned)(Y_QUANTABLE[j+1]) << 8);
- b = UV_QUANTABLE[j] | ((unsigned)(UV_QUANTABLE[j+1]) << 8);
- err += w9968cf_write_reg(cam, a, 0x40+i);
- err += w9968cf_write_reg(cam, b, 0x60+i);
- }
- err += w9968cf_write_reg(cam, 0x0012, 0x39); /* JPEG encoder enable */
-
- return err;
-}
-
-
-
-/****************************************************************************
- * Low-level I2C I/O functions. *
- * The adapter supports the following I2C transfer functions: *
- * i2c_adap_fastwrite_byte_data() (at 400 kHz bit frequency only) *
- * i2c_adap_read_byte_data() *
- * i2c_adap_read_byte() *
- ****************************************************************************/
-
-static int w9968cf_smbus_start(struct w9968cf_device* cam)
-{
- int err = 0;
-
- err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
-
- return err;
-}
-
-
-static int w9968cf_smbus_stop(struct w9968cf_device* cam)
-{
- int err = 0;
-
- err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
-
- return err;
-}
-
-
-static int w9968cf_smbus_write_byte(struct w9968cf_device* cam, u8 v)
-{
- u8 bit;
- int err = 0, sda;
-
- for (bit = 0 ; bit < 8 ; bit++) {
- sda = (v & 0x80) ? 2 : 0;
- v <<= 1;
- /* SDE=1, SDA=sda, SCL=0 */
- err += w9968cf_write_sb(cam, 0x10 | sda);
- /* SDE=1, SDA=sda, SCL=1 */
- err += w9968cf_write_sb(cam, 0x11 | sda);
- /* SDE=1, SDA=sda, SCL=0 */
- err += w9968cf_write_sb(cam, 0x10 | sda);
- }
-
- return err;
-}
-
-
-static int w9968cf_smbus_read_byte(struct w9968cf_device* cam, u8* v)
-{
- u8 bit;
- int err = 0;
-
- *v = 0;
- for (bit = 0 ; bit < 8 ; bit++) {
- *v <<= 1;
- err += w9968cf_write_sb(cam, 0x0013);
- *v |= (w9968cf_read_sb(cam) & 0x0008) ? 1 : 0;
- err += w9968cf_write_sb(cam, 0x0012);
- }
-
- return err;
-}
-
-
-static int w9968cf_smbus_write_ack(struct w9968cf_device* cam)
-{
- int err = 0;
-
- err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
- err += w9968cf_write_sb(cam, 0x0011); /* SDE=1, SDA=0, SCL=1 */
- err += w9968cf_write_sb(cam, 0x0010); /* SDE=1, SDA=0, SCL=0 */
-
- return err;
-}
-
-
-static int w9968cf_smbus_read_ack(struct w9968cf_device* cam)
-{
- int err = 0, sda;
-
- err += w9968cf_write_sb(cam, 0x0013); /* SDE=1, SDA=1, SCL=1 */
- sda = (w9968cf_read_sb(cam) & 0x08) ? 1 : 0; /* sda = SDA */
- err += w9968cf_write_sb(cam, 0x0012); /* SDE=1, SDA=1, SCL=0 */
- if (sda < 0)
- err += sda;
- if (sda == 1) {
- DBG(6, "Couldn't receive the ACK")
- err += -1;
- }
-
- return err;
-}
-
-
-/* This seems to refresh the communication through the serial bus */
-static int w9968cf_smbus_refresh_bus(struct w9968cf_device* cam)
-{
- int err = 0, j;
-
- for (j = 1; j <= 10; j++) {
- err = w9968cf_write_reg(cam, 0x0020, 0x01);
- err += w9968cf_write_reg(cam, 0x0000, 0x01);
- if (err)
- break;
- }
-
- return err;
-}
-
-
-/* SMBus protocol: S Addr Wr [A] Subaddr [A] Value [A] P */
-static int
-w9968cf_i2c_adap_fastwrite_byte_data(struct w9968cf_device* cam,
- u16 address, u8 subaddress,u8 value)
-{
- u16* data = cam->data_buffer;
- int err = 0;
-
- err += w9968cf_smbus_refresh_bus(cam);
-
- /* Enable SBUS outputs */
- err += w9968cf_write_sb(cam, 0x0020);
-
- data[0] = 0x082f | ((address & 0x80) ? 0x1500 : 0x0);
- data[0] |= (address & 0x40) ? 0x4000 : 0x0;
- data[1] = 0x2082 | ((address & 0x40) ? 0x0005 : 0x0);
- data[1] |= (address & 0x20) ? 0x0150 : 0x0;
- data[1] |= (address & 0x10) ? 0x5400 : 0x0;
- data[2] = 0x8208 | ((address & 0x08) ? 0x0015 : 0x0);
- data[2] |= (address & 0x04) ? 0x0540 : 0x0;
- data[2] |= (address & 0x02) ? 0x5000 : 0x0;
- data[3] = 0x1d20 | ((address & 0x02) ? 0x0001 : 0x0);
- data[3] |= (address & 0x01) ? 0x0054 : 0x0;
-
- err += w9968cf_write_fsb(cam, data);
-
- data[0] = 0x8208 | ((subaddress & 0x80) ? 0x0015 : 0x0);
- data[0] |= (subaddress & 0x40) ? 0x0540 : 0x0;
- data[0] |= (subaddress & 0x20) ? 0x5000 : 0x0;
- data[1] = 0x0820 | ((subaddress & 0x20) ? 0x0001 : 0x0);
- data[1] |= (subaddress & 0x10) ? 0x0054 : 0x0;
- data[1] |= (subaddress & 0x08) ? 0x1500 : 0x0;
- data[1] |= (subaddress & 0x04) ? 0x4000 : 0x0;
- data[2] = 0x2082 | ((subaddress & 0x04) ? 0x0005 : 0x0);
- data[2] |= (subaddress & 0x02) ? 0x0150 : 0x0;
- data[2] |= (subaddress & 0x01) ? 0x5400 : 0x0;
- data[3] = 0x001d;
-
- err += w9968cf_write_fsb(cam, data);
-
- data[0] = 0x8208 | ((value & 0x80) ? 0x0015 : 0x0);
- data[0] |= (value & 0x40) ? 0x0540 : 0x0;
- data[0] |= (value & 0x20) ? 0x5000 : 0x0;
- data[1] = 0x0820 | ((value & 0x20) ? 0x0001 : 0x0);
- data[1] |= (value & 0x10) ? 0x0054 : 0x0;
- data[1] |= (value & 0x08) ? 0x1500 : 0x0;
- data[1] |= (value & 0x04) ? 0x4000 : 0x0;
- data[2] = 0x2082 | ((value & 0x04) ? 0x0005 : 0x0);
- data[2] |= (value & 0x02) ? 0x0150 : 0x0;
- data[2] |= (value & 0x01) ? 0x5400 : 0x0;
- data[3] = 0xfe1d;
-
- err += w9968cf_write_fsb(cam, data);
-
- /* Disable SBUS outputs */
- err += w9968cf_write_sb(cam, 0x0000);
-
- if (!err)
- DBG(5, "I2C write byte data done, addr.0x%04X, subaddr.0x%02X "
- "value 0x%02X", address, subaddress, value)
- else
- DBG(5, "I2C write byte data failed, addr.0x%04X, "
- "subaddr.0x%02X, value 0x%02X",
- address, subaddress, value)
-
- return err;
-}
-
-
-/* SMBus protocol: S Addr Wr [A] Subaddr [A] P S Addr+1 Rd [A] [Value] NA P */
-static int
-w9968cf_i2c_adap_read_byte_data(struct w9968cf_device* cam,
- u16 address, u8 subaddress,
- u8* value)
-{
- int err = 0;
-
- /* Serial data enable */
- err += w9968cf_write_sb(cam, 0x0013); /* don't change ! */
-
- err += w9968cf_smbus_start(cam);
- err += w9968cf_smbus_write_byte(cam, address);
- err += w9968cf_smbus_read_ack(cam);
- err += w9968cf_smbus_write_byte(cam, subaddress);
- err += w9968cf_smbus_read_ack(cam);
- err += w9968cf_smbus_stop(cam);
- err += w9968cf_smbus_start(cam);
- err += w9968cf_smbus_write_byte(cam, address + 1);
- err += w9968cf_smbus_read_ack(cam);
- err += w9968cf_smbus_read_byte(cam, value);
- err += w9968cf_smbus_write_ack(cam);
- err += w9968cf_smbus_stop(cam);
-
- /* Serial data disable */
- err += w9968cf_write_sb(cam, 0x0000);
-
- if (!err)
- DBG(5, "I2C read byte data done, addr.0x%04X, "
- "subaddr.0x%02X, value 0x%02X",
- address, subaddress, *value)
- else
- DBG(5, "I2C read byte data failed, addr.0x%04X, "
- "subaddr.0x%02X, wrong value 0x%02X",
- address, subaddress, *value)
-
- return err;
-}
-
-
-/* SMBus protocol: S Addr+1 Rd [A] [Value] NA P */
-static int
-w9968cf_i2c_adap_read_byte(struct w9968cf_device* cam,
- u16 address, u8* value)
-{
- int err = 0;
-
- /* Serial data enable */
- err += w9968cf_write_sb(cam, 0x0013);
-
- err += w9968cf_smbus_start(cam);
- err += w9968cf_smbus_write_byte(cam, address + 1);
- err += w9968cf_smbus_read_ack(cam);
- err += w9968cf_smbus_read_byte(cam, value);
- err += w9968cf_smbus_write_ack(cam);
- err += w9968cf_smbus_stop(cam);
-
- /* Serial data disable */
- err += w9968cf_write_sb(cam, 0x0000);
-
- if (!err)
- DBG(5, "I2C read byte done, addr.0x%04X, "
- "value 0x%02X", address, *value)
- else
- DBG(5, "I2C read byte failed, addr.0x%04X, "
- "wrong value 0x%02X", address, *value)
-
- return err;
-}
-
-
-/* SMBus protocol: S Addr Wr [A] Value [A] P */
-static int
-w9968cf_i2c_adap_write_byte(struct w9968cf_device* cam,
- u16 address, u8 value)
-{
- DBG(4, "i2c_write_byte() is an unsupported transfer mode")
- return -EINVAL;
-}
-
-
-
-/****************************************************************************
- * I2C interface to kernel *
- ****************************************************************************/
-
-static int
-w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
- unsigned short flags, char read_write, u8 command,
- int size, union i2c_smbus_data *data)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
- struct w9968cf_device *cam = to_cam(v4l2_dev);
- u8 i;
- int err = 0;
-
- if (size == I2C_SMBUS_BYTE) {
- /* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
- addr <<= 1;
-
- if (read_write == I2C_SMBUS_WRITE)
- err = w9968cf_i2c_adap_write_byte(cam, addr, command);
- else if (read_write == I2C_SMBUS_READ)
- for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
- err = w9968cf_i2c_adap_read_byte(cam, addr,
- &data->byte);
- if (err) {
- if (w9968cf_smbus_refresh_bus(cam)) {
- err = -EIO;
- break;
- }
- } else
- break;
- }
- } else if (size == I2C_SMBUS_BYTE_DATA) {
- addr <<= 1;
-
- if (read_write == I2C_SMBUS_WRITE)
- err = w9968cf_i2c_adap_fastwrite_byte_data(cam, addr,
- command, data->byte);
- else if (read_write == I2C_SMBUS_READ) {
- for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
- err = w9968cf_i2c_adap_read_byte_data(cam,addr,
- command, &data->byte);
- if (err) {
- if (w9968cf_smbus_refresh_bus(cam)) {
- err = -EIO;
- break;
- }
- } else
- break;
- }
-
- } else
- return -EINVAL;
-
- } else {
- DBG(4, "Unsupported I2C transfer mode (%d)", size)
- return -EINVAL;
- }
- return err;
-}
-
-
-static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
-{
- return I2C_FUNC_SMBUS_READ_BYTE |
- I2C_FUNC_SMBUS_READ_BYTE_DATA |
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA;
-}
-
-
-static int w9968cf_i2c_init(struct w9968cf_device* cam)
-{
- int err = 0;
-
- static struct i2c_algorithm algo = {
- .smbus_xfer = w9968cf_i2c_smbus_xfer,
- .functionality = w9968cf_i2c_func,
- };
-
- static struct i2c_adapter adap = {
- .owner = THIS_MODULE,
- .algo = &algo,
- };
-
- memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
- strcpy(cam->i2c_adapter.name, "w9968cf");
- cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
- i2c_set_adapdata(&cam->i2c_adapter, &cam->v4l2_dev);
-
- DBG(6, "Registering I2C adapter with kernel...")
-
- err = i2c_add_adapter(&cam->i2c_adapter);
- if (err)
- DBG(1, "Failed to register the I2C adapter")
- else
- DBG(5, "I2C adapter registered")
-
- return err;
-}
-
-
-
-/****************************************************************************
- * Helper functions *
- ****************************************************************************/
-
-/*--------------------------------------------------------------------------
- Turn on the LED on some webcams. A beep should be heard too.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_turn_on_led(struct w9968cf_device* cam)
-{
- int err = 0;
-
- err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power-down */
- err += w9968cf_write_reg(cam, 0xbf17, 0x00); /* reset everything */
- err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* normal operation */
- err += w9968cf_write_reg(cam, 0x0010, 0x01); /* serial bus, SDS high */
- err += w9968cf_write_reg(cam, 0x0000, 0x01); /* serial bus, SDS low */
- err += w9968cf_write_reg(cam, 0x0010, 0x01); /* ..high 'beep-beep' */
-
- if (err)
- DBG(2, "Couldn't turn on the LED")
-
- DBG(5, "LED turned on")
-
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Write some registers for the device initialization.
- This function is called once on open().
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_init_chip(struct w9968cf_device* cam)
-{
- unsigned long hw_bufsize = cam->maxwidth*cam->maxheight*2,
- y0 = 0x0000,
- u0 = y0 + hw_bufsize/2,
- v0 = u0 + hw_bufsize/4,
- y1 = v0 + hw_bufsize/4,
- u1 = y1 + hw_bufsize/2,
- v1 = u1 + hw_bufsize/4;
- int err = 0;
-
- err += w9968cf_write_reg(cam, 0xff00, 0x00); /* power off */
- err += w9968cf_write_reg(cam, 0xbf10, 0x00); /* power on */
-
- err += w9968cf_write_reg(cam, 0x405d, 0x03); /* DRAM timings */
- err += w9968cf_write_reg(cam, 0x0030, 0x04); /* SDRAM timings */
-
- err += w9968cf_write_reg(cam, y0 & 0xffff, 0x20); /* Y buf.0, low */
- err += w9968cf_write_reg(cam, y0 >> 16, 0x21); /* Y buf.0, high */
- err += w9968cf_write_reg(cam, u0 & 0xffff, 0x24); /* U buf.0, low */
- err += w9968cf_write_reg(cam, u0 >> 16, 0x25); /* U buf.0, high */
- err += w9968cf_write_reg(cam, v0 & 0xffff, 0x28); /* V buf.0, low */
- err += w9968cf_write_reg(cam, v0 >> 16, 0x29); /* V buf.0, high */
-
- err += w9968cf_write_reg(cam, y1 & 0xffff, 0x22); /* Y buf.1, low */
- err += w9968cf_write_reg(cam, y1 >> 16, 0x23); /* Y buf.1, high */
- err += w9968cf_write_reg(cam, u1 & 0xffff, 0x26); /* U buf.1, low */
- err += w9968cf_write_reg(cam, u1 >> 16, 0x27); /* U buf.1, high */
- err += w9968cf_write_reg(cam, v1 & 0xffff, 0x2a); /* V buf.1, low */
- err += w9968cf_write_reg(cam, v1 >> 16, 0x2b); /* V buf.1, high */
-
- err += w9968cf_write_reg(cam, y1 & 0xffff, 0x32); /* JPEG buf 0 low */
- err += w9968cf_write_reg(cam, y1 >> 16, 0x33); /* JPEG buf 0 high */
-
- err += w9968cf_write_reg(cam, y1 & 0xffff, 0x34); /* JPEG buf 1 low */
- err += w9968cf_write_reg(cam, y1 >> 16, 0x35); /* JPEG bug 1 high */
-
- err += w9968cf_write_reg(cam, 0x0000, 0x36);/* JPEG restart interval */
- err += w9968cf_write_reg(cam, 0x0804, 0x37);/*JPEG VLE FIFO threshold*/
- err += w9968cf_write_reg(cam, 0x0000, 0x38);/* disable hw up-scaling */
- err += w9968cf_write_reg(cam, 0x0000, 0x3f); /* JPEG/MCTL test data */
-
- err += w9968cf_set_picture(cam, cam->picture); /* this before */
- err += w9968cf_set_window(cam, cam->window);
-
- if (err)
- DBG(1, "Chip initialization failed")
- else
- DBG(5, "Chip successfully initialized")
-
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Return non-zero if the palette is supported, 0 otherwise.
- --------------------------------------------------------------------------*/
-static inline u16 w9968cf_valid_palette(u16 palette)
-{
- u8 i = 0;
- while (w9968cf_formatlist[i].palette != 0) {
- if (palette == w9968cf_formatlist[i].palette)
- return palette;
- i++;
- }
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Return the depth corresponding to the given palette.
- Palette _must_ be supported !
- --------------------------------------------------------------------------*/
-static inline u16 w9968cf_valid_depth(u16 palette)
-{
- u8 i=0;
- while (w9968cf_formatlist[i].palette != palette)
- i++;
-
- return w9968cf_formatlist[i].depth;
-}
-
-
-/*--------------------------------------------------------------------------
- Return non-zero if the format requires decompression, 0 otherwise.
- --------------------------------------------------------------------------*/
-static inline u8 w9968cf_need_decompression(u16 palette)
-{
- u8 i = 0;
- while (w9968cf_formatlist[i].palette != 0) {
- if (palette == w9968cf_formatlist[i].palette)
- return w9968cf_formatlist[i].compression;
- i++;
- }
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Change the picture settings of the camera.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int
-w9968cf_set_picture(struct w9968cf_device* cam, struct video_picture pict)
-{
- u16 fmt, hw_depth, hw_palette, reg_v = 0x0000;
- int err = 0;
-
- /* Make sure we are using a valid depth */
- pict.depth = w9968cf_valid_depth(pict.palette);
-
- fmt = pict.palette;
-
- hw_depth = pict.depth; /* depth used by the winbond chip */
- hw_palette = pict.palette; /* palette used by the winbond chip */
-
- /* VS & HS polarities */
- reg_v = (cam->vs_polarity << 12) | (cam->hs_polarity << 11);
-
- switch (fmt)
- {
- case VIDEO_PALETTE_UYVY:
- reg_v |= 0x0000;
- cam->vpp_flag = VPP_NONE;
- break;
- case VIDEO_PALETTE_YUV422P:
- reg_v |= 0x0002;
- cam->vpp_flag = VPP_DECOMPRESSION;
- break;
- case VIDEO_PALETTE_YUV420:
- case VIDEO_PALETTE_YUV420P:
- reg_v |= 0x0003;
- cam->vpp_flag = VPP_DECOMPRESSION;
- break;
- case VIDEO_PALETTE_YUYV:
- case VIDEO_PALETTE_YUV422:
- reg_v |= 0x0000;
- cam->vpp_flag = VPP_SWAP_YUV_BYTES;
- hw_palette = VIDEO_PALETTE_UYVY;
- break;
- /* Original video is used instead of RGBX palettes.
- Software conversion later. */
- case VIDEO_PALETTE_GREY:
- case VIDEO_PALETTE_RGB555:
- case VIDEO_PALETTE_RGB565:
- case VIDEO_PALETTE_RGB24:
- case VIDEO_PALETTE_RGB32:
- reg_v |= 0x0000; /* UYVY 16 bit is used */
- hw_depth = 16;
- hw_palette = VIDEO_PALETTE_UYVY;
- cam->vpp_flag = VPP_UYVY_TO_RGBX;
- break;
- }
-
- /* NOTE: due to memory issues, it is better to disable the hardware
- double buffering during compression */
- if (cam->double_buffer && !(cam->vpp_flag & VPP_DECOMPRESSION))
- reg_v |= 0x0080;
-
- if (cam->clamping)
- reg_v |= 0x0020;
-
- if (cam->filter_type == 1)
- reg_v |= 0x0008;
- else if (cam->filter_type == 2)
- reg_v |= 0x000c;
-
- if ((err = w9968cf_write_reg(cam, reg_v, 0x16)))
- goto error;
-
- if ((err = w9968cf_sensor_update_picture(cam, pict)))
- goto error;
-
- /* If all went well, update the device data structure */
- memcpy(&cam->picture, &pict, sizeof(pict));
- cam->hw_depth = hw_depth;
- cam->hw_palette = hw_palette;
-
- /* Settings changed, so we clear the frame buffers */
- memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
-
- DBG(4, "Palette is %s, depth is %u bpp",
- symbolic(v4l1_plist, pict.palette), pict.depth)
-
- return 0;
-
-error:
- DBG(1, "Failed to change picture settings")
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Change the capture area size of the camera.
- This function _must_ be called _after_ w9968cf_set_picture().
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int
-w9968cf_set_window(struct w9968cf_device* cam, struct video_window win)
-{
- u16 x, y, w, h, scx, scy, cw, ch, ax, ay;
- unsigned long fw, fh;
- struct ovcamchip_window s_win;
- int err = 0;
-
- /* Work around to avoid FP arithmetics */
- #define SC(x) ((x) << 10)
- #define UNSC(x) ((x) >> 10)
-
- /* Make sure we are using a supported resolution */
- if ((err = w9968cf_adjust_window_size(cam, &win.width, &win.height)))
- goto error;
-
- /* Scaling factors */
- fw = SC(win.width) / cam->maxwidth;
- fh = SC(win.height) / cam->maxheight;
-
- /* Set up the width and height values used by the chip */
- if ((win.width > cam->maxwidth) || (win.height > cam->maxheight)) {
- cam->vpp_flag |= VPP_UPSCALE;
- /* Calculate largest w,h mantaining the same w/h ratio */
- w = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
- h = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
- if (w < cam->minwidth) /* just in case */
- w = cam->minwidth;
- if (h < cam->minheight) /* just in case */
- h = cam->minheight;
- } else {
- cam->vpp_flag &= ~VPP_UPSCALE;
- w = win.width;
- h = win.height;
- }
-
- /* x,y offsets of the cropped area */
- scx = cam->start_cropx;
- scy = cam->start_cropy;
-
- /* Calculate cropped area manteining the right w/h ratio */
- if (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE)) {
- cw = (fw >= fh) ? cam->maxwidth : SC(win.width)/fh;
- ch = (fw >= fh) ? SC(win.height)/fw : cam->maxheight;
- } else {
- cw = w;
- ch = h;
- }
-
- /* Setup the window of the sensor */
- s_win.format = VIDEO_PALETTE_UYVY;
- s_win.width = cam->maxwidth;
- s_win.height = cam->maxheight;
- s_win.quarter = 0; /* full progressive video */
-
- /* Center it */
- s_win.x = (s_win.width - cw) / 2;
- s_win.y = (s_win.height - ch) / 2;
-
- /* Clock divisor */
- if (cam->clockdiv >= 0)
- s_win.clockdiv = cam->clockdiv; /* manual override */
- else
- switch (cam->sensor) {
- case CC_OV6620:
- s_win.clockdiv = 0;
- break;
- case CC_OV6630:
- s_win.clockdiv = 0;
- break;
- case CC_OV76BE:
- case CC_OV7610:
- case CC_OV7620:
- s_win.clockdiv = 0;
- break;
- default:
- s_win.clockdiv = W9968CF_DEF_CLOCKDIVISOR;
- }
-
- /* We have to scale win.x and win.y offsets */
- if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
- || (cam->vpp_flag & VPP_UPSCALE) ) {
- ax = SC(win.x)/fw;
- ay = SC(win.y)/fh;
- } else {
- ax = win.x;
- ay = win.y;
- }
-
- if ((ax + cw) > cam->maxwidth)
- ax = cam->maxwidth - cw;
-
- if ((ay + ch) > cam->maxheight)
- ay = cam->maxheight - ch;
-
- /* Adjust win.x, win.y */
- if ( (cam->largeview && !(cam->vpp_flag & VPP_UPSCALE))
- || (cam->vpp_flag & VPP_UPSCALE) ) {
- win.x = UNSC(ax*fw);
- win.y = UNSC(ay*fh);
- } else {
- win.x = ax;
- win.y = ay;
- }
-
- /* Offsets used by the chip */
- x = ax + s_win.x;
- y = ay + s_win.y;
-
- /* Go ! */
- if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_MODE, &s_win)))
- goto error;
-
- err += w9968cf_write_reg(cam, scx + x, 0x10);
- err += w9968cf_write_reg(cam, scy + y, 0x11);
- err += w9968cf_write_reg(cam, scx + x + cw, 0x12);
- err += w9968cf_write_reg(cam, scy + y + ch, 0x13);
- err += w9968cf_write_reg(cam, w, 0x14);
- err += w9968cf_write_reg(cam, h, 0x15);
-
- /* JPEG width & height */
- err += w9968cf_write_reg(cam, w, 0x30);
- err += w9968cf_write_reg(cam, h, 0x31);
-
- /* Y & UV frame buffer strides (in WORD) */
- if (cam->vpp_flag & VPP_DECOMPRESSION) {
- err += w9968cf_write_reg(cam, w/2, 0x2c);
- err += w9968cf_write_reg(cam, w/4, 0x2d);
- } else
- err += w9968cf_write_reg(cam, w, 0x2c);
-
- if (err)
- goto error;
-
- /* If all went well, update the device data structure */
- memcpy(&cam->window, &win, sizeof(win));
- cam->hw_width = w;
- cam->hw_height = h;
-
- /* Settings changed, so we clear the frame buffers */
- memset(cam->frame[0].buffer, 0, cam->nbuffers*cam->frame[0].size);
-
- DBG(4, "The capture area is %dx%d, Offset (x,y)=(%u,%u)",
- win.width, win.height, win.x, win.y)
-
- PDBGG("x=%u ,y=%u, w=%u, h=%u, ax=%u, ay=%u, s_win.x=%u, s_win.y=%u, "
- "cw=%u, ch=%u, win.x=%u, win.y=%u, win.width=%u, win.height=%u",
- x, y, w, h, ax, ay, s_win.x, s_win.y, cw, ch, win.x, win.y,
- win.width, win.height)
-
- return 0;
-
-error:
- DBG(1, "Failed to change the capture area size")
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Adjust the asked values for window width and height.
- Return 0 on success, -1 otherwise.
- --------------------------------------------------------------------------*/
-static int
-w9968cf_adjust_window_size(struct w9968cf_device *cam, u32 *width, u32 *height)
-{
- unsigned int maxw, maxh, align;
-
- maxw = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
- w9968cf_vpp ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
- : cam->maxwidth;
- maxh = cam->upscaling && !(cam->vpp_flag & VPP_DECOMPRESSION) &&
- w9968cf_vpp ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
- : cam->maxheight;
- align = (cam->vpp_flag & VPP_DECOMPRESSION) ? 4 : 0;
-
- v4l_bound_align_image(width, cam->minwidth, maxw, align,
- height, cam->minheight, maxh, align, 0);
-
- PDBGG("Window size adjusted w=%u, h=%u ", *width, *height)
-
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Initialize the FIFO list of requested frames.
- --------------------------------------------------------------------------*/
-static void w9968cf_init_framelist(struct w9968cf_device* cam)
-{
- u8 i;
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->requested_frame[i] = NULL;
- cam->frame[i].queued = 0;
- cam->frame[i].status = F_UNUSED;
- }
-}
-
-
-/*--------------------------------------------------------------------------
- Add a frame in the FIFO list of requested frames.
- This function is called in process context.
- --------------------------------------------------------------------------*/
-static void w9968cf_push_frame(struct w9968cf_device* cam, u8 f_num)
-{
- u8 f;
- unsigned long lock_flags;
-
- spin_lock_irqsave(&cam->flist_lock, lock_flags);
-
- for (f=0; cam->requested_frame[f] != NULL; f++);
- cam->requested_frame[f] = &cam->frame[f_num];
- cam->frame[f_num].queued = 1;
- cam->frame[f_num].status = F_UNUSED; /* clear the status */
-
- spin_unlock_irqrestore(&cam->flist_lock, lock_flags);
-
- DBG(6, "Frame #%u pushed into the FIFO list. Position %u", f_num, f)
-}
-
-
-/*--------------------------------------------------------------------------
- Read, store and remove the first pointer in the FIFO list of requested
- frames. This function is called in interrupt context.
- --------------------------------------------------------------------------*/
-static void
-w9968cf_pop_frame(struct w9968cf_device* cam, struct w9968cf_frame_t** framep)
-{
- u8 i;
-
- spin_lock(&cam->flist_lock);
-
- *framep = cam->requested_frame[0];
-
- /* Shift the list of pointers */
- for (i = 0; i < cam->nbuffers-1; i++)
- cam->requested_frame[i] = cam->requested_frame[i+1];
- cam->requested_frame[i] = NULL;
-
- spin_unlock(&cam->flist_lock);
-
- DBG(6,"Popped frame #%d from the list", (*framep)->number)
-}
-
-
-/*--------------------------------------------------------------------------
- High-level video post-processing routine on grabbed frames.
- Return 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int
-w9968cf_postprocess_frame(struct w9968cf_device* cam,
- struct w9968cf_frame_t* fr)
-{
- void *pIn = fr->buffer, *pOut = cam->frame_vpp.buffer, *tmp;
- u16 w = cam->window.width,
- h = cam->window.height,
- d = cam->picture.depth,
- fmt = cam->picture.palette,
- rgb = cam->force_rgb,
- hw_w = cam->hw_width,
- hw_h = cam->hw_height,
- hw_d = cam->hw_depth;
- int err = 0;
-
- #define _PSWAP(pIn, pOut) {tmp = (pIn); (pIn) = (pOut); (pOut) = tmp;}
-
- if (cam->vpp_flag & VPP_DECOMPRESSION) {
- memcpy(pOut, pIn, fr->length);
- _PSWAP(pIn, pOut)
- err = w9968cf_vpp->decode(pIn, fr->length, hw_w, hw_h, pOut);
- PDBGG("Compressed frame length: %lu",(unsigned long)fr->length)
- fr->length = (hw_w*hw_h*hw_d)/8;
- _PSWAP(pIn, pOut)
- if (err) {
- DBG(4, "An error occurred while decoding the frame: "
- "%s", symbolic(decoder_errlist, err))
- return err;
- } else
- DBG(6, "Frame decoded")
- }
-
- if (cam->vpp_flag & VPP_SWAP_YUV_BYTES) {
- w9968cf_vpp->swap_yuvbytes(pIn, fr->length);
- DBG(6, "Original UYVY component ordering changed")
- }
-
- if (cam->vpp_flag & VPP_UPSCALE) {
- w9968cf_vpp->scale_up(pIn, pOut, hw_w, hw_h, hw_d, w, h);
- fr->length = (w*h*hw_d)/8;
- _PSWAP(pIn, pOut)
- DBG(6, "Vertical up-scaling done: %u,%u,%ubpp->%u,%u",
- hw_w, hw_h, hw_d, w, h)
- }
-
- if (cam->vpp_flag & VPP_UYVY_TO_RGBX) {
- w9968cf_vpp->uyvy_to_rgbx(pIn, fr->length, pOut, fmt, rgb);
- fr->length = (w*h*d)/8;
- _PSWAP(pIn, pOut)
- DBG(6, "UYVY-16bit to %s conversion done",
- symbolic(v4l1_plist, fmt))
- }
-
- if (pOut == fr->buffer)
- memcpy(fr->buffer, cam->frame_vpp.buffer, fr->length);
-
- return 0;
-}
-
-
-
-/****************************************************************************
- * Image sensor control routines *
- ****************************************************************************/
-
-static int
-w9968cf_sensor_set_control(struct w9968cf_device* cam, int cid, int val)
-{
- struct ovcamchip_control ctl;
- int err;
-
- ctl.id = cid;
- ctl.value = val;
-
- err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_S_CTRL, &ctl);
-
- return err;
-}
-
-
-static int
-w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
-{
- struct ovcamchip_control ctl;
- int err;
-
- ctl.id = cid;
-
- err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_G_CTRL, &ctl);
- if (!err)
- *val = ctl.value;
-
- return err;
-}
-
-
-static int
-w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
-{
- int rc;
-
- rc = v4l2_subdev_call(cam->sensor_sd, core, ioctl, cmd, arg);
- /* The I2C driver returns -EPERM on non-supported controls */
- return (rc < 0 && rc != -EPERM) ? rc : 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Update some settings of the image sensor.
- Returns: 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_sensor_update_settings(struct w9968cf_device* cam)
-{
- int err = 0;
-
- /* Auto brightness */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOBRIGHT,
- cam->auto_brt);
- if (err)
- return err;
-
- /* Auto exposure */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_AUTOEXP,
- cam->auto_exp);
- if (err)
- return err;
-
- /* Banding filter */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BANDFILT,
- cam->bandfilt);
- if (err)
- return err;
-
- /* Light frequency */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_FREQ,
- cam->lightfreq);
- if (err)
- return err;
-
- /* Back light */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BACKLIGHT,
- cam->backlight);
- if (err)
- return err;
-
- /* Mirror */
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_MIRROR,
- cam->mirror);
- if (err)
- return err;
-
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Get some current picture settings from the image sensor and update the
- internal 'picture' structure of the camera.
- Returns: 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_sensor_get_picture(struct w9968cf_device* cam)
-{
- int err, v;
-
- err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_CONT, &v);
- if (err)
- return err;
- cam->picture.contrast = v;
-
- err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_BRIGHT, &v);
- if (err)
- return err;
- cam->picture.brightness = v;
-
- err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_SAT, &v);
- if (err)
- return err;
- cam->picture.colour = v;
-
- err = w9968cf_sensor_get_control(cam, OVCAMCHIP_CID_HUE, &v);
- if (err)
- return err;
- cam->picture.hue = v;
-
- DBG(5, "Got picture settings from the image sensor")
-
- PDBGG("Brightness, contrast, hue, colour, whiteness are "
- "%u,%u,%u,%u,%u", cam->picture.brightness,cam->picture.contrast,
- cam->picture.hue, cam->picture.colour, cam->picture.whiteness)
-
- return 0;
-}
-
-
-/*--------------------------------------------------------------------------
- Update picture settings of the image sensor.
- Returns: 0 on success, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int
-w9968cf_sensor_update_picture(struct w9968cf_device* cam,
- struct video_picture pict)
-{
- int err = 0;
-
- if ((!cam->sensor_initialized)
- || pict.contrast != cam->picture.contrast) {
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_CONT,
- pict.contrast);
- if (err)
- goto fail;
- DBG(4, "Contrast changed from %u to %u",
- cam->picture.contrast, pict.contrast)
- cam->picture.contrast = pict.contrast;
- }
-
- if (((!cam->sensor_initialized) ||
- pict.brightness != cam->picture.brightness) && (!cam->auto_brt)) {
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_BRIGHT,
- pict.brightness);
- if (err)
- goto fail;
- DBG(4, "Brightness changed from %u to %u",
- cam->picture.brightness, pict.brightness)
- cam->picture.brightness = pict.brightness;
- }
-
- if ((!cam->sensor_initialized) || pict.colour != cam->picture.colour) {
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_SAT,
- pict.colour);
- if (err)
- goto fail;
- DBG(4, "Colour changed from %u to %u",
- cam->picture.colour, pict.colour)
- cam->picture.colour = pict.colour;
- }
-
- if ((!cam->sensor_initialized) || pict.hue != cam->picture.hue) {
- err = w9968cf_sensor_set_control(cam, OVCAMCHIP_CID_HUE,
- pict.hue);
- if (err)
- goto fail;
- DBG(4, "Hue changed from %u to %u",
- cam->picture.hue, pict.hue)
- cam->picture.hue = pict.hue;
- }
-
- return 0;
-
-fail:
- DBG(4, "Failed to change sensor picture setting")
- return err;
-}
-
-
-
-/****************************************************************************
- * Camera configuration *
- ****************************************************************************/
-
-/*--------------------------------------------------------------------------
- This function is called when a supported image sensor is detected.
- Return 0 if the initialization succeeds, a negative number otherwise.
- --------------------------------------------------------------------------*/
-static int w9968cf_sensor_init(struct w9968cf_device* cam)
-{
- int err = 0;
-
- if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_INITIALIZE,
- &cam->monochrome)))
- goto error;
-
- if ((err = w9968cf_sensor_cmd(cam, OVCAMCHIP_CMD_Q_SUBTYPE,
- &cam->sensor)))
- goto error;
-
- /* NOTE: Make sure width and height are a multiple of 16 */
- switch (v4l2_i2c_subdev_addr(cam->sensor_sd)) {
- case OV6xx0_SID:
- cam->maxwidth = 352;
- cam->maxheight = 288;
- cam->minwidth = 64;
- cam->minheight = 48;
- break;
- case OV7xx0_SID:
- cam->maxwidth = 640;
- cam->maxheight = 480;
- cam->minwidth = 64;
- cam->minheight = 48;
- break;
- default:
- DBG(1, "Not supported image sensor detected for %s",
- symbolic(camlist, cam->id))
- return -EINVAL;
- }
-
- /* These values depend on the ones in the ovxxx0.c sources */
- switch (cam->sensor) {
- case CC_OV7620:
- cam->start_cropx = 287;
- cam->start_cropy = 35;
- /* Seems to work around a bug in the image sensor */
- cam->vs_polarity = 1;
- cam->hs_polarity = 1;
- break;
- default:
- cam->start_cropx = 320;
- cam->start_cropy = 35;
- cam->vs_polarity = 1;
- cam->hs_polarity = 0;
- }
-
- if ((err = w9968cf_sensor_update_settings(cam)))
- goto error;
-
- if ((err = w9968cf_sensor_update_picture(cam, cam->picture)))
- goto error;
-
- cam->sensor_initialized = 1;
-
- DBG(2, "%s image sensor initialized", symbolic(senlist, cam->sensor))
- return 0;
-
-error:
- cam->sensor_initialized = 0;
- cam->sensor = CC_UNKNOWN;
- DBG(1, "Image sensor initialization failed for %s (%s). "
- "Try to detach and attach this device again",
- symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
- return err;
-}
-
-
-/*--------------------------------------------------------------------------
- Fill some basic fields in the main device data structure.
- This function is called once on w9968cf_usb_probe() for each recognized
- camera.
- --------------------------------------------------------------------------*/
-static void
-w9968cf_configure_camera(struct w9968cf_device* cam,
- struct usb_device* udev,
- enum w9968cf_model_id mod_id,
- const unsigned short dev_nr)
-{
- mutex_init(&cam->fileop_mutex);
- init_waitqueue_head(&cam->open);
- spin_lock_init(&cam->urb_lock);
- spin_lock_init(&cam->flist_lock);
-
- cam->users = 0;
- cam->disconnected = 0;
- cam->id = mod_id;
- cam->sensor = CC_UNKNOWN;
- cam->sensor_initialized = 0;
-
- /* Calculate the alternate setting number (from 1 to 16)
- according to the 'packet_size' module parameter */
- if (packet_size[dev_nr] < W9968CF_MIN_PACKET_SIZE)
- packet_size[dev_nr] = W9968CF_MIN_PACKET_SIZE;
- for (cam->altsetting = 1;
- packet_size[dev_nr] < wMaxPacketSize[cam->altsetting-1];
- cam->altsetting++);
-
- cam->max_buffers = (max_buffers[dev_nr] < 2 ||
- max_buffers[dev_nr] > W9968CF_MAX_BUFFERS)
- ? W9968CF_BUFFERS : (u8)max_buffers[dev_nr];
-
- cam->double_buffer = (double_buffer[dev_nr] == 0 ||
- double_buffer[dev_nr] == 1)
- ? (u8)double_buffer[dev_nr]:W9968CF_DOUBLE_BUFFER;
-
- cam->clamping = (clamping[dev_nr] == 0 || clamping[dev_nr] == 1)
- ? (u8)clamping[dev_nr] : W9968CF_CLAMPING;
-
- cam->filter_type = (filter_type[dev_nr] == 0 ||
- filter_type[dev_nr] == 1 ||
- filter_type[dev_nr] == 2)
- ? (u8)filter_type[dev_nr] : W9968CF_FILTER_TYPE;
-
- cam->capture = 1;
-
- cam->largeview = (largeview[dev_nr] == 0 || largeview[dev_nr] == 1)
- ? (u8)largeview[dev_nr] : W9968CF_LARGEVIEW;
-
- cam->decompression = (decompression[dev_nr] == 0 ||
- decompression[dev_nr] == 1 ||
- decompression[dev_nr] == 2)
- ? (u8)decompression[dev_nr]:W9968CF_DECOMPRESSION;
-
- cam->upscaling = (upscaling[dev_nr] == 0 ||
- upscaling[dev_nr] == 1)
- ? (u8)upscaling[dev_nr] : W9968CF_UPSCALING;
-
- cam->auto_brt = (autobright[dev_nr] == 0 || autobright[dev_nr] == 1)
- ? (u8)autobright[dev_nr] : W9968CF_AUTOBRIGHT;
-
- cam->auto_exp = (autoexp[dev_nr] == 0 || autoexp[dev_nr] == 1)
- ? (u8)autoexp[dev_nr] : W9968CF_AUTOEXP;
-
- cam->lightfreq = (lightfreq[dev_nr] == 50 || lightfreq[dev_nr] == 60)
- ? (u8)lightfreq[dev_nr] : W9968CF_LIGHTFREQ;
-
- cam->bandfilt = (bandingfilter[dev_nr] == 0 ||
- bandingfilter[dev_nr] == 1)
- ? (u8)bandingfilter[dev_nr] : W9968CF_BANDINGFILTER;
-
- cam->backlight = (backlight[dev_nr] == 0 || backlight[dev_nr] == 1)
- ? (u8)backlight[dev_nr] : W9968CF_BACKLIGHT;
-
- cam->clockdiv = (clockdiv[dev_nr] == -1 || clockdiv[dev_nr] >= 0)
- ? (s8)clockdiv[dev_nr] : W9968CF_CLOCKDIV;
-
- cam->mirror = (mirror[dev_nr] == 0 || mirror[dev_nr] == 1)
- ? (u8)mirror[dev_nr] : W9968CF_MIRROR;
-
- cam->monochrome = (monochrome[dev_nr] == 0 || monochrome[dev_nr] == 1)
- ? monochrome[dev_nr] : W9968CF_MONOCHROME;
-
- cam->picture.brightness = (u16)brightness[dev_nr];
- cam->picture.hue = (u16)hue[dev_nr];
- cam->picture.colour = (u16)colour[dev_nr];
- cam->picture.contrast = (u16)contrast[dev_nr];
- cam->picture.whiteness = (u16)whiteness[dev_nr];
- if (w9968cf_valid_palette((u16)force_palette[dev_nr])) {
- cam->picture.palette = (u16)force_palette[dev_nr];
- cam->force_palette = 1;
- } else {
- cam->force_palette = 0;
- if (cam->decompression == 0)
- cam->picture.palette = W9968CF_PALETTE_DECOMP_OFF;
- else if (cam->decompression == 1)
- cam->picture.palette = W9968CF_PALETTE_DECOMP_FORCE;
- else
- cam->picture.palette = W9968CF_PALETTE_DECOMP_ON;
- }
- cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
-
- cam->force_rgb = (force_rgb[dev_nr] == 0 || force_rgb[dev_nr] == 1)
- ? (u8)force_rgb[dev_nr] : W9968CF_FORCE_RGB;
-
- cam->window.x = 0;
- cam->window.y = 0;
- cam->window.width = W9968CF_WIDTH;
- cam->window.height = W9968CF_HEIGHT;
- cam->window.chromakey = 0;
- cam->window.clipcount = 0;
- cam->window.flags = 0;
-
- DBG(3, "%s configured with settings #%u:",
- symbolic(camlist, cam->id), dev_nr)
-
- DBG(3, "- Data packet size for USB isochrnous transfer: %u bytes",
- wMaxPacketSize[cam->altsetting-1])
-
- DBG(3, "- Number of requested video frame buffers: %u",
- cam->max_buffers)
-
- if (cam->double_buffer)
- DBG(3, "- Hardware double buffering enabled")
- else
- DBG(3, "- Hardware double buffering disabled")
-
- if (cam->filter_type == 0)
- DBG(3, "- Video filtering disabled")
- else if (cam->filter_type == 1)
- DBG(3, "- Video filtering enabled: type 1-2-1")
- else if (cam->filter_type == 2)
- DBG(3, "- Video filtering enabled: type 2-3-6-3-2")
-
- if (cam->clamping)
- DBG(3, "- Video data clamping (CCIR-601 format) enabled")
- else
- DBG(3, "- Video data clamping (CCIR-601 format) disabled")
-
- if (cam->largeview)
- DBG(3, "- Large view enabled")
- else
- DBG(3, "- Large view disabled")
-
- if ((cam->decompression) == 0 && (!cam->force_palette))
- DBG(3, "- Decompression disabled")
- else if ((cam->decompression) == 1 && (!cam->force_palette))
- DBG(3, "- Decompression forced")
- else if ((cam->decompression) == 2 && (!cam->force_palette))
- DBG(3, "- Decompression allowed")
-
- if (cam->upscaling)
- DBG(3, "- Software image scaling enabled")
- else
- DBG(3, "- Software image scaling disabled")
-
- if (cam->force_palette)
- DBG(3, "- Image palette forced to %s",
- symbolic(v4l1_plist, cam->picture.palette))
-
- if (cam->force_rgb)
- DBG(3, "- RGB component ordering will be used instead of BGR")
-
- if (cam->auto_brt)
- DBG(3, "- Auto brightness enabled")
- else
- DBG(3, "- Auto brightness disabled")
-
- if (cam->auto_exp)
- DBG(3, "- Auto exposure enabled")
- else
- DBG(3, "- Auto exposure disabled")
-
- if (cam->backlight)
- DBG(3, "- Backlight exposure algorithm enabled")
- else
- DBG(3, "- Backlight exposure algorithm disabled")
-
- if (cam->mirror)
- DBG(3, "- Mirror enabled")
- else
- DBG(3, "- Mirror disabled")
-
- if (cam->bandfilt)
- DBG(3, "- Banding filter enabled")
- else
- DBG(3, "- Banding filter disabled")
-
- DBG(3, "- Power lighting frequency: %u", cam->lightfreq)
-
- if (cam->clockdiv == -1)
- DBG(3, "- Automatic clock divisor enabled")
- else
- DBG(3, "- Clock divisor: %d", cam->clockdiv)
-
- if (cam->monochrome)
- DBG(3, "- Image sensor used as monochrome")
- else
- DBG(3, "- Image sensor not used as monochrome")
-}
-
-
-/*--------------------------------------------------------------------------
- If the video post-processing module is not loaded, some parameters
- must be overridden.
- --------------------------------------------------------------------------*/
-static void w9968cf_adjust_configuration(struct w9968cf_device* cam)
-{
- if (!w9968cf_vpp) {
- if (cam->decompression == 1) {
- cam->decompression = 2;
- DBG(2, "Video post-processing module not found: "
- "'decompression' parameter forced to 2")
- }
- if (cam->upscaling) {
- cam->upscaling = 0;
- DBG(2, "Video post-processing module not found: "
- "'upscaling' parameter forced to 0")
- }
- if (cam->picture.palette != VIDEO_PALETTE_UYVY) {
- cam->force_palette = 0;
- DBG(2, "Video post-processing module not found: "
- "'force_palette' parameter forced to 0")
- }
- cam->picture.palette = VIDEO_PALETTE_UYVY;
- cam->picture.depth = w9968cf_valid_depth(cam->picture.palette);
- }
-}
-
-
-/*--------------------------------------------------------------------------
- Release the resources used by the driver.
- This function is called on disconnect
- (or on close if deallocation has been deferred)
- --------------------------------------------------------------------------*/
-static void w9968cf_release_resources(struct w9968cf_device* cam)
-{
- mutex_lock(&w9968cf_devlist_mutex);
-
- DBG(2, "V4L device deregistered: %s",
- video_device_node_name(cam->v4ldev))
-
- video_unregister_device(cam->v4ldev);
- list_del(&cam->v4llist);
- i2c_del_adapter(&cam->i2c_adapter);
- w9968cf_deallocate_memory(cam);
- kfree(cam->control_buffer);
- kfree(cam->data_buffer);
- v4l2_device_unregister(&cam->v4l2_dev);
-
- mutex_unlock(&w9968cf_devlist_mutex);
-}
-
-
-
-/****************************************************************************
- * Video4Linux interface *
- ****************************************************************************/
-
-static int w9968cf_open(struct file *filp)
-{
- struct w9968cf_device* cam;
- int err;
-
- /* This the only safe way to prevent race conditions with disconnect */
- if (!down_read_trylock(&w9968cf_disconnect))
- return -EAGAIN;
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
- mutex_lock(&cam->dev_mutex);
-
- if (cam->sensor == CC_UNKNOWN) {
- DBG(2, "No supported image sensor has been detected by the "
- "'ovcamchip' module for the %s (%s). Make sure "
- "it is loaded *before* (re)connecting the camera.",
- symbolic(camlist, cam->id),
- video_device_node_name(cam->v4ldev))
- mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return -ENODEV;
- }
-
- if (cam->users) {
- DBG(2, "%s (%s) has been already occupied by '%s'",
- symbolic(camlist, cam->id),
- video_device_node_name(cam->v4ldev), cam->command)
- if ((filp->f_flags & O_NONBLOCK)||(filp->f_flags & O_NDELAY)) {
- mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return -EWOULDBLOCK;
- }
- mutex_unlock(&cam->dev_mutex);
- err = wait_event_interruptible_exclusive(cam->open,
- cam->disconnected ||
- !cam->users);
- if (err) {
- up_read(&w9968cf_disconnect);
- return err;
- }
- if (cam->disconnected) {
- up_read(&w9968cf_disconnect);
- return -ENODEV;
- }
- mutex_lock(&cam->dev_mutex);
- }
-
- DBG(5, "Opening '%s', %s ...",
- symbolic(camlist, cam->id), video_device_node_name(cam->v4ldev))
-
- cam->streaming = 0;
- cam->misconfigured = 0;
-
- w9968cf_adjust_configuration(cam);
-
- if ((err = w9968cf_allocate_memory(cam)))
- goto deallocate_memory;
-
- if ((err = w9968cf_init_chip(cam)))
- goto deallocate_memory;
-
- if ((err = w9968cf_start_transfer(cam)))
- goto deallocate_memory;
-
- filp->private_data = cam;
-
- cam->users++;
- strcpy(cam->command, current->comm);
-
- init_waitqueue_head(&cam->wait_queue);
-
- DBG(5, "Video device is open")
-
- mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
-
- return 0;
-
-deallocate_memory:
- w9968cf_deallocate_memory(cam);
- DBG(2, "Failed to open the video device")
- mutex_unlock(&cam->dev_mutex);
- up_read(&w9968cf_disconnect);
- return err;
-}
-
-
-static int w9968cf_release(struct file *filp)
-{
- struct w9968cf_device* cam;
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
- mutex_lock(&cam->dev_mutex); /* prevent disconnect() to be called */
-
- w9968cf_stop_transfer(cam);
-
- if (cam->disconnected) {
- w9968cf_release_resources(cam);
- mutex_unlock(&cam->dev_mutex);
- kfree(cam);
- return 0;
- }
-
- cam->users--;
- w9968cf_deallocate_memory(cam);
- wake_up_interruptible_nr(&cam->open, 1);
-
- DBG(5, "Video device closed")
- mutex_unlock(&cam->dev_mutex);
- return 0;
-}
-
-
-static ssize_t
-w9968cf_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
-{
- struct w9968cf_device* cam;
- struct w9968cf_frame_t* fr;
- int err = 0;
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
- if (filp->f_flags & O_NONBLOCK)
- return -EWOULDBLOCK;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->disconnected) {
- DBG(2, "Device not present")
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->misconfigured) {
- DBG(2, "The camera is misconfigured. Close and open it again.")
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (!cam->frame[0].queued)
- w9968cf_push_frame(cam, 0);
-
- if (!cam->frame[1].queued)
- w9968cf_push_frame(cam, 1);
-
- err = wait_event_interruptible(cam->wait_queue,
- cam->frame[0].status == F_READY ||
- cam->frame[1].status == F_READY ||
- cam->disconnected);
- if (err) {
- mutex_unlock(&cam->fileop_mutex);
- return err;
- }
- if (cam->disconnected) {
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- fr = (cam->frame[0].status == F_READY) ? &cam->frame[0]:&cam->frame[1];
-
- if (w9968cf_vpp)
- w9968cf_postprocess_frame(cam, fr);
-
- if (count > fr->length)
- count = fr->length;
-
- if (copy_to_user(buf, fr->buffer, count)) {
- fr->status = F_UNUSED;
- mutex_unlock(&cam->fileop_mutex);
- return -EFAULT;
- }
- *f_pos += count;
-
- fr->status = F_UNUSED;
-
- DBG(5, "%zu bytes read", count)
-
- mutex_unlock(&cam->fileop_mutex);
- return count;
-}
-
-
-static int w9968cf_mmap(struct file* filp, struct vm_area_struct *vma)
-{
- struct w9968cf_device* cam = (struct w9968cf_device*)
- video_get_drvdata(video_devdata(filp));
- unsigned long vsize = vma->vm_end - vma->vm_start,
- psize = cam->nbuffers * cam->frame[0].size,
- start = vma->vm_start,
- pos = (unsigned long)cam->frame[0].buffer,
- page;
-
- if (cam->disconnected) {
- DBG(2, "Device not present")
- return -ENODEV;
- }
-
- if (cam->misconfigured) {
- DBG(2, "The camera is misconfigured. Close and open it again")
- return -EIO;
- }
-
- PDBGG("mmapping %lu bytes...", vsize)
-
- if (vsize > psize - (vma->vm_pgoff << PAGE_SHIFT))
- return -EINVAL;
-
- while (vsize > 0) {
- page = vmalloc_to_pfn((void *)pos);
- if (remap_pfn_range(vma, start, page + vma->vm_pgoff,
- PAGE_SIZE, vma->vm_page_prot))
- return -EAGAIN;
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- vsize -= PAGE_SIZE;
- }
-
- DBG(5, "mmap method successfully called")
- return 0;
-}
-
-
-static long
-w9968cf_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct w9968cf_device* cam;
- long err;
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->disconnected) {
- DBG(2, "Device not present")
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->misconfigured) {
- DBG(2, "The camera is misconfigured. Close and open it again.")
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- err = w9968cf_v4l_ioctl(filp, cmd, (void __user *)arg);
-
- mutex_unlock(&cam->fileop_mutex);
- return err;
-}
-
-
-static long w9968cf_v4l_ioctl(struct file *filp,
- unsigned int cmd, void __user *arg)
-{
- struct w9968cf_device* cam;
- const char* v4l1_ioctls[] = {
- "?", "CGAP", "GCHAN", "SCHAN", "GTUNER", "STUNER",
- "GPICT", "SPICT", "CCAPTURE", "GWIN", "SWIN", "GFBUF",
- "SFBUF", "KEY", "GFREQ", "SFREQ", "GAUDIO", "SAUDIO",
- "SYNC", "MCAPTURE", "GMBUF", "GUNIT", "GCAPTURE", "SCAPTURE",
- "SPLAYMODE", "SWRITEMODE", "GPLAYINFO", "SMICROCODE",
- "GVBIFMT", "SVBIFMT"
- };
-
- #define V4L1_IOCTL(cmd) \
- ((_IOC_NR((cmd)) < ARRAY_SIZE(v4l1_ioctls)) ? \
- v4l1_ioctls[_IOC_NR((cmd))] : "?")
-
- cam = (struct w9968cf_device*)video_get_drvdata(video_devdata(filp));
-
- switch (cmd) {
-
- case VIDIOCGCAP: /* get video capability */
- {
- struct video_capability cap = {
- .type = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
- .channels = 1,
- .audios = 0,
- .minwidth = cam->minwidth,
- .minheight = cam->minheight,
- };
- sprintf(cap.name, "W996[87]CF USB Camera");
- cap.maxwidth = (cam->upscaling && w9968cf_vpp)
- ? max((u16)W9968CF_MAX_WIDTH, cam->maxwidth)
- : cam->maxwidth;
- cap.maxheight = (cam->upscaling && w9968cf_vpp)
- ? max((u16)W9968CF_MAX_HEIGHT, cam->maxheight)
- : cam->maxheight;
-
- if (copy_to_user(arg, &cap, sizeof(cap)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGCAP successfully called")
- return 0;
- }
-
- case VIDIOCGCHAN: /* get video channel informations */
- {
- struct video_channel chan;
- if (copy_from_user(&chan, arg, sizeof(chan)))
- return -EFAULT;
-
- if (chan.channel != 0)
- return -EINVAL;
-
- strcpy(chan.name, "Camera");
- chan.tuners = 0;
- chan.flags = 0;
- chan.type = VIDEO_TYPE_CAMERA;
- chan.norm = VIDEO_MODE_AUTO;
-
- if (copy_to_user(arg, &chan, sizeof(chan)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGCHAN successfully called")
- return 0;
- }
-
- case VIDIOCSCHAN: /* set active channel */
- {
- struct video_channel chan;
-
- if (copy_from_user(&chan, arg, sizeof(chan)))
- return -EFAULT;
-
- if (chan.channel != 0)
- return -EINVAL;
-
- DBG(5, "VIDIOCSCHAN successfully called")
- return 0;
- }
-
- case VIDIOCGPICT: /* get image properties of the picture */
- {
- if (w9968cf_sensor_get_picture(cam))
- return -EIO;
-
- if (copy_to_user(arg, &cam->picture, sizeof(cam->picture)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGPICT successfully called")
- return 0;
- }
-
- case VIDIOCSPICT: /* change picture settings */
- {
- struct video_picture pict;
- int err = 0;
-
- if (copy_from_user(&pict, arg, sizeof(pict)))
- return -EFAULT;
-
- if ( (cam->force_palette || !w9968cf_vpp)
- && pict.palette != cam->picture.palette ) {
- DBG(4, "Palette %s rejected: only %s is allowed",
- symbolic(v4l1_plist, pict.palette),
- symbolic(v4l1_plist, cam->picture.palette))
- return -EINVAL;
- }
-
- if (!w9968cf_valid_palette(pict.palette)) {
- DBG(4, "Palette %s not supported. VIDIOCSPICT failed",
- symbolic(v4l1_plist, pict.palette))
- return -EINVAL;
- }
-
- if (!cam->force_palette) {
- if (cam->decompression == 0) {
- if (w9968cf_need_decompression(pict.palette)) {
- DBG(4, "Decompression disabled: palette %s is not "
- "allowed. VIDIOCSPICT failed",
- symbolic(v4l1_plist, pict.palette))
- return -EINVAL;
- }
- } else if (cam->decompression == 1) {
- if (!w9968cf_need_decompression(pict.palette)) {
- DBG(4, "Decompression forced: palette %s is not "
- "allowed. VIDIOCSPICT failed",
- symbolic(v4l1_plist, pict.palette))
- return -EINVAL;
- }
- }
- }
-
- if (pict.depth != w9968cf_valid_depth(pict.palette)) {
- DBG(4, "Requested depth %u bpp is not valid for %s "
- "palette: ignored and changed to %u bpp",
- pict.depth, symbolic(v4l1_plist, pict.palette),
- w9968cf_valid_depth(pict.palette))
- pict.depth = w9968cf_valid_depth(pict.palette);
- }
-
- if (pict.palette != cam->picture.palette) {
- if(*cam->requested_frame
- || cam->frame_current->queued) {
- err = wait_event_interruptible
- ( cam->wait_queue,
- cam->disconnected ||
- (!*cam->requested_frame &&
- !cam->frame_current->queued) );
- if (err)
- return err;
- if (cam->disconnected)
- return -ENODEV;
- }
-
- if (w9968cf_stop_transfer(cam))
- goto ioctl_fail;
-
- if (w9968cf_set_picture(cam, pict))
- goto ioctl_fail;
-
- if (w9968cf_start_transfer(cam))
- goto ioctl_fail;
-
- } else if (w9968cf_sensor_update_picture(cam, pict))
- return -EIO;
-
-
- DBG(5, "VIDIOCSPICT successfully called")
- return 0;
- }
-
- case VIDIOCSWIN: /* set capture area */
- {
- struct video_window win;
- int err = 0;
-
- if (copy_from_user(&win, arg, sizeof(win)))
- return -EFAULT;
-
- DBG(6, "VIDIOCSWIN called: clipcount=%d, flags=%u, "
- "x=%u, y=%u, %ux%u", win.clipcount, win.flags,
- win.x, win.y, win.width, win.height)
-
- if (win.clipcount != 0 || win.flags != 0)
- return -EINVAL;
-
- if ((err = w9968cf_adjust_window_size(cam, &win.width,
- &win.height))) {
- DBG(4, "Resolution not supported (%ux%u). "
- "VIDIOCSWIN failed", win.width, win.height)
- return err;
- }
-
- if (win.x != cam->window.x ||
- win.y != cam->window.y ||
- win.width != cam->window.width ||
- win.height != cam->window.height) {
- if(*cam->requested_frame
- || cam->frame_current->queued) {
- err = wait_event_interruptible
- ( cam->wait_queue,
- cam->disconnected ||
- (!*cam->requested_frame &&
- !cam->frame_current->queued) );
- if (err)
- return err;
- if (cam->disconnected)
- return -ENODEV;
- }
-
- if (w9968cf_stop_transfer(cam))
- goto ioctl_fail;
-
- /* This _must_ be called before set_window() */
- if (w9968cf_set_picture(cam, cam->picture))
- goto ioctl_fail;
-
- if (w9968cf_set_window(cam, win))
- goto ioctl_fail;
-
- if (w9968cf_start_transfer(cam))
- goto ioctl_fail;
- }
-
- DBG(5, "VIDIOCSWIN successfully called. ")
- return 0;
- }
-
- case VIDIOCGWIN: /* get current window properties */
- {
- if (copy_to_user(arg,&cam->window,sizeof(struct video_window)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGWIN successfully called")
- return 0;
- }
-
- case VIDIOCGMBUF: /* request for memory (mapped) buffer */
- {
- struct video_mbuf mbuf;
- u8 i;
-
- mbuf.size = cam->nbuffers * cam->frame[0].size;
- mbuf.frames = cam->nbuffers;
- for (i = 0; i < cam->nbuffers; i++)
- mbuf.offsets[i] = (unsigned long)cam->frame[i].buffer -
- (unsigned long)cam->frame[0].buffer;
-
- if (copy_to_user(arg, &mbuf, sizeof(mbuf)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGMBUF successfully called")
- return 0;
- }
-
- case VIDIOCMCAPTURE: /* start the capture to a frame */
- {
- struct video_mmap mmap;
- struct w9968cf_frame_t* fr;
- u32 w, h;
- int err = 0;
-
- if (copy_from_user(&mmap, arg, sizeof(mmap)))
- return -EFAULT;
-
- DBG(6, "VIDIOCMCAPTURE called: frame #%u, format=%s, %dx%d",
- mmap.frame, symbolic(v4l1_plist, mmap.format),
- mmap.width, mmap.height)
-
- if (mmap.frame >= cam->nbuffers) {
- DBG(4, "Invalid frame number (%u). "
- "VIDIOCMCAPTURE failed", mmap.frame)
- return -EINVAL;
- }
-
- if (mmap.format!=cam->picture.palette &&
- (cam->force_palette || !w9968cf_vpp)) {
- DBG(4, "Palette %s rejected: only %s is allowed",
- symbolic(v4l1_plist, mmap.format),
- symbolic(v4l1_plist, cam->picture.palette))
- return -EINVAL;
- }
-
- if (!w9968cf_valid_palette(mmap.format)) {
- DBG(4, "Palette %s not supported. "
- "VIDIOCMCAPTURE failed",
- symbolic(v4l1_plist, mmap.format))
- return -EINVAL;
- }
-
- if (!cam->force_palette) {
- if (cam->decompression == 0) {
- if (w9968cf_need_decompression(mmap.format)) {
- DBG(4, "Decompression disabled: palette %s is not "
- "allowed. VIDIOCSPICT failed",
- symbolic(v4l1_plist, mmap.format))
- return -EINVAL;
- }
- } else if (cam->decompression == 1) {
- if (!w9968cf_need_decompression(mmap.format)) {
- DBG(4, "Decompression forced: palette %s is not "
- "allowed. VIDIOCSPICT failed",
- symbolic(v4l1_plist, mmap.format))
- return -EINVAL;
- }
- }
- }
-
- w = mmap.width; h = mmap.height;
- err = w9968cf_adjust_window_size(cam, &w, &h);
- mmap.width = w; mmap.height = h;
- if (err) {
- DBG(4, "Resolution not supported (%dx%d). "
- "VIDIOCMCAPTURE failed",
- mmap.width, mmap.height)
- return err;
- }
-
- fr = &cam->frame[mmap.frame];
-
- if (mmap.width != cam->window.width ||
- mmap.height != cam->window.height ||
- mmap.format != cam->picture.palette) {
-
- struct video_window win;
- struct video_picture pict;
-
- if(*cam->requested_frame
- || cam->frame_current->queued) {
- DBG(6, "VIDIOCMCAPTURE. Change settings for "
- "frame #%u: %dx%d, format %s. Wait...",
- mmap.frame, mmap.width, mmap.height,
- symbolic(v4l1_plist, mmap.format))
- err = wait_event_interruptible
- ( cam->wait_queue,
- cam->disconnected ||
- (!*cam->requested_frame &&
- !cam->frame_current->queued) );
- if (err)
- return err;
- if (cam->disconnected)
- return -ENODEV;
- }
-
- memcpy(&win, &cam->window, sizeof(win));
- memcpy(&pict, &cam->picture, sizeof(pict));
- win.width = mmap.width;
- win.height = mmap.height;
- pict.palette = mmap.format;
-
- if (w9968cf_stop_transfer(cam))
- goto ioctl_fail;
-
- /* This before set_window */
- if (w9968cf_set_picture(cam, pict))
- goto ioctl_fail;
-
- if (w9968cf_set_window(cam, win))
- goto ioctl_fail;
-
- if (w9968cf_start_transfer(cam))
- goto ioctl_fail;
-
- } else if (fr->queued) {
-
- DBG(6, "Wait until frame #%u is free", mmap.frame)
-
- err = wait_event_interruptible(cam->wait_queue,
- cam->disconnected ||
- (!fr->queued));
- if (err)
- return err;
- if (cam->disconnected)
- return -ENODEV;
- }
-
- w9968cf_push_frame(cam, mmap.frame);
- DBG(5, "VIDIOCMCAPTURE(%u): successfully called", mmap.frame)
- return 0;
- }
-
- case VIDIOCSYNC: /* wait until the capture of a frame is finished */
- {
- unsigned int f_num;
- struct w9968cf_frame_t* fr;
- int err = 0;
-
- if (copy_from_user(&f_num, arg, sizeof(f_num)))
- return -EFAULT;
-
- if (f_num >= cam->nbuffers) {
- DBG(4, "Invalid frame number (%u). "
- "VIDIOCMCAPTURE failed", f_num)
- return -EINVAL;
- }
-
- DBG(6, "VIDIOCSYNC called for frame #%u", f_num)
-
- fr = &cam->frame[f_num];
-
- switch (fr->status) {
- case F_UNUSED:
- if (!fr->queued) {
- DBG(4, "VIDIOSYNC: Frame #%u not requested!",
- f_num)
- return -EFAULT;
- }
- case F_ERROR:
- case F_GRABBING:
- err = wait_event_interruptible(cam->wait_queue,
- (fr->status == F_READY)
- || cam->disconnected);
- if (err)
- return err;
- if (cam->disconnected)
- return -ENODEV;
- break;
- case F_READY:
- break;
- }
-
- if (w9968cf_vpp)
- w9968cf_postprocess_frame(cam, fr);
-
- fr->status = F_UNUSED;
-
- DBG(5, "VIDIOCSYNC(%u) successfully called", f_num)
- return 0;
- }
-
- case VIDIOCGUNIT:/* report the unit numbers of the associated devices*/
- {
- struct video_unit unit = {
- .video = cam->v4ldev->minor,
- .vbi = VIDEO_NO_UNIT,
- .radio = VIDEO_NO_UNIT,
- .audio = VIDEO_NO_UNIT,
- .teletext = VIDEO_NO_UNIT,
- };
-
- if (copy_to_user(arg, &unit, sizeof(unit)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGUNIT successfully called")
- return 0;
- }
-
- case VIDIOCKEY:
- return 0;
-
- case VIDIOCGFBUF:
- {
- if (clear_user(arg, sizeof(struct video_buffer)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGFBUF successfully called")
- return 0;
- }
-
- case VIDIOCGTUNER:
- {
- struct video_tuner tuner;
- if (copy_from_user(&tuner, arg, sizeof(tuner)))
- return -EFAULT;
-
- if (tuner.tuner != 0)
- return -EINVAL;
-
- strcpy(tuner.name, "no_tuner");
- tuner.rangelow = 0;
- tuner.rangehigh = 0;
- tuner.flags = VIDEO_TUNER_NORM;
- tuner.mode = VIDEO_MODE_AUTO;
- tuner.signal = 0xffff;
-
- if (copy_to_user(arg, &tuner, sizeof(tuner)))
- return -EFAULT;
-
- DBG(5, "VIDIOCGTUNER successfully called")
- return 0;
- }
-
- case VIDIOCSTUNER:
- {
- struct video_tuner tuner;
- if (copy_from_user(&tuner, arg, sizeof(tuner)))
- return -EFAULT;
-
- if (tuner.tuner != 0)
- return -EINVAL;
-
- if (tuner.mode != VIDEO_MODE_AUTO)
- return -EINVAL;
-
- DBG(5, "VIDIOCSTUNER successfully called")
- return 0;
- }
-
- case VIDIOCSFBUF:
- case VIDIOCCAPTURE:
- case VIDIOCGFREQ:
- case VIDIOCSFREQ:
- case VIDIOCGAUDIO:
- case VIDIOCSAUDIO:
- case VIDIOCSPLAYMODE:
- case VIDIOCSWRITEMODE:
- case VIDIOCGPLAYINFO:
- case VIDIOCSMICROCODE:
- case VIDIOCGVBIFMT:
- case VIDIOCSVBIFMT:
- DBG(4, "Unsupported V4L1 IOCtl: VIDIOC%s "
- "(type 0x%01X, "
- "n. 0x%01X, "
- "dir. 0x%01X, "
- "size 0x%02X)",
- V4L1_IOCTL(cmd),
- _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
-
- return -EINVAL;
-
- default:
- DBG(4, "Invalid V4L1 IOCtl: VIDIOC%s "
- "type 0x%01X, "
- "n. 0x%01X, "
- "dir. 0x%01X, "
- "size 0x%02X",
- V4L1_IOCTL(cmd),
- _IOC_TYPE(cmd),_IOC_NR(cmd),_IOC_DIR(cmd),_IOC_SIZE(cmd))
-
- return -ENOIOCTLCMD;
-
- } /* end of switch */
-
-ioctl_fail:
- cam->misconfigured = 1;
- DBG(1, "VIDIOC%s failed because of hardware problems. "
- "To use the camera, close and open it again.", V4L1_IOCTL(cmd))
- return -EFAULT;
-}
-
-
-static const struct v4l2_file_operations w9968cf_fops = {
- .owner = THIS_MODULE,
- .open = w9968cf_open,
- .release = w9968cf_release,
- .read = w9968cf_read,
- .ioctl = w9968cf_ioctl,
- .mmap = w9968cf_mmap,
-};
-
-
-
-/****************************************************************************
- * USB probe and V4L registration, disconnect and id_table[] definition *
- ****************************************************************************/
-
-static int
-w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct w9968cf_device* cam;
- int err = 0;
- enum w9968cf_model_id mod_id;
- struct list_head* ptr;
- u8 sc = 0; /* number of simultaneous cameras */
- static unsigned short dev_nr; /* 0 - we are handling device number n */
- static unsigned short addrs[] = {
- OV7xx0_SID,
- OV6xx0_SID,
- I2C_CLIENT_END
- };
-
- if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
- le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
- mod_id = W9968CF_MOD_CLVBWGP; /* see camlist[] table */
- else if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[1].idVendor &&
- le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[1].idProduct)
- mod_id = W9968CF_MOD_GENERIC; /* see camlist[] table */
- else
- return -ENODEV;
-
- cam = (struct w9968cf_device*)
- kzalloc(sizeof(struct w9968cf_device), GFP_KERNEL);
- if (!cam)
- return -ENOMEM;
-
- err = v4l2_device_register(&intf->dev, &cam->v4l2_dev);
- if (err)
- goto fail0;
-
- mutex_init(&cam->dev_mutex);
- mutex_lock(&cam->dev_mutex);
-
- cam->usbdev = udev;
-
- DBG(2, "%s detected", symbolic(camlist, mod_id))
-
- if (simcams > W9968CF_MAX_DEVICES)
- simcams = W9968CF_SIMCAMS;
-
- /* How many cameras are connected ? */
- mutex_lock(&w9968cf_devlist_mutex);
- list_for_each(ptr, &w9968cf_dev_list)
- sc++;
- mutex_unlock(&w9968cf_devlist_mutex);
-
- if (sc >= simcams) {
- DBG(2, "Device rejected: too many connected cameras "
- "(max. %u)", simcams)
- err = -EPERM;
- goto fail;
- }
-
-
- /* Allocate 2 bytes of memory for camera control USB transfers */
- if (!(cam->control_buffer = kzalloc(2, GFP_KERNEL))) {
- DBG(1,"Couldn't allocate memory for camera control transfers")
- err = -ENOMEM;
- goto fail;
- }
-
- /* Allocate 8 bytes of memory for USB data transfers to the FSB */
- if (!(cam->data_buffer = kzalloc(8, GFP_KERNEL))) {
- DBG(1, "Couldn't allocate memory for data "
- "transfers to the FSB")
- err = -ENOMEM;
- goto fail;
- }
-
- /* Register the V4L device */
- cam->v4ldev = video_device_alloc();
- if (!cam->v4ldev) {
- DBG(1, "Could not allocate memory for a V4L structure")
- err = -ENOMEM;
- goto fail;
- }
-
- strcpy(cam->v4ldev->name, symbolic(camlist, mod_id));
- cam->v4ldev->fops = &w9968cf_fops;
- cam->v4ldev->release = video_device_release;
- video_set_drvdata(cam->v4ldev, cam);
- cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
-
- err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
- video_nr[dev_nr]);
- if (err) {
- DBG(1, "V4L device registration failed")
- if (err == -ENFILE && video_nr[dev_nr] == -1)
- DBG(2, "Couldn't find a free /dev/videoX node")
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
- goto fail;
- }
-
- DBG(2, "V4L device registered as %s",
- video_device_node_name(cam->v4ldev))
-
- /* Set some basic constants */
- w9968cf_configure_camera(cam, udev, mod_id, dev_nr);
-
- /* Add a new entry into the list of V4L registered devices */
- mutex_lock(&w9968cf_devlist_mutex);
- list_add(&cam->v4llist, &w9968cf_dev_list);
- mutex_unlock(&w9968cf_devlist_mutex);
- dev_nr = (dev_nr < W9968CF_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
- w9968cf_turn_on_led(cam);
-
- w9968cf_i2c_init(cam);
- cam->sensor_sd = v4l2_i2c_new_subdev(&cam->v4l2_dev,
- &cam->i2c_adapter,
- "ovcamchip", "ovcamchip", 0, addrs);
-
- usb_set_intfdata(intf, cam);
- mutex_unlock(&cam->dev_mutex);
-
- err = w9968cf_sensor_init(cam);
- return 0;
-
-fail: /* Free unused memory */
- kfree(cam->control_buffer);
- kfree(cam->data_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
- mutex_unlock(&cam->dev_mutex);
- v4l2_device_unregister(&cam->v4l2_dev);
-fail0:
- kfree(cam);
- return err;
-}
-
-
-static void w9968cf_usb_disconnect(struct usb_interface* intf)
-{
- struct w9968cf_device* cam =
- (struct w9968cf_device*)usb_get_intfdata(intf);
-
- if (cam) {
- down_write(&w9968cf_disconnect);
- /* Prevent concurrent accesses to data */
- mutex_lock(&cam->dev_mutex);
-
- cam->disconnected = 1;
-
- DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id));
-
- v4l2_device_disconnect(&cam->v4l2_dev);
-
- wake_up_interruptible_all(&cam->open);
-
- if (cam->users) {
- DBG(2, "The device is open (%s)! "
- "Process name: %s. Deregistration and memory "
- "deallocation are deferred on close.",
- video_device_node_name(cam->v4ldev), cam->command)
- cam->misconfigured = 1;
- w9968cf_stop_transfer(cam);
- wake_up_interruptible(&cam->wait_queue);
- } else
- w9968cf_release_resources(cam);
-
- mutex_unlock(&cam->dev_mutex);
- up_write(&w9968cf_disconnect);
-
- if (!cam->users) {
- kfree(cam);
- }
- }
-}
-
-
-static struct usb_driver w9968cf_usb_driver = {
- .name = "w9968cf",
- .id_table = winbond_id_table,
- .probe = w9968cf_usb_probe,
- .disconnect = w9968cf_usb_disconnect,
-};
-
-
-
-/****************************************************************************
- * Module init, exit and intermodule communication *
- ****************************************************************************/
-
-static int __init w9968cf_module_init(void)
-{
- int err;
-
- KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
- KDBG(3, W9968CF_MODULE_AUTHOR)
-
- if ((err = usb_register(&w9968cf_usb_driver)))
- return err;
-
- return 0;
-}
-
-
-static void __exit w9968cf_module_exit(void)
-{
- /* w9968cf_usb_disconnect() will be called */
- usb_deregister(&w9968cf_usb_driver);
-
- KDBG(2, W9968CF_MODULE_NAME" deregistered")
-}
-
-
-module_init(w9968cf_module_init);
-module_exit(w9968cf_module_exit);
-
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
deleted file mode 100644
index 73ad864b4842..000000000000
--- a/drivers/media/video/w9968cf.h
+++ /dev/null
@@ -1,333 +0,0 @@
-/***************************************************************************
- * Video4Linux driver for W996[87]CF JPEG USB Dual Mode Camera Chip. *
- * *
- * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _W9968CF_H_
-#define _W9968CF_H_
-
-#include <linux/videodev2.h>
-#include <linux/usb.h>
-#include <linux/i2c.h>
-#include <linux/device.h>
-#include <linux/spinlock.h>
-#include <linux/list.h>
-#include <linux/wait.h>
-#include <linux/param.h>
-#include <linux/types.h>
-#include <linux/rwsem.h>
-#include <linux/mutex.h>
-
-#include <media/v4l2-device.h>
-#include <media/ovcamchip.h>
-
-#include "w9968cf_vpp.h"
-
-
-/****************************************************************************
- * Default values *
- ****************************************************************************/
-
-#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
-
-/* Comment/uncomment the following line to enable/disable debugging messages */
-#define W9968CF_DEBUG
-
-/* These have effect only if W9968CF_DEBUG is defined */
-#define W9968CF_DEBUG_LEVEL 2 /* from 0 to 6. 0 for no debug informations */
-#define W9968CF_SPECIFIC_DEBUG 0 /* 0 or 1 */
-
-#define W9968CF_MAX_DEVICES 32
-#define W9968CF_SIMCAMS W9968CF_MAX_DEVICES /* simultaneous cameras */
-
-#define W9968CF_MAX_BUFFERS 32
-#define W9968CF_BUFFERS 2 /* n. of frame buffers from 2 to MAX_BUFFERS */
-
-/* Maximum data payload sizes in bytes for alternate settings */
-static const u16 wMaxPacketSize[] = {1023, 959, 895, 831, 767, 703, 639, 575,
- 511, 447, 383, 319, 255, 191, 127, 63};
-#define W9968CF_PACKET_SIZE 1023 /* according to wMaxPacketSizes[] */
-#define W9968CF_MIN_PACKET_SIZE 63 /* minimum value */
-#define W9968CF_ISO_PACKETS 5 /* n.of packets for isochronous transfers */
-#define W9968CF_USB_CTRL_TIMEOUT 1000 /* timeout (ms) for usb control commands */
-#define W9968CF_URBS 2 /* n. of scheduled URBs for ISO transfer */
-
-#define W9968CF_I2C_BUS_DELAY 4 /* delay in us for I2C bit r/w operations */
-#define W9968CF_I2C_RW_RETRIES 15 /* number of max I2C r/w retries */
-
-/* Available video formats */
-struct w9968cf_format {
- const u16 palette;
- const u16 depth;
- const u8 compression;
-};
-
-static const struct w9968cf_format w9968cf_formatlist[] = {
- { VIDEO_PALETTE_UYVY, 16, 0 }, /* original video */
- { VIDEO_PALETTE_YUV422P, 16, 1 }, /* with JPEG compression */
- { VIDEO_PALETTE_YUV420P, 12, 1 }, /* with JPEG compression */
- { VIDEO_PALETTE_YUV420, 12, 1 }, /* same as YUV420P */
- { VIDEO_PALETTE_YUYV, 16, 0 }, /* software conversion */
- { VIDEO_PALETTE_YUV422, 16, 0 }, /* software conversion */
- { VIDEO_PALETTE_GREY, 8, 0 }, /* software conversion */
- { VIDEO_PALETTE_RGB555, 16, 0 }, /* software conversion */
- { VIDEO_PALETTE_RGB565, 16, 0 }, /* software conversion */
- { VIDEO_PALETTE_RGB24, 24, 0 }, /* software conversion */
- { VIDEO_PALETTE_RGB32, 32, 0 }, /* software conversion */
- { 0, 0, 0 } /* 0 is a terminating entry */
-};
-
-#define W9968CF_DECOMPRESSION 2 /* decomp:0=disable,1=force,2=any formats */
-#define W9968CF_PALETTE_DECOMP_OFF VIDEO_PALETTE_UYVY /* when decomp=0 */
-#define W9968CF_PALETTE_DECOMP_FORCE VIDEO_PALETTE_YUV420P /* when decomp=1 */
-#define W9968CF_PALETTE_DECOMP_ON VIDEO_PALETTE_UYVY /* when decomp=2 */
-
-#define W9968CF_FORCE_RGB 0 /* read RGB instead of BGR, yes=1/no=0 */
-
-#define W9968CF_MAX_WIDTH 800 /* Has effect if up-scaling is on */
-#define W9968CF_MAX_HEIGHT 600 /* Has effect if up-scaling is on */
-#define W9968CF_WIDTH 320 /* from 128 to 352, multiple of 16 */
-#define W9968CF_HEIGHT 240 /* from 96 to 288, multiple of 16 */
-
-#define W9968CF_CLAMPING 0 /* 0 disable, 1 enable video data clamping */
-#define W9968CF_FILTER_TYPE 0 /* 0 disable 1 (1-2-1), 2 (2-3-6-3-2) */
-#define W9968CF_DOUBLE_BUFFER 1 /* 0 disable, 1 enable double buffer */
-#define W9968CF_LARGEVIEW 1 /* 0 disable, 1 enable */
-#define W9968CF_UPSCALING 0 /* 0 disable, 1 enable */
-
-#define W9968CF_MONOCHROME 0 /* 0 not monochrome, 1 monochrome sensor */
-#define W9968CF_BRIGHTNESS 31000 /* from 0 to 65535 */
-#define W9968CF_HUE 32768 /* from 0 to 65535 */
-#define W9968CF_COLOUR 32768 /* from 0 to 65535 */
-#define W9968CF_CONTRAST 50000 /* from 0 to 65535 */
-#define W9968CF_WHITENESS 32768 /* from 0 to 65535 */
-
-#define W9968CF_AUTOBRIGHT 0 /* 0 disable, 1 enable automatic brightness */
-#define W9968CF_AUTOEXP 1 /* 0 disable, 1 enable automatic exposure */
-#define W9968CF_LIGHTFREQ 50 /* light frequency. 50Hz (Europe) or 60Hz */
-#define W9968CF_BANDINGFILTER 0 /* 0 disable, 1 enable banding filter */
-#define W9968CF_BACKLIGHT 0 /* 0 or 1, 1=object is lit from behind */
-#define W9968CF_MIRROR 0 /* 0 or 1 [don't] reverse image horizontally*/
-
-#define W9968CF_CLOCKDIV -1 /* -1 = automatic clock divisor */
-#define W9968CF_DEF_CLOCKDIVISOR 0 /* default sensor clock divisor value */
-
-
-/****************************************************************************
- * Globals *
- ****************************************************************************/
-
-#define W9968CF_MODULE_NAME "V4L driver for W996[87]CF JPEG USB " \
- "Dual Mode Camera Chip"
-#define W9968CF_MODULE_VERSION "1:1.34-basic"
-#define W9968CF_MODULE_AUTHOR "(C) 2002-2004 Luca Risolia"
-#define W9968CF_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
-#define W9968CF_MODULE_LICENSE "GPL"
-
-static const struct usb_device_id winbond_id_table[] = {
- {
- /* Creative Labs Video Blaster WebCam Go Plus */
- USB_DEVICE(0x041e, 0x4003),
- .driver_info = (unsigned long)"w9968cf",
- },
- {
- /* Generic W996[87]CF JPEG USB Dual Mode Camera */
- USB_DEVICE(0x1046, 0x9967),
- .driver_info = (unsigned long)"w9968cf",
- },
- { } /* terminating entry */
-};
-
-/* W996[87]CF camera models, internal ids: */
-enum w9968cf_model_id {
- W9968CF_MOD_GENERIC = 1, /* Generic W996[87]CF based device */
- W9968CF_MOD_CLVBWGP = 11,/*Creative Labs Video Blaster WebCam Go Plus*/
- W9968CF_MOD_ADPVDMA = 21, /* Aroma Digi Pen VGA Dual Mode ADG-5000 */
- W9986CF_MOD_AAU = 31, /* AVerMedia AVerTV USB */
- W9968CF_MOD_CLVBWG = 34, /* Creative Labs Video Blaster WebCam Go */
- W9968CF_MOD_LL = 37, /* Lebon LDC-035A */
- W9968CF_MOD_EEEMC = 40, /* Ezonics EZ-802 EZMega Cam */
- W9968CF_MOD_OOE = 42, /* OmniVision OV8610-EDE */
- W9968CF_MOD_ODPVDMPC = 43,/* OPCOM Digi Pen VGA Dual Mode Pen Camera */
- W9968CF_MOD_PDPII = 46, /* Pretec Digi Pen-II */
- W9968CF_MOD_PDP480 = 49, /* Pretec DigiPen-480 */
-};
-
-enum w9968cf_frame_status {
- F_READY, /* finished grabbing & ready to be read/synced */
- F_GRABBING, /* in the process of being grabbed into */
- F_ERROR, /* something bad happened while processing */
- F_UNUSED /* unused (no VIDIOCMCAPTURE) */
-};
-
-struct w9968cf_frame_t {
- void* buffer;
- unsigned long size;
- u32 length;
- int number;
- enum w9968cf_frame_status status;
- struct w9968cf_frame_t* next;
- u8 queued;
-};
-
-enum w9968cf_vpp_flag {
- VPP_NONE = 0x00,
- VPP_UPSCALE = 0x01,
- VPP_SWAP_YUV_BYTES = 0x02,
- VPP_DECOMPRESSION = 0x04,
- VPP_UYVY_TO_RGBX = 0x08,
-};
-
-/* Main device driver structure */
-struct w9968cf_device {
- enum w9968cf_model_id id; /* private device identifier */
-
- struct v4l2_device v4l2_dev;
- struct video_device* v4ldev; /* -> V4L structure */
- struct list_head v4llist; /* entry of the list of V4L cameras */
-
- struct usb_device* usbdev; /* -> main USB structure */
- struct urb* urb[W9968CF_URBS]; /* -> USB request block structs */
- void* transfer_buffer[W9968CF_URBS]; /* -> ISO transfer buffers */
- u16* control_buffer; /* -> buffer for control req.*/
- u16* data_buffer; /* -> data to send to the FSB */
-
- struct w9968cf_frame_t frame[W9968CF_MAX_BUFFERS];
- struct w9968cf_frame_t frame_tmp; /* temporary frame */
- struct w9968cf_frame_t frame_vpp; /* helper frame.*/
- struct w9968cf_frame_t* frame_current; /* -> frame being grabbed */
- struct w9968cf_frame_t* requested_frame[W9968CF_MAX_BUFFERS];
-
- u8 max_buffers, /* number of requested buffers */
- force_palette, /* yes=1/no=0 */
- force_rgb, /* read RGB instead of BGR, yes=1, no=0 */
- double_buffer, /* hardware double buffering yes=1/no=0 */
- clamping, /* video data clamping yes=1/no=0 */
- filter_type, /* 0=disabled, 1=3 tap, 2=5 tap filter */
- capture, /* 0=disabled, 1=enabled */
- largeview, /* 0=disabled, 1=enabled */
- decompression, /* 0=disabled, 1=forced, 2=allowed */
- upscaling; /* software image scaling, 0=enabled, 1=disabled */
-
- struct video_picture picture; /* current picture settings */
- struct video_window window; /* current window settings */
-
- u16 hw_depth, /* depth (used by the chip) */
- hw_palette, /* palette (used by the chip) */
- hw_width, /* width (used by the chip) */
- hw_height, /* height (used by the chip) */
- hs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
- vs_polarity, /* 0=negative sync pulse, 1=positive sync pulse */
- start_cropx, /* pixels from HS inactive edge to 1st cropped pixel*/
- start_cropy; /* pixels from VS inactive edge to 1st cropped pixel*/
-
- enum w9968cf_vpp_flag vpp_flag; /* post-processing routines in use */
-
- u8 nbuffers, /* number of allocated frame buffers */
- altsetting, /* camera alternate setting */
- disconnected, /* flag: yes=1, no=0 */
- misconfigured, /* flag: yes=1, no=0 */
- users, /* flag: number of users holding the device */
- streaming; /* flag: yes=1, no=0 */
-
- u8 sensor_initialized; /* flag: yes=1, no=0 */
-
- /* Determined by the image sensor type: */
- int sensor, /* type of image sensor chip (CC_*) */
- monochrome; /* image sensor is (probably) monochrome */
- u16 maxwidth, /* maximum width supported by the image sensor */
- maxheight, /* maximum height supported by the image sensor */
- minwidth, /* minimum width supported by the image sensor */
- minheight; /* minimum height supported by the image sensor */
- u8 auto_brt, /* auto brightness enabled flag */
- auto_exp, /* auto exposure enabled flag */
- backlight, /* backlight exposure algorithm flag */
- mirror, /* image is reversed horizontally */
- lightfreq, /* power (lighting) frequency */
- bandfilt; /* banding filter enabled flag */
- s8 clockdiv; /* clock divisor */
-
- /* I2C interface to kernel */
- struct i2c_adapter i2c_adapter;
- struct v4l2_subdev *sensor_sd;
-
- /* Locks */
- struct mutex dev_mutex, /* for probe, disconnect,open and close */
- fileop_mutex; /* for read and ioctl */
- spinlock_t urb_lock, /* for submit_urb() and unlink_urb() */
- flist_lock; /* for requested frame list accesses */
- wait_queue_head_t open, wait_queue;
-
- char command[16]; /* name of the program holding the device */
-};
-
-static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev)
-{
- return container_of(v4l2_dev, struct w9968cf_device, v4l2_dev);
-}
-
-
-/****************************************************************************
- * Macros for debugging *
- ****************************************************************************/
-
-#undef DBG
-#undef KDBG
-#ifdef W9968CF_DEBUG
-/* For device specific debugging messages */
-# define DBG(level, fmt, args...) \
-{ \
- if ( ((specific_debug) && (debug == (level))) || \
- ((!specific_debug) && (debug >= (level))) ) { \
- if ((level) == 1) \
- v4l2_err(&cam->v4l2_dev, fmt "\n", ## args); \
- else if ((level) == 2 || (level) == 3) \
- v4l2_info(&cam->v4l2_dev, fmt "\n", ## args); \
- else if ((level) == 4) \
- v4l2_warn(&cam->v4l2_dev, fmt "\n", ## args); \
- else if ((level) >= 5) \
- v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
- } \
-}
-/* For generic kernel (not device specific) messages */
-# define KDBG(level, fmt, args...) \
-{ \
- if ( ((specific_debug) && (debug == (level))) || \
- ((!specific_debug) && (debug >= (level))) ) { \
- if ((level) >= 1 && (level) <= 4) \
- pr_info("w9968cf: " fmt "\n", ## args); \
- else if ((level) >= 5) \
- pr_debug("w9968cf: [%s:%d] " fmt "\n", __func__, \
- __LINE__ , ## args); \
- } \
-}
-#else
- /* Not debugging: nothing */
-# define DBG(level, fmt, args...) do {;} while(0);
-# define KDBG(level, fmt, args...) do {;} while(0);
-#endif
-
-#undef PDBG
-#define PDBG(fmt, args...) \
-v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
-
-#undef PDBGG
-#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
-
-#endif /* _W9968CF_H_ */
diff --git a/drivers/media/video/w9968cf_decoder.h b/drivers/media/video/w9968cf_decoder.h
deleted file mode 100644
index 59decbfc540a..000000000000
--- a/drivers/media/video/w9968cf_decoder.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/***************************************************************************
- * Video decoder for the W996[87]CF driver for Linux. *
- * *
- * Copyright (C) 2003 2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _W9968CF_DECODER_H_
-#define _W9968CF_DECODER_H_
-
-/* Comment/uncomment this for high/low quality of compressed video */
-#define W9968CF_DEC_FAST_LOWQUALITY_VIDEO
-
-#ifdef W9968CF_DEC_FAST_LOWQUALITY_VIDEO
-static const unsigned char Y_QUANTABLE[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-
-static const unsigned char UV_QUANTABLE[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99
-};
-#else
-static const unsigned char Y_QUANTABLE[64] = {
- 8, 5, 5, 8, 12, 20, 25, 30,
- 6, 6, 7, 9, 13, 29, 30, 27,
- 7, 6, 8, 12, 20, 28, 34, 28,
- 7, 8, 11, 14, 25, 43, 40, 31,
- 9, 11, 18, 28, 34, 54, 51, 38,
- 12, 17, 27, 32, 40, 52, 56, 46,
- 24, 32, 39, 43, 51, 60, 60, 50,
- 36, 46, 47, 49, 56, 50, 51, 49
-};
-
-static const unsigned char UV_QUANTABLE[64] = {
- 8, 9, 12, 23, 49, 49, 49, 49,
- 9, 10, 13, 33, 49, 49, 49, 49,
- 12, 13, 28, 49, 49, 49, 49, 49,
- 23, 33, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49,
- 49, 49, 49, 49, 49, 49, 49, 49
-};
-#endif
-
-#define W9968CF_DEC_ERR_CORRUPTED_DATA -1
-#define W9968CF_DEC_ERR_BUF_OVERFLOW -2
-#define W9968CF_DEC_ERR_NO_SOI -3
-#define W9968CF_DEC_ERR_NO_SOF0 -4
-#define W9968CF_DEC_ERR_NO_SOS -5
-#define W9968CF_DEC_ERR_NO_EOI -6
-
-extern void w9968cf_init_decoder(void);
-extern int w9968cf_check_headers(const unsigned char* Pin,
- const unsigned long BUF_SIZE);
-extern int w9968cf_decode(const char* Pin, const unsigned long BUF_SIZE,
- const unsigned W, const unsigned H, char* Pout);
-
-#endif /* _W9968CF_DECODER_H_ */
diff --git a/drivers/media/video/w9968cf_vpp.h b/drivers/media/video/w9968cf_vpp.h
deleted file mode 100644
index 88c9b6c0cc36..000000000000
--- a/drivers/media/video/w9968cf_vpp.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/***************************************************************************
- * Interface for video post-processing functions for the W996[87]CF driver *
- * for Linux. *
- * *
- * Copyright (C) 2002-2004 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _W9968CF_VPP_H_
-#define _W9968CF_VPP_H_
-
-#include <linux/module.h>
-#include <asm/types.h>
-
-struct w9968cf_vpp_t {
- struct module* owner;
- int (*check_headers)(const unsigned char*, const unsigned long);
- int (*decode)(const char*, const unsigned long, const unsigned,
- const unsigned, char*);
- void (*swap_yuvbytes)(void*, unsigned long);
- void (*uyvy_to_rgbx)(u8*, unsigned long, u8*, u16, u8);
- void (*scale_up)(u8*, u8*, u16, u16, u16, u16, u16);
-
- u8 busy; /* read-only flag: module is/is not in use */
-};
-
-#endif /* _W9968CF_VPP_H_ */
diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig
deleted file mode 100644
index a7e610e0be9e..000000000000
--- a/drivers/media/video/zc0301/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-config USB_ZC0301
- tristate "USB ZC0301[P] webcam support (DEPRECATED)"
- depends on VIDEO_V4L2
- default n
- ---help---
- This driver is DEPRECATED please use the gspca zc3xx module
- instead.
-
- Say Y here if you want support for cameras based on the ZC0301 or
- ZC0301P Image Processors and Control Chips.
-
- See <file:Documentation/video4linux/zc0301.txt> for more info.
-
- To compile this driver as a module, choose M here: the
- module will be called zc0301.
diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile
deleted file mode 100644
index d9e6d97fade6..000000000000
--- a/drivers/media/video/zc0301/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-zc0301-objs := zc0301_core.o zc0301_pb0330.o zc0301_pas202bcb.o
-
-obj-$(CONFIG_USB_ZC0301) += zc0301.o
diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h
deleted file mode 100644
index b1b5cceb4baa..000000000000
--- a/drivers/media/video/zc0301/zc0301.h
+++ /dev/null
@@ -1,196 +0,0 @@
-/***************************************************************************
- * V4L2 driver for ZC0301[P] Image Processor and Control Chip *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _ZC0301_H_
-#define _ZC0301_H_
-
-#include <linux/version.h>
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/device.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/time.h>
-#include <linux/wait.h>
-#include <linux/types.h>
-#include <linux/param.h>
-#include <linux/mutex.h>
-#include <linux/rwsem.h>
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/kref.h>
-
-#include "zc0301_sensor.h"
-
-/*****************************************************************************/
-
-#define ZC0301_DEBUG
-#define ZC0301_DEBUG_LEVEL 2
-#define ZC0301_MAX_DEVICES 64
-#define ZC0301_FORCE_MUNMAP 0
-#define ZC0301_MAX_FRAMES 32
-#define ZC0301_COMPRESSION_QUALITY 0
-#define ZC0301_URBS 2
-#define ZC0301_ISO_PACKETS 7
-#define ZC0301_ALTERNATE_SETTING 7
-#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS)
-#define ZC0301_CTRL_TIMEOUT 100
-#define ZC0301_FRAME_TIMEOUT 2
-
-/*****************************************************************************/
-
-ZC0301_ID_TABLE
-ZC0301_SENSOR_TABLE
-
-enum zc0301_frame_state {
- F_UNUSED,
- F_QUEUED,
- F_GRABBING,
- F_DONE,
- F_ERROR,
-};
-
-struct zc0301_frame_t {
- void* bufmem;
- struct v4l2_buffer buf;
- enum zc0301_frame_state state;
- struct list_head frame;
- unsigned long vma_use_count;
-};
-
-enum zc0301_dev_state {
- DEV_INITIALIZED = 0x01,
- DEV_DISCONNECTED = 0x02,
- DEV_MISCONFIGURED = 0x04,
-};
-
-enum zc0301_io_method {
- IO_NONE,
- IO_READ,
- IO_MMAP,
-};
-
-enum zc0301_stream_state {
- STREAM_OFF,
- STREAM_INTERRUPT,
- STREAM_ON,
-};
-
-struct zc0301_module_param {
- u8 force_munmap;
- u16 frame_timeout;
-};
-
-static DECLARE_RWSEM(zc0301_dev_lock);
-
-struct zc0301_device {
- struct video_device* v4ldev;
-
- struct zc0301_sensor sensor;
-
- struct usb_device* usbdev;
- struct urb* urb[ZC0301_URBS];
- void* transfer_buffer[ZC0301_URBS];
- u8* control_buffer;
-
- struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES];
- struct list_head inqueue, outqueue;
- u32 frame_count, nbuffers, nreadbuffers;
-
- enum zc0301_io_method io;
- enum zc0301_stream_state stream;
-
- struct v4l2_jpegcompression compression;
-
- struct zc0301_module_param module_param;
-
- struct kref kref;
- enum zc0301_dev_state state;
- u8 users;
-
- struct completion probe;
- struct mutex open_mutex, fileop_mutex;
- spinlock_t queue_lock;
- wait_queue_head_t wait_open, wait_frame, wait_stream;
-};
-
-/*****************************************************************************/
-
-struct zc0301_device*
-zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id)
-{
- return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL;
-}
-
-void
-zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
-{
- memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor));
-}
-
-/*****************************************************************************/
-
-#undef DBG
-#undef KDBG
-#ifdef ZC0301_DEBUG
-# define DBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1) \
- dev_err(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) == 2) \
- dev_info(&cam->usbdev->dev, fmt "\n", ## args); \
- else if ((level) >= 3) \
- dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \
- __FILE__, __func__, __LINE__ , ## args); \
- } \
-} while (0)
-# define KDBG(level, fmt, args...) \
-do { \
- if (debug >= (level)) { \
- if ((level) == 1 || (level) == 2) \
- pr_info("zc0301: " fmt "\n", ## args); \
- else if ((level) == 3) \
- pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \
- __func__, __LINE__ , ## args); \
- } \
-} while (0)
-# define V4LDBG(level, name, cmd) \
-do { \
- if (debug >= (level)) \
- v4l_print_ioctl(name, cmd); \
-} while (0)
-#else
-# define DBG(level, fmt, args...) do {;} while(0)
-# define KDBG(level, fmt, args...) do {;} while(0)
-# define V4LDBG(level, name, cmd) do {;} while(0)
-#endif
-
-#undef PDBG
-#define PDBG(fmt, args...) \
-dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \
- __LINE__ , ## args)
-
-#undef PDBGG
-#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */
-
-#endif /* _ZC0301_H_ */
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
deleted file mode 100644
index bb51cfb0c647..000000000000
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ /dev/null
@@ -1,2098 +0,0 @@
-/***************************************************************************
- * Video4Linux2 driver for ZC0301[P] Image Processor and Control Chip *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * Informations about the chip internals needed to enable the I2C protocol *
- * have been taken from the documentation of the ZC030x Video4Linux1 *
- * driver written by Andrew Birkett <andy@nobugs.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., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/device.h>
-#include <linux/fs.h>
-#include <linux/delay.h>
-#include <linux/compiler.h>
-#include <linux/ioctl.h>
-#include <linux/poll.h>
-#include <linux/stat.h>
-#include <linux/mm.h>
-#include <linux/vmalloc.h>
-#include <linux/page-flags.h>
-#include <asm/byteorder.h>
-#include <asm/page.h>
-#include <asm/uaccess.h>
-
-#include "zc0301.h"
-
-/*****************************************************************************/
-
-#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \
- "Image Processor and Control Chip"
-#define ZC0301_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia"
-#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
-#define ZC0301_MODULE_LICENSE "GPL"
-#define ZC0301_MODULE_VERSION "1:1.10"
-#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 10)
-
-/*****************************************************************************/
-
-MODULE_DEVICE_TABLE(usb, zc0301_id_table);
-
-MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL);
-MODULE_DESCRIPTION(ZC0301_MODULE_NAME);
-MODULE_VERSION(ZC0301_MODULE_VERSION);
-MODULE_LICENSE(ZC0301_MODULE_LICENSE);
-
-static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1};
-module_param_array(video_nr, short, NULL, 0444);
-MODULE_PARM_DESC(video_nr,
- "\n<-1|n[,...]> Specify V4L2 minor mode number."
- "\n -1 = use next available (default)"
- "\n n = use minor number n (integer >= 0)"
- "\nYou can specify up to "
- __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way."
- "\nFor example:"
- "\nvideo_nr=-1,2,-1 would assign minor number 2 to"
- "\nthe second registered camera and use auto for the first"
- "\none and for every other camera."
- "\n");
-
-static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] =
- ZC0301_FORCE_MUNMAP};
-module_param_array(force_munmap, bool, NULL, 0444);
-MODULE_PARM_DESC(force_munmap,
- "\n<0|1[,...]> Force the application to unmap previously"
- "\nmapped buffer memory before calling any VIDIOC_S_CROP or"
- "\nVIDIOC_S_FMT ioctl's. Not all the applications support"
- "\nthis feature. This parameter is specific for each"
- "\ndetected camera."
- "\n 0 = do not force memory unmapping"
- "\n 1 = force memory unmapping (save memory)"
- "\nDefault value is "__MODULE_STRING(ZC0301_FORCE_MUNMAP)"."
- "\n");
-
-static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] =
- ZC0301_FRAME_TIMEOUT};
-module_param_array(frame_timeout, uint, NULL, 0644);
-MODULE_PARM_DESC(frame_timeout,
- "\n<n[,...]> Timeout for a video frame in seconds."
- "\nThis parameter is specific for each detected camera."
- "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"."
- "\n");
-
-#ifdef ZC0301_DEBUG
-static unsigned short debug = ZC0301_DEBUG_LEVEL;
-module_param(debug, ushort, 0644);
-MODULE_PARM_DESC(debug,
- "\n<n> Debugging information level, from 0 to 3:"
- "\n0 = none (use carefully)"
- "\n1 = critical errors"
- "\n2 = significant informations"
- "\n3 = more verbose messages"
- "\nLevel 3 is useful for testing only, when only "
- "one device is used."
- "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"."
- "\n");
-#endif
-
-/*****************************************************************************/
-
-static u32
-zc0301_request_buffers(struct zc0301_device* cam, u32 count,
- enum zc0301_io_method io)
-{
- struct v4l2_pix_format* p = &(cam->sensor.pix_format);
- struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
- const size_t imagesize = cam->module_param.force_munmap ||
- io == IO_READ ?
- (p->width * p->height * p->priv) / 8 :
- (r->width * r->height * p->priv) / 8;
- void* buff = NULL;
- u32 i;
-
- if (count > ZC0301_MAX_FRAMES)
- count = ZC0301_MAX_FRAMES;
-
- cam->nbuffers = count;
- while (cam->nbuffers > 0) {
- if ((buff = vmalloc_32_user(cam->nbuffers *
- PAGE_ALIGN(imagesize))))
- break;
- cam->nbuffers--;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.index = i;
- cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize);
- cam->frame[i].buf.length = imagesize;
- cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cam->frame[i].buf.sequence = 0;
- cam->frame[i].buf.field = V4L2_FIELD_NONE;
- cam->frame[i].buf.memory = V4L2_MEMORY_MMAP;
- cam->frame[i].buf.flags = 0;
- }
-
- return cam->nbuffers;
-}
-
-
-static void zc0301_release_buffers(struct zc0301_device* cam)
-{
- if (cam->nbuffers) {
- vfree(cam->frame[0].bufmem);
- cam->nbuffers = 0;
- }
- cam->frame_current = NULL;
-}
-
-
-static void zc0301_empty_framequeues(struct zc0301_device* cam)
-{
- u32 i;
-
- INIT_LIST_HEAD(&cam->inqueue);
- INIT_LIST_HEAD(&cam->outqueue);
-
- for (i = 0; i < ZC0301_MAX_FRAMES; i++) {
- cam->frame[i].state = F_UNUSED;
- cam->frame[i].buf.bytesused = 0;
- }
-}
-
-
-static void zc0301_requeue_outqueue(struct zc0301_device* cam)
-{
- struct zc0301_frame_t *i;
-
- list_for_each_entry(i, &cam->outqueue, frame) {
- i->state = F_QUEUED;
- list_add(&i->frame, &cam->inqueue);
- }
-
- INIT_LIST_HEAD(&cam->outqueue);
-}
-
-
-static void zc0301_queue_unusedframes(struct zc0301_device* cam)
-{
- unsigned long lock_flags;
- u32 i;
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].state == F_UNUSED) {
- cam->frame[i].state = F_QUEUED;
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[i].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- }
-}
-
-/*****************************************************************************/
-
-int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value)
-{
- struct usb_device* udev = cam->usbdev;
- int res;
-
- res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40,
- value, index, NULL, 0, ZC0301_CTRL_TIMEOUT);
- if (res < 0) {
- DBG(3, "Failed to write a register (index 0x%04X, "
- "value 0x%02X, error %d)",index, value, res);
- return -1;
- }
-
- return 0;
-}
-
-
-int zc0301_read_reg(struct zc0301_device* cam, u16 index)
-{
- struct usb_device* udev = cam->usbdev;
- u8* buff = cam->control_buffer;
- int res;
-
- res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0,
- 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT);
- if (res < 0)
- DBG(3, "Failed to read a register (index 0x%04X, error %d)",
- index, res);
-
- PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff));
-
- return (res >= 0) ? (int)(*buff) : -1;
-}
-
-
-int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length)
-{
- int err = 0, res, r0, r1;
-
- err += zc0301_write_reg(cam, 0x0092, address);
- err += zc0301_write_reg(cam, 0x0090, 0x02);
-
- msleep(1);
-
- res = zc0301_read_reg(cam, 0x0091);
- if (res < 0)
- err += res;
- r0 = zc0301_read_reg(cam, 0x0095);
- if (r0 < 0)
- err += r0;
- r1 = zc0301_read_reg(cam, 0x0096);
- if (r1 < 0)
- err += r1;
-
- res = (length <= 1) ? r0 : r0 | (r1 << 8);
-
- if (err)
- DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X",
- address, res);
-
-
- PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res);
-
- return err ? -1 : res;
-}
-
-
-int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value)
-{
- int err = 0, res;
-
- err += zc0301_write_reg(cam, 0x0092, address);
- err += zc0301_write_reg(cam, 0x0093, value & 0xff);
- err += zc0301_write_reg(cam, 0x0094, value >> 8);
- err += zc0301_write_reg(cam, 0x0090, 0x01);
-
- msleep(1);
-
- res = zc0301_read_reg(cam, 0x0091);
- if (res < 0)
- err += res;
-
- if (err)
- DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X",
- address, value);
-
- PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value);
-
- return err ? -1 : 0;
-}
-
-/*****************************************************************************/
-
-static void zc0301_urb_complete(struct urb *urb)
-{
- struct zc0301_device* cam = urb->context;
- struct zc0301_frame_t** f;
- size_t imagesize;
- u8 i;
- int err = 0;
-
- if (urb->status == -ENOENT)
- return;
-
- f = &cam->frame_current;
-
- if (cam->stream == STREAM_INTERRUPT) {
- cam->stream = STREAM_OFF;
- if ((*f))
- (*f)->state = F_QUEUED;
- DBG(3, "Stream interrupted");
- wake_up(&cam->wait_stream);
- }
-
- if (cam->state & DEV_DISCONNECTED)
- return;
-
- if (cam->state & DEV_MISCONFIGURED) {
- wake_up_interruptible(&cam->wait_frame);
- return;
- }
-
- if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue))
- goto resubmit_urb;
-
- if (!(*f))
- (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t,
- frame);
-
- imagesize = (cam->sensor.pix_format.width *
- cam->sensor.pix_format.height *
- cam->sensor.pix_format.priv) / 8;
-
- for (i = 0; i < urb->number_of_packets; i++) {
- unsigned int len, status;
- void *pos;
- u16* soi;
- u8 sof;
-
- len = urb->iso_frame_desc[i].actual_length;
- status = urb->iso_frame_desc[i].status;
- pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer;
-
- if (status) {
- DBG(3, "Error in isochronous frame");
- (*f)->state = F_ERROR;
- continue;
- }
-
- sof = (*(soi = pos) == 0xd8ff);
-
- PDBGG("Isochrnous frame: length %u, #%u i,", len, i);
-
- if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR)
-start_of_frame:
- if (sof) {
- (*f)->state = F_GRABBING;
- (*f)->buf.bytesused = 0;
- do_gettimeofday(&(*f)->buf.timestamp);
- DBG(3, "SOF detected: new video frame");
- }
-
- if ((*f)->state == F_GRABBING) {
- if (sof && (*f)->buf.bytesused)
- goto end_of_frame;
-
- if ((*f)->buf.bytesused + len > imagesize) {
- DBG(3, "Video frame size exceeded");
- (*f)->state = F_ERROR;
- continue;
- }
-
- memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len);
- (*f)->buf.bytesused += len;
-
- if ((*f)->buf.bytesused == imagesize) {
- u32 b;
-end_of_frame:
- b = (*f)->buf.bytesused;
- (*f)->state = F_DONE;
- (*f)->buf.sequence= ++cam->frame_count;
- spin_lock(&cam->queue_lock);
- list_move_tail(&(*f)->frame, &cam->outqueue);
- if (!list_empty(&cam->inqueue))
- (*f) = list_entry(cam->inqueue.next,
- struct zc0301_frame_t,
- frame);
- else
- (*f) = NULL;
- spin_unlock(&cam->queue_lock);
- DBG(3, "Video frame captured: : %lu bytes",
- (unsigned long)(b));
-
- if (!(*f))
- goto resubmit_urb;
-
- if (sof)
- goto start_of_frame;
- }
- }
- }
-
-resubmit_urb:
- urb->dev = cam->usbdev;
- err = usb_submit_urb(urb, GFP_ATOMIC);
- if (err < 0 && err != -EPERM) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "usb_submit_urb() failed");
- }
-
- wake_up_interruptible(&cam->wait_frame);
-}
-
-
-static int zc0301_start_transfer(struct zc0301_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- struct usb_host_interface* altsetting = usb_altnum_to_altsetting(
- usb_ifnum_to_if(udev, 0),
- ZC0301_ALTERNATE_SETTING);
- const unsigned int psz = le16_to_cpu(altsetting->
- endpoint[0].desc.wMaxPacketSize);
- struct urb* urb;
- s8 i, j;
- int err = 0;
-
- for (i = 0; i < ZC0301_URBS; i++) {
- cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz,
- GFP_KERNEL);
- if (!cam->transfer_buffer[i]) {
- err = -ENOMEM;
- DBG(1, "Not enough memory");
- goto free_buffers;
- }
- }
-
- for (i = 0; i < ZC0301_URBS; i++) {
- urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL);
- cam->urb[i] = urb;
- if (!urb) {
- err = -ENOMEM;
- DBG(1, "usb_alloc_urb() failed");
- goto free_urbs;
- }
- urb->dev = udev;
- urb->context = cam;
- urb->pipe = usb_rcvisocpipe(udev, 1);
- urb->transfer_flags = URB_ISO_ASAP;
- urb->number_of_packets = ZC0301_ISO_PACKETS;
- urb->complete = zc0301_urb_complete;
- urb->transfer_buffer = cam->transfer_buffer[i];
- urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS;
- urb->interval = 1;
- for (j = 0; j < ZC0301_ISO_PACKETS; j++) {
- urb->iso_frame_desc[j].offset = psz * j;
- urb->iso_frame_desc[j].length = psz;
- }
- }
-
- err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING);
- if (err) {
- DBG(1, "usb_set_interface() failed");
- goto free_urbs;
- }
-
- cam->frame_current = NULL;
-
- for (i = 0; i < ZC0301_URBS; i++) {
- err = usb_submit_urb(cam->urb[i], GFP_KERNEL);
- if (err) {
- for (j = i-1; j >= 0; j--)
- usb_kill_urb(cam->urb[j]);
- DBG(1, "usb_submit_urb() failed, error %d", err);
- goto free_urbs;
- }
- }
-
- return 0;
-
-free_urbs:
- for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++)
- usb_free_urb(cam->urb[i]);
-
-free_buffers:
- for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++)
- kfree(cam->transfer_buffer[i]);
-
- return err;
-}
-
-
-static int zc0301_stop_transfer(struct zc0301_device* cam)
-{
- struct usb_device *udev = cam->usbdev;
- s8 i;
- int err = 0;
-
- if (cam->state & DEV_DISCONNECTED)
- return 0;
-
- for (i = ZC0301_URBS-1; i >= 0; i--) {
- usb_kill_urb(cam->urb[i]);
- usb_free_urb(cam->urb[i]);
- kfree(cam->transfer_buffer[i]);
- }
-
- err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */
- if (err)
- DBG(3, "usb_set_interface() failed");
-
- return err;
-}
-
-
-static int zc0301_stream_interrupt(struct zc0301_device* cam)
-{
- long timeout;
-
- cam->stream = STREAM_INTERRUPT;
- timeout = wait_event_timeout(cam->wait_stream,
- (cam->stream == STREAM_OFF) ||
- (cam->state & DEV_DISCONNECTED),
- ZC0301_URB_TIMEOUT);
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- else if (cam->stream != STREAM_OFF) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "URB timeout reached. The camera is misconfigured. To "
- "use it, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int
-zc0301_set_compression(struct zc0301_device* cam,
- struct v4l2_jpegcompression* compression)
-{
- int r, err = 0;
-
- if ((r = zc0301_read_reg(cam, 0x0008)) < 0)
- err += r;
- err += zc0301_write_reg(cam, 0x0008, r | 0x11 | compression->quality);
-
- return err ? -EIO : 0;
-}
-
-
-static int zc0301_init(struct zc0301_device* cam)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- struct v4l2_queryctrl *qctrl;
- struct v4l2_rect* rect;
- u8 i = 0;
- int err = 0;
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->open_mutex);
- init_waitqueue_head(&cam->wait_open);
- qctrl = s->qctrl;
- rect = &(s->cropcap.defrect);
- cam->compression.quality = ZC0301_COMPRESSION_QUALITY;
- } else { /* use current values */
- qctrl = s->_qctrl;
- rect = &(s->_rect);
- }
-
- if (s->init) {
- err = s->init(cam);
- if (err) {
- DBG(3, "Sensor initialization failed");
- return err;
- }
- }
-
- if ((err = zc0301_set_compression(cam, &cam->compression))) {
- DBG(3, "set_compression() failed");
- return err;
- }
-
- if (s->set_crop)
- if ((err = s->set_crop(cam, rect))) {
- DBG(3, "set_crop() failed");
- return err;
- }
-
- if (s->set_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (s->qctrl[i].id != 0 &&
- !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) {
- ctrl.id = s->qctrl[i].id;
- ctrl.value = qctrl[i].default_value;
- err = s->set_ctrl(cam, &ctrl);
- if (err) {
- DBG(3, "Set %s control failed",
- s->qctrl[i].name);
- return err;
- }
- DBG(3, "Image sensor supports '%s' control",
- s->qctrl[i].name);
- }
- }
-
- if (!(cam->state & DEV_INITIALIZED)) {
- mutex_init(&cam->fileop_mutex);
- spin_lock_init(&cam->queue_lock);
- init_waitqueue_head(&cam->wait_frame);
- init_waitqueue_head(&cam->wait_stream);
- cam->nreadbuffers = 2;
- memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl));
- memcpy(&(s->_rect), &(s->cropcap.defrect),
- sizeof(struct v4l2_rect));
- cam->state |= DEV_INITIALIZED;
- }
-
- DBG(2, "Initialization succeeded");
- return 0;
-}
-
-/*****************************************************************************/
-
-static void zc0301_release_resources(struct kref *kref)
-{
- struct zc0301_device *cam = container_of(kref, struct zc0301_device,
- kref);
- DBG(2, "V4L2 device %s deregistered",
- video_device_node_name(cam->v4ldev));
- video_set_drvdata(cam->v4ldev, NULL);
- video_unregister_device(cam->v4ldev);
- usb_put_dev(cam->usbdev);
- kfree(cam->control_buffer);
- kfree(cam);
-}
-
-
-static int zc0301_open(struct file *filp)
-{
- struct zc0301_device* cam;
- int err = 0;
-
- if (!down_read_trylock(&zc0301_dev_lock))
- return -EAGAIN;
-
- cam = video_drvdata(filp);
-
- if (wait_for_completion_interruptible(&cam->probe)) {
- up_read(&zc0301_dev_lock);
- return -ERESTARTSYS;
- }
-
- kref_get(&cam->kref);
-
- if (mutex_lock_interruptible(&cam->open_mutex)) {
- kref_put(&cam->kref, zc0301_release_resources);
- up_read(&zc0301_dev_lock);
- return -ERESTARTSYS;
- }
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- err = -ENODEV;
- goto out;
- }
-
- if (cam->users) {
- DBG(2, "Device %s is busy...",
- video_device_node_name(cam->v4ldev));
- DBG(3, "Simultaneous opens are not supported");
- if ((filp->f_flags & O_NONBLOCK) ||
- (filp->f_flags & O_NDELAY)) {
- err = -EWOULDBLOCK;
- goto out;
- }
- DBG(2, "A blocking open() has been requested. Wait for the "
- "device to be released...");
- up_read(&zc0301_dev_lock);
- err = wait_event_interruptible_exclusive(cam->wait_open,
- (cam->state & DEV_DISCONNECTED)
- || !cam->users);
- down_read(&zc0301_dev_lock);
- if (err)
- goto out;
- if (cam->state & DEV_DISCONNECTED) {
- err = -ENODEV;
- goto out;
- }
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- err = zc0301_init(cam);
- if (err) {
- DBG(1, "Initialization failed again. "
- "I will retry on next open().");
- goto out;
- }
- cam->state &= ~DEV_MISCONFIGURED;
- }
-
- if ((err = zc0301_start_transfer(cam)))
- goto out;
-
- filp->private_data = cam;
- cam->users++;
- cam->io = IO_NONE;
- cam->stream = STREAM_OFF;
- cam->nbuffers = 0;
- cam->frame_count = 0;
- zc0301_empty_framequeues(cam);
-
- DBG(3, "Video device %s is open",
- video_device_node_name(cam->v4ldev));
-
-out:
- mutex_unlock(&cam->open_mutex);
- if (err)
- kref_put(&cam->kref, zc0301_release_resources);
- up_read(&zc0301_dev_lock);
- return err;
-}
-
-
-static int zc0301_release(struct file *filp)
-{
- struct zc0301_device* cam;
-
- down_write(&zc0301_dev_lock);
-
- cam = video_drvdata(filp);
-
- zc0301_stop_transfer(cam);
- zc0301_release_buffers(cam);
- cam->users--;
- wake_up_interruptible_nr(&cam->wait_open, 1);
-
- DBG(3, "Video device %s closed",
- video_device_node_name(cam->v4ldev));
-
- kref_put(&cam->kref, zc0301_release_resources);
-
- up_write(&zc0301_dev_lock);
-
- return 0;
-}
-
-
-static ssize_t
-zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
-{
- struct zc0301_device *cam = video_drvdata(filp);
- struct zc0301_frame_t* f, * i;
- unsigned long lock_flags;
- long timeout;
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (cam->io == IO_MMAP) {
- DBG(3, "Close and open the device again to choose the read "
- "method");
- mutex_unlock(&cam->fileop_mutex);
- return -EBUSY;
- }
-
- if (cam->io == IO_NONE) {
- if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
- DBG(1, "read() failed, not enough memory");
- mutex_unlock(&cam->fileop_mutex);
- return -ENOMEM;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (list_empty(&cam->inqueue)) {
- if (!list_empty(&cam->outqueue))
- zc0301_empty_framequeues(cam);
- zc0301_queue_unusedframes(cam);
- }
-
- if (!count) {
- mutex_unlock(&cam->fileop_mutex);
- return 0;
- }
-
- if (list_empty(&cam->outqueue)) {
- if (filp->f_flags & O_NONBLOCK) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- msecs_to_jiffies(
- cam->module_param.frame_timeout * 1000
- )
- );
- if (timeout < 0) {
- mutex_unlock(&cam->fileop_mutex);
- return timeout;
- }
- if (cam->state & DEV_DISCONNECTED) {
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
- if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
- }
-
- f = list_entry(cam->outqueue.prev, struct zc0301_frame_t, frame);
-
- if (count > f->buf.bytesused)
- count = f->buf.bytesused;
-
- if (copy_to_user(buf, f->bufmem, count)) {
- err = -EFAULT;
- goto exit;
- }
- *f_pos += count;
-
-exit:
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(i, &cam->outqueue, frame)
- i->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- zc0301_queue_unusedframes(cam);
-
- PDBGG("Frame #%lu, bytes read: %zu",
- (unsigned long)f->buf.index, count);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return err ? err : count;
-}
-
-
-static unsigned int zc0301_poll(struct file *filp, poll_table *wait)
-{
- struct zc0301_device *cam = video_drvdata(filp);
- struct zc0301_frame_t* f;
- unsigned long lock_flags;
- unsigned int mask = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return POLLERR;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- goto error;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- goto error;
- }
-
- if (cam->io == IO_NONE) {
- if (!zc0301_request_buffers(cam, cam->nreadbuffers, IO_READ)) {
- DBG(1, "poll() failed, not enough memory");
- goto error;
- }
- cam->io = IO_READ;
- cam->stream = STREAM_ON;
- }
-
- if (cam->io == IO_READ) {
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_for_each_entry(f, &cam->outqueue, frame)
- f->state = F_UNUSED;
- INIT_LIST_HEAD(&cam->outqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
- zc0301_queue_unusedframes(cam);
- }
-
- poll_wait(filp, &cam->wait_frame, wait);
-
- if (!list_empty(&cam->outqueue))
- mask |= POLLIN | POLLRDNORM;
-
- mutex_unlock(&cam->fileop_mutex);
-
- return mask;
-
-error:
- mutex_unlock(&cam->fileop_mutex);
- return POLLERR;
-}
-
-
-static void zc0301_vm_open(struct vm_area_struct* vma)
-{
- struct zc0301_frame_t* f = vma->vm_private_data;
- f->vma_use_count++;
-}
-
-
-static void zc0301_vm_close(struct vm_area_struct* vma)
-{
- /* NOTE: buffers are not freed here */
- struct zc0301_frame_t* f = vma->vm_private_data;
- f->vma_use_count--;
-}
-
-
-static const struct vm_operations_struct zc0301_vm_ops = {
- .open = zc0301_vm_open,
- .close = zc0301_vm_close,
-};
-
-
-static int zc0301_mmap(struct file* filp, struct vm_area_struct *vma)
-{
- struct zc0301_device *cam = video_drvdata(filp);
- unsigned long size = vma->vm_end - vma->vm_start,
- start = vma->vm_start;
- void *pos;
- u32 i;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- if (!(vma->vm_flags & (VM_WRITE | VM_READ))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EACCES;
- }
-
- if (cam->io != IO_MMAP ||
- size != PAGE_ALIGN(cam->frame[0].buf.length)) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- for (i = 0; i < cam->nbuffers; i++) {
- if ((cam->frame[i].buf.m.offset>>PAGE_SHIFT) == vma->vm_pgoff)
- break;
- }
- if (i == cam->nbuffers) {
- mutex_unlock(&cam->fileop_mutex);
- return -EINVAL;
- }
-
- vma->vm_flags |= VM_IO;
- vma->vm_flags |= VM_RESERVED;
-
- pos = cam->frame[i].bufmem;
- while (size > 0) { /* size is page-aligned */
- if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
- mutex_unlock(&cam->fileop_mutex);
- return -EAGAIN;
- }
- start += PAGE_SIZE;
- pos += PAGE_SIZE;
- size -= PAGE_SIZE;
- }
-
- vma->vm_ops = &zc0301_vm_ops;
- vma->vm_private_data = &cam->frame[i];
- zc0301_vm_open(vma);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return 0;
-}
-
-/*****************************************************************************/
-
-static int
-zc0301_vidioc_querycap(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_capability cap = {
- .driver = "zc0301",
- .version = ZC0301_MODULE_VERSION_CODE,
- .capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING,
- };
-
- strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card));
- if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0)
- strlcpy(cap.bus_info, dev_name(&cam->usbdev->dev),
- sizeof(cap.bus_info));
-
- if (copy_to_user(arg, &cap, sizeof(cap)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_enuminput(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_input i;
-
- if (copy_from_user(&i, arg, sizeof(i)))
- return -EFAULT;
-
- if (i.index)
- return -EINVAL;
-
- memset(&i, 0, sizeof(i));
- strcpy(i.name, "Camera");
- i.type = V4L2_INPUT_TYPE_CAMERA;
-
- if (copy_to_user(arg, &i, sizeof(i)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_g_input(struct zc0301_device* cam, void __user * arg)
-{
- int index = 0;
-
- if (copy_to_user(arg, &index, sizeof(index)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg)
-{
- int index;
-
- if (copy_from_user(&index, arg, sizeof(index)))
- return -EFAULT;
-
- if (index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_queryctrl qc;
- u8 i;
-
- if (copy_from_user(&qc, arg, sizeof(qc)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (qc.id && qc.id == s->qctrl[i].id) {
- memcpy(&qc, &(s->qctrl[i]), sizeof(qc));
- if (copy_to_user(arg, &qc, sizeof(qc)))
- return -EFAULT;
- return 0;
- }
-
- return -EINVAL;
-}
-
-
-static int
-zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- int err = 0;
- u8 i;
-
- if (!s->get_ctrl && !s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- if (!s->get_ctrl) {
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
- if (ctrl.id == s->qctrl[i].id) {
- ctrl.value = s->_qctrl[i].default_value;
- goto exit;
- }
- return -EINVAL;
- } else
- err = s->get_ctrl(cam, &ctrl);
-
-exit:
- if (copy_to_user(arg, &ctrl, sizeof(ctrl)))
- return -EFAULT;
-
- return err;
-}
-
-
-static int
-zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_control ctrl;
- u8 i;
- int err = 0;
-
- if (!s->set_ctrl)
- return -EINVAL;
-
- if (copy_from_user(&ctrl, arg, sizeof(ctrl)))
- return -EFAULT;
-
- for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) {
- if (ctrl.id == s->qctrl[i].id) {
- if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
- return -EINVAL;
- if (ctrl.value < s->qctrl[i].minimum ||
- ctrl.value > s->qctrl[i].maximum)
- return -ERANGE;
- ctrl.value -= ctrl.value % s->qctrl[i].step;
- break;
- }
- }
- if (i == ARRAY_SIZE(s->qctrl))
- return -EINVAL;
- if ((err = s->set_ctrl(cam, &ctrl)))
- return err;
-
- s->_qctrl[i].default_value = ctrl.value;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
-
- cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- cc->pixelaspect.numerator = 1;
- cc->pixelaspect.denominator = 1;
-
- if (copy_to_user(arg, cc, sizeof(*cc)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_crop crop = {
- .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
- };
-
- memcpy(&(crop.c), &(s->_rect), sizeof(struct v4l2_rect));
-
- if (copy_to_user(arg, &crop, sizeof(crop)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_crop crop;
- struct v4l2_rect* rect;
- struct v4l2_rect* bounds = &(s->cropcap.bounds);
- const enum zc0301_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&crop, arg, sizeof(crop)))
- return -EFAULT;
-
- rect = &(crop.c);
-
- if (crop.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_CROP failed. "
- "Unmap the buffers first.");
- return -EBUSY;
- }
-
- if (!s->set_crop) {
- memcpy(rect, &(s->_rect), sizeof(*rect));
- if (copy_to_user(arg, &crop, sizeof(crop)))
- return -EFAULT;
- return 0;
- }
-
- rect->left &= ~7L;
- rect->top &= ~7L;
- if (rect->width < 8)
- rect->width = 8;
- if (rect->height < 8)
- rect->height = 8;
- if (rect->width > bounds->width)
- rect->width = bounds->width;
- if (rect->height > bounds->height)
- rect->height = bounds->height;
- if (rect->left < bounds->left)
- rect->left = bounds->left;
- if (rect->top < bounds->top)
- rect->top = bounds->top;
- if (rect->left + rect->width > bounds->left + bounds->width)
- rect->left = bounds->left+bounds->width - rect->width;
- if (rect->top + rect->height > bounds->top + bounds->height)
- rect->top = bounds->top+bounds->height - rect->height;
- rect->width &= ~7L;
- rect->height &= ~7L;
-
- if (cam->stream == STREAM_ON)
- if ((err = zc0301_stream_interrupt(cam)))
- return err;
-
- if (copy_to_user(arg, &crop, sizeof(crop))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- zc0301_release_buffers(cam);
-
- if (s->set_crop)
- err += s->set_crop(cam, rect);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- s->pix_format.width = rect->width;
- s->pix_format.height = rect->height;
- memcpy(&(s->_rect), rect, sizeof(*rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_CROP failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- zc0301_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- zc0301_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_enum_framesizes(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_frmsizeenum frmsize;
-
- if (copy_from_user(&frmsize, arg, sizeof(frmsize)))
- return -EFAULT;
-
- if (frmsize.index != 0 && frmsize.index != 1)
- return -EINVAL;
-
- if (frmsize.pixel_format != V4L2_PIX_FMT_JPEG)
- return -EINVAL;
-
- frmsize.type = V4L2_FRMSIZE_TYPE_DISCRETE;
-
- if (frmsize.index == 1) {
- frmsize.discrete.width = cam->sensor.cropcap.defrect.width;
- frmsize.discrete.height = cam->sensor.cropcap.defrect.height;
- }
- memset(&frmsize.reserved, 0, sizeof(frmsize.reserved));
-
- if (copy_to_user(arg, &frmsize, sizeof(frmsize)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_enum_fmt(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_fmtdesc fmtd;
-
- if (copy_from_user(&fmtd, arg, sizeof(fmtd)))
- return -EFAULT;
-
- if (fmtd.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- if (fmtd.index == 0) {
- strcpy(fmtd.description, "JPEG");
- fmtd.pixelformat = V4L2_PIX_FMT_JPEG;
- fmtd.flags = V4L2_FMT_FLAG_COMPRESSED;
- } else
- return -EINVAL;
-
- fmtd.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- memset(&fmtd.reserved, 0, sizeof(fmtd.reserved));
-
- if (copy_to_user(arg, &fmtd, sizeof(fmtd)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_format format;
- struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- pfmt->bytesperline = 0;
- pfmt->sizeimage = pfmt->height * ((pfmt->width*pfmt->priv)/8);
- pfmt->field = V4L2_FIELD_NONE;
- memcpy(&(format.fmt.pix), pfmt, sizeof(*pfmt));
-
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
- void __user * arg)
-{
- struct zc0301_sensor* s = &cam->sensor;
- struct v4l2_format format;
- struct v4l2_pix_format* pix;
- struct v4l2_pix_format* pfmt = &(s->pix_format);
- struct v4l2_rect* bounds = &(s->cropcap.bounds);
- struct v4l2_rect rect;
- const enum zc0301_stream_state stream = cam->stream;
- const u32 nbuffers = cam->nbuffers;
- u32 i;
- int err = 0;
-
- if (copy_from_user(&format, arg, sizeof(format)))
- return -EFAULT;
-
- pix = &(format.fmt.pix);
-
- if (format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memcpy(&rect, &(s->_rect), sizeof(rect));
-
- if (!s->set_crop) {
- pix->width = rect.width;
- pix->height = rect.height;
- } else {
- rect.width = pix->width;
- rect.height = pix->height;
- }
-
- if (rect.width < 8)
- rect.width = 8;
- if (rect.height < 8)
- rect.height = 8;
- if (rect.width > bounds->left + bounds->width - rect.left)
- rect.width = bounds->left + bounds->width - rect.left;
- if (rect.height > bounds->top + bounds->height - rect.top)
- rect.height = bounds->top + bounds->height - rect.top;
- rect.width &= ~7L;
- rect.height &= ~7L;
-
- pix->width = rect.width;
- pix->height = rect.height;
- pix->pixelformat = pfmt->pixelformat;
- pix->priv = pfmt->priv;
- pix->colorspace = pfmt->colorspace;
- pix->bytesperline = 0;
- pix->sizeimage = pix->height * ((pix->width * pix->priv) / 8);
- pix->field = V4L2_FIELD_NONE;
-
- if (cmd == VIDIOC_TRY_FMT) {
- if (copy_to_user(arg, &format, sizeof(format)))
- return -EFAULT;
- return 0;
- }
-
- if (cam->module_param.force_munmap)
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_S_FMT failed. "
- "Unmap the buffers first.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON)
- if ((err = zc0301_stream_interrupt(cam)))
- return err;
-
- if (copy_to_user(arg, &format, sizeof(format))) {
- cam->stream = stream;
- return -EFAULT;
- }
-
- if (cam->module_param.force_munmap || cam->io == IO_READ)
- zc0301_release_buffers(cam);
-
- if (s->set_crop)
- err += s->set_crop(cam, &rect);
-
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of hardware problems. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- memcpy(pfmt, pix, sizeof(*pix));
- memcpy(&(s->_rect), &rect, sizeof(rect));
-
- if ((cam->module_param.force_munmap || cam->io == IO_READ) &&
- nbuffers != zc0301_request_buffers(cam, nbuffers, cam->io)) {
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_FMT failed because of not enough memory. To "
- "use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -ENOMEM;
- }
-
- if (cam->io == IO_READ)
- zc0301_empty_framequeues(cam);
- else if (cam->module_param.force_munmap)
- zc0301_requeue_outqueue(cam);
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_g_jpegcomp(struct zc0301_device* cam, void __user * arg)
-{
- if (copy_to_user(arg, &cam->compression, sizeof(cam->compression)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_s_jpegcomp(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_jpegcompression jc;
- const enum zc0301_stream_state stream = cam->stream;
- int err = 0;
-
- if (copy_from_user(&jc, arg, sizeof(jc)))
- return -EFAULT;
-
- if (jc.quality != 0)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON)
- if ((err = zc0301_stream_interrupt(cam)))
- return err;
-
- err += zc0301_set_compression(cam, &jc);
- if (err) { /* atomic, no rollback in ioctl() */
- cam->state |= DEV_MISCONFIGURED;
- DBG(1, "VIDIOC_S_JPEGCOMP failed because of hardware "
- "problems. To use the camera, close and open %s again.",
- video_device_node_name(cam->v4ldev));
- return -EIO;
- }
-
- cam->compression.quality = jc.quality;
-
- cam->stream = stream;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_reqbufs(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_requestbuffers rb;
- u32 i;
- int err;
-
- if (copy_from_user(&rb, arg, sizeof(rb)))
- return -EFAULT;
-
- if (rb.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- rb.memory != V4L2_MEMORY_MMAP)
- return -EINVAL;
-
- if (cam->io == IO_READ) {
- DBG(3, "Close and open the device again to choose the mmap "
- "I/O method");
- return -EBUSY;
- }
-
- for (i = 0; i < cam->nbuffers; i++)
- if (cam->frame[i].vma_use_count) {
- DBG(3, "VIDIOC_REQBUFS failed. "
- "Previous buffers are still mapped.");
- return -EBUSY;
- }
-
- if (cam->stream == STREAM_ON)
- if ((err = zc0301_stream_interrupt(cam)))
- return err;
-
- zc0301_empty_framequeues(cam);
-
- zc0301_release_buffers(cam);
- if (rb.count)
- rb.count = zc0301_request_buffers(cam, rb.count, IO_MMAP);
-
- if (copy_to_user(arg, &rb, sizeof(rb))) {
- zc0301_release_buffers(cam);
- cam->io = IO_NONE;
- return -EFAULT;
- }
-
- cam->io = rb.count ? IO_MMAP : IO_NONE;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_querybuf(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_buffer b;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- memcpy(&b, &cam->frame[b.index].buf, sizeof(b));
-
- if (cam->frame[b.index].vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (cam->frame[b.index].state == F_DONE)
- b.flags |= V4L2_BUF_FLAG_DONE;
- else if (cam->frame[b.index].state != F_UNUSED)
- b.flags |= V4L2_BUF_FLAG_QUEUED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_qbuf(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_buffer b;
- unsigned long lock_flags;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- b.index >= cam->nbuffers || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->frame[b.index].state != F_UNUSED)
- return -EINVAL;
-
- cam->frame[b.index].state = F_QUEUED;
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- list_add_tail(&cam->frame[b.index].frame, &cam->inqueue);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- PDBGG("Frame #%lu queued", (unsigned long)b.index);
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp,
- void __user * arg)
-{
- struct v4l2_buffer b;
- struct zc0301_frame_t *f;
- unsigned long lock_flags;
- long timeout;
-
- if (copy_from_user(&b, arg, sizeof(b)))
- return -EFAULT;
-
- if (b.type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io!= IO_MMAP)
- return -EINVAL;
-
- if (list_empty(&cam->outqueue)) {
- if (cam->stream == STREAM_OFF)
- return -EINVAL;
- if (filp->f_flags & O_NONBLOCK)
- return -EAGAIN;
- timeout = wait_event_interruptible_timeout
- ( cam->wait_frame,
- (!list_empty(&cam->outqueue)) ||
- (cam->state & DEV_DISCONNECTED) ||
- (cam->state & DEV_MISCONFIGURED),
- cam->module_param.frame_timeout *
- 1000 * msecs_to_jiffies(1) );
- if (timeout < 0)
- return timeout;
- if (cam->state & DEV_DISCONNECTED)
- return -ENODEV;
- if (!timeout || (cam->state & DEV_MISCONFIGURED))
- return -EIO;
- }
-
- spin_lock_irqsave(&cam->queue_lock, lock_flags);
- f = list_entry(cam->outqueue.next, struct zc0301_frame_t, frame);
- list_del(cam->outqueue.next);
- spin_unlock_irqrestore(&cam->queue_lock, lock_flags);
-
- f->state = F_UNUSED;
-
- memcpy(&b, &f->buf, sizeof(b));
- if (f->vma_use_count)
- b.flags |= V4L2_BUF_FLAG_MAPPED;
-
- if (copy_to_user(arg, &b, sizeof(b)))
- return -EFAULT;
-
- PDBGG("Frame #%lu dequeued", (unsigned long)f->buf.index);
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_streamon(struct zc0301_device* cam, void __user * arg)
-{
- int type;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- cam->stream = STREAM_ON;
-
- DBG(3, "Stream on");
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_streamoff(struct zc0301_device* cam, void __user * arg)
-{
- int type, err;
-
- if (copy_from_user(&type, arg, sizeof(type)))
- return -EFAULT;
-
- if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE || cam->io != IO_MMAP)
- return -EINVAL;
-
- if (cam->stream == STREAM_ON)
- if ((err = zc0301_stream_interrupt(cam)))
- return err;
-
- zc0301_empty_framequeues(cam);
-
- DBG(3, "Stream off");
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_g_parm(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- return 0;
-}
-
-
-static int
-zc0301_vidioc_s_parm(struct zc0301_device* cam, void __user * arg)
-{
- struct v4l2_streamparm sp;
-
- if (copy_from_user(&sp, arg, sizeof(sp)))
- return -EFAULT;
-
- if (sp.type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp.parm.capture.extendedmode = 0;
-
- if (sp.parm.capture.readbuffers == 0)
- sp.parm.capture.readbuffers = cam->nreadbuffers;
-
- if (sp.parm.capture.readbuffers > ZC0301_MAX_FRAMES)
- sp.parm.capture.readbuffers = ZC0301_MAX_FRAMES;
-
- if (copy_to_user(arg, &sp, sizeof(sp)))
- return -EFAULT;
-
- cam->nreadbuffers = sp.parm.capture.readbuffers;
-
- return 0;
-}
-
-
-static long zc0301_ioctl_v4l2(struct file *filp,
- unsigned int cmd, void __user *arg)
-{
- struct zc0301_device *cam = video_drvdata(filp);
-
- switch (cmd) {
-
- case VIDIOC_QUERYCAP:
- return zc0301_vidioc_querycap(cam, arg);
-
- case VIDIOC_ENUMINPUT:
- return zc0301_vidioc_enuminput(cam, arg);
-
- case VIDIOC_G_INPUT:
- return zc0301_vidioc_g_input(cam, arg);
-
- case VIDIOC_S_INPUT:
- return zc0301_vidioc_s_input(cam, arg);
-
- case VIDIOC_QUERYCTRL:
- return zc0301_vidioc_query_ctrl(cam, arg);
-
- case VIDIOC_G_CTRL:
- return zc0301_vidioc_g_ctrl(cam, arg);
-
- case VIDIOC_S_CTRL:
- return zc0301_vidioc_s_ctrl(cam, arg);
-
- case VIDIOC_CROPCAP:
- return zc0301_vidioc_cropcap(cam, arg);
-
- case VIDIOC_G_CROP:
- return zc0301_vidioc_g_crop(cam, arg);
-
- case VIDIOC_S_CROP:
- return zc0301_vidioc_s_crop(cam, arg);
-
- case VIDIOC_ENUM_FMT:
- return zc0301_vidioc_enum_fmt(cam, arg);
-
- case VIDIOC_G_FMT:
- return zc0301_vidioc_g_fmt(cam, arg);
-
- case VIDIOC_TRY_FMT:
- case VIDIOC_S_FMT:
- return zc0301_vidioc_try_s_fmt(cam, cmd, arg);
-
- case VIDIOC_ENUM_FRAMESIZES:
- return zc0301_vidioc_enum_framesizes(cam, arg);
-
- case VIDIOC_G_JPEGCOMP:
- return zc0301_vidioc_g_jpegcomp(cam, arg);
-
- case VIDIOC_S_JPEGCOMP:
- return zc0301_vidioc_s_jpegcomp(cam, arg);
-
- case VIDIOC_REQBUFS:
- return zc0301_vidioc_reqbufs(cam, arg);
-
- case VIDIOC_QUERYBUF:
- return zc0301_vidioc_querybuf(cam, arg);
-
- case VIDIOC_QBUF:
- return zc0301_vidioc_qbuf(cam, arg);
-
- case VIDIOC_DQBUF:
- return zc0301_vidioc_dqbuf(cam, filp, arg);
-
- case VIDIOC_STREAMON:
- return zc0301_vidioc_streamon(cam, arg);
-
- case VIDIOC_STREAMOFF:
- return zc0301_vidioc_streamoff(cam, arg);
-
- case VIDIOC_G_PARM:
- return zc0301_vidioc_g_parm(cam, arg);
-
- case VIDIOC_S_PARM:
- return zc0301_vidioc_s_parm(cam, arg);
-
- case VIDIOC_G_STD:
- case VIDIOC_S_STD:
- case VIDIOC_QUERYSTD:
- case VIDIOC_ENUMSTD:
- case VIDIOC_QUERYMENU:
- case VIDIOC_ENUM_FRAMEINTERVALS:
- return -EINVAL;
-
- default:
- return -EINVAL;
-
- }
-}
-
-
-static long zc0301_ioctl(struct file *filp,
- unsigned int cmd, unsigned long arg)
-{
- struct zc0301_device *cam = video_drvdata(filp);
- int err = 0;
-
- if (mutex_lock_interruptible(&cam->fileop_mutex))
- return -ERESTARTSYS;
-
- if (cam->state & DEV_DISCONNECTED) {
- DBG(1, "Device not present");
- mutex_unlock(&cam->fileop_mutex);
- return -ENODEV;
- }
-
- if (cam->state & DEV_MISCONFIGURED) {
- DBG(1, "The camera is misconfigured. Close and open it "
- "again.");
- mutex_unlock(&cam->fileop_mutex);
- return -EIO;
- }
-
- V4LDBG(3, "zc0301", cmd);
-
- err = zc0301_ioctl_v4l2(filp, cmd, (void __user *)arg);
-
- mutex_unlock(&cam->fileop_mutex);
-
- return err;
-}
-
-
-static const struct v4l2_file_operations zc0301_fops = {
- .owner = THIS_MODULE,
- .open = zc0301_open,
- .release = zc0301_release,
- .ioctl = zc0301_ioctl,
- .read = zc0301_read,
- .poll = zc0301_poll,
- .mmap = zc0301_mmap,
-};
-
-/*****************************************************************************/
-
-static int
-zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
-{
- struct usb_device *udev = interface_to_usbdev(intf);
- struct zc0301_device* cam;
- static unsigned int dev_nr;
- unsigned int i;
- int err = 0;
-
- if (!(cam = kzalloc(sizeof(struct zc0301_device), GFP_KERNEL)))
- return -ENOMEM;
-
- cam->usbdev = udev;
-
- if (!(cam->control_buffer = kzalloc(4, GFP_KERNEL))) {
- DBG(1, "kmalloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- if (!(cam->v4ldev = video_device_alloc())) {
- DBG(1, "video_device_alloc() failed");
- err = -ENOMEM;
- goto fail;
- }
-
- DBG(2, "ZC0301[P] Image Processor and Control Chip detected "
- "(vid/pid 0x%04X:0x%04X)",id->idVendor, id->idProduct);
-
- for (i = 0; zc0301_sensor_table[i]; i++) {
- err = zc0301_sensor_table[i](cam);
- if (!err)
- break;
- }
-
- if (!err)
- DBG(2, "%s image sensor detected", cam->sensor.name);
- else {
- DBG(1, "No supported image sensor detected");
- err = -ENODEV;
- goto fail;
- }
-
- if (zc0301_init(cam)) {
- DBG(1, "Initialization failed. I will retry on open().");
- cam->state |= DEV_MISCONFIGURED;
- }
-
- strcpy(cam->v4ldev->name, "ZC0301[P] PC Camera");
- cam->v4ldev->fops = &zc0301_fops;
- cam->v4ldev->release = video_device_release;
- cam->v4ldev->parent = &udev->dev;
- video_set_drvdata(cam->v4ldev, cam);
-
- init_completion(&cam->probe);
-
- err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
- video_nr[dev_nr]);
- if (err) {
- DBG(1, "V4L2 device registration failed");
- if (err == -ENFILE && video_nr[dev_nr] == -1)
- DBG(1, "Free /dev/videoX node not found");
- video_nr[dev_nr] = -1;
- dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
- complete_all(&cam->probe);
- goto fail;
- }
-
- DBG(2, "V4L2 device registered as %s",
- video_device_node_name(cam->v4ldev));
-
- cam->module_param.force_munmap = force_munmap[dev_nr];
- cam->module_param.frame_timeout = frame_timeout[dev_nr];
-
- dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
-
- usb_set_intfdata(intf, cam);
- kref_init(&cam->kref);
- usb_get_dev(cam->usbdev);
-
- complete_all(&cam->probe);
-
- return 0;
-
-fail:
- if (cam) {
- kfree(cam->control_buffer);
- if (cam->v4ldev)
- video_device_release(cam->v4ldev);
- kfree(cam);
- }
- return err;
-}
-
-
-static void zc0301_usb_disconnect(struct usb_interface* intf)
-{
- struct zc0301_device* cam;
-
- down_write(&zc0301_dev_lock);
-
- cam = usb_get_intfdata(intf);
-
- DBG(2, "Disconnecting %s...", cam->v4ldev->name);
-
- if (cam->users) {
- DBG(2, "Device %s is open! Deregistration and "
- "memory deallocation are deferred.",
- video_device_node_name(cam->v4ldev));
- cam->state |= DEV_MISCONFIGURED;
- zc0301_stop_transfer(cam);
- cam->state |= DEV_DISCONNECTED;
- wake_up_interruptible(&cam->wait_frame);
- wake_up(&cam->wait_stream);
- } else
- cam->state |= DEV_DISCONNECTED;
-
- wake_up_interruptible_all(&cam->wait_open);
-
- kref_put(&cam->kref, zc0301_release_resources);
-
- up_write(&zc0301_dev_lock);
-}
-
-
-static struct usb_driver zc0301_usb_driver = {
- .name = "zc0301",
- .id_table = zc0301_id_table,
- .probe = zc0301_usb_probe,
- .disconnect = zc0301_usb_disconnect,
-};
-
-/*****************************************************************************/
-
-static int __init zc0301_module_init(void)
-{
- int err = 0;
-
- KDBG(2, ZC0301_MODULE_NAME " v" ZC0301_MODULE_VERSION);
- KDBG(3, ZC0301_MODULE_AUTHOR);
-
- if ((err = usb_register(&zc0301_usb_driver)))
- KDBG(1, "usb_register() failed");
-
- return err;
-}
-
-
-static void __exit zc0301_module_exit(void)
-{
- usb_deregister(&zc0301_usb_driver);
-}
-
-
-module_init(zc0301_module_init);
-module_exit(zc0301_module_exit);
diff --git a/drivers/media/video/zc0301/zc0301_pas202bcb.c b/drivers/media/video/zc0301/zc0301_pas202bcb.c
deleted file mode 100644
index 24b0dfba357e..000000000000
--- a/drivers/media/video/zc0301/zc0301_pas202bcb.c
+++ /dev/null
@@ -1,362 +0,0 @@
-/***************************************************************************
- * Plug-in for PAS202BCB image sensor connected to the ZC0301 Image *
- * Processor and Control Chip *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * Initialization values of the ZC0301[P] have been taken from the SPCA5XX *
- * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-/*
- NOTE: Sensor controls are disabled for now, becouse changing them while
- streaming sometimes results in out-of-sync video frames. We'll use
- the default initialization, until we know how to stop and start video
- in the chip. However, the image quality still looks good under various
- light conditions.
-*/
-
-#include <linux/delay.h>
-#include "zc0301_sensor.h"
-
-
-static struct zc0301_sensor pas202bcb;
-
-
-static int pas202bcb_init(struct zc0301_device* cam)
-{
- int err = 0;
-
- err += zc0301_write_reg(cam, 0x0002, 0x00);
- err += zc0301_write_reg(cam, 0x0003, 0x02);
- err += zc0301_write_reg(cam, 0x0004, 0x80);
- err += zc0301_write_reg(cam, 0x0005, 0x01);
- err += zc0301_write_reg(cam, 0x0006, 0xE0);
- err += zc0301_write_reg(cam, 0x0098, 0x00);
- err += zc0301_write_reg(cam, 0x009A, 0x03);
- err += zc0301_write_reg(cam, 0x011A, 0x00);
- err += zc0301_write_reg(cam, 0x011C, 0x03);
- err += zc0301_write_reg(cam, 0x009B, 0x01);
- err += zc0301_write_reg(cam, 0x009C, 0xE6);
- err += zc0301_write_reg(cam, 0x009D, 0x02);
- err += zc0301_write_reg(cam, 0x009E, 0x86);
-
- err += zc0301_i2c_write(cam, 0x02, 0x02);
- err += zc0301_i2c_write(cam, 0x0A, 0x01);
- err += zc0301_i2c_write(cam, 0x0B, 0x01);
- err += zc0301_i2c_write(cam, 0x0D, 0x00);
- err += zc0301_i2c_write(cam, 0x12, 0x05);
- err += zc0301_i2c_write(cam, 0x13, 0x63);
- err += zc0301_i2c_write(cam, 0x15, 0x70);
-
- err += zc0301_write_reg(cam, 0x0101, 0xB7);
- err += zc0301_write_reg(cam, 0x0100, 0x0D);
- err += zc0301_write_reg(cam, 0x0189, 0x06);
- err += zc0301_write_reg(cam, 0x01AD, 0x00);
- err += zc0301_write_reg(cam, 0x01C5, 0x03);
- err += zc0301_write_reg(cam, 0x01CB, 0x13);
- err += zc0301_write_reg(cam, 0x0250, 0x08);
- err += zc0301_write_reg(cam, 0x0301, 0x08);
- err += zc0301_write_reg(cam, 0x018D, 0x70);
- err += zc0301_write_reg(cam, 0x0008, 0x03);
- err += zc0301_write_reg(cam, 0x01C6, 0x04);
- err += zc0301_write_reg(cam, 0x01CB, 0x07);
- err += zc0301_write_reg(cam, 0x0120, 0x11);
- err += zc0301_write_reg(cam, 0x0121, 0x37);
- err += zc0301_write_reg(cam, 0x0122, 0x58);
- err += zc0301_write_reg(cam, 0x0123, 0x79);
- err += zc0301_write_reg(cam, 0x0124, 0x91);
- err += zc0301_write_reg(cam, 0x0125, 0xA6);
- err += zc0301_write_reg(cam, 0x0126, 0xB8);
- err += zc0301_write_reg(cam, 0x0127, 0xC7);
- err += zc0301_write_reg(cam, 0x0128, 0xD3);
- err += zc0301_write_reg(cam, 0x0129, 0xDE);
- err += zc0301_write_reg(cam, 0x012A, 0xE6);
- err += zc0301_write_reg(cam, 0x012B, 0xED);
- err += zc0301_write_reg(cam, 0x012C, 0xF3);
- err += zc0301_write_reg(cam, 0x012D, 0xF8);
- err += zc0301_write_reg(cam, 0x012E, 0xFB);
- err += zc0301_write_reg(cam, 0x012F, 0xFF);
- err += zc0301_write_reg(cam, 0x0130, 0x26);
- err += zc0301_write_reg(cam, 0x0131, 0x23);
- err += zc0301_write_reg(cam, 0x0132, 0x20);
- err += zc0301_write_reg(cam, 0x0133, 0x1C);
- err += zc0301_write_reg(cam, 0x0134, 0x16);
- err += zc0301_write_reg(cam, 0x0135, 0x13);
- err += zc0301_write_reg(cam, 0x0136, 0x10);
- err += zc0301_write_reg(cam, 0x0137, 0x0D);
- err += zc0301_write_reg(cam, 0x0138, 0x0B);
- err += zc0301_write_reg(cam, 0x0139, 0x09);
- err += zc0301_write_reg(cam, 0x013A, 0x07);
- err += zc0301_write_reg(cam, 0x013B, 0x06);
- err += zc0301_write_reg(cam, 0x013C, 0x05);
- err += zc0301_write_reg(cam, 0x013D, 0x04);
- err += zc0301_write_reg(cam, 0x013E, 0x03);
- err += zc0301_write_reg(cam, 0x013F, 0x02);
- err += zc0301_write_reg(cam, 0x010A, 0x4C);
- err += zc0301_write_reg(cam, 0x010B, 0xF5);
- err += zc0301_write_reg(cam, 0x010C, 0xFF);
- err += zc0301_write_reg(cam, 0x010D, 0xF9);
- err += zc0301_write_reg(cam, 0x010E, 0x51);
- err += zc0301_write_reg(cam, 0x010F, 0xF5);
- err += zc0301_write_reg(cam, 0x0110, 0xFB);
- err += zc0301_write_reg(cam, 0x0111, 0xED);
- err += zc0301_write_reg(cam, 0x0112, 0x5F);
- err += zc0301_write_reg(cam, 0x0180, 0x00);
- err += zc0301_write_reg(cam, 0x0019, 0x00);
- err += zc0301_write_reg(cam, 0x0087, 0x20);
- err += zc0301_write_reg(cam, 0x0088, 0x21);
-
- err += zc0301_i2c_write(cam, 0x20, 0x02);
- err += zc0301_i2c_write(cam, 0x21, 0x1B);
- err += zc0301_i2c_write(cam, 0x03, 0x44);
- err += zc0301_i2c_write(cam, 0x0E, 0x01);
- err += zc0301_i2c_write(cam, 0x0F, 0x00);
-
- err += zc0301_write_reg(cam, 0x01A9, 0x14);
- err += zc0301_write_reg(cam, 0x01AA, 0x24);
- err += zc0301_write_reg(cam, 0x0190, 0x00);
- err += zc0301_write_reg(cam, 0x0191, 0x02);
- err += zc0301_write_reg(cam, 0x0192, 0x1B);
- err += zc0301_write_reg(cam, 0x0195, 0x00);
- err += zc0301_write_reg(cam, 0x0196, 0x00);
- err += zc0301_write_reg(cam, 0x0197, 0x4D);
- err += zc0301_write_reg(cam, 0x018C, 0x10);
- err += zc0301_write_reg(cam, 0x018F, 0x20);
- err += zc0301_write_reg(cam, 0x001D, 0x44);
- err += zc0301_write_reg(cam, 0x001E, 0x6F);
- err += zc0301_write_reg(cam, 0x001F, 0xAD);
- err += zc0301_write_reg(cam, 0x0020, 0xEB);
- err += zc0301_write_reg(cam, 0x0087, 0x0F);
- err += zc0301_write_reg(cam, 0x0088, 0x0E);
- err += zc0301_write_reg(cam, 0x0180, 0x40);
- err += zc0301_write_reg(cam, 0x0192, 0x1B);
- err += zc0301_write_reg(cam, 0x0191, 0x02);
- err += zc0301_write_reg(cam, 0x0190, 0x00);
- err += zc0301_write_reg(cam, 0x0116, 0x1D);
- err += zc0301_write_reg(cam, 0x0117, 0x40);
- err += zc0301_write_reg(cam, 0x0118, 0x99);
- err += zc0301_write_reg(cam, 0x0180, 0x42);
- err += zc0301_write_reg(cam, 0x0116, 0x1D);
- err += zc0301_write_reg(cam, 0x0117, 0x40);
- err += zc0301_write_reg(cam, 0x0118, 0x99);
- err += zc0301_write_reg(cam, 0x0007, 0x00);
-
- err += zc0301_i2c_write(cam, 0x11, 0x01);
-
- msleep(100);
-
- return err;
-}
-
-
-static int pas202bcb_get_ctrl(struct zc0301_device* cam,
- struct v4l2_control* ctrl)
-{
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- {
- int r1 = zc0301_i2c_read(cam, 0x04, 1),
- r2 = zc0301_i2c_read(cam, 0x05, 1);
- if (r1 < 0 || r2 < 0)
- return -EIO;
- ctrl->value = (r1 << 6) | (r2 & 0x3f);
- }
- return 0;
- case V4L2_CID_RED_BALANCE:
- if ((ctrl->value = zc0301_i2c_read(cam, 0x09, 1)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_BLUE_BALANCE:
- if ((ctrl->value = zc0301_i2c_read(cam, 0x07, 1)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case V4L2_CID_GAIN:
- if ((ctrl->value = zc0301_i2c_read(cam, 0x10, 1)) < 0)
- return -EIO;
- ctrl->value &= 0x1f;
- return 0;
- case ZC0301_V4L2_CID_GREEN_BALANCE:
- if ((ctrl->value = zc0301_i2c_read(cam, 0x08, 1)) < 0)
- return -EIO;
- ctrl->value &= 0x0f;
- return 0;
- case ZC0301_V4L2_CID_DAC_MAGNITUDE:
- if ((ctrl->value = zc0301_i2c_read(cam, 0x0c, 1)) < 0)
- return -EIO;
- return 0;
- default:
- return -EINVAL;
- }
-}
-
-
-static int pas202bcb_set_ctrl(struct zc0301_device* cam,
- const struct v4l2_control* ctrl)
-{
- int err = 0;
-
- switch (ctrl->id) {
- case V4L2_CID_EXPOSURE:
- err += zc0301_i2c_write(cam, 0x04, ctrl->value >> 6);
- err += zc0301_i2c_write(cam, 0x05, ctrl->value & 0x3f);
- break;
- case V4L2_CID_RED_BALANCE:
- err += zc0301_i2c_write(cam, 0x09, ctrl->value);
- break;
- case V4L2_CID_BLUE_BALANCE:
- err += zc0301_i2c_write(cam, 0x07, ctrl->value);
- break;
- case V4L2_CID_GAIN:
- err += zc0301_i2c_write(cam, 0x10, ctrl->value);
- break;
- case ZC0301_V4L2_CID_GREEN_BALANCE:
- err += zc0301_i2c_write(cam, 0x08, ctrl->value);
- break;
- case ZC0301_V4L2_CID_DAC_MAGNITUDE:
- err += zc0301_i2c_write(cam, 0x0c, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- err += zc0301_i2c_write(cam, 0x11, 0x01);
-
- return err ? -EIO : 0;
-}
-
-
-static struct zc0301_sensor pas202bcb = {
- .name = "PAS202BCB",
- .init = &pas202bcb_init,
- .qctrl = {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x01e5,
- .maximum = 0x3fff,
- .step = 0x0001,
- .default_value = 0x01e5,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "global gain",
- .minimum = 0x00,
- .maximum = 0x1f,
- .step = 0x01,
- .default_value = 0x0c,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "DAC magnitude",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x01,
- .default_value = 0x00,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "red balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x01,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "blue balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x05,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- {
- .id = ZC0301_V4L2_CID_GREEN_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "green balance",
- .minimum = 0x00,
- .maximum = 0x0f,
- .step = 0x01,
- .default_value = 0x00,
- .flags = V4L2_CTRL_FLAG_DISABLED,
- },
- },
- .get_ctrl = &pas202bcb_get_ctrl,
- .set_ctrl = &pas202bcb_set_ctrl,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_JPEG,
- .priv = 8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
-};
-
-
-int zc0301_probe_pas202bcb(struct zc0301_device* cam)
-{
- int r0 = 0, r1 = 0, err = 0;
- unsigned int pid = 0;
-
- err += zc0301_write_reg(cam, 0x0000, 0x01);
- err += zc0301_write_reg(cam, 0x0010, 0x0e);
- err += zc0301_write_reg(cam, 0x0001, 0x01);
- err += zc0301_write_reg(cam, 0x0012, 0x03);
- err += zc0301_write_reg(cam, 0x0012, 0x01);
- err += zc0301_write_reg(cam, 0x008d, 0x08);
-
- msleep(10);
-
- r0 = zc0301_i2c_read(cam, 0x00, 1);
- r1 = zc0301_i2c_read(cam, 0x01, 1);
-
- if (r0 < 0 || r1 < 0 || err)
- return -EIO;
-
- pid = (r0 << 4) | ((r1 & 0xf0) >> 4);
- if (pid != 0x017)
- return -ENODEV;
-
- zc0301_attach_sensor(cam, &pas202bcb);
-
- return 0;
-}
diff --git a/drivers/media/video/zc0301/zc0301_pb0330.c b/drivers/media/video/zc0301/zc0301_pb0330.c
deleted file mode 100644
index 9519aba3612e..000000000000
--- a/drivers/media/video/zc0301/zc0301_pb0330.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/***************************************************************************
- * Plug-in for PB-0330 image sensor connected to the ZC0301P Image *
- * Processor and Control Chip *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * Initialization values of the ZC0301[P] have been taken from the SPCA5XX *
- * driver maintained by Michel Xhaard <mxhaard@magic.fr> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#include <linux/delay.h>
-#include "zc0301_sensor.h"
-
-
-static struct zc0301_sensor pb0330;
-
-
-static int pb0330_init(struct zc0301_device* cam)
-{
- int err = 0;
-
- err += zc0301_write_reg(cam, 0x0000, 0x01);
- err += zc0301_write_reg(cam, 0x0008, 0x03);
- err += zc0301_write_reg(cam, 0x0010, 0x0A);
- err += zc0301_write_reg(cam, 0x0002, 0x00);
- err += zc0301_write_reg(cam, 0x0003, 0x02);
- err += zc0301_write_reg(cam, 0x0004, 0x80);
- err += zc0301_write_reg(cam, 0x0005, 0x01);
- err += zc0301_write_reg(cam, 0x0006, 0xE0);
- err += zc0301_write_reg(cam, 0x0001, 0x01);
- err += zc0301_write_reg(cam, 0x0012, 0x05);
- err += zc0301_write_reg(cam, 0x0012, 0x07);
- err += zc0301_write_reg(cam, 0x0098, 0x00);
- err += zc0301_write_reg(cam, 0x009A, 0x00);
- err += zc0301_write_reg(cam, 0x011A, 0x00);
- err += zc0301_write_reg(cam, 0x011C, 0x00);
- err += zc0301_write_reg(cam, 0x0012, 0x05);
-
- err += zc0301_i2c_write(cam, 0x01, 0x0006);
- err += zc0301_i2c_write(cam, 0x02, 0x0011);
- err += zc0301_i2c_write(cam, 0x03, 0x01E7);
- err += zc0301_i2c_write(cam, 0x04, 0x0287);
- err += zc0301_i2c_write(cam, 0x06, 0x0003);
- err += zc0301_i2c_write(cam, 0x07, 0x3002);
- err += zc0301_i2c_write(cam, 0x20, 0x1100);
- err += zc0301_i2c_write(cam, 0x2F, 0xF7B0);
- err += zc0301_i2c_write(cam, 0x30, 0x0005);
- err += zc0301_i2c_write(cam, 0x31, 0x0000);
- err += zc0301_i2c_write(cam, 0x34, 0x0100);
- err += zc0301_i2c_write(cam, 0x35, 0x0060);
- err += zc0301_i2c_write(cam, 0x3D, 0x068F);
- err += zc0301_i2c_write(cam, 0x40, 0x01E0);
- err += zc0301_i2c_write(cam, 0x58, 0x0078);
- err += zc0301_i2c_write(cam, 0x62, 0x0411);
-
- err += zc0301_write_reg(cam, 0x0087, 0x10);
- err += zc0301_write_reg(cam, 0x0101, 0x37);
- err += zc0301_write_reg(cam, 0x0012, 0x05);
- err += zc0301_write_reg(cam, 0x0100, 0x0D);
- err += zc0301_write_reg(cam, 0x0189, 0x06);
- err += zc0301_write_reg(cam, 0x01AD, 0x00);
- err += zc0301_write_reg(cam, 0x01C5, 0x03);
- err += zc0301_write_reg(cam, 0x01CB, 0x13);
- err += zc0301_write_reg(cam, 0x0250, 0x08);
- err += zc0301_write_reg(cam, 0x0301, 0x08);
- err += zc0301_write_reg(cam, 0x01A8, 0x60);
- err += zc0301_write_reg(cam, 0x018D, 0x6C);
- err += zc0301_write_reg(cam, 0x01AD, 0x09);
- err += zc0301_write_reg(cam, 0x01AE, 0x15);
- err += zc0301_write_reg(cam, 0x010A, 0x50);
- err += zc0301_write_reg(cam, 0x010B, 0xF8);
- err += zc0301_write_reg(cam, 0x010C, 0xF8);
- err += zc0301_write_reg(cam, 0x010D, 0xF8);
- err += zc0301_write_reg(cam, 0x010E, 0x50);
- err += zc0301_write_reg(cam, 0x010F, 0xF8);
- err += zc0301_write_reg(cam, 0x0110, 0xF8);
- err += zc0301_write_reg(cam, 0x0111, 0xF8);
- err += zc0301_write_reg(cam, 0x0112, 0x50);
- err += zc0301_write_reg(cam, 0x0008, 0x03);
- err += zc0301_write_reg(cam, 0x01C6, 0x08);
- err += zc0301_write_reg(cam, 0x01CB, 0x0F);
- err += zc0301_write_reg(cam, 0x010A, 0x50);
- err += zc0301_write_reg(cam, 0x010B, 0xF8);
- err += zc0301_write_reg(cam, 0x010C, 0xF8);
- err += zc0301_write_reg(cam, 0x010D, 0xF8);
- err += zc0301_write_reg(cam, 0x010E, 0x50);
- err += zc0301_write_reg(cam, 0x010F, 0xF8);
- err += zc0301_write_reg(cam, 0x0110, 0xF8);
- err += zc0301_write_reg(cam, 0x0111, 0xF8);
- err += zc0301_write_reg(cam, 0x0112, 0x50);
- err += zc0301_write_reg(cam, 0x0180, 0x00);
- err += zc0301_write_reg(cam, 0x0019, 0x00);
-
- err += zc0301_i2c_write(cam, 0x05, 0x0066);
- err += zc0301_i2c_write(cam, 0x09, 0x02B2);
- err += zc0301_i2c_write(cam, 0x10, 0x0002);
-
- err += zc0301_write_reg(cam, 0x011D, 0x60);
- err += zc0301_write_reg(cam, 0x0190, 0x00);
- err += zc0301_write_reg(cam, 0x0191, 0x07);
- err += zc0301_write_reg(cam, 0x0192, 0x8C);
- err += zc0301_write_reg(cam, 0x0195, 0x00);
- err += zc0301_write_reg(cam, 0x0196, 0x00);
- err += zc0301_write_reg(cam, 0x0197, 0x8A);
- err += zc0301_write_reg(cam, 0x018C, 0x10);
- err += zc0301_write_reg(cam, 0x018F, 0x20);
- err += zc0301_write_reg(cam, 0x01A9, 0x14);
- err += zc0301_write_reg(cam, 0x01AA, 0x24);
- err += zc0301_write_reg(cam, 0x001D, 0xD7);
- err += zc0301_write_reg(cam, 0x001E, 0xF0);
- err += zc0301_write_reg(cam, 0x001F, 0xF8);
- err += zc0301_write_reg(cam, 0x0020, 0xFF);
- err += zc0301_write_reg(cam, 0x01AD, 0x09);
- err += zc0301_write_reg(cam, 0x01AE, 0x15);
- err += zc0301_write_reg(cam, 0x0180, 0x40);
- err += zc0301_write_reg(cam, 0x0180, 0x42);
-
- msleep(100);
-
- return err;
-}
-
-
-static struct zc0301_sensor pb0330 = {
- .name = "PB-0330",
- .init = &pb0330_init,
- .cropcap = {
- .bounds = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- .defrect = {
- .left = 0,
- .top = 0,
- .width = 640,
- .height = 480,
- },
- },
- .pix_format = {
- .width = 640,
- .height = 480,
- .pixelformat = V4L2_PIX_FMT_JPEG,
- .priv = 8,
- .colorspace = V4L2_COLORSPACE_JPEG,
- },
-};
-
-
-int zc0301_probe_pb0330(struct zc0301_device* cam)
-{
- int r0, err = 0;
-
- err += zc0301_write_reg(cam, 0x0000, 0x01);
- err += zc0301_write_reg(cam, 0x0010, 0x0a);
- err += zc0301_write_reg(cam, 0x0001, 0x01);
- err += zc0301_write_reg(cam, 0x0012, 0x03);
- err += zc0301_write_reg(cam, 0x0012, 0x01);
-
- msleep(10);
-
- r0 = zc0301_i2c_read(cam, 0x00, 2);
-
- if (r0 < 0 || err)
- return -EIO;
-
- if (r0 != 0x8243)
- return -ENODEV;
-
- zc0301_attach_sensor(cam, &pb0330);
-
- return 0;
-}
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
deleted file mode 100644
index 0be783c203f7..000000000000
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/***************************************************************************
- * API for image sensors connected to the ZC0301[P] Image Processor and *
- * Control Chip *
- * *
- * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
- ***************************************************************************/
-
-#ifndef _ZC0301_SENSOR_H_
-#define _ZC0301_SENSOR_H_
-
-#include <linux/usb.h>
-#include <linux/videodev2.h>
-#include <linux/device.h>
-#include <linux/stddef.h>
-#include <linux/errno.h>
-#include <asm/types.h>
-
-struct zc0301_device;
-struct zc0301_sensor;
-
-/*****************************************************************************/
-
-extern int zc0301_probe_pas202bcb(struct zc0301_device* cam);
-extern int zc0301_probe_pb0330(struct zc0301_device* cam);
-
-#define ZC0301_SENSOR_TABLE \
-/* Weak detections must go at the end of the list */ \
-static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
- &zc0301_probe_pas202bcb, \
- &zc0301_probe_pb0330, \
- NULL, \
-};
-
-extern struct zc0301_device*
-zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id);
-
-extern void
-zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
-
-#define ZC0301_USB_DEVICE(vend, prod, intclass) \
- .match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
- USB_DEVICE_ID_MATCH_INT_CLASS, \
- .idVendor = (vend), \
- .idProduct = (prod), \
- .bInterfaceClass = (intclass)
-
-#if !defined CONFIG_USB_GSPCA_ZC3XX && !defined CONFIG_USB_GSPCA_ZC3XX_MODULE
-#define ZC0301_ID_TABLE \
-static const struct usb_device_id zc0301_id_table[] = { \
- { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
- { ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
- { } \
-};
-#else
-#define ZC0301_ID_TABLE \
-static const struct usb_device_id zc0301_id_table[] = { \
- { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
- { } \
-};
-#endif
-
-/*****************************************************************************/
-
-extern int zc0301_write_reg(struct zc0301_device*, u16 index, u16 value);
-extern int zc0301_read_reg(struct zc0301_device*, u16 index);
-extern int zc0301_i2c_write(struct zc0301_device*, u16 address, u16 value);
-extern int zc0301_i2c_read(struct zc0301_device*, u16 address, u8 length);
-
-/*****************************************************************************/
-
-#define ZC0301_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-#define ZC0301_V4L2_CID_DAC_MAGNITUDE (V4L2_CID_PRIVATE_BASE + 0)
-#define ZC0301_V4L2_CID_GREEN_BALANCE (V4L2_CID_PRIVATE_BASE + 1)
-
-struct zc0301_sensor {
- char name[32];
-
- struct v4l2_queryctrl qctrl[ZC0301_MAX_CTRLS];
- struct v4l2_cropcap cropcap;
- struct v4l2_pix_format pix_format;
-
- int (*init)(struct zc0301_device*);
- int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl);
- int (*set_ctrl)(struct zc0301_device*,
- const struct v4l2_control* ctrl);
- int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect);
-
- /* Private */
- struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
- struct v4l2_rect _rect;
-};
-
-#endif /* _ZC0301_SENSOR_H_ */
diff --git a/drivers/media/video/zoran/videocodec.c b/drivers/media/video/zoran/videocodec.c
index cf24956f3204..c01071635290 100644
--- a/drivers/media/video/zoran/videocodec.c
+++ b/drivers/media/video/zoran/videocodec.c
@@ -107,15 +107,14 @@ videocodec_attach (struct videocodec_master *master)
if (!try_module_get(h->codec->owner))
return NULL;
- codec =
- kmalloc(sizeof(struct videocodec), GFP_KERNEL);
+ codec = kmemdup(h->codec, sizeof(struct videocodec),
+ GFP_KERNEL);
if (!codec) {
dprintk(1,
KERN_ERR
"videocodec_attach: no mem\n");
goto out_module_put;
}
- memcpy(codec, h->codec, sizeof(struct videocodec));
snprintf(codec->name, sizeof(codec->name),
"%s[%d]", codec->name, h->attached);
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 24e09454e522..57e00cffb26b 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1057,22 +1057,6 @@ msmsdcc_init_dma(struct msmsdcc_host *host)
return 0;
}
-#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ
-static void
-do_resume_work(struct work_struct *work)
-{
- struct msmsdcc_host *host =
- container_of(work, struct msmsdcc_host, resume_task);
- struct mmc_host *mmc = host->mmc;
-
- if (mmc) {
- mmc_resume_host(mmc);
- if (host->stat_irq)
- enable_irq(host->stat_irq);
- }
-}
-#endif
-
static int
msmsdcc_probe(struct platform_device *pdev)
{
@@ -1314,6 +1298,24 @@ msmsdcc_probe(struct platform_device *pdev)
return ret;
}
+#ifdef CONFIG_PM
+#ifdef CONFIG_MMC_MSM7X00A_RESUME_IN_WQ
+static void
+do_resume_work(struct work_struct *work)
+{
+ struct msmsdcc_host *host =
+ container_of(work, struct msmsdcc_host, resume_task);
+ struct mmc_host *mmc = host->mmc;
+
+ if (mmc) {
+ mmc_resume_host(mmc);
+ if (host->stat_irq)
+ enable_irq(host->stat_irq);
+ }
+}
+#endif
+
+
static int
msmsdcc_suspend(struct platform_device *dev, pm_message_t state)
{
@@ -1358,6 +1360,10 @@ msmsdcc_resume(struct platform_device *dev)
}
return 0;
}
+#else
+#define msmsdcc_suspend 0
+#define msmsdcc_resume 0
+#endif
static struct platform_driver msmsdcc_driver = {
.probe = msmsdcc_probe,
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index d9d4a72e0ec7..fdf33e837a73 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -119,6 +119,7 @@ struct mxcmci_host {
int detect_irq;
int dma;
int do_dma;
+ int default_irq_mask;
int use_sdio;
unsigned int power_mode;
struct imxmmc_platform_data *pdata;
@@ -228,7 +229,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
unsigned int cmdat)
{
- u32 int_cntr;
+ u32 int_cntr = host->default_irq_mask;
unsigned long flags;
WARN_ON(host->cmd != NULL);
@@ -275,7 +276,7 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
static void mxcmci_finish_request(struct mxcmci_host *host,
struct mmc_request *req)
{
- u32 int_cntr = 0;
+ u32 int_cntr = host->default_irq_mask;
unsigned long flags;
spin_lock_irqsave(&host->lock, flags);
@@ -585,6 +586,9 @@ static irqreturn_t mxcmci_irq(int irq, void *devid)
(stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
mxcmci_data_done(host, stat);
#endif
+ if (host->default_irq_mask &&
+ (stat & (STATUS_CARD_INSERTION | STATUS_CARD_REMOVAL)))
+ mmc_detect_change(host->mmc, msecs_to_jiffies(200));
return IRQ_HANDLED;
}
@@ -809,6 +813,12 @@ static int mxcmci_probe(struct platform_device *pdev)
else
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ if (host->pdata && host->pdata->dat3_card_detect)
+ host->default_irq_mask =
+ INT_CARD_INSERTION_EN | INT_CARD_REMOVAL_EN;
+ else
+ host->default_irq_mask = 0;
+
host->res = r;
host->irq = irq;
@@ -835,7 +845,7 @@ static int mxcmci_probe(struct platform_device *pdev)
/* recommended in data sheet */
writew(0x2db4, host->base + MMC_REG_READ_TO);
- writel(0, host->base + MMC_REG_INT_CNTR);
+ writel(host->default_irq_mask, host->base + MMC_REG_INT_CNTR);
#ifdef HAS_DMA
host->dma = imx_dma_request_by_prio(DRIVER_NAME, DMA_PRIO_LOW);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 82e94389824e..0d76b169482f 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -623,8 +623,7 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
else
host->buf_start = column + mtd->writesize;
- if (mtd->writesize > 512)
- command = NAND_CMD_READ0; /* only READ0 is valid */
+ command = NAND_CMD_READ0; /* only READ0 is valid */
send_cmd(host, command, false);
mxc_do_addr_cycle(mtd, column, page_addr);
@@ -639,31 +638,11 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
break;
case NAND_CMD_SEQIN:
- if (column >= mtd->writesize) {
- /*
- * FIXME: before send SEQIN command for write OOB,
- * We must read one page out.
- * For K9F1GXX has no READ1 command to set current HW
- * pointer to spare area, we must write the whole page
- * including OOB together.
- */
- if (mtd->writesize > 512)
- /* call ourself to read a page */
- mxc_nand_command(mtd, NAND_CMD_READ0, 0,
- page_addr);
-
- host->buf_start = column;
-
- /* Set program pointer to spare region */
- if (mtd->writesize == 512)
- send_cmd(host, NAND_CMD_READOOB, false);
- } else {
- host->buf_start = column;
+ if (column >= mtd->writesize)
+ /* call ourself to read a page */
+ mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr);
- /* Set program pointer to page start */
- if (mtd->writesize == 512)
- send_cmd(host, NAND_CMD_READ0, false);
- }
+ host->buf_start = column;
send_cmd(host, command, false);
mxc_do_addr_cycle(mtd, column, page_addr);
@@ -853,6 +832,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
parse_mtd_partitions(mtd, part_probes, &host->parts, 0);
if (nr_parts > 0)
add_mtd_partitions(mtd, host->parts, nr_parts);
+ else if (pdata->parts)
+ add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
else
#endif
{
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 57a7e41da69e..4afc8dd9b935 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5721,11 +5721,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
e1000_print_device_info(adapter);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- }
- pm_schedule_suspend(&pdev->dev, MSEC_PER_SEC);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_put_noidle(&pdev->dev);
return 0;
@@ -5771,8 +5768,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
bool down = test_bit(__E1000_DOWN, &adapter->state);
- pm_runtime_get_sync(&pdev->dev);
-
/*
* flush_scheduled work may reschedule our watchdog task, so
* explicitly disable watchdog tasks from being rescheduled
@@ -5797,11 +5792,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
clear_bit(__E1000_DOWN, &adapter->state);
unregister_netdev(netdev);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- }
- pm_runtime_put_noidle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_get_noresume(&pdev->dev);
/*
* Release control of h/w to f/w. If f/w is AMT enabled, this
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 5b3dfb4ab279..33525bf2a3d3 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -1168,6 +1168,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
int interrupts, nr_serviced = 0, i;
struct ei_device *ei_local;
int handled = 0;
+ unsigned long flags;
e8390_base = dev->base_addr;
ei_local = netdev_priv(dev);
@@ -1176,7 +1177,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
* Protect the irq test too.
*/
- spin_lock(&ei_local->page_lock);
+ spin_lock_irqsave(&ei_local->page_lock, flags);
if (ei_local->irqlock)
{
@@ -1188,7 +1189,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
dev->name, inb_p(e8390_base + EN0_ISR),
inb_p(e8390_base + EN0_IMR));
#endif
- spin_unlock(&ei_local->page_lock);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_NONE;
}
@@ -1261,7 +1262,7 @@ static irqreturn_t ax_interrupt(int irq, void *dev_id)
ei_local->irqlock = 0;
outb_p(ENISR_ALL, e8390_base + EN0_IMR);
- spin_unlock(&ei_local->page_lock);
+ spin_unlock_irqrestore(&ei_local->page_lock, flags);
return IRQ_RETVAL(handled);
}
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 96b6cfbf0a3a..c982a4763bef 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1316,7 +1316,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
/* 8168C family. */
- { 0x7cf00000, 0x3ca00000, RTL_GIGA_MAC_VER_24 },
+ { 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
{ 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 },
{ 0x7cf00000, 0x3c800000, RTL_GIGA_MAC_VER_18 },
{ 0x7c800000, 0x3c800000, RTL_GIGA_MAC_VER_24 },
@@ -3219,11 +3219,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- }
- pm_runtime_idle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_put_noidle(&pdev->dev);
out:
return rc;
@@ -3246,17 +3243,12 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- pm_runtime_get_sync(&pdev->dev);
-
flush_scheduled_work();
unregister_netdev(dev);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- }
- pm_runtime_put_noidle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_get_noresume(&pdev->dev);
/* restore original MAC address */
rtl_rar_set(tp, dev->perm_addr);
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 77b359162d6c..23c15aa9fbd5 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -730,13 +730,17 @@ static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
/* RX */
if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0)
- goto err;
+ goto err_rx;
/* Register Read */
if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
- goto err;
+ goto err_reg;
return 0;
+err_reg:
+ ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
+err_rx:
+ ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
err:
return -ENOMEM;
}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index d24dc7dc0723..972a9c3af39e 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -330,6 +330,7 @@ static int prism2_pci_probe(struct pci_dev *pdev,
dev->irq = pdev->irq;
hw_priv->mem_start = mem;
+ dev->base_addr = (unsigned long) mem;
prism2_pci_cor_sreset(local);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index c2a453a1a991..dc43ebd1f1fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -97,6 +97,17 @@ static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
spin_lock_irqsave(&priv->sta_lock, flags);
memset(priv->stations, 0, sizeof(priv->stations));
priv->num_stations = 0;
+
+ /*
+ * Remove all key information that is not stored as part of station
+ * information since mac80211 may not have had a
+ * chance to remove all the keys. When device is reconfigured by
+ * mac80211 after an error all keys will be reconfigured.
+ */
+ priv->ucode_key_table = 0;
+ priv->key_mapping_key = 0;
+ memset(priv->wep_keys, 0, sizeof(priv->wep_keys));
+
spin_unlock_irqrestore(&priv->sta_lock, flags);
}
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 628ea20a8841..7f0af0e9b826 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -56,7 +56,7 @@ void pci_bus_remove_resources(struct pci_bus *bus)
int i;
for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++)
- bus->resource[i] = 0;
+ bus->resource[i] = NULL;
list_for_each_entry_safe(bus_res, tmp, &bus->resources, list) {
list_del(&bus_res->list);
@@ -240,6 +240,8 @@ void pci_enable_bridges(struct pci_bus *bus)
if (dev->subordinate) {
if (!pci_is_enabled(dev)) {
retval = pci_enable_device(dev);
+ if (retval)
+ dev_err(&dev->dev, "Error enabling bridge (%d), continuing\n", retval);
pci_set_master(dev);
}
pci_enable_bridges(dev->subordinate);
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c
index 2fce726758d2..a4031dfe938e 100644
--- a/drivers/pci/hotplug/pciehp_pci.c
+++ b/drivers/pci/hotplug/pciehp_pci.c
@@ -137,7 +137,7 @@ int pciehp_unconfigure_device(struct slot *p_slot)
"Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
- rc = EINVAL;
+ rc = -EINVAL;
break;
}
}
diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c
index 5f5e8d2e3552..d3985e7deab7 100644
--- a/drivers/pci/hotplug/shpchp_hpc.c
+++ b/drivers/pci/hotplug/shpchp_hpc.c
@@ -113,7 +113,7 @@
#define CON_PFAULT_INTR_MASK (1 << 28)
#define MRL_CHANGE_SERR_MASK (1 << 29)
#define CON_PFAULT_SERR_MASK (1 << 30)
-#define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21)
+#define SLOT_REG_RSVDZ_MASK ((1 << 15) | (7 << 21))
/*
* SHPC Command Code definitnions
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 8c3d3219f227..a2ccfcd3c298 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -60,12 +60,6 @@ int __ref shpchp_configure_device(struct slot *p_slot)
dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
if (!dev)
continue;
- if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
- ctrl_err(ctrl, "Cannot hot-add display device %s\n",
- pci_name(dev));
- pci_dev_put(dev);
- continue;
- }
if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
/* Find an unused bus number for the new bridge */
@@ -114,17 +108,11 @@ int shpchp_unconfigure_device(struct slot *p_slot)
ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n",
__func__, pci_domain_nr(parent), p_slot->bus, p_slot->device);
- for (j=0; j<8 ; j++) {
- struct pci_dev* temp = pci_get_slot(parent,
+ for (j = 0; j < 8 ; j++) {
+ struct pci_dev *temp = pci_get_slot(parent,
(p_slot->device << 3) | j);
if (!temp)
continue;
- if ((temp->class >> 16) == PCI_BASE_CLASS_DISPLAY) {
- ctrl_err(ctrl, "Cannot remove display device %s\n",
- pci_name(temp));
- pci_dev_put(temp);
- continue;
- }
if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl);
if (bctl & PCI_BRIDGE_CTL_VGA) {
@@ -132,7 +120,8 @@ int shpchp_unconfigure_device(struct slot *p_slot)
"Cannot remove display device %s\n",
pci_name(temp));
pci_dev_put(temp);
- continue;
+ rc = -EINVAL;
+ break;
}
}
pci_remove_bus_device(temp);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 77b68eaf021e..4c14f31f2b4d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -196,30 +196,15 @@ void unmask_msi_irq(unsigned int irq)
void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- if (entry->msi_attrib.is_msix) {
- void __iomem *base = entry->mask_base +
- entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
- msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR);
- msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
- msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
- } else {
- struct pci_dev *dev = entry->dev;
- int pos = entry->msi_attrib.pos;
- u16 data;
+ /* We do not touch the hardware (which may not even be
+ * accessible at the moment) but return the last message
+ * written. Assert that this is valid, assuming that
+ * valid messages are not all-zeroes. */
+ BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo |
+ entry->msg.data));
- pci_read_config_dword(dev, msi_lower_address_reg(pos),
- &msg->address_lo);
- if (entry->msi_attrib.is_64) {
- pci_read_config_dword(dev, msi_upper_address_reg(pos),
- &msg->address_hi);
- pci_read_config_word(dev, msi_data_reg(pos, 1), &data);
- } else {
- msg->address_hi = 0;
- pci_read_config_word(dev, msi_data_reg(pos, 0), &data);
- }
- msg->data = data;
- }
+ *msg = entry->msg;
}
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
@@ -232,7 +217,10 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- if (entry->msi_attrib.is_msix) {
+
+ if (entry->dev->current_state != PCI_D0) {
+ /* Don't touch the hardware now */
+ } else if (entry->msi_attrib.is_msix) {
void __iomem *base;
base = entry->mask_base +
entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
@@ -435,7 +423,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
static void __iomem *msix_map_region(struct pci_dev *dev, unsigned pos,
unsigned nr_entries)
{
- unsigned long phys_addr;
+ resource_size_t phys_addr;
u32 table_offset;
u8 bir;
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index f9a0aec3abcf..8a6f797de8e5 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -289,8 +289,26 @@ struct drv_dev_and_id {
static long local_pci_probe(void *_ddi)
{
struct drv_dev_and_id *ddi = _ddi;
-
- return ddi->drv->probe(ddi->dev, ddi->id);
+ struct device *dev = &ddi->dev->dev;
+ int rc;
+
+ /* Unbound PCI devices are always set to disabled and suspended.
+ * During probe, the device is set to enabled and active and the
+ * usage count is incremented. If the driver supports runtime PM,
+ * it should call pm_runtime_put_noidle() in its probe routine and
+ * pm_runtime_get_noresume() in its remove routine.
+ */
+ pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev);
+ pm_runtime_enable(dev);
+
+ rc = ddi->drv->probe(ddi->dev, ddi->id);
+ if (rc) {
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+ }
+ return rc;
}
static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
@@ -369,11 +387,19 @@ static int pci_device_remove(struct device * dev)
struct pci_driver * drv = pci_dev->driver;
if (drv) {
- if (drv->remove)
+ if (drv->remove) {
+ pm_runtime_get_sync(dev);
drv->remove(pci_dev);
+ pm_runtime_put_noidle(dev);
+ }
pci_dev->driver = NULL;
}
+ /* Undo the runtime PM settings in local_pci_probe() */
+ pm_runtime_disable(dev);
+ pm_runtime_set_suspended(dev);
+ pm_runtime_put_noidle(dev);
+
/*
* If the device is still on, set the power state as "unknown",
* since it might change by the next time we load the driver.
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c9957f68ac9b..5935b854917f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -734,7 +734,7 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr,
{
struct pci_dev *pdev = to_pci_dev(container_of(kobj,
struct device, kobj));
- struct resource *res = (struct resource *)attr->private;
+ struct resource *res = attr->private;
enum pci_mmap_state mmap_type;
resource_size_t start, end;
int i;
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index b8b494b3e0d0..dda70981b7a6 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -31,14 +31,22 @@ source "drivers/pci/pcie/aer/Kconfig"
# PCI Express ASPM
#
config PCIEASPM
- bool "PCI Express ASPM support(Experimental)"
- depends on PCI && EXPERIMENTAL && PCIEPORTBUS
- default n
+ bool "PCI Express ASPM control" if EMBEDDED
+ depends on PCI && PCIEPORTBUS
+ default y
help
- This enables PCI Express ASPM (Active State Power Management) and
- Clock Power Management. ASPM supports state L0/L0s/L1.
+ This enables OS control over PCI Express ASPM (Active State
+ Power Management) and Clock Power Management. ASPM supports
+ state L0/L0s/L1.
- When in doubt, say N.
+ ASPM is initially set up the the firmware. With this option enabled,
+ Linux can modify this state in order to disable ASPM on known-bad
+ hardware or configurations and enable it when known-safe.
+
+ ASPM can be disabled or enabled at runtime via
+ /sys/module/pcie_aspm/parameters/policy
+
+ When in doubt, say Y.
config PCIEASPM_DEBUG
bool "Debug PCI Express ASPM"
depends on PCIEASPM
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 8af4f619bba2..fc0b5a93e1de 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -727,20 +727,21 @@ static void aer_isr_one_error(struct pcie_device *p_device,
static int get_e_source(struct aer_rpc *rpc, struct aer_err_source *e_src)
{
unsigned long flags;
- int ret = 0;
/* Lock access to Root error producer/consumer index */
spin_lock_irqsave(&rpc->e_lock, flags);
- if (rpc->prod_idx != rpc->cons_idx) {
- *e_src = rpc->e_sources[rpc->cons_idx];
- rpc->cons_idx++;
- if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
- rpc->cons_idx = 0;
- ret = 1;
+ if (rpc->prod_idx == rpc->cons_idx) {
+ spin_unlock_irqrestore(&rpc->e_lock, flags);
+ return 0;
}
+
+ *e_src = rpc->e_sources[rpc->cons_idx];
+ rpc->cons_idx++;
+ if (rpc->cons_idx == AER_ERROR_SOURCES_MAX)
+ rpc->cons_idx = 0;
spin_unlock_irqrestore(&rpc->e_lock, flags);
- return ret;
+ return 1;
}
/**
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index be53d98fa384..71222814c1ec 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -588,11 +588,23 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev)
* update through pcie_aspm_cap_init().
*/
pcie_aspm_cap_init(link, blacklist);
- pcie_config_aspm_path(link);
/* Setup initial Clock PM state */
pcie_clkpm_cap_init(link, blacklist);
- pcie_set_clkpm(link, policy_to_clkpm_state(link));
+
+ /*
+ * At this stage drivers haven't had an opportunity to change the
+ * link policy setting. Enabling ASPM on broken hardware can cripple
+ * it even before the driver has had a chance to disable ASPM, so
+ * default to a safe level right now. If we're enabling ASPM beyond
+ * the BIOS's expectation, we'll do so once pci_enable_device() is
+ * called.
+ */
+ if (aspm_policy != POLICY_POWERSAVE) {
+ pcie_config_aspm_path(link);
+ pcie_set_clkpm(link, policy_to_clkpm_state(link));
+ }
+
unlock:
mutex_unlock(&aspm_lock);
out:
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 449e890267a2..68316b59d7d3 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -431,8 +431,6 @@ int pci_proc_detach_device(struct pci_dev *dev)
struct proc_dir_entry *e;
if ((e = dev->procent)) {
- if (atomic_read(&e->count) > 1)
- return -EBUSY;
remove_proc_entry(e->name, dev->bus->procdir);
dev->procent = NULL;
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 477345d41641..3a81d9d44019 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2115,6 +2115,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disabl
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3336, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3364, quirk_disable_all_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8380_0, quirk_disable_all_msi);
/* Disable MSI on chipsets that are known to not support it */
static void __devinit quirk_disable_msi(struct pci_dev *dev)
@@ -2126,12 +2127,29 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9602, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ASUSTEK, 0x9602, quirk_disable_msi);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AI, 0x9602, quirk_disable_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, 0xa238, quirk_disable_msi);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, 0x5a3f, quirk_disable_msi);
+/*
+ * The APC bridge device in AMD 780 family northbridges has some random
+ * OEM subsystem ID in its vendor ID register (erratum 18), so instead
+ * we use the possible vendor/device IDs of the host bridge for the
+ * declared quirk, and search for the APC bridge by slot number.
+ */
+static void __devinit quirk_amd_780_apc_msi(struct pci_dev *host_bridge)
+{
+ struct pci_dev *apc_bridge;
+
+ apc_bridge = pci_get_slot(host_bridge->bus, PCI_DEVFN(1, 0));
+ if (apc_bridge) {
+ if (apc_bridge->device == 0x9602)
+ quirk_disable_msi(apc_bridge);
+ pci_dev_put(apc_bridge);
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9600, quirk_amd_780_apc_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, 0x9601, quirk_amd_780_apc_msi);
+
/* Go through the list of Hypertransport capabilities and
* return 1 if a HT MSI capability is found and enabled */
static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 19b111383f62..66cb8f4cc5f4 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -874,19 +874,16 @@ void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
again:
pci_bus_size_bridges(parent);
__pci_bridge_assign_resources(bridge, &head);
- retval = pci_reenable_device(bridge);
- pci_set_master(bridge);
- pci_enable_bridges(parent);
tried_times++;
if (!head.next)
- return;
+ goto enable_all;
if (tried_times >= 2) {
/* still fail, don't need to try more */
free_failed_list(&head);
- return;
+ goto enable_all;
}
printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
@@ -919,5 +916,10 @@ again:
free_failed_list(&head);
goto again;
+
+enable_all:
+ retval = pci_reenable_device(bridge);
+ pci_set_master(bridge);
+ pci_enable_bridges(parent);
}
EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources);
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 34d51dd4c539..bed7b4634ccd 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -948,8 +948,10 @@ static ssize_t dasd_alias_show(struct device *dev,
if (device->discipline && device->discipline->get_uid &&
!device->discipline->get_uid(device, &uid)) {
if (uid.type == UA_BASE_PAV_ALIAS ||
- uid.type == UA_HYPER_PAV_ALIAS)
+ uid.type == UA_HYPER_PAV_ALIAS) {
+ dasd_put_device(device);
return sprintf(buf, "1\n");
+ }
}
dasd_put_device(device);
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c
index 7f206ed44fdf..fd0368785ee0 100644
--- a/drivers/s390/cio/ccwreq.c
+++ b/drivers/s390/cio/ccwreq.c
@@ -182,6 +182,8 @@ static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb)
/* Ask the driver what to do */
if (cdev->drv && cdev->drv->uc_handler) {
todo = cdev->drv->uc_handler(cdev, lcirb);
+ CIO_TRACE_EVENT(2, "uc_response");
+ CIO_HEX_EVENT(2, &todo, sizeof(todo));
switch (todo) {
case UC_TODO_RETRY:
return IO_STATUS_ERROR;
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index ce7cb87479fe..5e4830d1d9d7 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -29,6 +29,7 @@
#include "chsc.h"
static void *sei_page;
+static DEFINE_SPINLOCK(siosl_lock);
static DEFINE_SPINLOCK(sda_lock);
/**
@@ -48,6 +49,7 @@ int chsc_error_from_response(int response)
case 0x0007:
case 0x0008:
case 0x000a:
+ case 0x0104:
return -EINVAL;
case 0x0004:
return -EOPNOTSUPP;
@@ -713,7 +715,7 @@ int chsc_determine_base_channel_path_desc(struct chp_id chpid,
ret = chsc_determine_channel_path_desc(chpid, 0, 0, 0, 0, chsc_resp);
if (ret)
goto out_free;
- memcpy(desc, &chsc_resp->data, chsc_resp->length);
+ memcpy(desc, &chsc_resp->data, sizeof(*desc));
out_free:
kfree(chsc_resp);
return ret;
@@ -974,3 +976,50 @@ int chsc_sstpi(void *page, void *result, size_t size)
return (rr->response.code == 0x0001) ? 0 : -EIO;
}
+static struct {
+ struct chsc_header request;
+ u32 word1;
+ struct subchannel_id sid;
+ u32 word3;
+ struct chsc_header response;
+ u32 word[11];
+} __attribute__ ((packed)) siosl_area __attribute__ ((__aligned__(PAGE_SIZE)));
+
+int chsc_siosl(struct subchannel_id schid)
+{
+ unsigned long flags;
+ int ccode;
+ int rc;
+
+ spin_lock_irqsave(&siosl_lock, flags);
+ memset(&siosl_area, 0, sizeof(siosl_area));
+ siosl_area.request.length = 0x0010;
+ siosl_area.request.code = 0x0046;
+ siosl_area.word1 = 0x80000000;
+ siosl_area.sid = schid;
+
+ ccode = chsc(&siosl_area);
+ if (ccode > 0) {
+ if (ccode == 3)
+ rc = -ENODEV;
+ else
+ rc = -EBUSY;
+ CIO_MSG_EVENT(2, "chsc: chsc failed for 0.%x.%04x (ccode=%d)\n",
+ schid.ssid, schid.sch_no, ccode);
+ goto out;
+ }
+ rc = chsc_error_from_response(siosl_area.response.code);
+ if (rc)
+ CIO_MSG_EVENT(2, "chsc: siosl failed for 0.%x.%04x (rc=%04x)\n",
+ schid.ssid, schid.sch_no,
+ siosl_area.response.code);
+ else
+ CIO_MSG_EVENT(4, "chsc: siosl succeeded for 0.%x.%04x\n",
+ schid.ssid, schid.sch_no);
+out:
+ spin_unlock_irqrestore(&siosl_lock, flags);
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(chsc_siosl);
+
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index 37aa611d4ac5..5453013f094b 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -80,4 +80,6 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp);
int chsc_error_from_response(int response);
+int chsc_siosl(struct subchannel_id schid);
+
#endif
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 6d229f3523a0..51bd3687d163 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -36,6 +36,7 @@
#include "ioasm.h"
#include "io_sch.h"
#include "blacklist.h"
+#include "chsc.h"
static struct timer_list recovery_timer;
static DEFINE_SPINLOCK(recovery_lock);
@@ -486,9 +487,11 @@ static int online_store_handle_offline(struct ccw_device *cdev)
spin_lock_irq(cdev->ccwlock);
ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL);
spin_unlock_irq(cdev->ccwlock);
- } else if (cdev->online && cdev->drv && cdev->drv->set_offline)
+ return 0;
+ }
+ if (cdev->drv && cdev->drv->set_offline)
return ccw_device_set_offline(cdev);
- return 0;
+ return -EINVAL;
}
static int online_store_recog_and_online(struct ccw_device *cdev)
@@ -505,8 +508,8 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
return -EAGAIN;
}
if (cdev->drv && cdev->drv->set_online)
- ccw_device_set_online(cdev);
- return 0;
+ return ccw_device_set_online(cdev);
+ return -EINVAL;
}
static int online_store_handle_online(struct ccw_device *cdev, int force)
@@ -598,6 +601,25 @@ available_show (struct device *dev, struct device_attribute *attr, char *buf)
}
}
+static ssize_t
+initiate_logging(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct subchannel *sch = to_subchannel(dev);
+ int rc;
+
+ rc = chsc_siosl(sch->schid);
+ if (rc < 0) {
+ pr_warning("Logging for subchannel 0.%x.%04x failed with "
+ "errno=%d\n",
+ sch->schid.ssid, sch->schid.sch_no, rc);
+ return rc;
+ }
+ pr_notice("Logging for subchannel 0.%x.%04x was triggered\n",
+ sch->schid.ssid, sch->schid.sch_no);
+ return count;
+}
+
static DEVICE_ATTR(chpids, 0444, chpids_show, NULL);
static DEVICE_ATTR(pimpampom, 0444, pimpampom_show, NULL);
static DEVICE_ATTR(devtype, 0444, devtype_show, NULL);
@@ -605,10 +627,12 @@ static DEVICE_ATTR(cutype, 0444, cutype_show, NULL);
static DEVICE_ATTR(modalias, 0444, modalias_show, NULL);
static DEVICE_ATTR(online, 0644, online_show, online_store);
static DEVICE_ATTR(availability, 0444, available_show, NULL);
+static DEVICE_ATTR(logging, 0200, NULL, initiate_logging);
static struct attribute *io_subchannel_attrs[] = {
&dev_attr_chpids.attr,
&dev_attr_pimpampom.attr,
+ &dev_attr_logging.attr,
NULL,
};
@@ -2036,6 +2060,21 @@ void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo)
}
}
+/**
+ * ccw_device_siosl() - initiate logging
+ * @cdev: ccw device
+ *
+ * This function is used to invoke model-dependent logging within the channel
+ * subsystem.
+ */
+int ccw_device_siosl(struct ccw_device *cdev)
+{
+ struct subchannel *sch = to_subchannel(cdev->dev.parent);
+
+ return chsc_siosl(sch->schid);
+}
+EXPORT_SYMBOL_GPL(ccw_device_siosl);
+
MODULE_LICENSE("GPL");
EXPORT_SYMBOL(ccw_device_set_online);
EXPORT_SYMBOL(ccw_device_set_offline);
diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c
index 137688790207..4d2ea4000422 100644
--- a/drivers/s390/net/smsgiucv_app.c
+++ b/drivers/s390/net/smsgiucv_app.c
@@ -180,6 +180,13 @@ static int __init smsgiucv_app_init(void)
goto fail_put_driver;
}
+ /* convert sender to uppercase characters */
+ if (sender) {
+ int len = strlen(sender);
+ while (len--)
+ sender[len] = toupper(sender[len]);
+ }
+
/* register with the smsgiucv device driver */
rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback);
if (rc) {
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 82ea4a8226b0..c5564191732c 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -173,15 +173,15 @@ static const struct ipr_chip_cfg_t ipr_chip_cfg[] = {
};
static const struct ipr_chip_t ipr_chip[] = {
- { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, &ipr_chip_cfg[0] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
- { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, &ipr_chip_cfg[1] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] },
- { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, &ipr_chip_cfg[2] }
+ { PCI_VENDOR_ID_MYLEX, PCI_DEVICE_ID_IBM_GEMSTONE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CITRINE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_OBSIDIAN_E, IPR_USE_MSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[0] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_SNIPE, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] },
+ { PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_SCAMP, IPR_USE_LSI, IPR_SIS32, IPR_PCI_CFG, &ipr_chip_cfg[1] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_FPGA_E2, IPR_USE_MSI, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] },
+ { PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CROC_ASIC_E2, IPR_USE_MSI, IPR_SIS64, IPR_MMIO, &ipr_chip_cfg[2] }
};
static int ipr_max_bus_speeds [] = {
@@ -7423,20 +7423,25 @@ static int ipr_reset_bist_done(struct ipr_cmnd *ipr_cmd)
static int ipr_reset_start_bist(struct ipr_cmnd *ipr_cmd)
{
struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
- int rc;
+ int rc = PCIBIOS_SUCCESSFUL;
ENTER;
pci_block_user_cfg_access(ioa_cfg->pdev);
- rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START);
- if (rc != PCIBIOS_SUCCESSFUL) {
- pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
- ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
- rc = IPR_RC_JOB_CONTINUE;
- } else {
+ if (ioa_cfg->ipr_chip->bist_method == IPR_MMIO)
+ writel(IPR_UPROCI_SIS64_START_BIST,
+ ioa_cfg->regs.set_uproc_interrupt_reg32);
+ else
+ rc = pci_write_config_byte(ioa_cfg->pdev, PCI_BIST, PCI_BIST_START);
+
+ if (rc == PCIBIOS_SUCCESSFUL) {
ipr_cmd->job_step = ipr_reset_bist_done;
ipr_reset_start_timer(ipr_cmd, IPR_WAIT_FOR_BIST_TIMEOUT);
rc = IPR_RC_JOB_RETURN;
+ } else {
+ pci_unblock_user_cfg_access(ipr_cmd->ioa_cfg->pdev);
+ ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR);
+ rc = IPR_RC_JOB_CONTINUE;
}
LEAVE;
diff --git a/drivers/scsi/ipr.h b/drivers/scsi/ipr.h
index 9ecd2259eb39..7e6ec7631bb8 100644
--- a/drivers/scsi/ipr.h
+++ b/drivers/scsi/ipr.h
@@ -272,6 +272,7 @@ IPR_PCII_NO_HOST_RRQ | IPR_PCII_IOARRIN_LOST | IPR_PCII_MMIO_ERROR)
#define IPR_UPROCI_RESET_ALERT (0x80000000 >> 7)
#define IPR_UPROCI_IO_DEBUG_ALERT (0x80000000 >> 9)
+#define IPR_UPROCI_SIS64_START_BIST (0x80000000 >> 23)
#define IPR_LDUMP_MAX_LONG_ACK_DELAY_IN_USEC 200000 /* 200 ms */
#define IPR_LDUMP_MAX_SHORT_ACK_DELAY_IN_USEC 200000 /* 200 ms */
@@ -1296,6 +1297,9 @@ struct ipr_chip_t {
u16 sis_type;
#define IPR_SIS32 0x00
#define IPR_SIS64 0x01
+ u16 bist_method;
+#define IPR_PCI_CFG 0x00
+#define IPR_MMIO 0x01
const struct ipr_chip_cfg_t *cfg;
};
diff --git a/drivers/serial/68328serial.c b/drivers/serial/68328serial.c
index 30463862603b..9330edb323e2 100644
--- a/drivers/serial/68328serial.c
+++ b/drivers/serial/68328serial.c
@@ -78,10 +78,6 @@ struct m68k_serial *m68k_consinfo = 0;
#define M68K_CLOCK (16667000) /* FIXME: 16MHz is likely wrong */
-#ifdef CONFIG_CONSOLE
-extern wait_queue_head_t keypress_wait;
-#endif
-
struct tty_driver *serial_driver;
/* number of characters left in xmit buffer before we ask for more */
@@ -300,10 +296,6 @@ static void receive_chars(struct m68k_serial *info, unsigned short rx)
return;
#endif /* CONFIG_MAGIC_SYSRQ */
}
- /* It is a 'keyboard interrupt' ;-) */
-#ifdef CONFIG_CONSOLE
- wake_up(&keypress_wait);
-#endif
}
if(!tty)
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index eed3c2d8dd1c..a182def7007d 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -41,6 +41,7 @@
#include <linux/uaccess.h>
#include <asm/io.h>
+#include <asm/ioctls.h>
#include <asm/mach/serial_at91.h>
#include <mach/board.h>
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 84a35f699016..1a88b363005c 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -113,7 +113,9 @@ struct psc_ops {
unsigned char (*read_char)(struct uart_port *port);
void (*cw_disable_ints)(struct uart_port *port);
void (*cw_restore_ints)(struct uart_port *port);
- unsigned long (*getuartclk)(void *p);
+ unsigned int (*set_baudrate)(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old);
int (*clock)(struct uart_port *port, int enable);
int (*fifoc_init)(void);
void (*fifoc_uninit)(void);
@@ -121,6 +123,16 @@ struct psc_ops {
irqreturn_t (*handle_irq)(struct uart_port *port);
};
+/* setting the prescaler and divisor reg is common for all chips */
+static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc,
+ u16 prescaler, unsigned int divisor)
+{
+ /* select prescaler */
+ out_be16(&psc->mpc52xx_psc_clock_select, prescaler);
+ out_8(&psc->ctur, divisor >> 8);
+ out_8(&psc->ctlr, divisor & 0xff);
+}
+
#ifdef CONFIG_PPC_MPC52xx
#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
static void mpc52xx_psc_fifo_init(struct uart_port *port)
@@ -128,9 +140,6 @@ static void mpc52xx_psc_fifo_init(struct uart_port *port)
struct mpc52xx_psc __iomem *psc = PSC(port);
struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port);
- /* /32 prescaler */
- out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
-
out_8(&fifo->rfcntl, 0x00);
out_be16(&fifo->rfalarm, 0x1ff);
out_8(&fifo->tfcntl, 0x07);
@@ -219,15 +228,47 @@ static void mpc52xx_psc_cw_restore_ints(struct uart_port *port)
out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
}
-/* Search for bus-frequency property in this node or a parent */
-static unsigned long mpc52xx_getuartclk(void *p)
+static unsigned int mpc5200_psc_set_baudrate(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
{
- /*
- * 5200 UARTs have a / 32 prescaler
- * but the generic serial code assumes 16
- * so return ipb freq / 2
- */
- return mpc5xxx_get_bus_frequency(p) / 2;
+ unsigned int baud;
+ unsigned int divisor;
+
+ /* The 5200 has a fixed /32 prescaler, uartclk contains the ipb freq */
+ baud = uart_get_baud_rate(port, new, old,
+ port->uartclk / (32 * 0xffff) + 1,
+ port->uartclk / 32);
+ divisor = (port->uartclk + 16 * baud) / (32 * baud);
+
+ /* enable the /32 prescaler and set the divisor */
+ mpc52xx_set_divisor(PSC(port), 0xdd00, divisor);
+ return baud;
+}
+
+static unsigned int mpc5200b_psc_set_baudrate(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
+{
+ unsigned int baud;
+ unsigned int divisor;
+ u16 prescaler;
+
+ /* The 5200B has a selectable /4 or /32 prescaler, uartclk contains the
+ * ipb freq */
+ baud = uart_get_baud_rate(port, new, old,
+ port->uartclk / (32 * 0xffff) + 1,
+ port->uartclk / 4);
+ divisor = (port->uartclk + 2 * baud) / (4 * baud);
+
+ /* select the proper prescaler and set the divisor */
+ if (divisor > 0xffff) {
+ divisor = (divisor + 4) / 8;
+ prescaler = 0xdd00; /* /32 */
+ } else
+ prescaler = 0xff00; /* /4 */
+ mpc52xx_set_divisor(PSC(port), prescaler, divisor);
+ return baud;
}
static void mpc52xx_psc_get_irq(struct uart_port *port, struct device_node *np)
@@ -258,7 +299,28 @@ static struct psc_ops mpc52xx_psc_ops = {
.read_char = mpc52xx_psc_read_char,
.cw_disable_ints = mpc52xx_psc_cw_disable_ints,
.cw_restore_ints = mpc52xx_psc_cw_restore_ints,
- .getuartclk = mpc52xx_getuartclk,
+ .set_baudrate = mpc5200_psc_set_baudrate,
+ .get_irq = mpc52xx_psc_get_irq,
+ .handle_irq = mpc52xx_psc_handle_irq,
+};
+
+static struct psc_ops mpc5200b_psc_ops = {
+ .fifo_init = mpc52xx_psc_fifo_init,
+ .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
+ .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy,
+ .rx_rdy = mpc52xx_psc_rx_rdy,
+ .tx_rdy = mpc52xx_psc_tx_rdy,
+ .tx_empty = mpc52xx_psc_tx_empty,
+ .stop_rx = mpc52xx_psc_stop_rx,
+ .start_tx = mpc52xx_psc_start_tx,
+ .stop_tx = mpc52xx_psc_stop_tx,
+ .rx_clr_irq = mpc52xx_psc_rx_clr_irq,
+ .tx_clr_irq = mpc52xx_psc_tx_clr_irq,
+ .write_char = mpc52xx_psc_write_char,
+ .read_char = mpc52xx_psc_read_char,
+ .cw_disable_ints = mpc52xx_psc_cw_disable_ints,
+ .cw_restore_ints = mpc52xx_psc_cw_restore_ints,
+ .set_baudrate = mpc5200b_psc_set_baudrate,
.get_irq = mpc52xx_psc_get_irq,
.handle_irq = mpc52xx_psc_handle_irq,
};
@@ -392,9 +454,35 @@ static void mpc512x_psc_cw_restore_ints(struct uart_port *port)
out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
}
-static unsigned long mpc512x_getuartclk(void *p)
+static unsigned int mpc512x_psc_set_baudrate(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
{
- return mpc5xxx_get_bus_frequency(p);
+ unsigned int baud;
+ unsigned int divisor;
+
+ /*
+ * The "MPC5121e Microcontroller Reference Manual, Rev. 3" says on
+ * pg. 30-10 that the chip supports a /32 and a /10 prescaler.
+ * Furthermore, it states that "After reset, the prescaler by 10
+ * for the UART mode is selected", but the reset register value is
+ * 0x0000 which means a /32 prescaler. This is wrong.
+ *
+ * In reality using /32 prescaler doesn't work, as it is not supported!
+ * Use /16 or /10 prescaler, see "MPC5121e Hardware Design Guide",
+ * Chapter 4.1 PSC in UART Mode.
+ * Calculate with a /16 prescaler here.
+ */
+
+ /* uartclk contains the ips freq */
+ baud = uart_get_baud_rate(port, new, old,
+ port->uartclk / (16 * 0xffff) + 1,
+ port->uartclk / 16);
+ divisor = (port->uartclk + 8 * baud) / (16 * baud);
+
+ /* enable the /16 prescaler and set the divisor */
+ mpc52xx_set_divisor(PSC(port), 0xdd00, divisor);
+ return baud;
}
/* Init PSC FIFO Controller */
@@ -498,7 +586,7 @@ static struct psc_ops mpc512x_psc_ops = {
.read_char = mpc512x_psc_read_char,
.cw_disable_ints = mpc512x_psc_cw_disable_ints,
.cw_restore_ints = mpc512x_psc_cw_restore_ints,
- .getuartclk = mpc512x_getuartclk,
+ .set_baudrate = mpc512x_psc_set_baudrate,
.clock = mpc512x_psc_clock,
.fifoc_init = mpc512x_psc_fifoc_init,
.fifoc_uninit = mpc512x_psc_fifoc_uninit,
@@ -666,8 +754,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
struct mpc52xx_psc __iomem *psc = PSC(port);
unsigned long flags;
unsigned char mr1, mr2;
- unsigned short ctr;
- unsigned int j, baud, quot;
+ unsigned int j;
+ unsigned int baud;
/* Prepare what we're gonna write */
mr1 = 0;
@@ -704,16 +792,9 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
mr2 |= MPC52xx_PSC_MODE_TXCTS;
}
- baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
- ctr = quot & 0xffff;
-
/* Get the lock */
spin_lock_irqsave(&port->lock, flags);
- /* Update the per-port timeout */
- uart_update_timeout(port, new->c_cflag, baud);
-
/* Do our best to flush TX & RX, so we don't lose anything */
/* But we don't wait indefinitely ! */
j = 5000000; /* Maximum wait */
@@ -737,8 +818,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1);
out_8(&psc->mode, mr1);
out_8(&psc->mode, mr2);
- out_8(&psc->ctur, ctr >> 8);
- out_8(&psc->ctlr, ctr & 0xff);
+ baud = psc_ops->set_baudrate(port, new, old);
+
+ /* Update the per-port timeout */
+ uart_update_timeout(port, new->c_cflag, baud);
if (UART_ENABLE_MS(port, new->c_cflag))
mpc52xx_uart_enable_ms(port);
@@ -1118,7 +1201,7 @@ mpc52xx_console_setup(struct console *co, char *options)
return ret;
}
- uartclk = psc_ops->getuartclk(np);
+ uartclk = mpc5xxx_get_bus_frequency(np);
if (uartclk == 0) {
pr_debug("Could not find uart clock frequency!\n");
return -EINVAL;
@@ -1201,6 +1284,7 @@ static struct uart_driver mpc52xx_uart_driver = {
static struct of_device_id mpc52xx_uart_of_match[] = {
#ifdef CONFIG_PPC_MPC52xx
+ { .compatible = "fsl,mpc5200b-psc-uart", .data = &mpc5200b_psc_ops, },
{ .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
/* binding used by old lite5200 device trees: */
{ .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
@@ -1233,7 +1317,10 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
pr_debug("Found %s assigned to ttyPSC%x\n",
mpc52xx_uart_nodes[idx]->full_name, idx);
- uartclk = psc_ops->getuartclk(op->dev.of_node);
+ /* set the uart clock to the input clock of the psc, the different
+ * prescalers are taken into account in the set_baudrate() methods
+ * of the respective chip */
+ uartclk = mpc5xxx_get_bus_frequency(op->dev.of_node);
if (uartclk == 0) {
dev_dbg(&op->dev, "Could not find uart clock frequency!\n");
return -EINVAL;
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 5f90fcd7d107..c291b3add1d2 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -346,6 +346,27 @@ static int scif_rxfill(struct uart_port *port)
return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
}
}
+#elif defined(CONFIG_ARCH_SH7372)
+static int scif_txfill(struct uart_port *port)
+{
+ if (port->type == PORT_SCIFA)
+ return sci_in(port, SCFDR) >> 8;
+ else
+ return sci_in(port, SCTFDR);
+}
+
+static int scif_txroom(struct uart_port *port)
+{
+ return port->fifosize - scif_txfill(port);
+}
+
+static int scif_rxfill(struct uart_port *port)
+{
+ if (port->type == PORT_SCIFA)
+ return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
+ else
+ return sci_in(port, SCRFDR);
+}
#else
static int scif_txfill(struct uart_port *port)
{
@@ -683,7 +704,7 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
u16 ssr = sci_in(port, SCxSR);
/* Disable future Rx interrupts */
- if (port->type == PORT_SCIFA) {
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
disable_irq_nosync(irq);
scr |= 0x4000;
} else {
@@ -928,7 +949,7 @@ static void sci_dma_tx_complete(void *arg)
if (!uart_circ_empty(xmit)) {
schedule_work(&s->work_tx);
- } else if (port->type == PORT_SCIFA) {
+ } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
u16 ctrl = sci_in(port, SCSCR);
sci_out(port, SCSCR, ctrl & ~SCI_CTRL_FLAGS_TIE);
}
@@ -1184,7 +1205,7 @@ static void sci_start_tx(struct uart_port *port)
unsigned short ctrl;
#ifdef CONFIG_SERIAL_SH_SCI_DMA
- if (port->type == PORT_SCIFA) {
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
u16 new, scr = sci_in(port, SCSCR);
if (s->chan_tx)
new = scr | 0x8000;
@@ -1197,7 +1218,7 @@ static void sci_start_tx(struct uart_port *port)
s->cookie_tx < 0)
schedule_work(&s->work_tx);
#endif
- if (!s->chan_tx || port->type == PORT_SCIFA) {
+ if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
/* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
sci_out(port, SCSCR, ctrl | SCI_CTRL_FLAGS_TIE);
@@ -1210,7 +1231,7 @@ static void sci_stop_tx(struct uart_port *port)
/* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
- if (port->type == PORT_SCIFA)
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x8000;
ctrl &= ~SCI_CTRL_FLAGS_TIE;
sci_out(port, SCSCR, ctrl);
@@ -1222,7 +1243,7 @@ static void sci_start_rx(struct uart_port *port)
/* Set RIE (Receive Interrupt Enable) bit in SCSCR */
ctrl |= sci_in(port, SCSCR);
- if (port->type == PORT_SCIFA)
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
sci_out(port, SCSCR, ctrl);
}
@@ -1233,7 +1254,7 @@ static void sci_stop_rx(struct uart_port *port)
/* Clear RIE (Receive Interrupt Enable) bit in SCSCR */
ctrl = sci_in(port, SCSCR);
- if (port->type == PORT_SCIFA)
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
ctrl &= ~0x4000;
ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE);
sci_out(port, SCSCR, ctrl);
@@ -1271,7 +1292,7 @@ static void rx_timer_fn(unsigned long arg)
struct uart_port *port = &s->port;
u16 scr = sci_in(port, SCSCR);
- if (port->type == PORT_SCIFA) {
+ if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
scr &= ~0x4000;
enable_irq(s->irqs[1]);
}
@@ -1524,6 +1545,8 @@ static const char *sci_type(struct uart_port *port)
return "scif";
case PORT_SCIFA:
return "scifa";
+ case PORT_SCIFB:
+ return "scifb";
}
return NULL;
@@ -1612,6 +1635,9 @@ static int __devinit sci_init_single(struct platform_device *dev,
port->line = index;
switch (p->type) {
+ case PORT_SCIFB:
+ port->fifosize = 256;
+ break;
case PORT_SCIFA:
port->fifosize = 64;
break;
diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h
index f70c49f915fa..d2352ac437c5 100644
--- a/drivers/serial/sh-sci.h
+++ b/drivers/serial/sh-sci.h
@@ -140,7 +140,15 @@
# define SCSPTR0 0xffe00024 /* 16 bit SCIF */
# define SCSPTR1 0xffe10024 /* 16 bit SCIF */
# define SCIF_ORER 0x0001 /* Overrun error bit */
-# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */
+
+#if defined(CONFIG_SH_SH2007)
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=0 */
+# define SCSCR_INIT(port) 0x38
+#else
+/* TIE=0,RIE=0,TE=1,RE=1,REIE=1,CKE1=1 */
+# define SCSCR_INIT(port) 0x3a
+#endif
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \
defined(CONFIG_CPU_SUBTYPE_SH7786)
# define SCSPTR0 0xffea0024 /* 16 bit SCIF */
@@ -322,7 +330,7 @@
#define CPU_SCIx_FNS(name, sci_offset, sci_size, scif_offset, scif_size)\
static inline unsigned int sci_##name##_in(struct uart_port *port) \
{ \
- if (port->type == PORT_SCIF) { \
+ if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
SCI_IN(scif_size, scif_offset) \
} else { /* PORT_SCI or PORT_SCIFA */ \
SCI_IN(sci_size, sci_offset); \
@@ -330,7 +338,7 @@
} \
static inline void sci_##name##_out(struct uart_port *port, unsigned int value) \
{ \
- if (port->type == PORT_SCIF) { \
+ if (port->type == PORT_SCIF || port->type == PORT_SCIFB) { \
SCI_OUT(scif_size, scif_offset, value) \
} else { /* PORT_SCI or PORT_SCIFA */ \
SCI_OUT(sci_size, sci_offset, value); \
@@ -384,8 +392,12 @@
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH7367) || \
- defined(CONFIG_ARCH_SH7377) || \
- defined(CONFIG_ARCH_SH7372)
+ defined(CONFIG_ARCH_SH7377)
+#define SCIF_FNS(name, scif_offset, scif_size) \
+ CPU_SCIF_FNS(name, scif_offset, scif_size)
+#elif defined(CONFIG_ARCH_SH7372)
+#define SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size) \
+ CPU_SCIx_FNS(name, sh4_scifa_offset, sh4_scifa_size, sh4_scifb_offset, sh4_scifb_size)
#define SCIF_FNS(name, scif_offset, scif_size) \
CPU_SCIF_FNS(name, scif_offset, scif_size)
#else
@@ -422,8 +434,7 @@
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_ARCH_SH7367) || \
- defined(CONFIG_ARCH_SH7377) || \
- defined(CONFIG_ARCH_SH7372)
+ defined(CONFIG_ARCH_SH7377)
SCIF_FNS(SCSMR, 0x00, 16)
SCIF_FNS(SCBRR, 0x04, 8)
@@ -436,6 +447,20 @@ SCIF_FNS(SCFDR, 0x1c, 16)
SCIF_FNS(SCxTDR, 0x20, 8)
SCIF_FNS(SCxRDR, 0x24, 8)
SCIF_FNS(SCLSR, 0x00, 0)
+#elif defined(CONFIG_ARCH_SH7372)
+SCIF_FNS(SCSMR, 0x00, 16)
+SCIF_FNS(SCBRR, 0x04, 8)
+SCIF_FNS(SCSCR, 0x08, 16)
+SCIF_FNS(SCTDSR, 0x0c, 16)
+SCIF_FNS(SCFER, 0x10, 16)
+SCIF_FNS(SCxSR, 0x14, 16)
+SCIF_FNS(SCFCR, 0x18, 16)
+SCIF_FNS(SCFDR, 0x1c, 16)
+SCIF_FNS(SCTFDR, 0x38, 16)
+SCIF_FNS(SCRFDR, 0x3c, 16)
+SCIx_FNS(SCxTDR, 0x20, 8, 0x40, 8)
+SCIx_FNS(SCxRDR, 0x24, 8, 0x60, 8)
+SCIF_FNS(SCLSR, 0x00, 0)
#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\
defined(CONFIG_CPU_SUBTYPE_SH7724)
SCIx_FNS(SCSMR, 0x00, 16, 0x00, 16)
@@ -599,9 +624,10 @@ static inline int sci_rxd_in(struct uart_port *port)
* -- Mitch Davis - 15 Jul 2000
*/
-#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \
- defined(CONFIG_CPU_SUBTYPE_SH7785) || \
- defined(CONFIG_CPU_SUBTYPE_SH7786)
+#if (defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+ defined(CONFIG_CPU_SUBTYPE_SH7786)) && \
+ !defined(CONFIG_SH_SH2007)
#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1)
#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \
defined(CONFIG_CPU_SUBTYPE_SH7720) || \
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c
index ed7d958b0a01..544f2e25d0e5 100644
--- a/drivers/serial/suncore.c
+++ b/drivers/serial/suncore.c
@@ -71,7 +71,9 @@ int sunserial_console_match(struct console *con, struct device_node *dp,
con->index = line;
drv->cons = con;
- add_preferred_console(con->name, line, NULL);
+
+ if (!console_set_on_cmdline)
+ add_preferred_console(con->name, line, NULL);
return 1;
}
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c
index 234459c2f012..ffbf4553f665 100644
--- a/drivers/serial/sunsu.c
+++ b/drivers/serial/sunsu.c
@@ -1500,20 +1500,25 @@ out_unmap:
static int __devexit su_remove(struct of_device *op)
{
struct uart_sunsu_port *up = dev_get_drvdata(&op->dev);
+ bool kbdms = false;
if (up->su_type == SU_PORT_MS ||
- up->su_type == SU_PORT_KBD) {
+ up->su_type == SU_PORT_KBD)
+ kbdms = true;
+
+ if (kbdms) {
#ifdef CONFIG_SERIO
serio_unregister_port(&up->serio);
#endif
- kfree(up);
- } else if (up->port.type != PORT_UNKNOWN) {
+ } else if (up->port.type != PORT_UNKNOWN)
uart_remove_one_port(&sunsu_reg, &up->port);
- }
if (up->port.membase)
of_iounmap(&op->resource[0], up->port.membase, up->reg_size);
+ if (kbdms)
+ kfree(up);
+
dev_set_drvdata(&op->dev, NULL);
return 0;
diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile
index 78bb5127abd0..08fc653a825c 100644
--- a/drivers/sh/Makefile
+++ b/drivers/sh/Makefile
@@ -1,9 +1,10 @@
#
# Makefile for the SuperH specific drivers.
#
+obj-y := clk.o intc.o
+
obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_MAPLE) += maple/
+
obj-$(CONFIG_GENERIC_GPIO) += pfc.o
-obj-$(CONFIG_SUPERH) += clk.o
obj-$(CONFIG_SH_CLK_CPG) += clk-cpg.o
-obj-y += intc.o
diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c
index 5d84adac9ec4..cede14e34507 100644
--- a/drivers/sh/clk.c
+++ b/drivers/sh/clk.c
@@ -73,22 +73,14 @@ long clk_rate_table_round(struct clk *clk,
{
unsigned long rate_error, rate_error_prev = ~0UL;
unsigned long rate_best_fit = rate;
- unsigned long highest, lowest;
int i;
- highest = lowest = 0;
-
for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
unsigned long freq = freq_table[i].frequency;
if (freq == CPUFREQ_ENTRY_INVALID)
continue;
- if (freq > highest)
- highest = freq;
- if (freq < lowest)
- lowest = freq;
-
rate_error = abs(freq - rate);
if (rate_error < rate_error_prev) {
rate_best_fit = freq;
@@ -99,11 +91,6 @@ long clk_rate_table_round(struct clk *clk,
break;
}
- if (rate >= highest)
- rate_best_fit = highest;
- if (rate <= lowest)
- rate_best_fit = lowest;
-
return rate_best_fit;
}
@@ -354,10 +341,10 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
ret = clk_reparent(clk, parent);
if (ret == 0) {
- pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
- clk->name, clk->parent->name, clk->rate);
if (clk->ops->recalc)
clk->rate = clk->ops->recalc(clk);
+ pr_debug("clock: set parent of %s to %s (new rate %ld)\n",
+ clk->name, clk->parent->name, clk->rate);
propagate_rate(clk);
}
} else
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c
index 59be3efe0636..4bbb59ae1d40 100644
--- a/drivers/spi/coldfire_qspi.c
+++ b/drivers/spi/coldfire_qspi.c
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/platform_device.h>
diff --git a/drivers/spi/spi_mpc8xxx.c b/drivers/spi/spi_mpc8xxx.c
index ffa111a7e9d4..97ab0a81338a 100644
--- a/drivers/spi/spi_mpc8xxx.c
+++ b/drivers/spi/spi_mpc8xxx.c
@@ -66,28 +66,6 @@ struct mpc8xxx_spi_reg {
__be32 receive;
};
-/* SPI Parameter RAM */
-struct spi_pram {
- __be16 rbase; /* Rx Buffer descriptor base address */
- __be16 tbase; /* Tx Buffer descriptor base address */
- u8 rfcr; /* Rx function code */
- u8 tfcr; /* Tx function code */
- __be16 mrblr; /* Max receive buffer length */
- __be32 rstate; /* Internal */
- __be32 rdp; /* Internal */
- __be16 rbptr; /* Internal */
- __be16 rbc; /* Internal */
- __be32 rxtmp; /* Internal */
- __be32 tstate; /* Internal */
- __be32 tdp; /* Internal */
- __be16 tbptr; /* Internal */
- __be16 tbc; /* Internal */
- __be32 txtmp; /* Internal */
- __be32 res; /* Tx temp. */
- __be16 rpbase; /* Relocation pointer (CPM1 only) */
- __be16 res1; /* Reserved */
-};
-
/* SPI Controller mode register definitions */
#define SPMODE_LOOP (1 << 30)
#define SPMODE_CI_INACTIVEHIGH (1 << 29)
diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile
index 10f87f05d8e8..d0eb16eac092 100644
--- a/drivers/staging/cx25821/Makefile
+++ b/drivers/staging/cx25821/Makefile
@@ -1,9 +1,8 @@
-cx25821-objs := cx25821-core.o cx25821-cards.o cx25821-i2c.o cx25821-gpio.o \
- cx25821-medusa-video.o cx25821-video.o cx25821-video0.o cx25821-video1.o \
- cx25821-video2.o cx25821-video3.o cx25821-video4.o cx25821-video5.o \
- cx25821-video6.o cx25821-video7.o cx25821-vidups9.o cx25821-vidups10.o \
- cx25821-audups11.o cx25821-video-upstream.o cx25821-video-upstream-ch2.o \
- cx25821-audio-upstream.o cx25821-videoioctl.o
+cx25821-objs := cx25821-core.o cx25821-cards.o cx25821-i2c.o \
+ cx25821-gpio.o cx25821-medusa-video.o \
+ cx25821-video.o cx25821-video-upstream.o \
+ cx25821-video-upstream-ch2.o \
+ cx25821-audio-upstream.o
obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 1798975a69bd..a43b18816fa5 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -55,6 +55,12 @@
static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
static int devno;
+struct cx25821_audio_buffer {
+ unsigned int bpl;
+ struct btcx_riscmem risc;
+ struct videobuf_dmabuf dma;
+};
+
struct cx25821_audio_dev {
struct cx25821_dev *dev;
struct cx25821_dmaqueue q;
@@ -77,7 +83,7 @@ struct cx25821_audio_dev {
struct videobuf_dmabuf *dma_risc;
- struct cx25821_buffer *buf;
+ struct cx25821_audio_buffer *buf;
struct snd_pcm_substream *substream;
};
@@ -136,7 +142,7 @@ MODULE_PARM_DESC(debug, "enable debug messages");
static int _cx25821_start_audio_dma(struct cx25821_audio_dev *chip)
{
- struct cx25821_buffer *buf = chip->buf;
+ struct cx25821_audio_buffer *buf = chip->buf;
struct cx25821_dev *dev = chip->dev;
struct sram_channel *audio_ch =
&cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
@@ -331,7 +337,7 @@ static int dsp_buffer_free(struct cx25821_audio_dev *chip)
BUG_ON(!chip->dma_size);
dprintk(2, "Freeing buffer\n");
- videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
+ videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc);
videobuf_dma_free(chip->dma_risc);
btcx_riscmem_free(chip->pci, &chip->buf->risc);
kfree(chip->buf);
@@ -432,7 +438,7 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
struct cx25821_audio_dev *chip = snd_pcm_substream_chip(substream);
struct videobuf_dmabuf *dma;
- struct cx25821_buffer *buf;
+ struct cx25821_audio_buffer *buf;
int ret;
if (substream->runtime->dma_area) {
@@ -447,36 +453,31 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
BUG_ON(!chip->dma_size);
BUG_ON(chip->num_periods & (chip->num_periods - 1));
- buf = videobuf_sg_alloc(sizeof(*buf));
+ buf = kzalloc(sizeof(*buf), GFP_KERNEL);
if (NULL == buf)
return -ENOMEM;
if (chip->period_size > AUDIO_LINE_SIZE)
chip->period_size = AUDIO_LINE_SIZE;
- buf->vb.memory = V4L2_MEMORY_MMAP;
- buf->vb.field = V4L2_FIELD_NONE;
- buf->vb.width = chip->period_size;
buf->bpl = chip->period_size;
- buf->vb.height = chip->num_periods;
- buf->vb.size = chip->dma_size;
- dma = videobuf_to_dma(&buf->vb);
+ dma = &buf->dma;
videobuf_dma_init(dma);
-
ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
- (PAGE_ALIGN(buf->vb.size) >>
+ (PAGE_ALIGN(chip->dma_size) >>
PAGE_SHIFT));
if (ret < 0)
goto error;
- ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
+ ret = videobuf_dma_map(&chip->pci->dev, dma);
if (ret < 0)
goto error;
ret =
cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
- buf->vb.width, buf->vb.height, 1);
+ chip->period_size, chip->num_periods,
+ 1);
if (ret < 0) {
printk(KERN_INFO
"DEBUG: ERROR after cx25821_risc_databuffer_audio()\n");
@@ -488,12 +489,10 @@ static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
- buf->vb.state = VIDEOBUF_PREPARED;
-
chip->buf = buf;
chip->dma_risc = dma;
- substream->runtime->dma_area = chip->dma_risc->vmalloc;
+ substream->runtime->dma_area = chip->dma_risc->vaddr;
substream->runtime->dma_bytes = chip->dma_size;
substream->runtime->dma_addr = 0;
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
index eb39d13f7d75..cdff49f409f2 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -106,7 +106,7 @@ static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
{
unsigned int line;
struct sram_channel *sram_ch =
- &dev->sram_channels[dev->_audio_upstream_channel_select];
+ dev->channels[dev->_audio_upstream_channel_select].sram_channels;
int offset = 0;
/* scan lines */
@@ -217,7 +217,7 @@ void cx25821_free_memory_audio(struct cx25821_dev *dev)
void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
{
struct sram_channel *sram_ch =
- &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
+ dev->channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B].sram_channels;
u32 tmp = 0;
if (!dev->_audio_is_running) {
@@ -287,14 +287,14 @@ int cx25821_get_audio_data(struct cx25821_dev *dev,
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!\n",
+ printk(KERN_ERR "%s: File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk("%s: File has no READ operations registered!\n",
+ printk(KERN_ERR "%s: File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -353,8 +353,9 @@ static void cx25821_audioups_handler(struct work_struct *work)
}
cx25821_get_audio_data(dev,
- &dev->sram_channels[dev->
- _audio_upstream_channel_select]);
+ dev->channels[dev->
+ _audio_upstream_channel_select].
+ sram_channels);
}
int cx25821_openfile_audio(struct cx25821_dev *dev,
@@ -378,14 +379,14 @@ int cx25821_openfile_audio(struct cx25821_dev *dev,
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk("%s: File has no file operations registered!\n",
+ printk(KERN_ERR "%s: File has no file operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk("%s: File has no READ operations registered!\n",
+ printk(KERN_ERR "%s: File has no READ operations registered!\n",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -505,7 +506,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
{
int i = 0;
u32 int_msk_tmp;
- struct sram_channel *channel = &dev->sram_channels[chan_num];
+ struct sram_channel *channel = dev->channels[chan_num].sram_channels;
dma_addr_t risc_phys_jump_addr;
__le32 *rp;
@@ -569,15 +570,15 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
spin_unlock(&dev->slock);
} else {
if (status & FLD_AUD_SRC_OF)
- printk("%s: Audio Received Overflow Error Interrupt!\n",
+ printk(KERN_WARNING "%s: Audio Received Overflow Error Interrupt!\n",
__func__);
if (status & FLD_AUD_SRC_SYNC)
- printk("%s: Audio Received Sync Error Interrupt!\n",
+ printk(KERN_WARNING "%s: Audio Received Sync Error Interrupt!\n",
__func__);
if (status & FLD_AUD_SRC_OPC_ERR)
- printk("%s: Audio Received OpCode Error Interrupt!\n",
+ printk(KERN_WARNING "%s: Audio Received OpCode Error Interrupt!\n",
__func__);
/* Read and write back the interrupt status register to clear
@@ -586,7 +587,7 @@ int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
}
if (dev->_audiofile_status == END_OF_FILE) {
- printk("cx25821: EOF Channel Audio Framecount = %d\n",
+ printk(KERN_WARNING "cx25821: EOF Channel Audio Framecount = %d\n",
dev->_audioframe_count);
return -1;
}
@@ -607,7 +608,8 @@ static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
if (!dev)
return -1;
- sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
+ sram_ch = dev->channels[dev->_audio_upstream_channel_select].
+ sram_channels;
msk_stat = cx_read(sram_ch->int_mstat);
audio_status = cx_read(sram_ch->int_stat);
@@ -644,8 +646,8 @@ static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
/* 10 millisecond timeout */
if (count++ > 1000) {
- printk
- ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
+ printk(KERN_ERR
+ "cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
__func__);
return;
}
@@ -726,12 +728,12 @@ int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
int str_length = 0;
if (dev->_audio_is_running) {
- printk("Audio Channel is still running so return!\n");
+ printk(KERN_WARNING "Audio Channel is still running so return!\n");
return 0;
}
dev->_audio_upstream_channel_select = channel_select;
- sram_ch = &dev->sram_channels[channel_select];
+ sram_ch = dev->channels[channel_select].sram_channels;
/* Work queue */
INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
index 503f42f036a8..434b2a312a80 100644
--- a/drivers/staging/cx25821/cx25821-audio.h
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -27,24 +27,25 @@
#define LINES_PER_BUFFER 15
#define AUDIO_LINE_SIZE 128
-//Number of buffer programs to use at once.
+/* Number of buffer programs to use at once. */
#define NUMBER_OF_PROGRAMS 8
-//Max size of the RISC program for a buffer. - worst case is 2 writes per line
-// Space is also added for the 4 no-op instructions added on the end.
-
+/*
+ Max size of the RISC program for a buffer. - worst case is 2 writes per line
+ Space is also added for the 4 no-op instructions added on the end.
+*/
#ifndef USE_RISC_NOOP
#define MAX_BUFFER_PROGRAM_SIZE \
(2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
#endif
-// MAE 12 July 2005 Try to use NOOP RISC instruction instead
+/* MAE 12 July 2005 Try to use NOOP RISC instruction instead */
#ifdef USE_RISC_NOOP
#define MAX_BUFFER_PROGRAM_SIZE \
(2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
#endif
-//Sizes of various instructions in bytes. Used when adding instructions.
+/* Sizes of various instructions in bytes. Used when adding instructions. */
#define RISC_WRITE_INSTRUCTION_SIZE 12
#define RISC_JUMP_INSTRUCTION_SIZE 12
#define RISC_SKIP_INSTRUCTION_SIZE 4
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
deleted file mode 100644
index e49ead982f39..000000000000
--- a/drivers/staging/cx25821/cx25821-audups11.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/slab.h>
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH11];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH11]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = 10;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO11))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO11)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- //cx_write(channel11->dma_ctl, 0);
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO11)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO11);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO11)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO11);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
- return 0;
-}
-
-static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) {
- return 0;
- }
-
- dev->input_filename = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname = data_from_user->vid_stdname;
- dev->pixel_format = data_from_user->pixel_format;
- dev->channel_select = data_from_user->channel_select;
- dev->command = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_AUDIO:
- cx25821_start_upstream_audio(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_AUDIO:
- cx25821_stop_upstream_audio(dev);
- break;
- }
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev;
- int err;
-
- if (fh) {
- dev = fh->dev;
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
- return 0;
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl_upstream11,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template11 = {
- .name = "cx25821-audioupstream",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index d90abb383fc8..c487c19256b9 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -781,14 +781,14 @@ static void cx25821_shutdown(struct cx25821_dev *dev)
/* Disable Video A/B activity */
for (i = 0; i < VID_CHANNEL_NUM; i++) {
- cx_write(dev->sram_channels[i].dma_ctl, 0);
- cx_write(dev->sram_channels[i].int_msk, 0);
+ cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
+ cx_write(dev->channels[i].sram_channels->int_msk, 0);
}
for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
i++) {
- cx_write(dev->sram_channels[i].dma_ctl, 0);
- cx_write(dev->sram_channels[i].int_msk, 0);
+ cx_write(dev->channels[i].sram_channels->dma_ctl, 0);
+ cx_write(dev->channels[i].sram_channels->int_msk, 0);
}
/* Disable Audio activity */
@@ -805,12 +805,10 @@ static void cx25821_shutdown(struct cx25821_dev *dev)
void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
u32 format)
{
- struct sram_channel *ch;
-
if (channel_select <= 7 && channel_select >= 0) {
- ch = &cx25821_sram_channels[channel_select];
- cx_write(ch->pix_frmt, format);
- dev->pixel_formats[channel_select] = format;
+ cx_write(dev->channels[channel_select].
+ sram_channels->pix_frmt, format);
+ dev->channels[channel_select].pixel_formats = format;
}
}
@@ -831,7 +829,7 @@ static void cx25821_initialize(struct cx25821_dev *dev)
cx_write(PCI_INT_STAT, 0xffffffff);
for (i = 0; i < VID_CHANNEL_NUM; i++)
- cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
+ cx_write(dev->channels[i].sram_channels->int_stat, 0xffffffff);
cx_write(AUD_A_INT_STAT, 0xffffffff);
cx_write(AUD_B_INT_STAT, 0xffffffff);
@@ -845,21 +843,22 @@ static void cx25821_initialize(struct cx25821_dev *dev)
mdelay(100);
for (i = 0; i < VID_CHANNEL_NUM; i++) {
- cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
- cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440,
- 0);
- dev->pixel_formats[i] = PIXEL_FRMT_422;
- dev->use_cif_resolution[i] = FALSE;
+ cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
+ cx25821_sram_channel_setup(dev, dev->channels[i].sram_channels,
+ 1440, 0);
+ dev->channels[i].pixel_formats = PIXEL_FRMT_422;
+ dev->channels[i].use_cif_resolution = FALSE;
}
/* Probably only affect Downstream */
for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
i++) {
- cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
+ cx25821_set_vip_mode(dev, dev->channels[i].sram_channels);
}
- cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08],
- 128, 0);
+ cx25821_sram_channel_setup_audio(dev,
+ dev->channels[SRAM_CH08].sram_channels,
+ 128, 0);
cx25821_gpio_init(dev);
}
@@ -902,21 +901,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
{
int io_size = 0, i;
- struct video_device *video_template[] = {
- &cx25821_video_template0,
- &cx25821_video_template1,
- &cx25821_video_template2,
- &cx25821_video_template3,
- &cx25821_video_template4,
- &cx25821_video_template5,
- &cx25821_video_template6,
- &cx25821_video_template7,
- &cx25821_video_template9,
- &cx25821_video_template10,
- &cx25821_video_template11,
- &cx25821_videoioctl_template,
- };
-
printk(KERN_INFO "\n***********************************\n");
printk(KERN_INFO "cx25821 set up\n");
printk(KERN_INFO "***********************************\n\n");
@@ -947,7 +931,8 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
/* Apply a sensible clock frequency for the PCIe bridge */
dev->clk_freq = 28000000;
- dev->sram_channels = cx25821_sram_channels;
+ for (i = 0; i < MAX_VID_CHANNEL_NUM; i++)
+ dev->channels[i].sram_channels = &cx25821_sram_channels[i];
if (dev->nr > 1)
CX25821_INFO("dev->nr > 1!");
@@ -970,7 +955,6 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
-
if (cx25821_get_resources(dev) < 0) {
printk(KERN_ERR "%s No more PCIe resources for "
"subsystem: %04x:%04x\n",
@@ -1018,37 +1002,24 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
dev->i2c_bus[0].i2c_rc);
cx25821_card_setup(dev);
- medusa_video_init(dev);
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- if (cx25821_video_register(dev, i, video_template[i]) < 0) {
- printk(KERN_ERR
- "%s() Failed to register analog video adapters on VID channel %d\n",
- __func__, i);
- }
- }
+ if (medusa_video_init(dev) < 0)
+ CX25821_ERR("%s() Failed to initialize medusa!\n"
+ , __func__);
- for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
- i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
- /* Since we don't have template8 for Audio Downstream */
- if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
- printk(KERN_ERR
- "%s() Failed to register analog video adapters for Upstream channel %d.\n",
- __func__, i);
- }
- }
+ cx25821_video_register(dev);
/* register IOCTL device */
dev->ioctl_dev =
- cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
+ cx25821_vdev_init(dev, dev->pci, &cx25821_videoioctl_template,
"video");
if (video_register_device
(dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
cx25821_videoioctl_unregister(dev);
printk(KERN_ERR
- "%s() Failed to register video adapter for IOCTL so releasing.\n",
- __func__);
+ "%s() Failed to register video adapter for IOCTL, so \
+ unregistering videoioctl device.\n", __func__);
}
cx25821_dev_checkrevision(dev);
@@ -1349,7 +1320,7 @@ void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
BUG_ON(in_interrupt());
videobuf_waiton(&buf->vb, 0, 0);
- videobuf_dma_unmap(q, dma);
+ videobuf_dma_unmap(q->dev, dma);
videobuf_dma_free(dma);
btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
@@ -1371,7 +1342,8 @@ static irqreturn_t cx25821_irq(int irq, void *dev_id)
for (i = 0; i < VID_CHANNEL_NUM; i++) {
if (pci_status & mask[i]) {
- vid_status = cx_read(dev->sram_channels[i].int_stat);
+ vid_status = cx_read(dev->channels[i].
+ sram_channels->int_stat);
if (vid_status)
handled +=
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
index 08f45b52df6a..e43572e61ece 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -282,6 +282,9 @@ static u32 cx25821_functionality(struct i2c_adapter *adap)
static struct i2c_algorithm cx25821_i2c_algo_template = {
.master_xfer = i2c_xfer,
.functionality = cx25821_functionality,
+#ifdef NEED_ALGO_CONTROL
+ .algo_control = dummy_algo_control,
+#endif
};
static struct i2c_adapter cx25821_i2c_adap_template = {
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
index b0d216ba7f81..60d197f57556 100644
--- a/drivers/staging/cx25821/cx25821-medusa-defines.h
+++ b/drivers/staging/cx25821/cx25821-medusa-defines.h
@@ -23,7 +23,7 @@
#ifndef _MEDUSA_DEF_H_
#define _MEDUSA_DEF_H_
-// Video deocder that we supported
+/* Video deocder that we supported */
#define VDEC_A 0
#define VDEC_B 1
#define VDEC_C 2
@@ -33,19 +33,10 @@
#define VDEC_G 6
#define VDEC_H 7
-//#define AUTO_SWITCH_BIT[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
-
-// The following bit position enables automatic source switching for decoder A-H.
-// Display index per camera.
-//#define VDEC_INDEX[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
-
-// Select input bit to video decoder A-H.
-//#define CH_SRC_SEL_BIT[] = {24, 25, 26, 27, 28, 29, 30, 31};
-
-// end of display sequence
+/* end of display sequence */
#define END_OF_SEQ 0xF;
-// registry string size
+/* registry string size */
#define MAX_REGISTRY_SZ 40;
#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h
index 12c90f831b22..f7f33b3e7058 100644
--- a/drivers/staging/cx25821/cx25821-medusa-reg.h
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -23,11 +23,11 @@
#ifndef __MEDUSA_REGISTERS__
#define __MEDUSA_REGISTERS__
-// Serial Slave Registers
+/* Serial Slave Registers */
#define HOST_REGISTER1 0x0000
#define HOST_REGISTER2 0x0001
-// Chip Configuration Registers
+/* Chip Configuration Registers */
#define CHIP_CTRL 0x0100
#define AFE_AB_CTRL 0x0104
#define AFE_CD_CTRL 0x0108
@@ -92,7 +92,7 @@
#define ABIST_CLAMP_E 0x01F4
#define ABIST_CLAMP_F 0x01F8
-// Digital Video Encoder A Registers
+/* Digital Video Encoder A Registers */
#define DENC_A_REG_1 0x0200
#define DENC_A_REG_2 0x0204
#define DENC_A_REG_3 0x0208
@@ -102,7 +102,7 @@
#define DENC_A_REG_7 0x0218
#define DENC_A_REG_8 0x021C
-// Digital Video Encoder B Registers
+/* Digital Video Encoder B Registers */
#define DENC_B_REG_1 0x0300
#define DENC_B_REG_2 0x0304
#define DENC_B_REG_3 0x0308
@@ -112,7 +112,7 @@
#define DENC_B_REG_7 0x0318
#define DENC_B_REG_8 0x031C
-// Video Decoder A Registers
+/* Video Decoder A Registers */
#define MODE_CTRL 0x1000
#define OUT_CTRL1 0x1004
#define OUT_CTRL_NS 0x1008
@@ -153,7 +153,7 @@
#define VERSION 0x11F8
#define SOFT_RST_CTRL 0x11FC
-// Video Decoder B Registers
+/* Video Decoder B Registers */
#define VDEC_B_MODE_CTRL 0x1200
#define VDEC_B_OUT_CTRL1 0x1204
#define VDEC_B_OUT_CTRL_NS 0x1208
@@ -194,7 +194,7 @@
#define VDEC_B_VERSION 0x13F8
#define VDEC_B_SOFT_RST_CTRL 0x13FC
-// Video Decoder C Registers
+/* Video Decoder C Registers */
#define VDEC_C_MODE_CTRL 0x1400
#define VDEC_C_OUT_CTRL1 0x1404
#define VDEC_C_OUT_CTRL_NS 0x1408
@@ -235,7 +235,7 @@
#define VDEC_C_VERSION 0x15F8
#define VDEC_C_SOFT_RST_CTRL 0x15FC
-// Video Decoder D Registers
+/* Video Decoder D Registers */
#define VDEC_D_MODE_CTRL 0x1600
#define VDEC_D_OUT_CTRL1 0x1604
#define VDEC_D_OUT_CTRL_NS 0x1608
@@ -276,7 +276,7 @@
#define VDEC_D_VERSION 0x17F8
#define VDEC_D_SOFT_RST_CTRL 0x17FC
-// Video Decoder E Registers
+/* Video Decoder E Registers */
#define VDEC_E_MODE_CTRL 0x1800
#define VDEC_E_OUT_CTRL1 0x1804
#define VDEC_E_OUT_CTRL_NS 0x1808
@@ -317,7 +317,7 @@
#define VDEC_E_VERSION 0x19F8
#define VDEC_E_SOFT_RST_CTRL 0x19FC
-// Video Decoder F Registers
+/* Video Decoder F Registers */
#define VDEC_F_MODE_CTRL 0x1A00
#define VDEC_F_OUT_CTRL1 0x1A04
#define VDEC_F_OUT_CTRL_NS 0x1A08
@@ -358,7 +358,7 @@
#define VDEC_F_VERSION 0x1BF8
#define VDEC_F_SOFT_RST_CTRL 0x1BFC
-// Video Decoder G Registers
+/* Video Decoder G Registers */
#define VDEC_G_MODE_CTRL 0x1C00
#define VDEC_G_OUT_CTRL1 0x1C04
#define VDEC_G_OUT_CTRL_NS 0x1C08
@@ -399,7 +399,7 @@
#define VDEC_G_VERSION 0x1DF8
#define VDEC_G_SOFT_RST_CTRL 0x1DFC
-// Video Decoder H Registers
+/* Video Decoder H Registers */
#define VDEC_H_MODE_CTRL 0x1E00
#define VDEC_H_OUT_CTRL1 0x1E04
#define VDEC_H_OUT_CTRL_NS 0x1E08
@@ -440,14 +440,14 @@
#define VDEC_H_VERSION 0x1FF8
#define VDEC_H_SOFT_RST_CTRL 0x1FFC
-//*****************************************************************************
-// LUMA_CTRL register fields
+/*****************************************************************************/
+/* LUMA_CTRL register fields */
#define VDEC_A_BRITE_CTRL 0x1014
#define VDEC_A_CNTRST_CTRL 0x1015
#define VDEC_A_PEAK_SEL 0x1016
-//*****************************************************************************
-// CHROMA_CTRL register fields
+/*****************************************************************************/
+/* CHROMA_CTRL register fields */
#define VDEC_A_USAT_CTRL 0x1018
#define VDEC_A_VSAT_CTRL 0x1019
#define VDEC_A_HUE_CTRL 0x101A
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
index 34616dc507f9..ef9f2b82a860 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -778,9 +778,9 @@ int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
int medusa_video_init(struct cx25821_dev *dev)
{
- u32 value, tmp = 0;
- int ret_val;
- int i;
+ u32 value = 0, tmp = 0;
+ int ret_val = 0;
+ int i = 0;
mutex_lock(&dev->lock);
@@ -790,6 +790,7 @@ int medusa_video_init(struct cx25821_dev *dev)
value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
value &= 0xFFFFF0FF;
ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
+
if (ret_val < 0)
goto error;
@@ -797,6 +798,7 @@ int medusa_video_init(struct cx25821_dev *dev)
value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
value &= 0xFFFFFFDF;
ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
+
if (ret_val < 0)
goto error;
@@ -812,6 +814,7 @@ int medusa_video_init(struct cx25821_dev *dev)
value &= 0xFF70FF70;
value |= 0x00090008; /* set en_active */
ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
+
if (ret_val < 0)
goto error;
@@ -826,8 +829,10 @@ int medusa_video_init(struct cx25821_dev *dev)
/* select AFE clock to output mode */
value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
value &= 0x83FFFFFF;
- ret_val = cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
- value | 0x10000000);
+ ret_val =
+ cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
+ value | 0x10000000);
+
if (ret_val < 0)
goto error;
@@ -849,12 +854,15 @@ int medusa_video_init(struct cx25821_dev *dev)
value |= 7;
ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
+
if (ret_val < 0)
goto error;
+
mutex_unlock(&dev->lock);
ret_val = medusa_set_videostandard(dev);
+
return ret_val;
error:
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
index 2fab4b2f251c..6175e0961855 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.h
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -25,7 +25,7 @@
#include "cx25821-medusa-defines.h"
-// Color control constants
+/* Color control constants */
#define VIDEO_PROCAMP_MIN 0
#define VIDEO_PROCAMP_MAX 10000
#define UNSIGNED_BYTE_MIN 0
@@ -33,7 +33,7 @@
#define SIGNED_BYTE_MIN -128
#define SIGNED_BYTE_MAX 127
-// Default video color settings
+/* Default video color settings */
#define SHARPNESS_DEFAULT 50
#define SATURATION_DEFAULT 5000
#define BRIGHTNESS_DEFAULT 6200
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
index 7241e7ee3fd3..cfe0f32db377 100644
--- a/drivers/staging/cx25821/cx25821-reg.h
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -48,24 +48,24 @@
#define RISC_SYNC_EVEN_VBI 0x00000207
#define RISC_NOOP 0xF0000000
-//*****************************************************************************
-// ASB SRAM
-//*****************************************************************************
-#define TX_SRAM 0x000000 // Transmit SRAM
-
-//*****************************************************************************
-#define RX_RAM 0x010000 // Receive SRAM
-
-//*****************************************************************************
-// Application Layer (AL)
-//*****************************************************************************
-#define DEV_CNTRL2 0x040000 // Device control
+/*****************************************************************************
+* ASB SRAM
+ *****************************************************************************/
+#define TX_SRAM 0x000000 /* Transmit SRAM */
+
+/*****************************************************************************/
+#define RX_RAM 0x010000 /* Receive SRAM */
+
+/*****************************************************************************
+* Application Layer (AL)
+ *****************************************************************************/
+#define DEV_CNTRL2 0x040000 /* Device control */
#define FLD_RUN_RISC 0x00000020
-//*****************************************************************************
-#define PCI_INT_MSK 0x040010 // PCI interrupt mask
-#define PCI_INT_STAT 0x040014 // PCI interrupt status
-#define PCI_INT_MSTAT 0x040018 // PCI interrupt masked status
+/* ***************************************************************************** */
+#define PCI_INT_MSK 0x040010 /* PCI interrupt mask */
+#define PCI_INT_STAT 0x040014 /* PCI interrupt status */
+#define PCI_INT_MSTAT 0x040018 /* PCI interrupt masked status */
#define FLD_HAMMERHEAD_INT (1 << 27)
#define FLD_UART_INT (1 << 26)
#define FLD_IRQN_INT (1 << 25)
@@ -93,65 +93,65 @@
#define FLD_VID_B_INT (1 << 1)
#define FLD_VID_A_INT (1 << 0)
-//*****************************************************************************
-#define VID_A_INT_MSK 0x040020 // Video A interrupt mask
-#define VID_A_INT_STAT 0x040024 // Video A interrupt status
-#define VID_A_INT_MSTAT 0x040028 // Video A interrupt masked status
-#define VID_A_INT_SSTAT 0x04002C // Video A interrupt set status
-
-//*****************************************************************************
-#define VID_B_INT_MSK 0x040030 // Video B interrupt mask
-#define VID_B_INT_STAT 0x040034 // Video B interrupt status
-#define VID_B_INT_MSTAT 0x040038 // Video B interrupt masked status
-#define VID_B_INT_SSTAT 0x04003C // Video B interrupt set status
-
-//*****************************************************************************
-#define VID_C_INT_MSK 0x040040 // Video C interrupt mask
-#define VID_C_INT_STAT 0x040044 // Video C interrupt status
-#define VID_C_INT_MSTAT 0x040048 // Video C interrupt masked status
-#define VID_C_INT_SSTAT 0x04004C // Video C interrupt set status
-
-//*****************************************************************************
-#define VID_D_INT_MSK 0x040050 // Video D interrupt mask
-#define VID_D_INT_STAT 0x040054 // Video D interrupt status
-#define VID_D_INT_MSTAT 0x040058 // Video D interrupt masked status
-#define VID_D_INT_SSTAT 0x04005C // Video D interrupt set status
-
-//*****************************************************************************
-#define VID_E_INT_MSK 0x040060 // Video E interrupt mask
-#define VID_E_INT_STAT 0x040064 // Video E interrupt status
-#define VID_E_INT_MSTAT 0x040068 // Video E interrupt masked status
-#define VID_E_INT_SSTAT 0x04006C // Video E interrupt set status
-
-//*****************************************************************************
-#define VID_F_INT_MSK 0x040070 // Video F interrupt mask
-#define VID_F_INT_STAT 0x040074 // Video F interrupt status
-#define VID_F_INT_MSTAT 0x040078 // Video F interrupt masked status
-#define VID_F_INT_SSTAT 0x04007C // Video F interrupt set status
-
-//*****************************************************************************
-#define VID_G_INT_MSK 0x040080 // Video G interrupt mask
-#define VID_G_INT_STAT 0x040084 // Video G interrupt status
-#define VID_G_INT_MSTAT 0x040088 // Video G interrupt masked status
-#define VID_G_INT_SSTAT 0x04008C // Video G interrupt set status
-
-//*****************************************************************************
-#define VID_H_INT_MSK 0x040090 // Video H interrupt mask
-#define VID_H_INT_STAT 0x040094 // Video H interrupt status
-#define VID_H_INT_MSTAT 0x040098 // Video H interrupt masked status
-#define VID_H_INT_SSTAT 0x04009C // Video H interrupt set status
-
-//*****************************************************************************
-#define VID_I_INT_MSK 0x0400A0 // Video I interrupt mask
-#define VID_I_INT_STAT 0x0400A4 // Video I interrupt status
-#define VID_I_INT_MSTAT 0x0400A8 // Video I interrupt masked status
-#define VID_I_INT_SSTAT 0x0400AC // Video I interrupt set status
-
-//*****************************************************************************
-#define VID_J_INT_MSK 0x0400B0 // Video J interrupt mask
-#define VID_J_INT_STAT 0x0400B4 // Video J interrupt status
-#define VID_J_INT_MSTAT 0x0400B8 // Video J interrupt masked status
-#define VID_J_INT_SSTAT 0x0400BC // Video J interrupt set status
+/* ***************************************************************************** */
+#define VID_A_INT_MSK 0x040020 /* Video A interrupt mask */
+#define VID_A_INT_STAT 0x040024 /* Video A interrupt status */
+#define VID_A_INT_MSTAT 0x040028 /* Video A interrupt masked status */
+#define VID_A_INT_SSTAT 0x04002C /* Video A interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_B_INT_MSK 0x040030 /* Video B interrupt mask */
+#define VID_B_INT_STAT 0x040034 /* Video B interrupt status */
+#define VID_B_INT_MSTAT 0x040038 /* Video B interrupt masked status */
+#define VID_B_INT_SSTAT 0x04003C /* Video B interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_C_INT_MSK 0x040040 /* Video C interrupt mask */
+#define VID_C_INT_STAT 0x040044 /* Video C interrupt status */
+#define VID_C_INT_MSTAT 0x040048 /* Video C interrupt masked status */
+#define VID_C_INT_SSTAT 0x04004C /* Video C interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_D_INT_MSK 0x040050 /* Video D interrupt mask */
+#define VID_D_INT_STAT 0x040054 /* Video D interrupt status */
+#define VID_D_INT_MSTAT 0x040058 /* Video D interrupt masked status */
+#define VID_D_INT_SSTAT 0x04005C /* Video D interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_E_INT_MSK 0x040060 /* Video E interrupt mask */
+#define VID_E_INT_STAT 0x040064 /* Video E interrupt status */
+#define VID_E_INT_MSTAT 0x040068 /* Video E interrupt masked status */
+#define VID_E_INT_SSTAT 0x04006C /* Video E interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_F_INT_MSK 0x040070 /* Video F interrupt mask */
+#define VID_F_INT_STAT 0x040074 /* Video F interrupt status */
+#define VID_F_INT_MSTAT 0x040078 /* Video F interrupt masked status */
+#define VID_F_INT_SSTAT 0x04007C /* Video F interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_G_INT_MSK 0x040080 /* Video G interrupt mask */
+#define VID_G_INT_STAT 0x040084 /* Video G interrupt status */
+#define VID_G_INT_MSTAT 0x040088 /* Video G interrupt masked status */
+#define VID_G_INT_SSTAT 0x04008C /* Video G interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_H_INT_MSK 0x040090 /* Video H interrupt mask */
+#define VID_H_INT_STAT 0x040094 /* Video H interrupt status */
+#define VID_H_INT_MSTAT 0x040098 /* Video H interrupt masked status */
+#define VID_H_INT_SSTAT 0x04009C /* Video H interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_I_INT_MSK 0x0400A0 /* Video I interrupt mask */
+#define VID_I_INT_STAT 0x0400A4 /* Video I interrupt status */
+#define VID_I_INT_MSTAT 0x0400A8 /* Video I interrupt masked status */
+#define VID_I_INT_SSTAT 0x0400AC /* Video I interrupt set status */
+
+/* ***************************************************************************** */
+#define VID_J_INT_MSK 0x0400B0 /* Video J interrupt mask */
+#define VID_J_INT_STAT 0x0400B4 /* Video J interrupt status */
+#define VID_J_INT_MSTAT 0x0400B8 /* Video J interrupt masked status */
+#define VID_J_INT_SSTAT 0x0400BC /* Video J interrupt set status */
#define FLD_VID_SRC_OPC_ERR 0x00020000
#define FLD_VID_DST_OPC_ERR 0x00010000
@@ -166,35 +166,35 @@
#define FLD_VID_SRC_ERRORS FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF
#define FLD_VID_DST_ERRORS FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF
-//*****************************************************************************
-#define AUD_A_INT_MSK 0x0400C0 // Audio Int interrupt mask
-#define AUD_A_INT_STAT 0x0400C4 // Audio Int interrupt status
-#define AUD_A_INT_MSTAT 0x0400C8 // Audio Int interrupt masked status
-#define AUD_A_INT_SSTAT 0x0400CC // Audio Int interrupt set status
-
-//*****************************************************************************
-#define AUD_B_INT_MSK 0x0400D0 // Audio Int interrupt mask
-#define AUD_B_INT_STAT 0x0400D4 // Audio Int interrupt status
-#define AUD_B_INT_MSTAT 0x0400D8 // Audio Int interrupt masked status
-#define AUD_B_INT_SSTAT 0x0400DC // Audio Int interrupt set status
-
-//*****************************************************************************
-#define AUD_C_INT_MSK 0x0400E0 // Audio Int interrupt mask
-#define AUD_C_INT_STAT 0x0400E4 // Audio Int interrupt status
-#define AUD_C_INT_MSTAT 0x0400E8 // Audio Int interrupt masked status
-#define AUD_C_INT_SSTAT 0x0400EC // Audio Int interrupt set status
-
-//*****************************************************************************
-#define AUD_D_INT_MSK 0x0400F0 // Audio Int interrupt mask
-#define AUD_D_INT_STAT 0x0400F4 // Audio Int interrupt status
-#define AUD_D_INT_MSTAT 0x0400F8 // Audio Int interrupt masked status
-#define AUD_D_INT_SSTAT 0x0400FC // Audio Int interrupt set status
-
-//*****************************************************************************
-#define AUD_E_INT_MSK 0x040100 // Audio Int interrupt mask
-#define AUD_E_INT_STAT 0x040104 // Audio Int interrupt status
-#define AUD_E_INT_MSTAT 0x040108 // Audio Int interrupt masked status
-#define AUD_E_INT_SSTAT 0x04010C // Audio Int interrupt set status
+/* ***************************************************************************** */
+#define AUD_A_INT_MSK 0x0400C0 /* Audio Int interrupt mask */
+#define AUD_A_INT_STAT 0x0400C4 /* Audio Int interrupt status */
+#define AUD_A_INT_MSTAT 0x0400C8 /* Audio Int interrupt masked status */
+#define AUD_A_INT_SSTAT 0x0400CC /* Audio Int interrupt set status */
+
+/* ***************************************************************************** */
+#define AUD_B_INT_MSK 0x0400D0 /* Audio Int interrupt mask */
+#define AUD_B_INT_STAT 0x0400D4 /* Audio Int interrupt status */
+#define AUD_B_INT_MSTAT 0x0400D8 /* Audio Int interrupt masked status */
+#define AUD_B_INT_SSTAT 0x0400DC /* Audio Int interrupt set status */
+
+/* ***************************************************************************** */
+#define AUD_C_INT_MSK 0x0400E0 /* Audio Int interrupt mask */
+#define AUD_C_INT_STAT 0x0400E4 /* Audio Int interrupt status */
+#define AUD_C_INT_MSTAT 0x0400E8 /* Audio Int interrupt masked status */
+#define AUD_C_INT_SSTAT 0x0400EC /* Audio Int interrupt set status */
+
+/* ***************************************************************************** */
+#define AUD_D_INT_MSK 0x0400F0 /* Audio Int interrupt mask */
+#define AUD_D_INT_STAT 0x0400F4 /* Audio Int interrupt status */
+#define AUD_D_INT_MSTAT 0x0400F8 /* Audio Int interrupt masked status */
+#define AUD_D_INT_SSTAT 0x0400FC /* Audio Int interrupt set status */
+
+/* ***************************************************************************** */
+#define AUD_E_INT_MSK 0x040100 /* Audio Int interrupt mask */
+#define AUD_E_INT_STAT 0x040104 /* Audio Int interrupt status */
+#define AUD_E_INT_MSTAT 0x040108 /* Audio Int interrupt masked status */
+#define AUD_E_INT_SSTAT 0x04010C /* Audio Int interrupt set status */
#define FLD_AUD_SRC_OPC_ERR 0x00020000
#define FLD_AUD_DST_OPC_ERR 0x00010000
@@ -207,17 +207,17 @@
#define FLD_AUD_SRC_RISCI1 0x00000002
#define FLD_AUD_DST_RISCI1 0x00000001
-//*****************************************************************************
-#define MBIF_A_INT_MSK 0x040110 // MBIF Int interrupt mask
-#define MBIF_A_INT_STAT 0x040114 // MBIF Int interrupt status
-#define MBIF_A_INT_MSTAT 0x040118 // MBIF Int interrupt masked status
-#define MBIF_A_INT_SSTAT 0x04011C // MBIF Int interrupt set status
+/* ***************************************************************************** */
+#define MBIF_A_INT_MSK 0x040110 /* MBIF Int interrupt mask */
+#define MBIF_A_INT_STAT 0x040114 /* MBIF Int interrupt status */
+#define MBIF_A_INT_MSTAT 0x040118 /* MBIF Int interrupt masked status */
+#define MBIF_A_INT_SSTAT 0x04011C /* MBIF Int interrupt set status */
-//*****************************************************************************
-#define MBIF_B_INT_MSK 0x040120 // MBIF Int interrupt mask
-#define MBIF_B_INT_STAT 0x040124 // MBIF Int interrupt status
-#define MBIF_B_INT_MSTAT 0x040128 // MBIF Int interrupt masked status
-#define MBIF_B_INT_SSTAT 0x04012C // MBIF Int interrupt set status
+/* ***************************************************************************** */
+#define MBIF_B_INT_MSK 0x040120 /* MBIF Int interrupt mask */
+#define MBIF_B_INT_STAT 0x040124 /* MBIF Int interrupt status */
+#define MBIF_B_INT_MSTAT 0x040128 /* MBIF Int interrupt masked status */
+#define MBIF_B_INT_SSTAT 0x04012C /* MBIF Int interrupt set status */
#define FLD_MBIF_DST_OPC_ERR 0x00010000
#define FLD_MBIF_DST_SYNC 0x00001000
@@ -225,35 +225,35 @@
#define FLD_MBIF_DST_RISCI2 0x00000010
#define FLD_MBIF_DST_RISCI1 0x00000001
-//*****************************************************************************
-#define AUD_EXT_INT_MSK 0x040060 // Audio Ext interrupt mask
-#define AUD_EXT_INT_STAT 0x040064 // Audio Ext interrupt status
-#define AUD_EXT_INT_MSTAT 0x040068 // Audio Ext interrupt masked status
-#define AUD_EXT_INT_SSTAT 0x04006C // Audio Ext interrupt set status
+/* ***************************************************************************** */
+#define AUD_EXT_INT_MSK 0x040060 /* Audio Ext interrupt mask */
+#define AUD_EXT_INT_STAT 0x040064 /* Audio Ext interrupt status */
+#define AUD_EXT_INT_MSTAT 0x040068 /* Audio Ext interrupt masked status */
+#define AUD_EXT_INT_SSTAT 0x04006C /* Audio Ext interrupt set status */
#define FLD_AUD_EXT_OPC_ERR 0x00010000
#define FLD_AUD_EXT_SYNC 0x00001000
#define FLD_AUD_EXT_OF 0x00000100
#define FLD_AUD_EXT_RISCI2 0x00000010
#define FLD_AUD_EXT_RISCI1 0x00000001
-//*****************************************************************************
-#define GPIO_LO 0x110010 // Lower of GPIO pins [31:0]
-#define GPIO_HI 0x110014 // Upper WORD of GPIO pins [47:31]
+/* ***************************************************************************** */
+#define GPIO_LO 0x110010 /* Lower of GPIO pins [31:0] */
+#define GPIO_HI 0x110014 /* Upper WORD of GPIO pins [47:31] */
-#define GPIO_LO_OE 0x110018 // Lower of GPIO output enable [31:0]
-#define GPIO_HI_OE 0x11001C // Upper word of GPIO output enable [47:32]
+#define GPIO_LO_OE 0x110018 /* Lower of GPIO output enable [31:0] */
+#define GPIO_HI_OE 0x11001C /* Upper word of GPIO output enable [47:32] */
-#define GPIO_LO_INT_MSK 0x11003C // GPIO interrupt mask
-#define GPIO_LO_INT_STAT 0x110044 // GPIO interrupt status
-#define GPIO_LO_INT_MSTAT 0x11004C // GPIO interrupt masked status
-#define GPIO_LO_ISM_SNS 0x110054 // GPIO interrupt sensitivity
-#define GPIO_LO_ISM_POL 0x11005C // GPIO interrupt polarity
+#define GPIO_LO_INT_MSK 0x11003C /* GPIO interrupt mask */
+#define GPIO_LO_INT_STAT 0x110044 /* GPIO interrupt status */
+#define GPIO_LO_INT_MSTAT 0x11004C /* GPIO interrupt masked status */
+#define GPIO_LO_ISM_SNS 0x110054 /* GPIO interrupt sensitivity */
+#define GPIO_LO_ISM_POL 0x11005C /* GPIO interrupt polarity */
-#define GPIO_HI_INT_MSK 0x110040 // GPIO interrupt mask
-#define GPIO_HI_INT_STAT 0x110048 // GPIO interrupt status
-#define GPIO_HI_INT_MSTAT 0x110050 // GPIO interrupt masked status
-#define GPIO_HI_ISM_SNS 0x110058 // GPIO interrupt sensitivity
-#define GPIO_HI_ISM_POL 0x110060 // GPIO interrupt polarity
+#define GPIO_HI_INT_MSK 0x110040 /* GPIO interrupt mask */
+#define GPIO_HI_INT_STAT 0x110048 /* GPIO interrupt status */
+#define GPIO_HI_INT_MSTAT 0x110050 /* GPIO interrupt masked status */
+#define GPIO_HI_ISM_SNS 0x110058 /* GPIO interrupt sensitivity */
+#define GPIO_HI_ISM_POL 0x110060 /* GPIO interrupt polarity */
#define FLD_GPIO43_INT (1 << 11)
#define FLD_GPIO42_INT (1 << 10)
@@ -271,236 +271,236 @@
#define FLD_GPIO1_INT (1 << 1)
#define FLD_GPIO0_INT (1 << 0)
-//*****************************************************************************
-#define TC_REQ 0x040090 // Rider PCI Express traFFic class request
+/* ***************************************************************************** */
+#define TC_REQ 0x040090 /* Rider PCI Express traFFic class request */
-//*****************************************************************************
-#define TC_REQ_SET 0x040094 // Rider PCI Express traFFic class request set
+/* ***************************************************************************** */
+#define TC_REQ_SET 0x040094 /* Rider PCI Express traFFic class request set */
-//*****************************************************************************
-// Rider
-//*****************************************************************************
+/* ***************************************************************************** */
+/* Rider */
+/* ***************************************************************************** */
-// PCI Compatible Header
-//*****************************************************************************
+/* PCI Compatible Header */
+/* ***************************************************************************** */
#define RDR_CFG0 0x050000
#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG1 0x050004
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG2 0x050008
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG3 0x05000C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG4 0x050010
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG5 0x050014
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG6 0x050018
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG7 0x05001C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG8 0x050020
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFG9 0x050024
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGA 0x050028
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGB 0x05002C
#define RDR_SUSSYSTEM_ID_CFG 0x05002C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGC 0x050030
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGD 0x050034
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGE 0x050038
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_CFGF 0x05003C
-//*****************************************************************************
-// PCI-Express Capabilities
-//*****************************************************************************
+/* ***************************************************************************** */
+/* PCI-Express Capabilities */
+/* ***************************************************************************** */
#define RDR_PECAP 0x050040
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PEDEVCAP 0x050044
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PEDEVSC 0x050048
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PELINKCAP 0x05004C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PELINKSC 0x050050
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PMICAP 0x050080
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_PMCSR 0x050084
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VPDCAP 0x050090
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VPDDATA 0x050094
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MSICAP 0x0500A0
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MSIARL 0x0500A4
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MSIARU 0x0500A8
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MSIDATA 0x0500AC
-//*****************************************************************************
-// PCI Express Extended Capabilities
-//*****************************************************************************
+/* ***************************************************************************** */
+/* PCI Express Extended Capabilities */
+/* ***************************************************************************** */
#define RDR_AERXCAP 0x050100
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERUESTA 0x050104
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERUEMSK 0x050108
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERUESEV 0x05010C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERCESTA 0x050110
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERCEMSK 0x050114
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERCC 0x050118
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERHL0 0x05011C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERHL1 0x050120
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERHL2 0x050124
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_AERHL3 0x050128
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCXCAP 0x050200
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCCAP1 0x050204
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCCAP2 0x050208
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCSC 0x05020C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR0_CAP 0x050210
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR0_CTRL 0x050214
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR0_STAT 0x050218
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR1_CAP 0x05021C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR1_CTRL 0x050220
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR1_STAT 0x050224
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR2_CAP 0x050228
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR2_CTRL 0x05022C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR2_STAT 0x050230
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR3_CAP 0x050234
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR3_CTRL 0x050238
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR3_STAT 0x05023C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB0 0x050240
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB1 0x050244
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB2 0x050248
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB3 0x05024C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB4 0x050250
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB5 0x050254
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB6 0x050258
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCARB7 0x05025C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RDRSTAT0 0x050300
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RDRSTAT1 0x050304
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RDRCTL0 0x050308
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RDRCTL1 0x05030C
-//*****************************************************************************
-// Transaction Layer Registers
-//*****************************************************************************
+/* ***************************************************************************** */
+/* Transaction Layer Registers */
+/* ***************************************************************************** */
#define RDR_TLSTAT0 0x050310
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_TLSTAT1 0x050314
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_TLCTL0 0x050318
#define FLD_CFG_UR_CPL_MODE 0x00000040
#define FLD_CFG_CORR_ERR_QUITE 0x00000020
@@ -510,569 +510,569 @@
#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
#define FLD_CFG_TAG_ORDER_EN 0x00000001
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_TLCTL1 0x05031C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REQRCAL 0x050320
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REQRCAU 0x050324
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REQEPA 0x050328
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REQCTRL 0x05032C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REQSTAT 0x050330
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_TL_TEST 0x050334
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR01_CTL 0x050348
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_VCR23_CTL 0x05034C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RX_VCR0_FC 0x050350
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RX_VCR1_FC 0x050354
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RX_VCR2_FC 0x050358
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_RX_VCR3_FC 0x05035C
-//*****************************************************************************
-// Data Link Layer Registers
-//*****************************************************************************
+/* ***************************************************************************** */
+/* Data Link Layer Registers */
+/* ***************************************************************************** */
#define RDR_DLLSTAT 0x050360
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_DLLCTRL 0x050364
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_REPLAYTO 0x050368
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_ACKLATTO 0x05036C
-//*****************************************************************************
-// MAC Layer Registers
-//*****************************************************************************
+/* ***************************************************************************** */
+/* MAC Layer Registers */
+/* ***************************************************************************** */
#define RDR_MACSTAT0 0x050380
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MACSTAT1 0x050384
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MACCTRL0 0x050388
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MACCTRL1 0x05038C
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MACCTRL2 0x050390
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_MAC_LB_DATA 0x050394
-//*****************************************************************************
+/* ***************************************************************************** */
#define RDR_L0S_EXIT_LAT 0x050398
-//*****************************************************************************
-// DMAC
-//*****************************************************************************
-#define DMA1_PTR1 0x100000 // DMA Current Ptr : Ch#1
+/* ***************************************************************************** */
+/* DMAC */
+/* ***************************************************************************** */
+#define DMA1_PTR1 0x100000 /* DMA Current Ptr : Ch#1 */
-//*****************************************************************************
-#define DMA2_PTR1 0x100004 // DMA Current Ptr : Ch#2
+/* ***************************************************************************** */
+#define DMA2_PTR1 0x100004 /* DMA Current Ptr : Ch#2 */
-//*****************************************************************************
-#define DMA3_PTR1 0x100008 // DMA Current Ptr : Ch#3
+/* ***************************************************************************** */
+#define DMA3_PTR1 0x100008 /* DMA Current Ptr : Ch#3 */
-//*****************************************************************************
-#define DMA4_PTR1 0x10000C // DMA Current Ptr : Ch#4
+/* ***************************************************************************** */
+#define DMA4_PTR1 0x10000C /* DMA Current Ptr : Ch#4 */
-//*****************************************************************************
-#define DMA5_PTR1 0x100010 // DMA Current Ptr : Ch#5
+/* ***************************************************************************** */
+#define DMA5_PTR1 0x100010 /* DMA Current Ptr : Ch#5 */
-//*****************************************************************************
-#define DMA6_PTR1 0x100014 // DMA Current Ptr : Ch#6
+/* ***************************************************************************** */
+#define DMA6_PTR1 0x100014 /* DMA Current Ptr : Ch#6 */
-//*****************************************************************************
-#define DMA7_PTR1 0x100018 // DMA Current Ptr : Ch#7
+/* ***************************************************************************** */
+#define DMA7_PTR1 0x100018 /* DMA Current Ptr : Ch#7 */
-//*****************************************************************************
-#define DMA8_PTR1 0x10001C // DMA Current Ptr : Ch#8
+/* ***************************************************************************** */
+#define DMA8_PTR1 0x10001C /* DMA Current Ptr : Ch#8 */
-//*****************************************************************************
-#define DMA9_PTR1 0x100020 // DMA Current Ptr : Ch#9
+/* ***************************************************************************** */
+#define DMA9_PTR1 0x100020 /* DMA Current Ptr : Ch#9 */
-//*****************************************************************************
-#define DMA10_PTR1 0x100024 // DMA Current Ptr : Ch#10
+/* ***************************************************************************** */
+#define DMA10_PTR1 0x100024 /* DMA Current Ptr : Ch#10 */
-//*****************************************************************************
-#define DMA11_PTR1 0x100028 // DMA Current Ptr : Ch#11
+/* ***************************************************************************** */
+#define DMA11_PTR1 0x100028 /* DMA Current Ptr : Ch#11 */
-//*****************************************************************************
-#define DMA12_PTR1 0x10002C // DMA Current Ptr : Ch#12
+/* ***************************************************************************** */
+#define DMA12_PTR1 0x10002C /* DMA Current Ptr : Ch#12 */
-//*****************************************************************************
-#define DMA13_PTR1 0x100030 // DMA Current Ptr : Ch#13
+/* ***************************************************************************** */
+#define DMA13_PTR1 0x100030 /* DMA Current Ptr : Ch#13 */
-//*****************************************************************************
-#define DMA14_PTR1 0x100034 // DMA Current Ptr : Ch#14
+/* ***************************************************************************** */
+#define DMA14_PTR1 0x100034 /* DMA Current Ptr : Ch#14 */
-//*****************************************************************************
-#define DMA15_PTR1 0x100038 // DMA Current Ptr : Ch#15
+/* ***************************************************************************** */
+#define DMA15_PTR1 0x100038 /* DMA Current Ptr : Ch#15 */
-//*****************************************************************************
-#define DMA16_PTR1 0x10003C // DMA Current Ptr : Ch#16
+/* ***************************************************************************** */
+#define DMA16_PTR1 0x10003C /* DMA Current Ptr : Ch#16 */
-//*****************************************************************************
-#define DMA17_PTR1 0x100040 // DMA Current Ptr : Ch#17
+/* ***************************************************************************** */
+#define DMA17_PTR1 0x100040 /* DMA Current Ptr : Ch#17 */
-//*****************************************************************************
-#define DMA18_PTR1 0x100044 // DMA Current Ptr : Ch#18
+/* ***************************************************************************** */
+#define DMA18_PTR1 0x100044 /* DMA Current Ptr : Ch#18 */
-//*****************************************************************************
-#define DMA19_PTR1 0x100048 // DMA Current Ptr : Ch#19
+/* ***************************************************************************** */
+#define DMA19_PTR1 0x100048 /* DMA Current Ptr : Ch#19 */
-//*****************************************************************************
-#define DMA20_PTR1 0x10004C // DMA Current Ptr : Ch#20
+/* ***************************************************************************** */
+#define DMA20_PTR1 0x10004C /* DMA Current Ptr : Ch#20 */
-//*****************************************************************************
-#define DMA21_PTR1 0x100050 // DMA Current Ptr : Ch#21
+/* ***************************************************************************** */
+#define DMA21_PTR1 0x100050 /* DMA Current Ptr : Ch#21 */
-//*****************************************************************************
-#define DMA22_PTR1 0x100054 // DMA Current Ptr : Ch#22
+/* ***************************************************************************** */
+#define DMA22_PTR1 0x100054 /* DMA Current Ptr : Ch#22 */
-//*****************************************************************************
-#define DMA23_PTR1 0x100058 // DMA Current Ptr : Ch#23
+/* ***************************************************************************** */
+#define DMA23_PTR1 0x100058 /* DMA Current Ptr : Ch#23 */
-//*****************************************************************************
-#define DMA24_PTR1 0x10005C // DMA Current Ptr : Ch#24
+/* ***************************************************************************** */
+#define DMA24_PTR1 0x10005C /* DMA Current Ptr : Ch#24 */
-//*****************************************************************************
-#define DMA25_PTR1 0x100060 // DMA Current Ptr : Ch#25
+/* ***************************************************************************** */
+#define DMA25_PTR1 0x100060 /* DMA Current Ptr : Ch#25 */
-//*****************************************************************************
-#define DMA26_PTR1 0x100064 // DMA Current Ptr : Ch#26
+/* ***************************************************************************** */
+#define DMA26_PTR1 0x100064 /* DMA Current Ptr : Ch#26 */
-//*****************************************************************************
-#define DMA1_PTR2 0x100080 // DMA Tab Ptr : Ch#1
+/* ***************************************************************************** */
+#define DMA1_PTR2 0x100080 /* DMA Tab Ptr : Ch#1 */
-//*****************************************************************************
-#define DMA2_PTR2 0x100084 // DMA Tab Ptr : Ch#2
+/* ***************************************************************************** */
+#define DMA2_PTR2 0x100084 /* DMA Tab Ptr : Ch#2 */
-//*****************************************************************************
-#define DMA3_PTR2 0x100088 // DMA Tab Ptr : Ch#3
+/* ***************************************************************************** */
+#define DMA3_PTR2 0x100088 /* DMA Tab Ptr : Ch#3 */
-//*****************************************************************************
-#define DMA4_PTR2 0x10008C // DMA Tab Ptr : Ch#4
+/* ***************************************************************************** */
+#define DMA4_PTR2 0x10008C /* DMA Tab Ptr : Ch#4 */
-//*****************************************************************************
-#define DMA5_PTR2 0x100090 // DMA Tab Ptr : Ch#5
+/* ***************************************************************************** */
+#define DMA5_PTR2 0x100090 /* DMA Tab Ptr : Ch#5 */
-//*****************************************************************************
-#define DMA6_PTR2 0x100094 // DMA Tab Ptr : Ch#6
+/* ***************************************************************************** */
+#define DMA6_PTR2 0x100094 /* DMA Tab Ptr : Ch#6 */
-//*****************************************************************************
-#define DMA7_PTR2 0x100098 // DMA Tab Ptr : Ch#7
+/* ***************************************************************************** */
+#define DMA7_PTR2 0x100098 /* DMA Tab Ptr : Ch#7 */
-//*****************************************************************************
-#define DMA8_PTR2 0x10009C // DMA Tab Ptr : Ch#8
+/* ***************************************************************************** */
+#define DMA8_PTR2 0x10009C /* DMA Tab Ptr : Ch#8 */
-//*****************************************************************************
-#define DMA9_PTR2 0x1000A0 // DMA Tab Ptr : Ch#9
+/* ***************************************************************************** */
+#define DMA9_PTR2 0x1000A0 /* DMA Tab Ptr : Ch#9 */
-//*****************************************************************************
-#define DMA10_PTR2 0x1000A4 // DMA Tab Ptr : Ch#10
+/* ***************************************************************************** */
+#define DMA10_PTR2 0x1000A4 /* DMA Tab Ptr : Ch#10 */
-//*****************************************************************************
-#define DMA11_PTR2 0x1000A8 // DMA Tab Ptr : Ch#11
+/* ***************************************************************************** */
+#define DMA11_PTR2 0x1000A8 /* DMA Tab Ptr : Ch#11 */
-//*****************************************************************************
-#define DMA12_PTR2 0x1000AC // DMA Tab Ptr : Ch#12
+/* ***************************************************************************** */
+#define DMA12_PTR2 0x1000AC /* DMA Tab Ptr : Ch#12 */
-//*****************************************************************************
-#define DMA13_PTR2 0x1000B0 // DMA Tab Ptr : Ch#13
+/* ***************************************************************************** */
+#define DMA13_PTR2 0x1000B0 /* DMA Tab Ptr : Ch#13 */
-//*****************************************************************************
-#define DMA14_PTR2 0x1000B4 // DMA Tab Ptr : Ch#14
+/* ***************************************************************************** */
+#define DMA14_PTR2 0x1000B4 /* DMA Tab Ptr : Ch#14 */
-//*****************************************************************************
-#define DMA15_PTR2 0x1000B8 // DMA Tab Ptr : Ch#15
+/* ***************************************************************************** */
+#define DMA15_PTR2 0x1000B8 /* DMA Tab Ptr : Ch#15 */
-//*****************************************************************************
-#define DMA16_PTR2 0x1000BC // DMA Tab Ptr : Ch#16
+/* ***************************************************************************** */
+#define DMA16_PTR2 0x1000BC /* DMA Tab Ptr : Ch#16 */
-//*****************************************************************************
-#define DMA17_PTR2 0x1000C0 // DMA Tab Ptr : Ch#17
+/* ***************************************************************************** */
+#define DMA17_PTR2 0x1000C0 /* DMA Tab Ptr : Ch#17 */
-//*****************************************************************************
-#define DMA18_PTR2 0x1000C4 // DMA Tab Ptr : Ch#18
+/* ***************************************************************************** */
+#define DMA18_PTR2 0x1000C4 /* DMA Tab Ptr : Ch#18 */
-//*****************************************************************************
-#define DMA19_PTR2 0x1000C8 // DMA Tab Ptr : Ch#19
+/* ***************************************************************************** */
+#define DMA19_PTR2 0x1000C8 /* DMA Tab Ptr : Ch#19 */
-//*****************************************************************************
-#define DMA20_PTR2 0x1000CC // DMA Tab Ptr : Ch#20
+/* ***************************************************************************** */
+#define DMA20_PTR2 0x1000CC /* DMA Tab Ptr : Ch#20 */
-//*****************************************************************************
-#define DMA21_PTR2 0x1000D0 // DMA Tab Ptr : Ch#21
+/* ***************************************************************************** */
+#define DMA21_PTR2 0x1000D0 /* DMA Tab Ptr : Ch#21 */
-//*****************************************************************************
-#define DMA22_PTR2 0x1000D4 // DMA Tab Ptr : Ch#22
+/* ***************************************************************************** */
+#define DMA22_PTR2 0x1000D4 /* DMA Tab Ptr : Ch#22 */
-//*****************************************************************************
-#define DMA23_PTR2 0x1000D8 // DMA Tab Ptr : Ch#23
+/* ***************************************************************************** */
+#define DMA23_PTR2 0x1000D8 /* DMA Tab Ptr : Ch#23 */
-//*****************************************************************************
-#define DMA24_PTR2 0x1000DC // DMA Tab Ptr : Ch#24
+/* ***************************************************************************** */
+#define DMA24_PTR2 0x1000DC /* DMA Tab Ptr : Ch#24 */
-//*****************************************************************************
-#define DMA25_PTR2 0x1000E0 // DMA Tab Ptr : Ch#25
+/* ***************************************************************************** */
+#define DMA25_PTR2 0x1000E0 /* DMA Tab Ptr : Ch#25 */
-//*****************************************************************************
-#define DMA26_PTR2 0x1000E4 // DMA Tab Ptr : Ch#26
+/* ***************************************************************************** */
+#define DMA26_PTR2 0x1000E4 /* DMA Tab Ptr : Ch#26 */
-//*****************************************************************************
-#define DMA1_CNT1 0x100100 // DMA BuFFer Size : Ch#1
+/* ***************************************************************************** */
+#define DMA1_CNT1 0x100100 /* DMA BuFFer Size : Ch#1 */
-//*****************************************************************************
-#define DMA2_CNT1 0x100104 // DMA BuFFer Size : Ch#2
+/* ***************************************************************************** */
+#define DMA2_CNT1 0x100104 /* DMA BuFFer Size : Ch#2 */
-//*****************************************************************************
-#define DMA3_CNT1 0x100108 // DMA BuFFer Size : Ch#3
+/* ***************************************************************************** */
+#define DMA3_CNT1 0x100108 /* DMA BuFFer Size : Ch#3 */
-//*****************************************************************************
-#define DMA4_CNT1 0x10010C // DMA BuFFer Size : Ch#4
+/* ***************************************************************************** */
+#define DMA4_CNT1 0x10010C /* DMA BuFFer Size : Ch#4 */
-//*****************************************************************************
-#define DMA5_CNT1 0x100110 // DMA BuFFer Size : Ch#5
+/* ***************************************************************************** */
+#define DMA5_CNT1 0x100110 /* DMA BuFFer Size : Ch#5 */
-//*****************************************************************************
-#define DMA6_CNT1 0x100114 // DMA BuFFer Size : Ch#6
+/* ***************************************************************************** */
+#define DMA6_CNT1 0x100114 /* DMA BuFFer Size : Ch#6 */
-//*****************************************************************************
-#define DMA7_CNT1 0x100118 // DMA BuFFer Size : Ch#7
+/* ***************************************************************************** */
+#define DMA7_CNT1 0x100118 /* DMA BuFFer Size : Ch#7 */
-//*****************************************************************************
-#define DMA8_CNT1 0x10011C // DMA BuFFer Size : Ch#8
+/* ***************************************************************************** */
+#define DMA8_CNT1 0x10011C /* DMA BuFFer Size : Ch#8 */
-//*****************************************************************************
-#define DMA9_CNT1 0x100120 // DMA BuFFer Size : Ch#9
+/* ***************************************************************************** */
+#define DMA9_CNT1 0x100120 /* DMA BuFFer Size : Ch#9 */
-//*****************************************************************************
-#define DMA10_CNT1 0x100124 // DMA BuFFer Size : Ch#10
+/* ***************************************************************************** */
+#define DMA10_CNT1 0x100124 /* DMA BuFFer Size : Ch#10 */
-//*****************************************************************************
-#define DMA11_CNT1 0x100128 // DMA BuFFer Size : Ch#11
+/* ***************************************************************************** */
+#define DMA11_CNT1 0x100128 /* DMA BuFFer Size : Ch#11 */
-//*****************************************************************************
-#define DMA12_CNT1 0x10012C // DMA BuFFer Size : Ch#12
+/* ***************************************************************************** */
+#define DMA12_CNT1 0x10012C /* DMA BuFFer Size : Ch#12 */
-//*****************************************************************************
-#define DMA13_CNT1 0x100130 // DMA BuFFer Size : Ch#13
+/* ***************************************************************************** */
+#define DMA13_CNT1 0x100130 /* DMA BuFFer Size : Ch#13 */
-//*****************************************************************************
-#define DMA14_CNT1 0x100134 // DMA BuFFer Size : Ch#14
+/* ***************************************************************************** */
+#define DMA14_CNT1 0x100134 /* DMA BuFFer Size : Ch#14 */
-//*****************************************************************************
-#define DMA15_CNT1 0x100138 // DMA BuFFer Size : Ch#15
+/* ***************************************************************************** */
+#define DMA15_CNT1 0x100138 /* DMA BuFFer Size : Ch#15 */
-//*****************************************************************************
-#define DMA16_CNT1 0x10013C // DMA BuFFer Size : Ch#16
+/* ***************************************************************************** */
+#define DMA16_CNT1 0x10013C /* DMA BuFFer Size : Ch#16 */
-//*****************************************************************************
-#define DMA17_CNT1 0x100140 // DMA BuFFer Size : Ch#17
+/* ***************************************************************************** */
+#define DMA17_CNT1 0x100140 /* DMA BuFFer Size : Ch#17 */
-//*****************************************************************************
-#define DMA18_CNT1 0x100144 // DMA BuFFer Size : Ch#18
+/* ***************************************************************************** */
+#define DMA18_CNT1 0x100144 /* DMA BuFFer Size : Ch#18 */
-//*****************************************************************************
-#define DMA19_CNT1 0x100148 // DMA BuFFer Size : Ch#19
+/* ***************************************************************************** */
+#define DMA19_CNT1 0x100148 /* DMA BuFFer Size : Ch#19 */
-//*****************************************************************************
-#define DMA20_CNT1 0x10014C // DMA BuFFer Size : Ch#20
+/* ***************************************************************************** */
+#define DMA20_CNT1 0x10014C /* DMA BuFFer Size : Ch#20 */
-//*****************************************************************************
-#define DMA21_CNT1 0x100150 // DMA BuFFer Size : Ch#21
+/* ***************************************************************************** */
+#define DMA21_CNT1 0x100150 /* DMA BuFFer Size : Ch#21 */
-//*****************************************************************************
-#define DMA22_CNT1 0x100154 // DMA BuFFer Size : Ch#22
+/* ***************************************************************************** */
+#define DMA22_CNT1 0x100154 /* DMA BuFFer Size : Ch#22 */
-//*****************************************************************************
-#define DMA23_CNT1 0x100158 // DMA BuFFer Size : Ch#23
+/* ***************************************************************************** */
+#define DMA23_CNT1 0x100158 /* DMA BuFFer Size : Ch#23 */
-//*****************************************************************************
-#define DMA24_CNT1 0x10015C // DMA BuFFer Size : Ch#24
+/* ***************************************************************************** */
+#define DMA24_CNT1 0x10015C /* DMA BuFFer Size : Ch#24 */
-//*****************************************************************************
-#define DMA25_CNT1 0x100160 // DMA BuFFer Size : Ch#25
+/* ***************************************************************************** */
+#define DMA25_CNT1 0x100160 /* DMA BuFFer Size : Ch#25 */
-//*****************************************************************************
-#define DMA26_CNT1 0x100164 // DMA BuFFer Size : Ch#26
+/* ***************************************************************************** */
+#define DMA26_CNT1 0x100164 /* DMA BuFFer Size : Ch#26 */
-//*****************************************************************************
-#define DMA1_CNT2 0x100180 // DMA Table Size : Ch#1
+/* ***************************************************************************** */
+#define DMA1_CNT2 0x100180 /* DMA Table Size : Ch#1 */
-//*****************************************************************************
-#define DMA2_CNT2 0x100184 // DMA Table Size : Ch#2
+/* ***************************************************************************** */
+#define DMA2_CNT2 0x100184 /* DMA Table Size : Ch#2 */
-//*****************************************************************************
-#define DMA3_CNT2 0x100188 // DMA Table Size : Ch#3
+/* ***************************************************************************** */
+#define DMA3_CNT2 0x100188 /* DMA Table Size : Ch#3 */
-//*****************************************************************************
-#define DMA4_CNT2 0x10018C // DMA Table Size : Ch#4
+/* ***************************************************************************** */
+#define DMA4_CNT2 0x10018C /* DMA Table Size : Ch#4 */
-//*****************************************************************************
-#define DMA5_CNT2 0x100190 // DMA Table Size : Ch#5
+/* ***************************************************************************** */
+#define DMA5_CNT2 0x100190 /* DMA Table Size : Ch#5 */
-//*****************************************************************************
-#define DMA6_CNT2 0x100194 // DMA Table Size : Ch#6
+/* ***************************************************************************** */
+#define DMA6_CNT2 0x100194 /* DMA Table Size : Ch#6 */
-//*****************************************************************************
-#define DMA7_CNT2 0x100198 // DMA Table Size : Ch#7
+/* ***************************************************************************** */
+#define DMA7_CNT2 0x100198 /* DMA Table Size : Ch#7 */
-//*****************************************************************************
-#define DMA8_CNT2 0x10019C // DMA Table Size : Ch#8
+/* ***************************************************************************** */
+#define DMA8_CNT2 0x10019C /* DMA Table Size : Ch#8 */
-//*****************************************************************************
-#define DMA9_CNT2 0x1001A0 // DMA Table Size : Ch#9
+/* ***************************************************************************** */
+#define DMA9_CNT2 0x1001A0 /* DMA Table Size : Ch#9 */
-//*****************************************************************************
-#define DMA10_CNT2 0x1001A4 // DMA Table Size : Ch#10
+/* ***************************************************************************** */
+#define DMA10_CNT2 0x1001A4 /* DMA Table Size : Ch#10 */
-//*****************************************************************************
-#define DMA11_CNT2 0x1001A8 // DMA Table Size : Ch#11
+/* ***************************************************************************** */
+#define DMA11_CNT2 0x1001A8 /* DMA Table Size : Ch#11 */
-//*****************************************************************************
-#define DMA12_CNT2 0x1001AC // DMA Table Size : Ch#12
+/* ***************************************************************************** */
+#define DMA12_CNT2 0x1001AC /* DMA Table Size : Ch#12 */
-//*****************************************************************************
-#define DMA13_CNT2 0x1001B0 // DMA Table Size : Ch#13
+/* ***************************************************************************** */
+#define DMA13_CNT2 0x1001B0 /* DMA Table Size : Ch#13 */
-//*****************************************************************************
-#define DMA14_CNT2 0x1001B4 // DMA Table Size : Ch#14
+/* ***************************************************************************** */
+#define DMA14_CNT2 0x1001B4 /* DMA Table Size : Ch#14 */
-//*****************************************************************************
-#define DMA15_CNT2 0x1001B8 // DMA Table Size : Ch#15
+/* ***************************************************************************** */
+#define DMA15_CNT2 0x1001B8 /* DMA Table Size : Ch#15 */
-//*****************************************************************************
-#define DMA16_CNT2 0x1001BC // DMA Table Size : Ch#16
+/* ***************************************************************************** */
+#define DMA16_CNT2 0x1001BC /* DMA Table Size : Ch#16 */
-//*****************************************************************************
-#define DMA17_CNT2 0x1001C0 // DMA Table Size : Ch#17
+/* ***************************************************************************** */
+#define DMA17_CNT2 0x1001C0 /* DMA Table Size : Ch#17 */
-//*****************************************************************************
-#define DMA18_CNT2 0x1001C4 // DMA Table Size : Ch#18
+/* ***************************************************************************** */
+#define DMA18_CNT2 0x1001C4 /* DMA Table Size : Ch#18 */
-//*****************************************************************************
-#define DMA19_CNT2 0x1001C8 // DMA Table Size : Ch#19
+/* ***************************************************************************** */
+#define DMA19_CNT2 0x1001C8 /* DMA Table Size : Ch#19 */
-//*****************************************************************************
-#define DMA20_CNT2 0x1001CC // DMA Table Size : Ch#20
+/* ***************************************************************************** */
+#define DMA20_CNT2 0x1001CC /* DMA Table Size : Ch#20 */
-//*****************************************************************************
-#define DMA21_CNT2 0x1001D0 // DMA Table Size : Ch#21
+/* ***************************************************************************** */
+#define DMA21_CNT2 0x1001D0 /* DMA Table Size : Ch#21 */
-//*****************************************************************************
-#define DMA22_CNT2 0x1001D4 // DMA Table Size : Ch#22
+/* ***************************************************************************** */
+#define DMA22_CNT2 0x1001D4 /* DMA Table Size : Ch#22 */
-//*****************************************************************************
-#define DMA23_CNT2 0x1001D8 // DMA Table Size : Ch#23
+/* ***************************************************************************** */
+#define DMA23_CNT2 0x1001D8 /* DMA Table Size : Ch#23 */
-//*****************************************************************************
-#define DMA24_CNT2 0x1001DC // DMA Table Size : Ch#24
+/* ***************************************************************************** */
+#define DMA24_CNT2 0x1001DC /* DMA Table Size : Ch#24 */
-//*****************************************************************************
-#define DMA25_CNT2 0x1001E0 // DMA Table Size : Ch#25
+/* ***************************************************************************** */
+#define DMA25_CNT2 0x1001E0 /* DMA Table Size : Ch#25 */
-//*****************************************************************************
-#define DMA26_CNT2 0x1001E4 // DMA Table Size : Ch#26
+/* ***************************************************************************** */
+#define DMA26_CNT2 0x1001E4 /* DMA Table Size : Ch#26 */
-//*****************************************************************************
- // ITG
-//*****************************************************************************
-#define TM_CNT_LDW 0x110000 // Timer : Counter low
+/* ***************************************************************************** */
+ /* ITG */
+/* ***************************************************************************** */
+#define TM_CNT_LDW 0x110000 /* Timer : Counter low */
-//*****************************************************************************
-#define TM_CNT_UW 0x110004 // Timer : Counter high word
+/* ***************************************************************************** */
+#define TM_CNT_UW 0x110004 /* Timer : Counter high word */
-//*****************************************************************************
-#define TM_LMT_LDW 0x110008 // Timer : Limit low
+/* ***************************************************************************** */
+#define TM_LMT_LDW 0x110008 /* Timer : Limit low */
-//*****************************************************************************
-#define TM_LMT_UW 0x11000C // Timer : Limit high word
+/* ***************************************************************************** */
+#define TM_LMT_UW 0x11000C /* Timer : Limit high word */
-//*****************************************************************************
-#define GP0_IO 0x110010 // GPIO output enables data I/O
-#define FLD_GP_OE 0x00FF0000 // GPIO: GP_OE output enable
-#define FLD_GP_IN 0x0000FF00 // GPIO: GP_IN status
-#define FLD_GP_OUT 0x000000FF // GPIO: GP_OUT control
+/* ***************************************************************************** */
+#define GP0_IO 0x110010 /* GPIO output enables data I/O */
+#define FLD_GP_OE 0x00FF0000 /* GPIO: GP_OE output enable */
+#define FLD_GP_IN 0x0000FF00 /* GPIO: GP_IN status */
+#define FLD_GP_OUT 0x000000FF /* GPIO: GP_OUT control */
-//*****************************************************************************
-#define GPIO_ISM 0x110014 // GPIO interrupt sensitivity mode
+/* ***************************************************************************** */
+#define GPIO_ISM 0x110014 /* GPIO interrupt sensitivity mode */
#define FLD_GP_ISM_SNS 0x00000070
#define FLD_GP_ISM_POL 0x00000007
-//*****************************************************************************
-#define SOFT_RESET 0x11001C // Output system reset reg
+/* ***************************************************************************** */
+#define SOFT_RESET 0x11001C /* Output system reset reg */
#define FLD_PECOS_SOFT_RESET 0x00000001
-//*****************************************************************************
-#define MC416_RWD 0x110020 // MC416 GPIO[18:3] pin
-#define MC416_OEN 0x110024 // Output enable of GPIO[18:3]
+/* ***************************************************************************** */
+#define MC416_RWD 0x110020 /* MC416 GPIO[18:3] pin */
+#define MC416_OEN 0x110024 /* Output enable of GPIO[18:3] */
#define MC416_CTL 0x110028
-//*****************************************************************************
-#define ALT_PIN_OUT_SEL 0x11002C // Alternate GPIO output select
+/* ***************************************************************************** */
+#define ALT_PIN_OUT_SEL 0x11002C /* Alternate GPIO output select */
#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
-// 0 Disabled <-- default
-// 1 GPIO[0]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
-// 8 ATT_IF
+/* 0 Disabled <-- default */
+/* 1 GPIO[0] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
+/* 8 ATT_IF */
#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
-// 0 AUX_PLL_CLK<-- default
-// 1 GPIO[2]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 AUX_PLL_CLK<-- default */
+/* 1 GPIO[2] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_IR_TX_ALT_SEL 0x00F00000
-// 0 IR_TX <-- default
-// 1 GPIO[1]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 IR_TX <-- default */
+/* 1 GPIO[1] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_IR_RX_ALT_SEL 0x000F0000
-// 0 IR_RX <-- default
-// 1 GPIO[0]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 IR_RX <-- default */
+/* 1 GPIO[0] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_GPIO10_ALT_SEL 0x0000F000
-// 0 GPIO[10] <-- default
-// 1 GPIO[0]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 GPIO[10] <-- default */
+/* 1 GPIO[0] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_GPIO2_ALT_SEL 0x00000F00
-// 0 GPIO[2] <-- default
-// 1 GPIO[1]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 GPIO[2] <-- default */
+/* 1 GPIO[1] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_GPIO1_ALT_SEL 0x000000F0
-// 0 GPIO[1] <-- default
-// 1 GPIO[0]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 GPIO[1] <-- default */
+/* 1 GPIO[0] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
#define FLD_GPIO0_ALT_SEL 0x0000000F
-// 0 GPIO[0] <-- default
-// 1 GPIO[1]
-// 2 GPIO[10]
-// 3 VIP_656_DATA_VAL
-// 4 VIP_656_DATA[0]
-// 5 VIP_656_CLK
-// 6 VIP_656_DATA_EXT[1]
-// 7 VIP_656_DATA_EXT[0]
+/* 0 GPIO[0] <-- default */
+/* 1 GPIO[1] */
+/* 2 GPIO[10] */
+/* 3 VIP_656_DATA_VAL */
+/* 4 VIP_656_DATA[0] */
+/* 5 VIP_656_CLK */
+/* 6 VIP_656_DATA_EXT[1] */
+/* 7 VIP_656_DATA_EXT[0] */
-#define ALT_PIN_IN_SEL 0x110030 // Alternate GPIO input select
+#define ALT_PIN_IN_SEL 0x110030 /* Alternate GPIO input select */
#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
-// 0 GPIO[10] <-- default
-// 1 IR_RX
-// 2 IR_TX
-// 3 AUX_PLL_CLK
-// 4 IF_ATT_SEL
-// 5 GPIO[0]
-// 6 GPIO[1]
-// 7 GPIO[2]
+/* 0 GPIO[10] <-- default */
+/* 1 IR_RX */
+/* 2 IR_TX */
+/* 3 AUX_PLL_CLK */
+/* 4 IF_ATT_SEL */
+/* 5 GPIO[0] */
+/* 6 GPIO[1] */
+/* 7 GPIO[2] */
#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
-// 0 GPIO[2] <-- default
-// 1 IR_RX
-// 2 IR_TX
-// 3 AUX_PLL_CLK
-// 4 IF_ATT_SEL
+/* 0 GPIO[2] <-- default */
+/* 1 IR_RX */
+/* 2 IR_TX */
+/* 3 AUX_PLL_CLK */
+/* 4 IF_ATT_SEL */
#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
-// 0 GPIO[1] <-- default
-// 1 IR_RX
-// 2 IR_TX
-// 3 AUX_PLL_CLK
-// 4 IF_ATT_SEL
+/* 0 GPIO[1] <-- default */
+/* 1 IR_RX */
+/* 2 IR_TX */
+/* 3 AUX_PLL_CLK */
+/* 4 IF_ATT_SEL */
#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
-// 0 GPIO[0] <-- default
-// 1 IR_RX
-// 2 IR_TX
-// 3 AUX_PLL_CLK
-// 4 IF_ATT_SEL
+/* 0 GPIO[0] <-- default */
+/* 1 IR_RX */
+/* 2 IR_TX */
+/* 3 AUX_PLL_CLK */
+/* 4 IF_ATT_SEL */
-//*****************************************************************************
-#define TEST_BUS_CTL1 0x110040 // Test bus control register #1
+/* ***************************************************************************** */
+#define TEST_BUS_CTL1 0x110040 /* Test bus control register #1 */
-//*****************************************************************************
-#define TEST_BUS_CTL2 0x110044 // Test bus control register #2
+/* ***************************************************************************** */
+#define TEST_BUS_CTL2 0x110044 /* Test bus control register #2 */
-//*****************************************************************************
-#define CLK_DELAY 0x110048 // Clock delay
-#define FLD_MOE_CLK_DIS 0x80000000 // Disable MoE clock
+/* ***************************************************************************** */
+#define CLK_DELAY 0x110048 /* Clock delay */
+#define FLD_MOE_CLK_DIS 0x80000000 /* Disable MoE clock */
-//*****************************************************************************
-#define PAD_CTRL 0x110068 // Pad drive strength control
+/* ***************************************************************************** */
+#define PAD_CTRL 0x110068 /* Pad drive strength control */
-//*****************************************************************************
-#define MBIST_CTRL 0x110050 // SRAM memory built-in self test control
+/* ***************************************************************************** */
+#define MBIST_CTRL 0x110050 /* SRAM memory built-in self test control */
-//*****************************************************************************
-#define MBIST_STAT 0x110054 // SRAM memory built-in self test status
+/* ***************************************************************************** */
+#define MBIST_STAT 0x110054 /* SRAM memory built-in self test status */
-//*****************************************************************************
-// PLL registers
-//*****************************************************************************
+/* ***************************************************************************** */
+/* PLL registers */
+/* ***************************************************************************** */
#define PLL_A_INT_FRAC 0x110088
#define PLL_A_POST_STAT_BIST 0x11008C
#define PLL_B_INT_FRAC 0x110090
@@ -1090,260 +1090,260 @@
#define VID_CH_MODE_SEL 0x110078
#define VID_CH_CLK_SEL 0x11007C
-//*****************************************************************************
-#define VBI_A_DMA 0x130008 // VBI A DMA data port
+/* ***************************************************************************** */
+#define VBI_A_DMA 0x130008 /* VBI A DMA data port */
-//*****************************************************************************
-#define VID_A_VIP_CTL 0x130080 // Video A VIP format control
+/* ***************************************************************************** */
+#define VID_A_VIP_CTL 0x130080 /* Video A VIP format control */
#define FLD_VIP_MODE 0x00000001
-//*****************************************************************************
-#define VID_A_PIXEL_FRMT 0x130084 // Video A pixel format
+/* ***************************************************************************** */
+#define VID_A_PIXEL_FRMT 0x130084 /* Video A pixel format */
#define FLD_VID_A_GAMMA_DIS 0x00000008
#define FLD_VID_A_FORMAT 0x00000007
#define FLD_VID_A_GAMMA_FACTOR 0x00000010
-//*****************************************************************************
-#define VID_A_VBI_CTL 0x130088 // Video A VBI miscellaneous control
+/* ***************************************************************************** */
+#define VID_A_VBI_CTL 0x130088 /* Video A VBI miscellaneous control */
#define FLD_VID_A_VIP_EXT 0x00000003
-//*****************************************************************************
-#define VID_B_DMA 0x130100 // Video B DMA data port
+/* ***************************************************************************** */
+#define VID_B_DMA 0x130100 /* Video B DMA data port */
-//*****************************************************************************
-#define VBI_B_DMA 0x130108 // VBI B DMA data port
+/* ***************************************************************************** */
+#define VBI_B_DMA 0x130108 /* VBI B DMA data port */
-//*****************************************************************************
-#define VID_B_SRC_SEL 0x130144 // Video B source select
+/* ***************************************************************************** */
+#define VID_B_SRC_SEL 0x130144 /* Video B source select */
#define FLD_VID_B_SRC_SEL 0x00000000
-//*****************************************************************************
-#define VID_B_LNGTH 0x130150 // Video B line length
+/* ***************************************************************************** */
+#define VID_B_LNGTH 0x130150 /* Video B line length */
#define FLD_VID_B_LN_LNGTH 0x00000FFF
-//*****************************************************************************
-#define VID_B_VIP_CTL 0x130180 // Video B VIP format control
+/* ***************************************************************************** */
+#define VID_B_VIP_CTL 0x130180 /* Video B VIP format control */
-//*****************************************************************************
-#define VID_B_PIXEL_FRMT 0x130184 // Video B pixel format
+/* ***************************************************************************** */
+#define VID_B_PIXEL_FRMT 0x130184 /* Video B pixel format */
#define FLD_VID_B_GAMMA_DIS 0x00000008
#define FLD_VID_B_FORMAT 0x00000007
#define FLD_VID_B_GAMMA_FACTOR 0x00000010
-//*****************************************************************************
-#define VID_C_DMA 0x130200 // Video C DMA data port
+/* ***************************************************************************** */
+#define VID_C_DMA 0x130200 /* Video C DMA data port */
-//*****************************************************************************
-#define VID_C_LNGTH 0x130250 // Video C line length
+/* ***************************************************************************** */
+#define VID_C_LNGTH 0x130250 /* Video C line length */
#define FLD_VID_C_LN_LNGTH 0x00000FFF
-//*****************************************************************************
-// Video Destination Channels
-//*****************************************************************************
-
-#define VID_DST_A_GPCNT 0x130020 // Video A general purpose counter
-#define VID_DST_B_GPCNT 0x130120 // Video B general purpose counter
-#define VID_DST_C_GPCNT 0x130220 // Video C general purpose counter
-#define VID_DST_D_GPCNT 0x130320 // Video D general purpose counter
-#define VID_DST_E_GPCNT 0x130420 // Video E general purpose counter
-#define VID_DST_F_GPCNT 0x130520 // Video F general purpose counter
-#define VID_DST_G_GPCNT 0x130620 // Video G general purpose counter
-#define VID_DST_H_GPCNT 0x130720 // Video H general purpose counter
-
-//*****************************************************************************
-
-#define VID_DST_A_GPCNT_CTL 0x130030 // Video A general purpose control
-#define VID_DST_B_GPCNT_CTL 0x130130 // Video B general purpose control
-#define VID_DST_C_GPCNT_CTL 0x130230 // Video C general purpose control
-#define VID_DST_D_GPCNT_CTL 0x130330 // Video D general purpose control
-#define VID_DST_E_GPCNT_CTL 0x130430 // Video E general purpose control
-#define VID_DST_F_GPCNT_CTL 0x130530 // Video F general purpose control
-#define VID_DST_G_GPCNT_CTL 0x130630 // Video G general purpose control
-#define VID_DST_H_GPCNT_CTL 0x130730 // Video H general purpose control
-
-//*****************************************************************************
-
-#define VID_DST_A_DMA_CTL 0x130040 // Video A DMA control
-#define VID_DST_B_DMA_CTL 0x130140 // Video B DMA control
-#define VID_DST_C_DMA_CTL 0x130240 // Video C DMA control
-#define VID_DST_D_DMA_CTL 0x130340 // Video D DMA control
-#define VID_DST_E_DMA_CTL 0x130440 // Video E DMA control
-#define VID_DST_F_DMA_CTL 0x130540 // Video F DMA control
-#define VID_DST_G_DMA_CTL 0x130640 // Video G DMA control
-#define VID_DST_H_DMA_CTL 0x130740 // Video H DMA control
+/* ***************************************************************************** */
+/* Video Destination Channels */
+/* ***************************************************************************** */
+
+#define VID_DST_A_GPCNT 0x130020 /* Video A general purpose counter */
+#define VID_DST_B_GPCNT 0x130120 /* Video B general purpose counter */
+#define VID_DST_C_GPCNT 0x130220 /* Video C general purpose counter */
+#define VID_DST_D_GPCNT 0x130320 /* Video D general purpose counter */
+#define VID_DST_E_GPCNT 0x130420 /* Video E general purpose counter */
+#define VID_DST_F_GPCNT 0x130520 /* Video F general purpose counter */
+#define VID_DST_G_GPCNT 0x130620 /* Video G general purpose counter */
+#define VID_DST_H_GPCNT 0x130720 /* Video H general purpose counter */
+
+/* ***************************************************************************** */
+
+#define VID_DST_A_GPCNT_CTL 0x130030 /* Video A general purpose control */
+#define VID_DST_B_GPCNT_CTL 0x130130 /* Video B general purpose control */
+#define VID_DST_C_GPCNT_CTL 0x130230 /* Video C general purpose control */
+#define VID_DST_D_GPCNT_CTL 0x130330 /* Video D general purpose control */
+#define VID_DST_E_GPCNT_CTL 0x130430 /* Video E general purpose control */
+#define VID_DST_F_GPCNT_CTL 0x130530 /* Video F general purpose control */
+#define VID_DST_G_GPCNT_CTL 0x130630 /* Video G general purpose control */
+#define VID_DST_H_GPCNT_CTL 0x130730 /* Video H general purpose control */
+
+/* ***************************************************************************** */
+
+#define VID_DST_A_DMA_CTL 0x130040 /* Video A DMA control */
+#define VID_DST_B_DMA_CTL 0x130140 /* Video B DMA control */
+#define VID_DST_C_DMA_CTL 0x130240 /* Video C DMA control */
+#define VID_DST_D_DMA_CTL 0x130340 /* Video D DMA control */
+#define VID_DST_E_DMA_CTL 0x130440 /* Video E DMA control */
+#define VID_DST_F_DMA_CTL 0x130540 /* Video F DMA control */
+#define VID_DST_G_DMA_CTL 0x130640 /* Video G DMA control */
+#define VID_DST_H_DMA_CTL 0x130740 /* Video H DMA control */
#define FLD_VID_RISC_EN 0x00000010
#define FLD_VID_FIFO_EN 0x00000001
-//*****************************************************************************
-
-#define VID_DST_A_VIP_CTL 0x130080 // Video A VIP control
-#define VID_DST_B_VIP_CTL 0x130180 // Video B VIP control
-#define VID_DST_C_VIP_CTL 0x130280 // Video C VIP control
-#define VID_DST_D_VIP_CTL 0x130380 // Video D VIP control
-#define VID_DST_E_VIP_CTL 0x130480 // Video E VIP control
-#define VID_DST_F_VIP_CTL 0x130580 // Video F VIP control
-#define VID_DST_G_VIP_CTL 0x130680 // Video G VIP control
-#define VID_DST_H_VIP_CTL 0x130780 // Video H VIP control
-
-//*****************************************************************************
-
-#define VID_DST_A_PIX_FRMT 0x130084 // Video A Pixel format
-#define VID_DST_B_PIX_FRMT 0x130184 // Video B Pixel format
-#define VID_DST_C_PIX_FRMT 0x130284 // Video C Pixel format
-#define VID_DST_D_PIX_FRMT 0x130384 // Video D Pixel format
-#define VID_DST_E_PIX_FRMT 0x130484 // Video E Pixel format
-#define VID_DST_F_PIX_FRMT 0x130584 // Video F Pixel format
-#define VID_DST_G_PIX_FRMT 0x130684 // Video G Pixel format
-#define VID_DST_H_PIX_FRMT 0x130784 // Video H Pixel format
-
-//*****************************************************************************
-// Video Source Channels
-//*****************************************************************************
-
-#define VID_SRC_A_GPCNT_CTL 0x130804 // Video A general purpose control
-#define VID_SRC_B_GPCNT_CTL 0x130904 // Video B general purpose control
-#define VID_SRC_C_GPCNT_CTL 0x130A04 // Video C general purpose control
-#define VID_SRC_D_GPCNT_CTL 0x130B04 // Video D general purpose control
-#define VID_SRC_E_GPCNT_CTL 0x130C04 // Video E general purpose control
-#define VID_SRC_F_GPCNT_CTL 0x130D04 // Video F general purpose control
-#define VID_SRC_I_GPCNT_CTL 0x130E04 // Video I general purpose control
-#define VID_SRC_J_GPCNT_CTL 0x130F04 // Video J general purpose control
-
-//*****************************************************************************
-
-#define VID_SRC_A_GPCNT 0x130808 // Video A general purpose counter
-#define VID_SRC_B_GPCNT 0x130908 // Video B general purpose counter
-#define VID_SRC_C_GPCNT 0x130A08 // Video C general purpose counter
-#define VID_SRC_D_GPCNT 0x130B08 // Video D general purpose counter
-#define VID_SRC_E_GPCNT 0x130C08 // Video E general purpose counter
-#define VID_SRC_F_GPCNT 0x130D08 // Video F general purpose counter
-#define VID_SRC_I_GPCNT 0x130E08 // Video I general purpose counter
-#define VID_SRC_J_GPCNT 0x130F08 // Video J general purpose counter
-
-//*****************************************************************************
-
-#define VID_SRC_A_DMA_CTL 0x13080C // Video A DMA control
-#define VID_SRC_B_DMA_CTL 0x13090C // Video B DMA control
-#define VID_SRC_C_DMA_CTL 0x130A0C // Video C DMA control
-#define VID_SRC_D_DMA_CTL 0x130B0C // Video D DMA control
-#define VID_SRC_E_DMA_CTL 0x130C0C // Video E DMA control
-#define VID_SRC_F_DMA_CTL 0x130D0C // Video F DMA control
-#define VID_SRC_I_DMA_CTL 0x130E0C // Video I DMA control
-#define VID_SRC_J_DMA_CTL 0x130F0C // Video J DMA control
+/* ***************************************************************************** */
+
+#define VID_DST_A_VIP_CTL 0x130080 /* Video A VIP control */
+#define VID_DST_B_VIP_CTL 0x130180 /* Video B VIP control */
+#define VID_DST_C_VIP_CTL 0x130280 /* Video C VIP control */
+#define VID_DST_D_VIP_CTL 0x130380 /* Video D VIP control */
+#define VID_DST_E_VIP_CTL 0x130480 /* Video E VIP control */
+#define VID_DST_F_VIP_CTL 0x130580 /* Video F VIP control */
+#define VID_DST_G_VIP_CTL 0x130680 /* Video G VIP control */
+#define VID_DST_H_VIP_CTL 0x130780 /* Video H VIP control */
+
+/* ***************************************************************************** */
+
+#define VID_DST_A_PIX_FRMT 0x130084 /* Video A Pixel format */
+#define VID_DST_B_PIX_FRMT 0x130184 /* Video B Pixel format */
+#define VID_DST_C_PIX_FRMT 0x130284 /* Video C Pixel format */
+#define VID_DST_D_PIX_FRMT 0x130384 /* Video D Pixel format */
+#define VID_DST_E_PIX_FRMT 0x130484 /* Video E Pixel format */
+#define VID_DST_F_PIX_FRMT 0x130584 /* Video F Pixel format */
+#define VID_DST_G_PIX_FRMT 0x130684 /* Video G Pixel format */
+#define VID_DST_H_PIX_FRMT 0x130784 /* Video H Pixel format */
+
+/* ***************************************************************************** */
+/* Video Source Channels */
+/* ***************************************************************************** */
+
+#define VID_SRC_A_GPCNT_CTL 0x130804 /* Video A general purpose control */
+#define VID_SRC_B_GPCNT_CTL 0x130904 /* Video B general purpose control */
+#define VID_SRC_C_GPCNT_CTL 0x130A04 /* Video C general purpose control */
+#define VID_SRC_D_GPCNT_CTL 0x130B04 /* Video D general purpose control */
+#define VID_SRC_E_GPCNT_CTL 0x130C04 /* Video E general purpose control */
+#define VID_SRC_F_GPCNT_CTL 0x130D04 /* Video F general purpose control */
+#define VID_SRC_I_GPCNT_CTL 0x130E04 /* Video I general purpose control */
+#define VID_SRC_J_GPCNT_CTL 0x130F04 /* Video J general purpose control */
+
+/* ***************************************************************************** */
+
+#define VID_SRC_A_GPCNT 0x130808 /* Video A general purpose counter */
+#define VID_SRC_B_GPCNT 0x130908 /* Video B general purpose counter */
+#define VID_SRC_C_GPCNT 0x130A08 /* Video C general purpose counter */
+#define VID_SRC_D_GPCNT 0x130B08 /* Video D general purpose counter */
+#define VID_SRC_E_GPCNT 0x130C08 /* Video E general purpose counter */
+#define VID_SRC_F_GPCNT 0x130D08 /* Video F general purpose counter */
+#define VID_SRC_I_GPCNT 0x130E08 /* Video I general purpose counter */
+#define VID_SRC_J_GPCNT 0x130F08 /* Video J general purpose counter */
+
+/* ***************************************************************************** */
+
+#define VID_SRC_A_DMA_CTL 0x13080C /* Video A DMA control */
+#define VID_SRC_B_DMA_CTL 0x13090C /* Video B DMA control */
+#define VID_SRC_C_DMA_CTL 0x130A0C /* Video C DMA control */
+#define VID_SRC_D_DMA_CTL 0x130B0C /* Video D DMA control */
+#define VID_SRC_E_DMA_CTL 0x130C0C /* Video E DMA control */
+#define VID_SRC_F_DMA_CTL 0x130D0C /* Video F DMA control */
+#define VID_SRC_I_DMA_CTL 0x130E0C /* Video I DMA control */
+#define VID_SRC_J_DMA_CTL 0x130F0C /* Video J DMA control */
#define FLD_APB_RISC_EN 0x00000010
#define FLD_APB_FIFO_EN 0x00000001
-//*****************************************************************************
-
-#define VID_SRC_A_FMT_CTL 0x130810 // Video A format control
-#define VID_SRC_B_FMT_CTL 0x130910 // Video B format control
-#define VID_SRC_C_FMT_CTL 0x130A10 // Video C format control
-#define VID_SRC_D_FMT_CTL 0x130B10 // Video D format control
-#define VID_SRC_E_FMT_CTL 0x130C10 // Video E format control
-#define VID_SRC_F_FMT_CTL 0x130D10 // Video F format control
-#define VID_SRC_I_FMT_CTL 0x130E10 // Video I format control
-#define VID_SRC_J_FMT_CTL 0x130F10 // Video J format control
-
-//*****************************************************************************
-
-#define VID_SRC_A_ACTIVE_CTL1 0x130814 // Video A active control 1
-#define VID_SRC_B_ACTIVE_CTL1 0x130914 // Video B active control 1
-#define VID_SRC_C_ACTIVE_CTL1 0x130A14 // Video C active control 1
-#define VID_SRC_D_ACTIVE_CTL1 0x130B14 // Video D active control 1
-#define VID_SRC_E_ACTIVE_CTL1 0x130C14 // Video E active control 1
-#define VID_SRC_F_ACTIVE_CTL1 0x130D14 // Video F active control 1
-#define VID_SRC_I_ACTIVE_CTL1 0x130E14 // Video I active control 1
-#define VID_SRC_J_ACTIVE_CTL1 0x130F14 // Video J active control 1
-
-//*****************************************************************************
-
-#define VID_SRC_A_ACTIVE_CTL2 0x130818 // Video A active control 2
-#define VID_SRC_B_ACTIVE_CTL2 0x130918 // Video B active control 2
-#define VID_SRC_C_ACTIVE_CTL2 0x130A18 // Video C active control 2
-#define VID_SRC_D_ACTIVE_CTL2 0x130B18 // Video D active control 2
-#define VID_SRC_E_ACTIVE_CTL2 0x130C18 // Video E active control 2
-#define VID_SRC_F_ACTIVE_CTL2 0x130D18 // Video F active control 2
-#define VID_SRC_I_ACTIVE_CTL2 0x130E18 // Video I active control 2
-#define VID_SRC_J_ACTIVE_CTL2 0x130F18 // Video J active control 2
-
-//*****************************************************************************
-
-#define VID_SRC_A_CDT_SZ 0x13081C // Video A CDT size
-#define VID_SRC_B_CDT_SZ 0x13091C // Video B CDT size
-#define VID_SRC_C_CDT_SZ 0x130A1C // Video C CDT size
-#define VID_SRC_D_CDT_SZ 0x130B1C // Video D CDT size
-#define VID_SRC_E_CDT_SZ 0x130C1C // Video E CDT size
-#define VID_SRC_F_CDT_SZ 0x130D1C // Video F CDT size
-#define VID_SRC_I_CDT_SZ 0x130E1C // Video I CDT size
-#define VID_SRC_J_CDT_SZ 0x130F1C // Video J CDT size
-
-//*****************************************************************************
-// Audio I/F
-//*****************************************************************************
-#define AUD_DST_A_DMA 0x140000 // Audio Int A DMA data port
-#define AUD_SRC_A_DMA 0x140008 // Audio Int A DMA data port
-
-#define AUD_A_GPCNT 0x140010 // Audio Int A gp counter
+/* ***************************************************************************** */
+
+#define VID_SRC_A_FMT_CTL 0x130810 /* Video A format control */
+#define VID_SRC_B_FMT_CTL 0x130910 /* Video B format control */
+#define VID_SRC_C_FMT_CTL 0x130A10 /* Video C format control */
+#define VID_SRC_D_FMT_CTL 0x130B10 /* Video D format control */
+#define VID_SRC_E_FMT_CTL 0x130C10 /* Video E format control */
+#define VID_SRC_F_FMT_CTL 0x130D10 /* Video F format control */
+#define VID_SRC_I_FMT_CTL 0x130E10 /* Video I format control */
+#define VID_SRC_J_FMT_CTL 0x130F10 /* Video J format control */
+
+/* ***************************************************************************** */
+
+#define VID_SRC_A_ACTIVE_CTL1 0x130814 /* Video A active control 1 */
+#define VID_SRC_B_ACTIVE_CTL1 0x130914 /* Video B active control 1 */
+#define VID_SRC_C_ACTIVE_CTL1 0x130A14 /* Video C active control 1 */
+#define VID_SRC_D_ACTIVE_CTL1 0x130B14 /* Video D active control 1 */
+#define VID_SRC_E_ACTIVE_CTL1 0x130C14 /* Video E active control 1 */
+#define VID_SRC_F_ACTIVE_CTL1 0x130D14 /* Video F active control 1 */
+#define VID_SRC_I_ACTIVE_CTL1 0x130E14 /* Video I active control 1 */
+#define VID_SRC_J_ACTIVE_CTL1 0x130F14 /* Video J active control 1 */
+
+/* ***************************************************************************** */
+
+#define VID_SRC_A_ACTIVE_CTL2 0x130818 /* Video A active control 2 */
+#define VID_SRC_B_ACTIVE_CTL2 0x130918 /* Video B active control 2 */
+#define VID_SRC_C_ACTIVE_CTL2 0x130A18 /* Video C active control 2 */
+#define VID_SRC_D_ACTIVE_CTL2 0x130B18 /* Video D active control 2 */
+#define VID_SRC_E_ACTIVE_CTL2 0x130C18 /* Video E active control 2 */
+#define VID_SRC_F_ACTIVE_CTL2 0x130D18 /* Video F active control 2 */
+#define VID_SRC_I_ACTIVE_CTL2 0x130E18 /* Video I active control 2 */
+#define VID_SRC_J_ACTIVE_CTL2 0x130F18 /* Video J active control 2 */
+
+/* ***************************************************************************** */
+
+#define VID_SRC_A_CDT_SZ 0x13081C /* Video A CDT size */
+#define VID_SRC_B_CDT_SZ 0x13091C /* Video B CDT size */
+#define VID_SRC_C_CDT_SZ 0x130A1C /* Video C CDT size */
+#define VID_SRC_D_CDT_SZ 0x130B1C /* Video D CDT size */
+#define VID_SRC_E_CDT_SZ 0x130C1C /* Video E CDT size */
+#define VID_SRC_F_CDT_SZ 0x130D1C /* Video F CDT size */
+#define VID_SRC_I_CDT_SZ 0x130E1C /* Video I CDT size */
+#define VID_SRC_J_CDT_SZ 0x130F1C /* Video J CDT size */
+
+/* ***************************************************************************** */
+/* Audio I/F */
+/* ***************************************************************************** */
+#define AUD_DST_A_DMA 0x140000 /* Audio Int A DMA data port */
+#define AUD_SRC_A_DMA 0x140008 /* Audio Int A DMA data port */
+
+#define AUD_A_GPCNT 0x140010 /* Audio Int A gp counter */
#define FLD_AUD_A_GP_CNT 0x0000FFFF
-#define AUD_A_GPCNT_CTL 0x140014 // Audio Int A gp control
+#define AUD_A_GPCNT_CTL 0x140014 /* Audio Int A gp control */
-#define AUD_A_LNGTH 0x140018 // Audio Int A line length
+#define AUD_A_LNGTH 0x140018 /* Audio Int A line length */
-#define AUD_A_CFG 0x14001C // Audio Int A configuration
+#define AUD_A_CFG 0x14001C /* Audio Int A configuration */
-//*****************************************************************************
-#define AUD_DST_B_DMA 0x140100 // Audio Int B DMA data port
-#define AUD_SRC_B_DMA 0x140108 // Audio Int B DMA data port
+/* ***************************************************************************** */
+#define AUD_DST_B_DMA 0x140100 /* Audio Int B DMA data port */
+#define AUD_SRC_B_DMA 0x140108 /* Audio Int B DMA data port */
-#define AUD_B_GPCNT 0x140110 // Audio Int B gp counter
+#define AUD_B_GPCNT 0x140110 /* Audio Int B gp counter */
#define FLD_AUD_B_GP_CNT 0x0000FFFF
-#define AUD_B_GPCNT_CTL 0x140114 // Audio Int B gp control
+#define AUD_B_GPCNT_CTL 0x140114 /* Audio Int B gp control */
-#define AUD_B_LNGTH 0x140118 // Audio Int B line length
+#define AUD_B_LNGTH 0x140118 /* Audio Int B line length */
-#define AUD_B_CFG 0x14011C // Audio Int B configuration
+#define AUD_B_CFG 0x14011C /* Audio Int B configuration */
-//*****************************************************************************
-#define AUD_DST_C_DMA 0x140200 // Audio Int C DMA data port
-#define AUD_SRC_C_DMA 0x140208 // Audio Int C DMA data port
+/* ***************************************************************************** */
+#define AUD_DST_C_DMA 0x140200 /* Audio Int C DMA data port */
+#define AUD_SRC_C_DMA 0x140208 /* Audio Int C DMA data port */
-#define AUD_C_GPCNT 0x140210 // Audio Int C gp counter
+#define AUD_C_GPCNT 0x140210 /* Audio Int C gp counter */
#define FLD_AUD_C_GP_CNT 0x0000FFFF
-#define AUD_C_GPCNT_CTL 0x140214 // Audio Int C gp control
+#define AUD_C_GPCNT_CTL 0x140214 /* Audio Int C gp control */
-#define AUD_C_LNGTH 0x140218 // Audio Int C line length
+#define AUD_C_LNGTH 0x140218 /* Audio Int C line length */
-#define AUD_C_CFG 0x14021C // Audio Int C configuration
+#define AUD_C_CFG 0x14021C /* Audio Int C configuration */
-//*****************************************************************************
-#define AUD_DST_D_DMA 0x140300 // Audio Int D DMA data port
-#define AUD_SRC_D_DMA 0x140308 // Audio Int D DMA data port
+/* ***************************************************************************** */
+#define AUD_DST_D_DMA 0x140300 /* Audio Int D DMA data port */
+#define AUD_SRC_D_DMA 0x140308 /* Audio Int D DMA data port */
-#define AUD_D_GPCNT 0x140310 // Audio Int D gp counter
+#define AUD_D_GPCNT 0x140310 /* Audio Int D gp counter */
#define FLD_AUD_D_GP_CNT 0x0000FFFF
-#define AUD_D_GPCNT_CTL 0x140314 // Audio Int D gp control
+#define AUD_D_GPCNT_CTL 0x140314 /* Audio Int D gp control */
-#define AUD_D_LNGTH 0x140318 // Audio Int D line length
+#define AUD_D_LNGTH 0x140318 /* Audio Int D line length */
-#define AUD_D_CFG 0x14031C // Audio Int D configuration
+#define AUD_D_CFG 0x14031C /* Audio Int D configuration */
-//*****************************************************************************
-#define AUD_SRC_E_DMA 0x140400 // Audio Int E DMA data port
+/* ***************************************************************************** */
+#define AUD_SRC_E_DMA 0x140400 /* Audio Int E DMA data port */
-#define AUD_E_GPCNT 0x140410 // Audio Int E gp counter
+#define AUD_E_GPCNT 0x140410 /* Audio Int E gp counter */
#define FLD_AUD_E_GP_CNT 0x0000FFFF
-#define AUD_E_GPCNT_CTL 0x140414 // Audio Int E gp control
+#define AUD_E_GPCNT_CTL 0x140414 /* Audio Int E gp control */
-#define AUD_E_CFG 0x14041C // Audio Int E configuration
+#define AUD_E_CFG 0x14041C /* Audio Int E configuration */
-//*****************************************************************************
+/* ***************************************************************************** */
#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
@@ -1361,8 +1361,8 @@
#define FLD_AUD_SRC_ENABLE 0x00010000
-//*****************************************************************************
-#define AUD_INT_DMA_CTL 0x140500 // Audio Int DMA control
+/* ***************************************************************************** */
+#define AUD_INT_DMA_CTL 0x140500 /* Audio Int DMA control */
#define FLD_AUD_SRC_E_RISC_EN 0x00008000
#define FLD_AUD_SRC_C_RISC_EN 0x00004000
@@ -1384,15 +1384,15 @@
#define FLD_AUD_DST_B_FIFO_EN 0x00000002
#define FLD_AUD_DST_A_FIFO_EN 0x00000001
-//*****************************************************************************
-//
-// Mobilygen Interface Registers
-//
-//*****************************************************************************
-// Mobilygen Interface A
-//*****************************************************************************
-#define MB_IF_A_DMA 0x150000 // MBIF A DMA data port
-#define MB_IF_A_GPCN 0x150008 // MBIF A GP counter
+/* ***************************************************************************** */
+/* */
+/* Mobilygen Interface Registers */
+/* */
+/* ***************************************************************************** */
+/* Mobilygen Interface A */
+/* ***************************************************************************** */
+#define MB_IF_A_DMA 0x150000 /* MBIF A DMA data port */
+#define MB_IF_A_GPCN 0x150008 /* MBIF A GP counter */
#define MB_IF_A_GPCN_CTRL 0x15000C
#define MB_IF_A_DMA_CTRL 0x150010
#define MB_IF_A_LENGTH 0x150014
@@ -1415,11 +1415,11 @@
#define MB_IF_A_DATA_STRUCT_D 0x150058
#define MB_IF_A_DATA_STRUCT_E 0x15005C
#define MB_IF_A_DATA_STRUCT_F 0x150060
-//*****************************************************************************
-// Mobilygen Interface B
-//*****************************************************************************
-#define MB_IF_B_DMA 0x160000 // MBIF A DMA data port
-#define MB_IF_B_GPCN 0x160008 // MBIF A GP counter
+/* ***************************************************************************** */
+/* Mobilygen Interface B */
+/* ***************************************************************************** */
+#define MB_IF_B_DMA 0x160000 /* MBIF A DMA data port */
+#define MB_IF_B_GPCN 0x160008 /* MBIF A GP counter */
#define MB_IF_B_GPCN_CTRL 0x16000C
#define MB_IF_B_DMA_CTRL 0x160010
#define MB_IF_B_LENGTH 0x160014
@@ -1443,14 +1443,14 @@
#define MB_IF_B_DATA_STRUCT_E 0x16005C
#define MB_IF_B_DATA_STRUCT_F 0x160060
-// MB_DMA_CTRL
+/* MB_DMA_CTRL */
#define FLD_MB_IF_RISC_EN 0x00000010
#define FLD_MB_IF_FIFO_EN 0x00000001
-// MB_LENGTH
+/* MB_LENGTH */
#define FLD_MB_IF_LN_LNGTH 0x00000FFF
-// MB_HCMD register
+/* MB_HCMD register */
#define FLD_MB_HCMD_H_GO 0x80000000
#define FLD_MB_HCMD_H_BUSY 0x40000000
#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
@@ -1461,118 +1461,118 @@
#define FLD_MB_HCMD_H_ADDR 0x00FF0000
#define FLD_MB_HCMD_H_DATA 0x0000FFFF
-//*****************************************************************************
-// I2C #1
-//*****************************************************************************
-#define I2C1_ADDR 0x180000 // I2C #1 address
-#define FLD_I2C_DADDR 0xfe000000 // RW [31:25] I2C Device Address
- // RO [24] reserved
-//*****************************************************************************
-#define FLD_I2C_SADDR 0x00FFFFFF // RW [23:0] I2C Sub-address
-
-//*****************************************************************************
-#define I2C1_WDATA 0x180004 // I2C #1 write data
-#define FLD_I2C_WDATA 0xFFFFFFFF // RW [31:0]
-
-//*****************************************************************************
-#define I2C1_CTRL 0x180008 // I2C #1 control
-#define FLD_I2C_PERIOD 0xFF000000 // RW [31:24]
-#define FLD_I2C_SCL_IN 0x00200000 // RW [21]
-#define FLD_I2C_SDA_IN 0x00100000 // RW [20]
- // RO [19:18] reserved
-#define FLD_I2C_SCL_OUT 0x00020000 // RW [17]
-#define FLD_I2C_SDA_OUT 0x00010000 // RW [16]
- // RO [15] reserved
-#define FLD_I2C_DATA_LEN 0x00007000 // RW [14:12]
-#define FLD_I2C_SADDR_INC 0x00000800 // RW [11]
- // RO [10:9] reserved
-#define FLD_I2C_SADDR_LEN 0x00000300 // RW [9:8]
- // RO [7:6] reserved
-#define FLD_I2C_SOFT 0x00000020 // RW [5]
-#define FLD_I2C_NOSTOP 0x00000010 // RW [4]
-#define FLD_I2C_EXTEND 0x00000008 // RW [3]
-#define FLD_I2C_SYNC 0x00000004 // RW [2]
-#define FLD_I2C_READ_SA 0x00000002 // RW [1]
-#define FLD_I2C_READ_WRN 0x00000001 // RW [0]
-
-//*****************************************************************************
-#define I2C1_RDATA 0x18000C // I2C #1 read data
-#define FLD_I2C_RDATA 0xFFFFFFFF // RO [31:0]
-
-//*****************************************************************************
-#define I2C1_STAT 0x180010 // I2C #1 status
-#define FLD_I2C_XFER_IN_PROG 0x00000002 // RO [1]
-#define FLD_I2C_RACK 0x00000001 // RO [0]
-
-//*****************************************************************************
-// I2C #2
-//*****************************************************************************
-#define I2C2_ADDR 0x190000 // I2C #2 address
-
-//*****************************************************************************
-#define I2C2_WDATA 0x190004 // I2C #2 write data
-
-//*****************************************************************************
-#define I2C2_CTRL 0x190008 // I2C #2 control
-
-//*****************************************************************************
-#define I2C2_RDATA 0x19000C // I2C #2 read data
-
-//*****************************************************************************
-#define I2C2_STAT 0x190010 // I2C #2 status
-
-//*****************************************************************************
-// I2C #3
-//*****************************************************************************
-#define I2C3_ADDR 0x1A0000 // I2C #3 address
-
-//*****************************************************************************
-#define I2C3_WDATA 0x1A0004 // I2C #3 write data
-
-//*****************************************************************************
-#define I2C3_CTRL 0x1A0008 // I2C #3 control
-
-//*****************************************************************************
-#define I2C3_RDATA 0x1A000C // I2C #3 read data
-
-//*****************************************************************************
-#define I2C3_STAT 0x1A0010 // I2C #3 status
-
-//*****************************************************************************
-// UART
-//*****************************************************************************
-#define UART_CTL 0x1B0000 // UART Control Register
-#define FLD_LOOP_BACK_EN (1 << 7) // RW field - default 0
-#define FLD_RX_TRG_SZ (3 << 2) // RW field - default 0
-#define FLD_RX_EN (1 << 1) // RW field - default 0
-#define FLD_TX_EN (1 << 0) // RW field - default 0
-
-//*****************************************************************************
-#define UART_BRD 0x1B0004 // UART Baud Rate Divisor
-#define FLD_BRD 0x0000FFFF // RW field - default 0x197
-
-//*****************************************************************************
-#define UART_DBUF 0x1B0008 // UART Tx/Rx Data BuFFer
-#define FLD_DB 0xFFFFFFFF // RW field - default 0
-
-//*****************************************************************************
-#define UART_ISR 0x1B000C // UART Interrupt Status
-#define FLD_RXD_TIMEOUT_EN (1 << 7) // RW field - default 0
-#define FLD_FRM_ERR_EN (1 << 6) // RW field - default 0
-#define FLD_RXD_RDY_EN (1 << 5) // RW field - default 0
-#define FLD_TXD_EMPTY_EN (1 << 4) // RW field - default 0
-#define FLD_RXD_OVERFLOW (1 << 3) // RW field - default 0
-#define FLD_FRM_ERR (1 << 2) // RW field - default 0
-#define FLD_RXD_RDY (1 << 1) // RW field - default 0
-#define FLD_TXD_EMPTY (1 << 0) // RW field - default 0
-
-//*****************************************************************************
-#define UART_CNT 0x1B0010 // UART Tx/Rx FIFO Byte Count
-#define FLD_TXD_CNT (0x1F << 8) // RW field - default 0
-#define FLD_RXD_CNT (0x1F << 0) // RW field - default 0
-
-//*****************************************************************************
-// Motion Detection
+/* ***************************************************************************** */
+/* I2C #1 */
+/* ***************************************************************************** */
+#define I2C1_ADDR 0x180000 /* I2C #1 address */
+#define FLD_I2C_DADDR 0xfe000000 /* RW [31:25] I2C Device Address */
+ /* RO [24] reserved */
+/* ***************************************************************************** */
+#define FLD_I2C_SADDR 0x00FFFFFF /* RW [23:0] I2C Sub-address */
+
+/* ***************************************************************************** */
+#define I2C1_WDATA 0x180004 /* I2C #1 write data */
+#define FLD_I2C_WDATA 0xFFFFFFFF /* RW [31:0] */
+
+/* ***************************************************************************** */
+#define I2C1_CTRL 0x180008 /* I2C #1 control */
+#define FLD_I2C_PERIOD 0xFF000000 /* RW [31:24] */
+#define FLD_I2C_SCL_IN 0x00200000 /* RW [21] */
+#define FLD_I2C_SDA_IN 0x00100000 /* RW [20] */
+ /* RO [19:18] reserved */
+#define FLD_I2C_SCL_OUT 0x00020000 /* RW [17] */
+#define FLD_I2C_SDA_OUT 0x00010000 /* RW [16] */
+ /* RO [15] reserved */
+#define FLD_I2C_DATA_LEN 0x00007000 /* RW [14:12] */
+#define FLD_I2C_SADDR_INC 0x00000800 /* RW [11] */
+ /* RO [10:9] reserved */
+#define FLD_I2C_SADDR_LEN 0x00000300 /* RW [9:8] */
+ /* RO [7:6] reserved */
+#define FLD_I2C_SOFT 0x00000020 /* RW [5] */
+#define FLD_I2C_NOSTOP 0x00000010 /* RW [4] */
+#define FLD_I2C_EXTEND 0x00000008 /* RW [3] */
+#define FLD_I2C_SYNC 0x00000004 /* RW [2] */
+#define FLD_I2C_READ_SA 0x00000002 /* RW [1] */
+#define FLD_I2C_READ_WRN 0x00000001 /* RW [0] */
+
+/* ***************************************************************************** */
+#define I2C1_RDATA 0x18000C /* I2C #1 read data */
+#define FLD_I2C_RDATA 0xFFFFFFFF /* RO [31:0] */
+
+/* ***************************************************************************** */
+#define I2C1_STAT 0x180010 /* I2C #1 status */
+#define FLD_I2C_XFER_IN_PROG 0x00000002 /* RO [1] */
+#define FLD_I2C_RACK 0x00000001 /* RO [0] */
+
+/* ***************************************************************************** */
+/* I2C #2 */
+/* ***************************************************************************** */
+#define I2C2_ADDR 0x190000 /* I2C #2 address */
+
+/* ***************************************************************************** */
+#define I2C2_WDATA 0x190004 /* I2C #2 write data */
+
+/* ***************************************************************************** */
+#define I2C2_CTRL 0x190008 /* I2C #2 control */
+
+/* ***************************************************************************** */
+#define I2C2_RDATA 0x19000C /* I2C #2 read data */
+
+/* ***************************************************************************** */
+#define I2C2_STAT 0x190010 /* I2C #2 status */
+
+/* ***************************************************************************** */
+/* I2C #3 */
+/* ***************************************************************************** */
+#define I2C3_ADDR 0x1A0000 /* I2C #3 address */
+
+/* ***************************************************************************** */
+#define I2C3_WDATA 0x1A0004 /* I2C #3 write data */
+
+/* ***************************************************************************** */
+#define I2C3_CTRL 0x1A0008 /* I2C #3 control */
+
+/* ***************************************************************************** */
+#define I2C3_RDATA 0x1A000C /* I2C #3 read data */
+
+/* ***************************************************************************** */
+#define I2C3_STAT 0x1A0010 /* I2C #3 status */
+
+/* ***************************************************************************** */
+/* UART */
+/* ***************************************************************************** */
+#define UART_CTL 0x1B0000 /* UART Control Register */
+#define FLD_LOOP_BACK_EN (1 << 7) /* RW field - default 0 */
+#define FLD_RX_TRG_SZ (3 << 2) /* RW field - default 0 */
+#define FLD_RX_EN (1 << 1) /* RW field - default 0 */
+#define FLD_TX_EN (1 << 0) /* RW field - default 0 */
+
+/* ***************************************************************************** */
+#define UART_BRD 0x1B0004 /* UART Baud Rate Divisor */
+#define FLD_BRD 0x0000FFFF /* RW field - default 0x197 */
+
+/* ***************************************************************************** */
+#define UART_DBUF 0x1B0008 /* UART Tx/Rx Data BuFFer */
+#define FLD_DB 0xFFFFFFFF /* RW field - default 0 */
+
+/* ***************************************************************************** */
+#define UART_ISR 0x1B000C /* UART Interrupt Status */
+#define FLD_RXD_TIMEOUT_EN (1 << 7) /* RW field - default 0 */
+#define FLD_FRM_ERR_EN (1 << 6) /* RW field - default 0 */
+#define FLD_RXD_RDY_EN (1 << 5) /* RW field - default 0 */
+#define FLD_TXD_EMPTY_EN (1 << 4) /* RW field - default 0 */
+#define FLD_RXD_OVERFLOW (1 << 3) /* RW field - default 0 */
+#define FLD_FRM_ERR (1 << 2) /* RW field - default 0 */
+#define FLD_RXD_RDY (1 << 1) /* RW field - default 0 */
+#define FLD_TXD_EMPTY (1 << 0) /* RW field - default 0 */
+
+/* ***************************************************************************** */
+#define UART_CNT 0x1B0010 /* UART Tx/Rx FIFO Byte Count */
+#define FLD_TXD_CNT (0x1F << 8) /* RW field - default 0 */
+#define FLD_RXD_CNT (0x1F << 0) /* RW field - default 0 */
+
+/* ***************************************************************************** */
+/* Motion Detection */
#define MD_CH0_GRID_BLOCK_YCNT 0x170014
#define MD_CH1_GRID_BLOCK_YCNT 0x170094
#define MD_CH2_GRID_BLOCK_YCNT 0x170114
@@ -1589,4 +1589,4 @@
#define PIXEL_ENGINE_VIP1 0
#define PIXEL_ENGINE_VIP2 1
-#endif //Athena_REGISTERS
+#endif /* Athena_REGISTERS */
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
index bd677ee22996..5f05d153bc4d 100644
--- a/drivers/staging/cx25821/cx25821-sram.h
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -23,34 +23,34 @@
#ifndef __ATHENA_SRAM_H__
#define __ATHENA_SRAM_H__
-//#define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM
-#define VID_CMDS_SIZE 80 // Video CMDS size in bytes
-#define AUDIO_CMDS_SIZE 80 // AUDIO CMDS size in bytes
-#define MBIF_CMDS_SIZE 80 // MBIF CMDS size in bytes
+/* #define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM */
+#define VID_CMDS_SIZE 80 /* Video CMDS size in bytes */
+#define AUDIO_CMDS_SIZE 80 /* AUDIO CMDS size in bytes */
+#define MBIF_CMDS_SIZE 80 /* MBIF CMDS size in bytes */
-//#define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers
-#define VID_IQ_SIZE 64 // VID instruction queue size in bytes
+/* #define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers */
+#define VID_IQ_SIZE 64 /* VID instruction queue size in bytes */
#define MBIF_IQ_SIZE 64
-#define AUDIO_IQ_SIZE 64 // AUD instruction queue size in bytes
+#define AUDIO_IQ_SIZE 64 /* AUD instruction queue size in bytes */
-#define VID_CDT_SIZE 64 // VID cluster descriptor table size in bytes
-#define MBIF_CDT_SIZE 64 // MBIF/HBI cluster descriptor table size in bytes
-#define AUDIO_CDT_SIZE 48 // AUD cluster descriptor table size in bytes
+#define VID_CDT_SIZE 64 /* VID cluster descriptor table size in bytes */
+#define MBIF_CDT_SIZE 64 /* MBIF/HBI cluster descriptor table size in bytes */
+#define AUDIO_CDT_SIZE 48 /* AUD cluster descriptor table size in bytes */
-//#define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM
-//#define RX_SRAM_END_SIZE = 0; // End of RX SRAM
+/* #define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM */
+/* #define RX_SRAM_END_SIZE = 0; // End of RX SRAM */
-//#define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM
-//#define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora
+/* #define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM */
+/* #define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora */
-#define VID_CLUSTER_SIZE 1440 // VID cluster data line
-#define AUDIO_CLUSTER_SIZE 128 // AUDIO cluster data line
-#define MBIF_CLUSTER_SIZE 1440 // MBIF/HBI cluster data line
+#define VID_CLUSTER_SIZE 1440 /* VID cluster data line */
+#define AUDIO_CLUSTER_SIZE 128 /* AUDIO cluster data line */
+#define MBIF_CLUSTER_SIZE 1440 /* MBIF/HBI cluster data line */
-//#define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM
-//#define TX_SRAM_END_SIZE = 0; // End of TX SRAM
+/* #define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM */
+/* #define TX_SRAM_END_SIZE = 0; // End of TX SRAM */
-// Receive SRAM
+/* Receive SRAM */
#define RX_SRAM_START 0x10000
#define VID_A_DOWN_CMDS 0x10000
#define VID_B_DOWN_CMDS 0x10050
@@ -78,9 +78,9 @@
#define AUD_E_UP_CMDS 0x10730
#define MBIF_A_DOWN_CMDS 0x10780
#define MBIF_B_DOWN_CMDS 0x107D0
-#define DMA_SCRATCH_PAD 0x10820 // Scratch pad area from 0x10820 to 0x10B40
+#define DMA_SCRATCH_PAD 0x10820 /* Scratch pad area from 0x10820 to 0x10B40 */
-//#define RX_SRAM_POOL_START = 0x105B0;
+/* #define RX_SRAM_POOL_START = 0x105B0; */
#define VID_A_IQ 0x11000
#define VID_B_IQ 0x11040
@@ -118,7 +118,7 @@
#define MBIF_A_CDT 0x10C00
#define MBIF_B_CDT 0x10CC0
-// Cluster Buffer for RX
+/* Cluster Buffer for RX */
#define VID_A_UP_CLUSTER_1 0x11400
#define VID_A_UP_CLUSTER_2 0x119A0
#define VID_A_UP_CLUSTER_3 0x11F40
@@ -178,9 +178,9 @@
#define RX_SRAM_POOL_FREE 0x1CE00
#define RX_SRAM_END 0x1D000
-// Free Receive SRAM 144 Bytes
+/* Free Receive SRAM 144 Bytes */
-// Transmit SRAM
+/* Transmit SRAM */
#define TX_SRAM_POOL_START 0x00000
#define VID_A_DOWN_CLUSTER_1 0x00040
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
index 343df6619fe8..d12dbb572e8b 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -84,7 +84,7 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
{
unsigned int line, i;
struct sram_channel *sram_ch =
- &dev->sram_channels[dev->_channel2_upstream_select];
+ dev->channels[dev->_channel2_upstream_select].sram_channels;
int dist_betwn_starts = bpl * 2;
/* sync instruction */
@@ -110,8 +110,11 @@ static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
offset += dist_betwn_starts;
}
- // check if we need to enable the FIFO after the first 4 lines
- // For the upstream video channel, the risc engine will enable the FIFO.
+ /*
+ check if we need to enable the FIFO after the first 4 lines
+ For the upstream video channel, the risc engine will enable
+ the FIFO.
+ */
if (fifo_enable && line == 3) {
*(rp++) = RISC_WRITECR;
*(rp++) = sram_ch->dma_ctl;
@@ -130,7 +133,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
{
__le32 *rp;
int fifo_enable = 0;
- int singlefield_lines = lines >> 1; //get line count for single field
+ int singlefield_lines = lines >> 1; /*get line count for single field */
int odd_num_lines = singlefield_lines;
int frame = 0;
int frame_size = 0;
@@ -174,7 +177,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
fifo_enable = FIFO_DISABLE;
- //Even field
+ /* Even field */
rp = cx25821_risc_field_upstream_ch2(dev, rp,
dev->
_data_buf_phys_addr_ch2 +
@@ -192,7 +195,10 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
}
- // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
+ /*
+ Loop to 2ndFrameRISC or to Start of
+ Risc program & generate IRQ
+ */
*(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
*(rp++) = cpu_to_le32(risc_phys_jump_addr);
*(rp++) = cpu_to_le32(0);
@@ -204,7 +210,7 @@ int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
{
struct sram_channel *sram_ch =
- &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
+ dev->channels[VID_UPSTREAM_SRAM_CHANNEL_J].sram_channels;
u32 tmp = 0;
if (!dev->_is_running_ch2) {
@@ -212,15 +218,15 @@ void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
("cx25821: No video file is currently running so return!\n");
return;
}
- //Disable RISC interrupts
+ /* Disable RISC interrupts */
tmp = cx_read(sram_ch->int_msk);
cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
- //Turn OFF risc and fifo
+ /* Turn OFF risc and fifo */
tmp = cx_read(sram_ch->dma_ctl);
cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
- //Clear data buffer memory
+ /* Clear data buffer memory */
if (dev->_data_buf_virt_addr_ch2)
memset(dev->_data_buf_virt_addr_ch2, 0,
dev->_data_buf_size_ch2);
@@ -371,8 +377,8 @@ static void cx25821_vidups_handler_ch2(struct work_struct *work)
}
cx25821_get_frame_ch2(dev,
- &dev->sram_channels[dev->
- _channel2_upstream_select]);
+ dev->channels[dev->
+ _channel2_upstream_select].sram_channels);
}
int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
@@ -488,7 +494,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
return -ENOMEM;
}
- //Iniitize at this address until n bytes to 0
+ /* Iniitize at this address until n bytes to 0 */
memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
if (dev->_data_buf_virt_addr_ch2 != NULL) {
@@ -496,7 +502,7 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
dev->_data_buf_virt_addr_ch2,
dev->_data_buf_phys_addr_ch2);
}
- //For Video Data buffer allocation
+ /* For Video Data buffer allocation */
dev->_data_buf_virt_addr_ch2 =
pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
&data_dma_addr);
@@ -509,14 +515,14 @@ static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
return -ENOMEM;
}
- //Initialize at this address until n bytes to 0
+ /* Initialize at this address until n bytes to 0 */
memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
ret = cx25821_openfile_ch2(dev, sram_ch);
if (ret < 0)
return ret;
- //Creating RISC programs
+ /* Creating RISC programs */
ret =
cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
dev->_lines_count_ch2);
@@ -536,7 +542,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
u32 status)
{
u32 int_msk_tmp;
- struct sram_channel *channel = &dev->sram_channels[chan_num];
+ struct sram_channel *channel = dev->channels[chan_num].sram_channels;
int singlefield_lines = NTSC_FIELD_HEIGHT;
int line_size_in_bytes = Y422_LINE_SZ;
int odd_risc_prog_size = 0;
@@ -544,10 +550,13 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
__le32 *rp;
if (status & FLD_VID_SRC_RISC1) {
- // We should only process one program per call
+ /* We should only process one program per call */
u32 prog_cnt = cx_read(channel->gpcnt);
- //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
+ /*
+ Since we've identified our IRQ, clear our bits from the
+ interrupt mask and interrupt status registers
+ */
int_msk_tmp = cx_read(channel->int_msk);
cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
cx_write(channel->int_stat, _intr_msk);
@@ -588,7 +597,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
FIFO_DISABLE,
ODD_FIELD);
- // Jump to Even Risc program of 1st Frame
+ /* Jump to Even Risc program of 1st Frame */
*(rp++) = cpu_to_le32(RISC_JUMP);
*(rp++) = cpu_to_le32(risc_phys_jump_addr);
*(rp++) = cpu_to_le32(0);
@@ -603,7 +612,7 @@ int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
dev->_frame_count_ch2);
return -1;
}
- //ElSE, set the interrupt mask register, re-enable irq.
+ /* ElSE, set the interrupt mask register, re-enable irq. */
int_msk_tmp = cx_read(channel->int_msk);
cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
@@ -623,12 +632,12 @@ static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
- sram_ch = &dev->sram_channels[channel_num];
+ sram_ch = dev->channels[channel_num].sram_channels;
msk_stat = cx_read(sram_ch->int_mstat);
vid_status = cx_read(sram_ch->int_stat);
- // Only deal with our interrupt
+ /* Only deal with our interrupt */
if (vid_status) {
handled =
cx25821_video_upstream_irq_ch2(dev, channel_num,
@@ -658,7 +667,10 @@ static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
value |= dev->_isNTSC_ch2 ? 0 : 0x10;
cx_write(ch->vid_fmt_ctl, value);
- // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
+ /*
+ set number of active pixels in each line. Default is 720
+ pixels in both NTSC and PAL format
+ */
cx_write(ch->vid_active_ctl1, width);
num_lines = (height / 2) & 0x3FF;
@@ -670,7 +682,7 @@ static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
value = (num_lines << 16) | odd_num_lines;
- // set number of active lines in field 0 (top) and field 1 (bottom)
+ /* set number of active lines in field 0 (top) and field 1 (bottom) */
cx_write(ch->vid_active_ctl2, value);
cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
@@ -682,21 +694,27 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
u32 tmp = 0;
int err = 0;
- // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+ /*
+ 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface
+ for channel A-C
+ */
tmp = cx_read(VID_CH_MODE_SEL);
cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
- // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
+ /*
+ Set the physical start address of the RISC program in the initial
+ program counter(IPC) member of the cmds.
+ */
cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
- cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
+ cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
/* reset counter */
cx_write(sram_ch->gpcnt_ctl, 3);
- // Clear our bits from the interrupt status register.
+ /* Clear our bits from the interrupt status register. */
cx_write(sram_ch->int_stat, _intr_msk);
- //Set the interrupt mask register, enable irq.
+ /* Set the interrupt mask register, enable irq. */
cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
tmp = cx_read(sram_ch->int_msk);
cx_write(sram_ch->int_msk, tmp |= _intr_msk);
@@ -709,7 +727,7 @@ int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
dev->pci->irq);
goto fail_irq;
}
- // Start the DMA engine
+ /* Start the DMA engine */
tmp = cx_read(sram_ch->dma_ctl);
cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
@@ -740,7 +758,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
}
dev->_channel2_upstream_select = channel_select;
- sram_ch = &dev->sram_channels[channel_select];
+ sram_ch = dev->channels[channel_select].sram_channels;
INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
dev->_irq_queues_ch2 =
@@ -751,7 +769,10 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
return -ENOMEM;
}
- // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
+ /*
+ 656/VIP SRC Upstream Channel I & J and 7 -
+ Host Bus Interface for channel A-C
+ */
tmp = cx_read(VID_CH_MODE_SEL);
cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
@@ -787,7 +808,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
str_length + 1);
}
- //Default if filename is empty string
+ /* Default if filename is empty string */
if (strcmp(dev->input_filename_ch2, "") == 0) {
if (dev->_isNTSC_ch2) {
dev->_filename_ch2 =
@@ -812,7 +833,7 @@ int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
dev->upstream_databuf_size_ch2 = data_frame_size * 2;
- //Allocating buffers and prepare RISC program
+ /* Allocating buffers and prepare RISC program */
retval =
cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
dev->_line_size_ch2);
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
index 73feea114c1c..62340636c916 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -37,7 +37,7 @@
#define RESET_STATUS -1
#define NUM_NO_OPS 5
-// PAL and NTSC line sizes and number of lines.
+/* PAL and NTSC line sizes and number of lines. */
#define WIDTH_D1 720
#define NTSC_LINES_PER_FRAME 480
#define PAL_LINES_PER_FRAME 576
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
index 7a3dad91eba8..756a820a76cb 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -134,7 +134,7 @@ static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
{
unsigned int line, i;
struct sram_channel *sram_ch =
- &dev->sram_channels[dev->_channel_upstream_select];
+ dev->channels[dev->_channel_upstream_select].sram_channels;
int dist_betwn_starts = bpl * 2;
/* sync instruction */
@@ -253,7 +253,7 @@ int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
{
struct sram_channel *sram_ch =
- &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
+ dev->channels[VID_UPSTREAM_SRAM_CHANNEL_I].sram_channels;
u32 tmp = 0;
if (!dev->_is_running) {
@@ -346,20 +346,23 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
- __func__, dev->_filename, open_errno);
+ printk(KERN_ERR
+ "%s(): ERROR opening file(%s) with errno = %d!\n",
+ __func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!",
- __func__);
+ printk(KERN_ERR
+ "%s: File has no file operations registered!",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk(KERN_ERR "%s: File has no READ operations registered!",
- __func__);
+ printk(KERN_ERR
+ "%s: File has no READ operations registered!",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
@@ -386,7 +389,8 @@ int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (vfs_read_retval < line_size) {
printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
+ "Done: exit %s() since no more bytes to \
+ read from Video file.\n",
__func__);
break;
}
@@ -411,13 +415,15 @@ static void cx25821_vidups_handler(struct work_struct *work)
container_of(work, struct cx25821_dev, _irq_work_entry);
if (!dev) {
- printk(KERN_ERR "ERROR %s(): since container_of(work_struct) FAILED!\n",
- __func__);
+ printk(KERN_ERR
+ "ERROR %s(): since container_of(work_struct) FAILED!\n",
+ __func__);
return;
}
cx25821_get_frame(dev,
- &dev->sram_channels[dev->_channel_upstream_select]);
+ dev->channels[dev->_channel_upstream_select].
+ sram_channels);
}
int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
@@ -437,20 +443,22 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (IS_ERR(myfile)) {
const int open_errno = -PTR_ERR(myfile);
- printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
+ printk(KERN_ERR "%s(): ERROR opening file(%s) with errno = %d!\n",
__func__, dev->_filename, open_errno);
return PTR_ERR(myfile);
} else {
if (!(myfile->f_op)) {
- printk(KERN_ERR "%s: File has no file operations registered!",
- __func__);
+ printk(KERN_ERR
+ "%s: File has no file operations registered!",
+ __func__);
filp_close(myfile, NULL);
return -EIO;
}
if (!myfile->f_op->read) {
- printk
- (KERN_ERR "%s: File has no READ operations registered! Returning.",
+ printk(KERN_ERR
+ "%s: File has no READ operations registered! \
+ Returning.",
__func__);
filp_close(myfile, NULL);
return -EIO;
@@ -480,7 +488,8 @@ int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
if (vfs_read_retval < line_size) {
printk(KERN_INFO
- "Done: exit %s() since no more bytes to read from Video file.\n",
+ "Done: exit %s() since no more \
+ bytes to read from Video file.\n",
__func__);
break;
}
@@ -526,7 +535,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_dma_virt_addr) {
printk
- (KERN_ERR "cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
+ (KERN_ERR "cx25821: FAILED to allocate memory for Risc \
+ buffer! Returning.\n");
return -ENOMEM;
}
@@ -547,7 +557,8 @@ int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
if (!dev->_data_buf_virt_addr) {
printk
- (KERN_ERR "cx25821: FAILED to allocate memory for data buffer! Returning.\n");
+ (KERN_ERR "cx25821: FAILED to allocate memory for data \
+ buffer! Returning.\n");
return -ENOMEM;
}
@@ -578,7 +589,7 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
u32 status)
{
u32 int_msk_tmp;
- struct sram_channel *channel = &dev->sram_channels[chan_num];
+ struct sram_channel *channel = dev->channels[chan_num].sram_channels;
int singlefield_lines = NTSC_FIELD_HEIGHT;
int line_size_in_bytes = Y422_LINE_SZ;
int odd_risc_prog_size = 0;
@@ -642,16 +653,16 @@ int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
} else {
if (status & FLD_VID_SRC_UF)
printk
- (KERN_ERR "%s: Video Received Underflow Error Interrupt!\n",
- __func__);
+ (KERN_ERR "%s: Video Received Underflow Error \
+ Interrupt!\n", __func__);
if (status & FLD_VID_SRC_SYNC)
- printk(KERN_ERR "%s: Video Received Sync Error Interrupt!\n",
- __func__);
+ printk(KERN_ERR "%s: Video Received Sync Error \
+ Interrupt!\n", __func__);
if (status & FLD_VID_SRC_OPC_ERR)
- printk(KERN_ERR "%s: Video Received OpCode Error Interrupt!\n",
- __func__);
+ printk(KERN_ERR "%s: Video Received OpCode Error \
+ Interrupt!\n", __func__);
}
if (dev->_file_status == END_OF_FILE) {
@@ -679,7 +690,7 @@ static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
- sram_ch = &dev->sram_channels[channel_num];
+ sram_ch = dev->channels[channel_num].sram_channels;
msk_stat = cx_read(sram_ch->int_mstat);
vid_status = cx_read(sram_ch->int_stat);
@@ -800,14 +811,15 @@ int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
}
dev->_channel_upstream_select = channel_select;
- sram_ch = &dev->sram_channels[channel_select];
+ sram_ch = dev->channels[channel_select].sram_channels;
INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
if (!dev->_irq_queues) {
printk
- (KERN_ERR "cx25821: create_singlethread_workqueue() for Video FAILED!\n");
+ (KERN_ERR "cx25821: create_singlethread_workqueue() for \
+ Video FAILED!\n");
return -ENOMEM;
}
/* 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
index cc9f93842514..10dee5c24a81 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.h
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -38,7 +38,7 @@
#define RESET_STATUS -1
#define NUM_NO_OPS 5
-// PAL and NTSC line sizes and number of lines.
+/* PAL and NTSC line sizes and number of lines. */
#define WIDTH_D1 720
#define NTSC_LINES_PER_FRAME 480
#define PAL_LINES_PER_FRAME 576
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 791212c1a661..1d5e8796d383 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -4,6 +4,9 @@
* Copyright (C) 2009 Conexant Systems Inc.
* Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
* Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
+ * Parts adapted/taken from Eduardo Moscoso Rubino
+ * Copyright (C) 2009 Eduardo Moscoso Rubino <moscoso@TopoLogica.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
@@ -24,7 +27,7 @@
#include "cx25821-video.h"
MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
-MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
+MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
MODULE_LICENSE("GPL");
static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
@@ -48,7 +51,10 @@ unsigned int vid_limit = 16;
module_param(vid_limit, int, 0644);
MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
-static void init_controls(struct cx25821_dev *dev, int chan_num);
+static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num);
+
+static const struct v4l2_file_operations video_fops;
+static const struct v4l2_ioctl_ops video_ioctl_ops;
#define FORMAT_FLAGS_PACKED 0x01
@@ -211,7 +217,7 @@ static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
}
*/
-// resource management
+/* resource management */
int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
{
dprintk(1, "%s()\n", __func__);
@@ -221,14 +227,14 @@ int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int
/* is it free? */
mutex_lock(&dev->lock);
- if (dev->resources & bit) {
+ if (dev->channels[fh->channel_id].resources & bit) {
/* no, someone else uses it */
mutex_unlock(&dev->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
- dev->resources |= bit;
+ dev->channels[fh->channel_id].resources |= bit;
dprintk(1, "res: get %d\n", bit);
mutex_unlock(&dev->lock);
return 1;
@@ -239,9 +245,9 @@ int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit)
return fh->resources & bit;
}
-int cx25821_res_locked(struct cx25821_dev *dev, unsigned int bit)
+int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit)
{
- return dev->resources & bit;
+ return fh->dev->channels[fh->channel_id].resources & bit;
}
void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
@@ -251,7 +257,7 @@ void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned i
mutex_lock(&dev->lock);
fh->resources &= ~bits;
- dev->resources &= ~bits;
+ dev->channels[fh->channel_id].resources &= ~bits;
dprintk(1, "res: put %d\n", bits);
mutex_unlock(&dev->lock);
}
@@ -358,11 +364,11 @@ void cx25821_vid_timeout(unsigned long data)
struct cx25821_data *timeout_data = (struct cx25821_data *)data;
struct cx25821_dev *dev = timeout_data->dev;
struct sram_channel *channel = timeout_data->channel;
- struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
+ struct cx25821_dmaqueue *q = &dev->channels[channel->i].vidq;
struct cx25821_buffer *buf;
unsigned long flags;
- //cx25821_sram_channel_dump(dev, channel);
+ /* cx25821_sram_channel_dump(dev, channel); */
cx_clear(channel->dma_ctl, 0x11);
spin_lock_irqsave(&dev->slock, flags);
@@ -384,7 +390,7 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
u32 count = 0;
int handled = 0;
u32 mask;
- struct sram_channel *channel = &dev->sram_channels[chan_num];
+ struct sram_channel *channel = dev->channels[chan_num].sram_channels;
mask = cx_read(channel->int_msk);
if (0 == (status & mask))
@@ -404,7 +410,8 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
if (status & FLD_VID_DST_RISC1) {
spin_lock(&dev->slock);
count = cx_read(channel->gpcnt);
- cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
+ cx25821_video_wakeup(dev,
+ &dev->channels[channel->i].vidq, count);
spin_unlock(&dev->slock);
handled++;
}
@@ -413,8 +420,9 @@ int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
if (status & 0x10) {
dprintk(2, "stopper video\n");
spin_lock(&dev->slock);
- cx25821_restart_video_queue(dev, &dev->vidq[channel->i],
- channel);
+ cx25821_restart_video_queue(dev,
+ &dev->channels[channel->i].vidq,
+ channel);
spin_unlock(&dev->slock);
handled++;
}
@@ -437,72 +445,95 @@ void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
{
cx_clear(PCI_INT_MSK, 1);
- if (dev->video_dev[chan_num]) {
- if (video_is_registered(dev->video_dev[chan_num]))
- video_unregister_device(dev->video_dev[chan_num]);
+ if (dev->channels[chan_num].video_dev) {
+ if (video_is_registered(dev->channels[chan_num].video_dev))
+ video_unregister_device(
+ dev->channels[chan_num].video_dev);
else
- video_device_release(dev->video_dev[chan_num]);
+ video_device_release(
+ dev->channels[chan_num].video_dev);
- dev->video_dev[chan_num] = NULL;
+ dev->channels[chan_num].video_dev = NULL;
- btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
+ btcx_riscmem_free(dev->pci,
+ &dev->channels[chan_num].vidq.stopper);
printk(KERN_WARNING "device %d released!\n", chan_num);
}
}
-int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
- struct video_device *video_template)
+int cx25821_video_register(struct cx25821_dev *dev)
{
int err;
+ int i;
+
+ struct video_device cx25821_video_device = {
+ .name = "cx25821-video",
+ .fops = &video_fops,
+ .minor = -1,
+ .ioctl_ops = &video_ioctl_ops,
+ .tvnorms = CX25821_NORMS,
+ .current_norm = V4L2_STD_NTSC_M,
+ };
spin_lock_init(&dev->slock);
- //printk(KERN_WARNING "Channel %d\n", chan_num);
+ for (i = 0; i < MAX_VID_CHANNEL_NUM - 1; ++i) {
+ cx25821_init_controls(dev, i);
-#ifdef TUNER_FLAG
- dev->tvnorm = video_template->current_norm;
-#endif
+ cx25821_risc_stopper(dev->pci,
+ &dev->channels[i].vidq.stopper,
+ dev->channels[i].sram_channels->dma_ctl,
+ 0x11, 0);
+
+ dev->channels[i].sram_channels = &cx25821_sram_channels[i];
+ dev->channels[i].video_dev = NULL;
+ dev->channels[i].resources = 0;
+
+ cx_write(dev->channels[i].sram_channels->int_stat,
+ 0xffffffff);
+
+ INIT_LIST_HEAD(&dev->channels[i].vidq.active);
+ INIT_LIST_HEAD(&dev->channels[i].vidq.queued);
+
+ dev->channels[i].timeout_data.dev = dev;
+ dev->channels[i].timeout_data.channel =
+ &cx25821_sram_channels[i];
+ dev->channels[i].vidq.timeout.function =
+ cx25821_vid_timeout;
+ dev->channels[i].vidq.timeout.data =
+ (unsigned long)&dev->channels[i].timeout_data;
+ init_timer(&dev->channels[i].vidq.timeout);
+
+ /* register v4l devices */
+ dev->channels[i].video_dev = cx25821_vdev_init(dev,
+ dev->pci, &cx25821_video_device, "video");
+
+ err = video_register_device(dev->channels[i].video_dev,
+ VFL_TYPE_GRABBER, video_nr[dev->nr]);
+
+ if (err < 0)
+ goto fail_unreg;
- /* init video dma queues */
- dev->timeout_data[chan_num].dev = dev;
- dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
- INIT_LIST_HEAD(&dev->vidq[chan_num].active);
- INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
- dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
- dev->vidq[chan_num].timeout.data =
- (unsigned long)&dev->timeout_data[chan_num];
- init_timer(&dev->vidq[chan_num].timeout);
- cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
- dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
-
- /* register v4l devices */
- dev->video_dev[chan_num] =
- cx25821_vdev_init(dev, dev->pci, video_template, "video");
- err =
- video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
- video_nr[dev->nr]);
-
- if (err < 0) {
- goto fail_unreg;
}
- //set PCI interrupt
+
+ /* set PCI interrupt */
cx_set(PCI_INT_MSK, 0xff);
/* initial device configuration */
mutex_lock(&dev->lock);
#ifdef TUNER_FLAG
+ dev->tvnorm = cx25821_video_device.current_norm;
cx25821_set_tvnorm(dev, dev->tvnorm);
#endif
mutex_unlock(&dev->lock);
- init_controls(dev, chan_num);
- return 0;
+ return 0;
- fail_unreg:
- cx25821_video_unregister(dev, chan_num);
+fail_unreg:
+ cx25821_video_unregister(dev, i);
return err;
}
@@ -533,7 +564,7 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
u32 line0_offset, line1_offset;
struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
int bpl_local = LINE_SIZE_D1;
- int channel_opened = 0;
+ int channel_opened = fh->channel_id;
BUG_ON(NULL == fh->fmt);
if (fh->width < 48 || fh->width > 720 ||
@@ -572,26 +603,29 @@ int cx25821_buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
channel_opened = (channel_opened < 0
|| channel_opened > 7) ? 7 : channel_opened;
- if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
+ if (dev->channels[channel_opened]
+ .pixel_formats == PIXEL_FRMT_411)
buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
else
buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
- if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
+ if (dev->channels[channel_opened]
+ .pixel_formats == PIXEL_FRMT_411) {
bpl_local = buf->bpl;
} else {
- bpl_local = buf->bpl; //Default
+ bpl_local = buf->bpl; /* Default */
if (channel_opened >= 0 && channel_opened <= 7) {
- if (dev->use_cif_resolution[channel_opened]) {
+ if (dev->channels[channel_opened]
+ .use_cif_resolution) {
if (dev->tvnorm & V4L2_STD_PAL_BG
|| dev->tvnorm & V4L2_STD_PAL_DK)
bpl_local = 352 << 1;
else
bpl_local =
- dev->
- cif_width[channel_opened] <<
- 1;
+ dev->channels[channel_opened].
+ cif_width <<
+ 1;
}
}
}
@@ -685,6 +719,383 @@ int cx25821_video_mmap(struct file *file, struct vm_area_struct *vma)
return videobuf_mmap_mapper(get_queue(fh), vma);
}
+
+static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct cx25821_buffer *buf =
+ container_of(vb, struct cx25821_buffer, vb);
+ struct cx25821_buffer *prev;
+ struct cx25821_fh *fh = vq->priv_data;
+ struct cx25821_dev *dev = fh->dev;
+ struct cx25821_dmaqueue *q = &dev->channels[fh->channel_id].vidq;
+
+ /* add jump to stopper */
+ buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
+ buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
+ buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
+
+ dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
+
+ if (!list_empty(&q->queued)) {
+ list_add_tail(&buf->vb.queue, &q->queued);
+ buf->vb.state = VIDEOBUF_QUEUED;
+ dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
+ buf->vb.i);
+
+ } else if (list_empty(&q->active)) {
+ list_add_tail(&buf->vb.queue, &q->active);
+ cx25821_start_video_dma(dev, q, buf,
+ dev->channels[fh->channel_id].
+ sram_channels);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ buf->count = q->count++;
+ mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
+ dprintk(2,
+ "[%p/%d] buffer_queue - first active, buf cnt = %d, \
+ q->count = %d\n",
+ buf, buf->vb.i, buf->count, q->count);
+ } else {
+ prev =
+ list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
+ if (prev->vb.width == buf->vb.width
+ && prev->vb.height == buf->vb.height
+ && prev->fmt == buf->fmt) {
+ list_add_tail(&buf->vb.queue, &q->active);
+ buf->vb.state = VIDEOBUF_ACTIVE;
+ buf->count = q->count++;
+ prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
+
+ /* 64 bit bits 63-32 */
+ prev->risc.jmp[2] = cpu_to_le32(0);
+ dprintk(2,
+ "[%p/%d] buffer_queue - append to active, \
+ buf->count=%d\n",
+ buf, buf->vb.i, buf->count);
+
+ } else {
+ list_add_tail(&buf->vb.queue, &q->queued);
+ buf->vb.state = VIDEOBUF_QUEUED;
+ dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
+ buf->vb.i);
+ }
+ }
+
+ if (list_empty(&q->active))
+ dprintk(2, "active queue empty!\n");
+}
+
+static struct videobuf_queue_ops cx25821_video_qops = {
+ .buf_setup = cx25821_buffer_setup,
+ .buf_prepare = cx25821_buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = cx25821_buffer_release,
+};
+
+static int video_open(struct file *file)
+{
+ struct video_device *vdev = video_devdata(file);
+ struct cx25821_dev *h, *dev = video_drvdata(file);
+ struct cx25821_fh *fh;
+ struct list_head *list;
+ int minor = video_devdata(file)->minor;
+ enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ u32 pix_format;
+ int ch_id = 0;
+ int i;
+
+ dprintk(1, "open dev=%s type=%s\n",
+ video_device_node_name(vdev),
+ v4l2_type_names[type]);
+
+ /* allocate + initialize per filehandle data */
+ fh = kzalloc(sizeof(*fh), GFP_KERNEL);
+ if (NULL == fh)
+ return -ENOMEM;
+
+ lock_kernel();
+
+ list_for_each(list, &cx25821_devlist)
+ {
+ h = list_entry(list, struct cx25821_dev, devlist);
+
+ for (i = 0; i < MAX_VID_CHANNEL_NUM; i++) {
+ if (h->channels[i].video_dev &&
+ h->channels[i].video_dev->minor == minor) {
+ dev = h;
+ ch_id = i;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+ }
+ }
+
+ if (NULL == dev) {
+ unlock_kernel();
+ return -ENODEV;
+ }
+
+ file->private_data = fh;
+ fh->dev = dev;
+ fh->type = type;
+ fh->width = 720;
+ fh->channel_id = ch_id;
+
+ if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
+ fh->height = 576;
+ else
+ fh->height = 480;
+
+ dev->channel_opened = fh->channel_id;
+ pix_format =
+ (dev->channels[ch_id].pixel_formats ==
+ PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
+ fh->fmt = format_by_fourcc(pix_format);
+
+ v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio);
+
+ videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
+ &dev->pci->dev, &dev->slock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_INTERLACED,
+ sizeof(struct cx25821_buffer), fh);
+
+ dprintk(1, "post videobuf_queue_init()\n");
+ unlock_kernel();
+
+ return 0;
+}
+
+static ssize_t video_read(struct file *file, char __user * data, size_t count,
+ loff_t *ppos)
+{
+ struct cx25821_fh *fh = file->private_data;
+
+ switch (fh->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ if (cx25821_res_locked(fh, RESOURCE_VIDEO0))
+ return -EBUSY;
+
+ return videobuf_read_one(&fh->vidq, data, count, ppos,
+ file->f_flags & O_NONBLOCK);
+
+ default:
+ BUG();
+ return 0;
+ }
+}
+
+static unsigned int video_poll(struct file *file,
+ struct poll_table_struct *wait)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_buffer *buf;
+
+ if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
+ /* streaming capture */
+ if (list_empty(&fh->vidq.stream))
+ return POLLERR;
+ buf = list_entry(fh->vidq.stream.next,
+ struct cx25821_buffer, vb.stream);
+ } else {
+ /* read() capture */
+ buf = (struct cx25821_buffer *)fh->vidq.read_buf;
+ if (NULL == buf)
+ return POLLERR;
+ }
+
+ poll_wait(file, &buf->vb.done, wait);
+ if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
+ if (buf->vb.state == VIDEOBUF_DONE) {
+ struct cx25821_dev *dev = fh->dev;
+
+ if (dev && dev->channels[fh->channel_id]
+ .use_cif_resolution) {
+ u8 cam_id = *((char *)buf->vb.baddr + 3);
+ memcpy((char *)buf->vb.baddr,
+ (char *)buf->vb.baddr + (fh->width * 2),
+ (fh->width * 2));
+ *((char *)buf->vb.baddr + 3) = cam_id;
+ }
+ }
+
+ return POLLIN | POLLRDNORM;
+ }
+
+ return 0;
+}
+
+static int video_release(struct file *file)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_dev *dev = fh->dev;
+
+ /* stop the risc engine and fifo */
+ cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
+
+ /* stop video capture */
+ if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
+ videobuf_queue_cancel(&fh->vidq);
+ cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
+ }
+
+ if (fh->vidq.read_buf) {
+ cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
+ kfree(fh->vidq.read_buf);
+ }
+
+ videobuf_mmap_free(&fh->vidq);
+
+ v4l2_prio_close(&dev->channels[fh->channel_id].prio, fh->prio);
+ file->private_data = NULL;
+ kfree(fh);
+
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct cx25821_fh *fh = priv;
+ struct cx25821_dev *dev = fh->dev;
+
+ if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE))
+ return -EINVAL;
+
+ if (unlikely(i != fh->type))
+ return -EINVAL;
+
+ if (unlikely(!cx25821_res_get(dev, fh,
+ cx25821_get_resource(fh, RESOURCE_VIDEO0))))
+ return -EBUSY;
+
+ return videobuf_streamon(get_queue(fh));
+}
+
+static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+ struct cx25821_fh *fh = priv;
+ struct cx25821_dev *dev = fh->dev;
+ int err, res;
+
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (i != fh->type)
+ return -EINVAL;
+
+ res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
+ err = videobuf_streamoff(get_queue(fh));
+ if (err < 0)
+ return err;
+ cx25821_res_free(dev, fh, res);
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct cx25821_fh *fh = priv;
+ struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+ int err;
+ int pix_format = PIXEL_FRMT_422;
+
+ if (fh) {
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
+ if (0 != err)
+ return err;
+ }
+
+ dprintk(2, "%s()\n", __func__);
+ err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
+
+ if (0 != err)
+ return err;
+
+ fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
+ fh->vidq.field = f->fmt.pix.field;
+
+ /* check if width and height is valid based on set standard */
+ if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm))
+ fh->width = f->fmt.pix.width;
+
+ if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm))
+ fh->height = f->fmt.pix.height;
+
+ if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
+ pix_format = PIXEL_FRMT_411;
+ else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
+ pix_format = PIXEL_FRMT_422;
+ else
+ return -EINVAL;
+
+ cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
+
+ /* check if cif resolution */
+ if (fh->width == 320 || fh->width == 352)
+ dev->channels[fh->channel_id].use_cif_resolution = 1;
+ else
+ dev->channels[fh->channel_id].use_cif_resolution = 0;
+
+ dev->channels[fh->channel_id].cif_width = fh->width;
+ medusa_set_resolution(dev, fh->width, SRAM_CH00);
+
+ dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
+ fh->height, fh->vidq.field);
+ cx25821_call_all(dev, video, s_fmt, f);
+
+ return 0;
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+ int ret_val = 0;
+ struct cx25821_fh *fh = priv;
+ struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+
+ ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
+
+ p->sequence = dev->channels[fh->channel_id].vidq.count;
+
+ return ret_val;
+}
+
+static int vidioc_log_status(struct file *file, void *priv)
+{
+ struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+ struct cx25821_fh *fh = priv;
+ char name[32 + 2];
+
+ struct sram_channel *sram_ch = dev->channels[fh->channel_id]
+ .sram_channels;
+ u32 tmp = 0;
+
+ snprintf(name, sizeof(name), "%s/2", dev->name);
+ printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
+ dev->name);
+ cx25821_call_all(dev, core, log_status);
+ tmp = cx_read(sram_ch->dma_ctl);
+ printk(KERN_INFO "Video input 0 is %s\n",
+ (tmp & 0x11) ? "streaming" : "stopped");
+ printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
+ dev->name);
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctl)
+{
+ struct cx25821_fh *fh = priv;
+ struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+ int err;
+
+ if (fh) {
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
+ if (0 != err)
+ return err;
+ }
+
+ return cx25821_set_control(dev, ctl, fh->channel_id);
+}
+
/* VIDEO IOCTLS */
int cx25821_vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
{
@@ -822,8 +1233,9 @@ int cx25821_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
int cx25821_vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
{
struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
+ struct cx25821_fh *fh = f;
- *p = v4l2_prio_max(&dev->prio);
+ *p = v4l2_prio_max(&dev->channels[fh->channel_id].prio);
return 0;
}
@@ -833,7 +1245,8 @@ int cx25821_vidioc_s_priority(struct file *file, void *f, enum v4l2_priority pri
struct cx25821_fh *fh = f;
struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
- return v4l2_prio_change(&dev->prio, &fh->prio, prio);
+ return v4l2_prio_change(&dev->channels[fh->channel_id]
+ .prio, &fh->prio, prio);
}
#ifdef TUNER_FLAG
@@ -846,7 +1259,8 @@ int cx25821_vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
dprintk(1, "%s()\n", __func__);
if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
if (0 != err)
return err;
}
@@ -916,7 +1330,8 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
dprintk(1, "%s(%d)\n", __func__, i);
if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
if (0 != err)
return err;
}
@@ -967,9 +1382,14 @@ int cx25821_vidioc_s_frequency(struct file *file, void *priv, struct v4l2_freque
int err;
if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
+ dev = fh->dev;
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
if (0 != err)
return err;
+ } else {
+ printk(KERN_ERR "Invalid fh pointer!\n");
+ return -EINVAL;
}
return cx25821_set_freq(dev, f);
@@ -1031,7 +1451,8 @@ int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
int err;
if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
+ err = v4l2_prio_check(&dev->channels[fh->channel_id]
+ .prio, fh->prio);
if (0 != err)
return err;
}
@@ -1046,7 +1467,7 @@ int cx25821_vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
}
#endif
-// ******************************************************************************************
+/*****************************************************************************/
static const struct v4l2_queryctrl no_ctl = {
.name = "42",
.flags = V4L2_CTRL_FLAG_DISABLED,
@@ -1129,6 +1550,7 @@ static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
{
struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
+ struct cx25821_fh *fh = priv;
const struct v4l2_queryctrl *ctrl;
@@ -1138,16 +1560,16 @@ int cx25821_vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ct
return -EINVAL;
switch (ctl->id) {
case V4L2_CID_BRIGHTNESS:
- ctl->value = dev->ctl_bright;
+ ctl->value = dev->channels[fh->channel_id].ctl_bright;
break;
case V4L2_CID_HUE:
- ctl->value = dev->ctl_hue;
+ ctl->value = dev->channels[fh->channel_id].ctl_hue;
break;
case V4L2_CID_CONTRAST:
- ctl->value = dev->ctl_contrast;
+ ctl->value = dev->channels[fh->channel_id].ctl_contrast;
break;
case V4L2_CID_SATURATION:
- ctl->value = dev->ctl_saturation;
+ ctl->value = dev->channels[fh->channel_id].ctl_saturation;
break;
}
return 0;
@@ -1181,19 +1603,19 @@ int cx25821_set_control(struct cx25821_dev *dev,
switch (ctl->id) {
case V4L2_CID_BRIGHTNESS:
- dev->ctl_bright = ctl->value;
+ dev->channels[chan_num].ctl_bright = ctl->value;
medusa_set_brightness(dev, ctl->value, chan_num);
break;
case V4L2_CID_HUE:
- dev->ctl_hue = ctl->value;
+ dev->channels[chan_num].ctl_hue = ctl->value;
medusa_set_hue(dev, ctl->value, chan_num);
break;
case V4L2_CID_CONTRAST:
- dev->ctl_contrast = ctl->value;
+ dev->channels[chan_num].ctl_contrast = ctl->value;
medusa_set_contrast(dev, ctl->value, chan_num);
break;
case V4L2_CID_SATURATION:
- dev->ctl_saturation = ctl->value;
+ dev->channels[chan_num].ctl_saturation = ctl->value;
medusa_set_saturation(dev, ctl->value, chan_num);
break;
}
@@ -1203,7 +1625,7 @@ int cx25821_set_control(struct cx25821_dev *dev,
return err;
}
-static void init_controls(struct cx25821_dev *dev, int chan_num)
+static void cx25821_init_controls(struct cx25821_dev *dev, int chan_num)
{
struct v4l2_control ctrl;
int i;
@@ -1239,23 +1661,24 @@ int cx25821_vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
int err;
if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
+ err = v4l2_prio_check(&dev->channels[fh->channel_id].
+ prio, fh->prio);
if (0 != err)
return err;
}
- // cx25821_vidioc_s_crop not supported
+ /* cx25821_vidioc_s_crop not supported */
return -EINVAL;
}
int cx25821_vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
{
- // cx25821_vidioc_g_crop not supported
+ /* cx25821_vidioc_g_crop not supported */
return -EINVAL;
}
int cx25821_vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
{
- // medusa does not support video standard sensing of current input
+ /* medusa does not support video standard sensing of current input */
*norm = CX25821_NORMS;
return 0;
@@ -1297,3 +1720,325 @@ int cx25821_is_valid_height(u32 height, v4l2_std_id tvnorm)
return 0;
}
+
+static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_dev *dev = fh->dev;
+ int command = 0;
+ struct upstream_user_struct *data_from_user;
+
+ data_from_user = (struct upstream_user_struct *)arg;
+
+ if (!data_from_user) {
+ printk
+ ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+ __func__);
+ return 0;
+ }
+
+ command = data_from_user->command;
+
+ if (command != UPSTREAM_START_VIDEO &&
+ command != UPSTREAM_STOP_VIDEO)
+ return 0;
+
+ dev->input_filename = data_from_user->input_filename;
+ dev->input_audiofilename = data_from_user->input_filename;
+ dev->vid_stdname = data_from_user->vid_stdname;
+ dev->pixel_format = data_from_user->pixel_format;
+ dev->channel_select = data_from_user->channel_select;
+ dev->command = data_from_user->command;
+
+ switch (command) {
+ case UPSTREAM_START_VIDEO:
+ cx25821_start_upstream_video_ch1(dev, data_from_user);
+ break;
+
+ case UPSTREAM_STOP_VIDEO:
+ cx25821_stop_upstream_video_ch1(dev);
+ break;
+ }
+
+ return 0;
+}
+
+static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_dev *dev = fh->dev;
+ int command = 0;
+ struct upstream_user_struct *data_from_user;
+
+ data_from_user = (struct upstream_user_struct *)arg;
+
+ if (!data_from_user) {
+ printk
+ ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+ __func__);
+ return 0;
+ }
+
+ command = data_from_user->command;
+
+ if (command != UPSTREAM_START_VIDEO &&
+ command != UPSTREAM_STOP_VIDEO)
+ return 0;
+
+ dev->input_filename_ch2 = data_from_user->input_filename;
+ dev->input_audiofilename = data_from_user->input_filename;
+ dev->vid_stdname_ch2 = data_from_user->vid_stdname;
+ dev->pixel_format_ch2 = data_from_user->pixel_format;
+ dev->channel_select_ch2 = data_from_user->channel_select;
+ dev->command_ch2 = data_from_user->command;
+
+ switch (command) {
+ case UPSTREAM_START_VIDEO:
+ cx25821_start_upstream_video_ch2(dev, data_from_user);
+ break;
+
+ case UPSTREAM_STOP_VIDEO:
+ cx25821_stop_upstream_video_ch2(dev);
+ break;
+ }
+
+ return 0;
+}
+
+static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_dev *dev = fh->dev;
+ int command = 0;
+ struct upstream_user_struct *data_from_user;
+
+ data_from_user = (struct upstream_user_struct *)arg;
+
+ if (!data_from_user) {
+ printk
+ ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
+ __func__);
+ return 0;
+ }
+
+ command = data_from_user->command;
+
+ if (command != UPSTREAM_START_AUDIO &&
+ command != UPSTREAM_STOP_AUDIO)
+ return 0;
+
+ dev->input_filename = data_from_user->input_filename;
+ dev->input_audiofilename = data_from_user->input_filename;
+ dev->vid_stdname = data_from_user->vid_stdname;
+ dev->pixel_format = data_from_user->pixel_format;
+ dev->channel_select = data_from_user->channel_select;
+ dev->command = data_from_user->command;
+
+ switch (command) {
+ case UPSTREAM_START_AUDIO:
+ cx25821_start_upstream_audio(dev, data_from_user);
+ break;
+
+ case UPSTREAM_STOP_AUDIO:
+ cx25821_stop_upstream_audio(dev);
+ break;
+ }
+
+ return 0;
+}
+
+static long video_ioctl_set(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct cx25821_fh *fh = file->private_data;
+ struct cx25821_dev *dev = fh->dev;
+ struct downstream_user_struct *data_from_user;
+ int command;
+ int width = 720;
+ int selected_channel = 0, pix_format = 0, i = 0;
+ int cif_enable = 0, cif_width = 0;
+ u32 value = 0;
+
+ data_from_user = (struct downstream_user_struct *)arg;
+
+ if (!data_from_user) {
+ printk(
+ "cx25821 in %s(): User data is INVALID. Returning.\n",
+ __func__);
+ return 0;
+ }
+
+ command = data_from_user->command;
+
+ if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
+ && command != ENABLE_CIF_RESOLUTION && command != REG_READ
+ && command != REG_WRITE && command != MEDUSA_READ
+ && command != MEDUSA_WRITE) {
+ return 0;
+ }
+
+ switch (command) {
+ case SET_VIDEO_STD:
+ dev->tvnorm =
+ !strcmp(data_from_user->vid_stdname,
+ "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
+ medusa_set_videostandard(dev);
+ break;
+
+ case SET_PIXEL_FORMAT:
+ selected_channel = data_from_user->decoder_select;
+ pix_format = data_from_user->pixel_format;
+
+ if (!(selected_channel <= 7 && selected_channel >= 0)) {
+ selected_channel -= 4;
+ selected_channel = selected_channel % 8;
+ }
+
+ if (selected_channel >= 0)
+ cx25821_set_pixel_format(dev, selected_channel,
+ pix_format);
+
+ break;
+
+ case ENABLE_CIF_RESOLUTION:
+ selected_channel = data_from_user->decoder_select;
+ cif_enable = data_from_user->cif_resolution_enable;
+ cif_width = data_from_user->cif_width;
+
+ if (cif_enable) {
+ if (dev->tvnorm & V4L2_STD_PAL_BG
+ || dev->tvnorm & V4L2_STD_PAL_DK)
+ width = 352;
+ else
+ width = (cif_width == 320
+ || cif_width == 352) ? cif_width : 320;
+ }
+
+ if (!(selected_channel <= 7 && selected_channel >= 0)) {
+ selected_channel -= 4;
+ selected_channel = selected_channel % 8;
+ }
+
+ if (selected_channel <= 7 && selected_channel >= 0) {
+ dev->channels[selected_channel].
+ use_cif_resolution = cif_enable;
+ dev->channels[selected_channel].cif_width = width;
+ } else {
+ for (i = 0; i < VID_CHANNEL_NUM; i++) {
+ dev->channels[i].use_cif_resolution =
+ cif_enable;
+ dev->channels[i].cif_width = width;
+ }
+ }
+
+ medusa_set_resolution(dev, width, selected_channel);
+ break;
+ case REG_READ:
+ data_from_user->reg_data = cx_read(data_from_user->reg_address);
+ break;
+ case REG_WRITE:
+ cx_write(data_from_user->reg_address, data_from_user->reg_data);
+ break;
+ case MEDUSA_READ:
+ value =
+ cx25821_i2c_read(&dev->i2c_bus[0],
+ (u16) data_from_user->reg_address,
+ &data_from_user->reg_data);
+ break;
+ case MEDUSA_WRITE:
+ cx25821_i2c_write(&dev->i2c_bus[0],
+ (u16) data_from_user->reg_address,
+ data_from_user->reg_data);
+ break;
+ }
+
+ return 0;
+}
+
+static long cx25821_video_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0;
+
+ struct cx25821_fh *fh = file->private_data;
+
+ /* check to see if it's the video upstream */
+ if (fh->channel_id == SRAM_CH09) {
+ ret = video_ioctl_upstream9(file, cmd, arg);
+ return ret;
+ } else if (fh->channel_id == SRAM_CH10) {
+ ret = video_ioctl_upstream10(file, cmd, arg);
+ return ret;
+ } else if (fh->channel_id == SRAM_CH11) {
+ ret = video_ioctl_upstream11(file, cmd, arg);
+ ret = video_ioctl_set(file, cmd, arg);
+ return ret;
+ }
+
+ return video_ioctl2(file, cmd, arg);
+}
+
+/* exported stuff */
+static const struct v4l2_file_operations video_fops = {
+ .owner = THIS_MODULE,
+ .open = video_open,
+ .release = video_release,
+ .read = video_read,
+ .poll = video_poll,
+ .mmap = cx25821_video_mmap,
+ .ioctl = cx25821_video_ioctl,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+ .vidioc_querycap = cx25821_vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_reqbufs = cx25821_vidioc_reqbufs,
+ .vidioc_querybuf = cx25821_vidioc_querybuf,
+ .vidioc_qbuf = cx25821_vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+#ifdef TUNER_FLAG
+ .vidioc_s_std = cx25821_vidioc_s_std,
+ .vidioc_querystd = cx25821_vidioc_querystd,
+#endif
+ .vidioc_cropcap = cx25821_vidioc_cropcap,
+ .vidioc_s_crop = cx25821_vidioc_s_crop,
+ .vidioc_g_crop = cx25821_vidioc_g_crop,
+ .vidioc_enum_input = cx25821_vidioc_enum_input,
+ .vidioc_g_input = cx25821_vidioc_g_input,
+ .vidioc_s_input = cx25821_vidioc_s_input,
+ .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_queryctrl = cx25821_vidioc_queryctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_log_status = vidioc_log_status,
+ .vidioc_g_priority = cx25821_vidioc_g_priority,
+ .vidioc_s_priority = cx25821_vidioc_s_priority,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = cx25821_vidiocgmbuf,
+#endif
+#ifdef TUNER_FLAG
+ .vidioc_g_tuner = cx25821_vidioc_g_tuner,
+ .vidioc_s_tuner = cx25821_vidioc_s_tuner,
+ .vidioc_g_frequency = cx25821_vidioc_g_frequency,
+ .vidioc_s_frequency = cx25821_vidioc_s_frequency,
+#endif
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = cx25821_vidioc_g_register,
+ .vidioc_s_register = cx25821_vidioc_s_register,
+#endif
+};
+
+struct video_device cx25821_videoioctl_template = {
+ .name = "cx25821-videoioctl",
+ .fops = &video_fops,
+ .ioctl_ops = &video_ioctl_ops,
+ .tvnorms = CX25821_NORMS,
+ .current_norm = V4L2_STD_NTSC_M,
+};
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
index 0bddc02be57d..cc6034b1a95d 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -54,7 +54,7 @@
printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
} while (0)
-//For IOCTL to identify running upstream
+/* For IOCTL to identify running upstream */
#define UPSTREAM_START_VIDEO 700
#define UPSTREAM_STOP_VIDEO 701
#define UPSTREAM_START_AUDIO 702
@@ -80,19 +80,8 @@ extern struct sram_channel *channel7;
extern struct sram_channel *channel9;
extern struct sram_channel *channel10;
extern struct sram_channel *channel11;
-extern struct video_device cx25821_video_template0;
-extern struct video_device cx25821_video_template1;
-extern struct video_device cx25821_video_template2;
-extern struct video_device cx25821_video_template3;
-extern struct video_device cx25821_video_template4;
-extern struct video_device cx25821_video_template5;
-extern struct video_device cx25821_video_template6;
-extern struct video_device cx25821_video_template7;
-extern struct video_device cx25821_video_template9;
-extern struct video_device cx25821_video_template10;
-extern struct video_device cx25821_video_template11;
extern struct video_device cx25821_videoioctl_template;
-//extern const u32 *ctrl_classes[];
+/* extern const u32 *ctrl_classes[]; */
extern unsigned int vid_limit;
@@ -113,7 +102,7 @@ extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
extern int cx25821_res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
unsigned int bit);
extern int cx25821_res_check(struct cx25821_fh *fh, unsigned int bit);
-extern int cx25821_res_locked(struct cx25821_dev *dev, unsigned int bit);
+extern int cx25821_res_locked(struct cx25821_fh *fh, unsigned int bit);
extern void cx25821_res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
unsigned int bits);
extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
@@ -126,8 +115,7 @@ extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
unsigned int height, enum v4l2_field field);
extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
-extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
- struct video_device *video_template);
+extern int cx25821_video_register(struct cx25821_dev *dev);
extern int cx25821_get_format_size(void);
extern int cx25821_buffer_setup(struct videobuf_queue *q, unsigned int *count,
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
deleted file mode 100644
index 0be2cc15d856..000000000000
--- a/drivers/staging/cx25821/cx25821-video0.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH00];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH00]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH00;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO0))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH00]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO0)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO0);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO0)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO0);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = PIXEL_FRMT_422;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH00] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH00] = 0;
- }
- dev->cif_width[SRAM_CH00] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH00);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH00].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH00];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 0 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH00);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template0 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
deleted file mode 100644
index b0bae627bfb1..000000000000
--- a/drivers/staging/cx25821/cx25821-video1.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH01];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH01]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH01;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO1))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO1)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH01]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO1)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO1);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO1)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO1);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH01, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH01] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH01] = 0;
- }
- dev->cif_width[SRAM_CH01] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH01);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH01].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH01];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 1 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH01);
-}
-
-//exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template1 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
deleted file mode 100644
index 400cdb80674e..000000000000
--- a/drivers/staging/cx25821/cx25821-video2.c
+++ /dev/null
@@ -1,436 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH02];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH02]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH02;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO2))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO2)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH02]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO2)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO2);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO2)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO2);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH02, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH02] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH02] = 0;
- }
- dev->cif_width[SRAM_CH02] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH02);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH02].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
-
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 2 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH02);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template2 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
deleted file mode 100644
index 3b216ed0906e..000000000000
--- a/drivers/staging/cx25821/cx25821-video3.c
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH03];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH03]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH03;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO3))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO3)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH03]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO3)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO3);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO3)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO3);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH03, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH03] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH03] = 0;
- }
- dev->cif_width[SRAM_CH03] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH03);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH03].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 3 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH03);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template3 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
deleted file mode 100644
index f7b08c51868a..000000000000
--- a/drivers/staging/cx25821/cx25821-video4.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH04];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH04]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH04;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO4))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO4)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH04]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO4)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO4);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO4)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO4);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- // check priority
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH04, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH04] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH04] = 0;
- }
- dev->cif_width[SRAM_CH04] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH04);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH04].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 4 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH04);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template4 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
deleted file mode 100644
index 59370337b076..000000000000
--- a/drivers/staging/cx25821/cx25821-video5.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH05];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH05]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH05;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO5))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO5)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH05]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO5)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO5);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO5)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO5);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH05, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH05] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH05] = 0;
- }
- dev->cif_width[SRAM_CH05] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH05);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH05].count;
-
- return ret_val;
-}
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 5 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH05);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template5 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
deleted file mode 100644
index 4db2eb83d35a..000000000000
--- a/drivers/staging/cx25821/cx25821-video6.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH06];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH06]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH06;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO6))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO6)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH06]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO6)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO6);
- }
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO6)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO6);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH06, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH06] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH06] = 0;
- }
- dev->cif_width[SRAM_CH06] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH06);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH06].count;
-
- return ret_val;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 6 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH06);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template6 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
deleted file mode 100644
index 5e4a769badad..000000000000
--- a/drivers/staging/cx25821/cx25821-video7.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH07];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH07]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = SRAM_CH07;
- pix_format =
- (dev->pixel_formats[dev->channel_opened] ==
- PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO7))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO7)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
- if (buf->vb.state == VIDEOBUF_DONE) {
- struct cx25821_dev *dev = fh->dev;
-
- if (dev && dev->use_cif_resolution[SRAM_CH07]) {
- u8 cam_id = *((char *)buf->vb.baddr + 3);
- memcpy((char *)buf->vb.baddr,
- (char *)buf->vb.baddr + (fh->width * 2),
- (fh->width * 2));
- *((char *)buf->vb.baddr + 3) = cam_id;
- }
- }
-
- return POLLIN | POLLRDNORM;
- }
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO7)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO7);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO7)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO7);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
- int pix_format = 0;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
-
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->vidq.field = f->fmt.pix.field;
-
- // check if width and height is valid based on set standard
- if (cx25821_is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
- fh->width = f->fmt.pix.width;
- }
-
- if (cx25821_is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
- fh->height = f->fmt.pix.height;
- }
-
- if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
- pix_format = PIXEL_FRMT_411;
- else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- pix_format = PIXEL_FRMT_422;
- else
- return -EINVAL;
-
- cx25821_set_pixel_format(dev, SRAM_CH07, pix_format);
-
- // check if cif resolution
- if (fh->width == 320 || fh->width == 352) {
- dev->use_cif_resolution[SRAM_CH07] = 1;
- } else {
- dev->use_cif_resolution[SRAM_CH07] = 0;
- }
- dev->cif_width[SRAM_CH07] = fh->width;
- medusa_set_resolution(dev, fh->width, SRAM_CH07);
-
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
-
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- int ret_val = 0;
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
-
- ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-
- p->sequence = dev->vidq[SRAM_CH07].count;
-
- return ret_val;
-}
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
- u32 tmp = 0;
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
-
- tmp = cx_read(sram_ch->dma_ctl);
- printk(KERN_INFO "Video input 7 is %s\n",
- (tmp & 0x11) ? "streaming" : "stopped");
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return cx25821_set_control(dev, ctl, SRAM_CH07);
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template7 = {
- .name = "cx25821-video",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
deleted file mode 100644
index d16807d88be0..000000000000
--- a/drivers/staging/cx25821/cx25821-videoioctl.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[VIDEO_IOCTL_CH];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[VIDEO_IOCTL_CH]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- u32 pix_format;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = VIDEO_IOCTL_CH;
- pix_format = V4L2_PIX_FMT_YUYV;
- fh->fmt = format_by_fourcc(pix_format);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO_IOCTL)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
-
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO_IOCTL)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO_IOCTL);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-}
-
-static long video_ioctl_set(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- struct downstream_user_struct *data_from_user;
- int command;
- int width = 720;
- int selected_channel = 0, pix_format = 0, i = 0;
- int cif_enable = 0, cif_width = 0;
- u32 value = 0;
-
- data_from_user = (struct downstream_user_struct *)arg;
-
- if (!data_from_user) {
- printk("cx25821 in %s(): User data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
- && command != ENABLE_CIF_RESOLUTION && command != REG_READ
- && command != REG_WRITE && command != MEDUSA_READ
- && command != MEDUSA_WRITE) {
- return 0;
- }
-
- switch (command) {
- case SET_VIDEO_STD:
- dev->tvnorm =
- !strcmp(data_from_user->vid_stdname,
- "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
- medusa_set_videostandard(dev);
- break;
-
- case SET_PIXEL_FORMAT:
- selected_channel = data_from_user->decoder_select;
- pix_format = data_from_user->pixel_format;
-
- if (!(selected_channel <= 7 && selected_channel >= 0)) {
- selected_channel -= 4;
- selected_channel = selected_channel % 8;
- }
-
- if (selected_channel >= 0)
- cx25821_set_pixel_format(dev, selected_channel,
- pix_format);
-
- break;
-
- case ENABLE_CIF_RESOLUTION:
- selected_channel = data_from_user->decoder_select;
- cif_enable = data_from_user->cif_resolution_enable;
- cif_width = data_from_user->cif_width;
-
- if (cif_enable) {
- if (dev->tvnorm & V4L2_STD_PAL_BG
- || dev->tvnorm & V4L2_STD_PAL_DK)
- width = 352;
- else
- width = (cif_width == 320
- || cif_width == 352) ? cif_width : 320;
- }
-
- if (!(selected_channel <= 7 && selected_channel >= 0)) {
- selected_channel -= 4;
- selected_channel = selected_channel % 8;
- }
-
- if (selected_channel <= 7 && selected_channel >= 0) {
- dev->use_cif_resolution[selected_channel] = cif_enable;
- dev->cif_width[selected_channel] = width;
- } else {
- for (i = 0; i < VID_CHANNEL_NUM; i++) {
- dev->use_cif_resolution[i] = cif_enable;
- dev->cif_width[i] = width;
- }
- }
-
- medusa_set_resolution(dev, width, selected_channel);
- break;
- case REG_READ:
- data_from_user->reg_data = cx_read(data_from_user->reg_address);
- break;
- case REG_WRITE:
- cx_write(data_from_user->reg_address, data_from_user->reg_data);
- break;
- case MEDUSA_READ:
- value =
- cx25821_i2c_read(&dev->i2c_bus[0],
- (u16) data_from_user->reg_address,
- &data_from_user->reg_data);
- break;
- case MEDUSA_WRITE:
- cx25821_i2c_write(&dev->i2c_bus[0],
- (u16) data_from_user->reg_address,
- data_from_user->reg_data);
- break;
- }
-
- return 0;
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return 0;
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl_set,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_videoioctl_template = {
- .name = "cx25821-videoioctl",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
deleted file mode 100644
index c746a17ccbd2..000000000000
--- a/drivers/staging/cx25821/cx25821-vidups10.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH10];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH10]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = 9;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO10))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO10)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- //cx_write(channel10->dma_ctl, 0);
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO10)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO10);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO10)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO10);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
- return 0;
- }
-
- dev->input_filename_ch2 = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname_ch2 = data_from_user->vid_stdname;
- dev->pixel_format_ch2 = data_from_user->pixel_format;
- dev->channel_select_ch2 = data_from_user->channel_select;
- dev->command_ch2 = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_VIDEO:
- cx25821_start_upstream_video_ch2(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_VIDEO:
- cx25821_stop_upstream_video_ch2(dev);
- break;
- }
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return 0;
-}
-
-//exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl_upstream10,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template10 = {
- .name = "cx25821-upstream10",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
deleted file mode 100644
index 466e0f34ae34..000000000000
--- a/drivers/staging/cx25821/cx25821-vidups9.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Driver for the Conexant CX25821 PCIe bridge
- *
- * Copyright (C) 2009 Conexant Systems Inc.
- * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
- * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include "cx25821-video.h"
-
-static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
-{
- struct cx25821_buffer *buf =
- container_of(vb, struct cx25821_buffer, vb);
- struct cx25821_buffer *prev;
- struct cx25821_fh *fh = vq->priv_data;
- struct cx25821_dev *dev = fh->dev;
- struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH09];
-
- /* add jump to stopper */
- buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
- buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
- buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
-
- dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
-
- if (!list_empty(&q->queued)) {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
- buf->vb.i);
-
- } else if (list_empty(&q->active)) {
- list_add_tail(&buf->vb.queue, &q->active);
- cx25821_start_video_dma(dev, q, buf,
- &dev->sram_channels[SRAM_CH09]);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
- dprintk(2,
- "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
- buf, buf->vb.i, buf->count, q->count);
- } else {
- prev =
- list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
- if (prev->vb.width == buf->vb.width
- && prev->vb.height == buf->vb.height
- && prev->fmt == buf->fmt) {
- list_add_tail(&buf->vb.queue, &q->active);
- buf->vb.state = VIDEOBUF_ACTIVE;
- buf->count = q->count++;
- prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
-
- /* 64 bit bits 63-32 */
- prev->risc.jmp[2] = cpu_to_le32(0);
- dprintk(2,
- "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
- buf, buf->vb.i, buf->count);
-
- } else {
- list_add_tail(&buf->vb.queue, &q->queued);
- buf->vb.state = VIDEOBUF_QUEUED;
- dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
- buf->vb.i);
- }
- }
-
- if (list_empty(&q->active)) {
- dprintk(2, "active queue empty!\n");
- }
-}
-
-static struct videobuf_queue_ops cx25821_video_qops = {
- .buf_setup = cx25821_buffer_setup,
- .buf_prepare = cx25821_buffer_prepare,
- .buf_queue = buffer_queue,
- .buf_release = cx25821_buffer_release,
-};
-
-static int video_open(struct file *file)
-{
- struct video_device *vdev = video_devdata(file);
- struct cx25821_dev *dev = video_drvdata(file);
- struct cx25821_fh *fh;
- enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- printk("open dev=%s type=%s\n", video_device_node_name(vdev),
- v4l2_type_names[type]);
-
- /* allocate + initialize per filehandle data */
- fh = kzalloc(sizeof(*fh), GFP_KERNEL);
- if (NULL == fh)
- return -ENOMEM;
-
- lock_kernel();
-
- file->private_data = fh;
- fh->dev = dev;
- fh->type = type;
- fh->width = 720;
-
- if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
- fh->height = 576;
- else
- fh->height = 480;
-
- dev->channel_opened = 8;
- fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
-
- v4l2_prio_open(&dev->prio, &fh->prio);
-
- videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
- &dev->pci->dev, &dev->slock,
- V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_INTERLACED,
- sizeof(struct cx25821_buffer), fh);
-
- dprintk(1, "post videobuf_queue_init()\n");
- unlock_kernel();
-
- return 0;
-}
-
-static ssize_t video_read(struct file *file, char __user * data, size_t count,
- loff_t * ppos)
-{
- struct cx25821_fh *fh = file->private_data;
-
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if (cx25821_res_locked(fh->dev, RESOURCE_VIDEO9))
- return -EBUSY;
-
- return videobuf_read_one(&fh->vidq, data, count, ppos,
- file->f_flags & O_NONBLOCK);
-
- default:
- BUG();
- return 0;
- }
-}
-
-static unsigned int video_poll(struct file *file,
- struct poll_table_struct *wait)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_buffer *buf;
-
- if (cx25821_res_check(fh, RESOURCE_VIDEO9)) {
- /* streaming capture */
- if (list_empty(&fh->vidq.stream))
- return POLLERR;
- buf = list_entry(fh->vidq.stream.next,
- struct cx25821_buffer, vb.stream);
- } else {
- /* read() capture */
- buf = (struct cx25821_buffer *)fh->vidq.read_buf;
- if (NULL == buf)
- return POLLERR;
- }
-
- poll_wait(file, &buf->vb.done, wait);
- if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
- return POLLIN | POLLRDNORM;
- return 0;
-}
-
-static int video_release(struct file *file)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
-
- //stop the risc engine and fifo
- //cx_write(channel9->dma_ctl, 0);
-
- /* stop video capture */
- if (cx25821_res_check(fh, RESOURCE_VIDEO9)) {
- videobuf_queue_cancel(&fh->vidq);
- cx25821_res_free(dev, fh, RESOURCE_VIDEO9);
- }
-
- if (fh->vidq.read_buf) {
- cx25821_buffer_release(&fh->vidq, fh->vidq.read_buf);
- kfree(fh->vidq.read_buf);
- }
-
- videobuf_mmap_free(&fh->vidq);
-
- v4l2_prio_close(&dev->prio, fh->prio);
-
- file->private_data = NULL;
- kfree(fh);
-
- return 0;
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
-
- if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
- return -EINVAL;
- }
-
- if (unlikely(i != fh->type)) {
- return -EINVAL;
- }
-
- if (unlikely(!cx25821_res_get(dev, fh, cx25821_get_resource(fh, RESOURCE_VIDEO9)))) {
- return -EBUSY;
- }
-
- return videobuf_streamon(get_queue(fh));
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = fh->dev;
- int err, res;
-
- if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- if (i != fh->type)
- return -EINVAL;
-
- res = cx25821_get_resource(fh, RESOURCE_VIDEO9);
- err = videobuf_streamoff(get_queue(fh));
- if (err < 0)
- return err;
- cx25821_res_free(dev, fh, res);
- return 0;
-}
-
-static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct cx25821_fh *fh = file->private_data;
- struct cx25821_dev *dev = fh->dev;
- int command = 0;
- struct upstream_user_struct *data_from_user;
-
- data_from_user = (struct upstream_user_struct *)arg;
-
- if (!data_from_user) {
- printk
- ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
- __func__);
- return 0;
- }
-
- command = data_from_user->command;
-
- if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
- return 0;
- }
-
- dev->input_filename = data_from_user->input_filename;
- dev->input_audiofilename = data_from_user->input_filename;
- dev->vid_stdname = data_from_user->vid_stdname;
- dev->pixel_format = data_from_user->pixel_format;
- dev->channel_select = data_from_user->channel_select;
- dev->command = data_from_user->command;
-
- switch (command) {
- case UPSTREAM_START_VIDEO:
- cx25821_start_upstream_video_ch1(dev, data_from_user);
- break;
-
- case UPSTREAM_STOP_VIDEO:
- cx25821_stop_upstream_video_ch1(dev);
- break;
- }
-
- return 0;
-}
-
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
-{
- struct cx25821_fh *fh = priv;
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- int err;
-
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- dprintk(2, "%s()\n", __func__);
- err = cx25821_vidioc_try_fmt_vid_cap(file, priv, f);
-
- if (0 != err)
- return err;
- fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vidq.field = f->fmt.pix.field;
- dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
- fh->height, fh->vidq.field);
- cx25821_call_all(dev, video, s_fmt, f);
- return 0;
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
- struct cx25821_fh *fh = priv;
- return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
-}
-static int vidioc_log_status(struct file *file, void *priv)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- char name[32 + 2];
-
- snprintf(name, sizeof(name), "%s/2", dev->name);
- printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
- dev->name);
- cx25821_call_all(dev, core, log_status);
- printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
- dev->name);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctl)
-{
- struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
- struct cx25821_fh *fh = priv;
- int err;
- if (fh) {
- err = v4l2_prio_check(&dev->prio, fh->prio);
- if (0 != err)
- return err;
- }
-
- return 0;
-}
-
-// exported stuff
-static const struct v4l2_file_operations video_fops = {
- .owner = THIS_MODULE,
- .open = video_open,
- .release = video_release,
- .read = video_read,
- .poll = video_poll,
- .mmap = cx25821_video_mmap,
- .ioctl = video_ioctl_upstream9,
-};
-
-static const struct v4l2_ioctl_ops video_ioctl_ops = {
- .vidioc_querycap = cx25821_vidioc_querycap,
- .vidioc_enum_fmt_vid_cap = cx25821_vidioc_enum_fmt_vid_cap,
- .vidioc_g_fmt_vid_cap = cx25821_vidioc_g_fmt_vid_cap,
- .vidioc_try_fmt_vid_cap = cx25821_vidioc_try_fmt_vid_cap,
- .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
- .vidioc_reqbufs = cx25821_vidioc_reqbufs,
- .vidioc_querybuf = cx25821_vidioc_querybuf,
- .vidioc_qbuf = cx25821_vidioc_qbuf,
- .vidioc_dqbuf = vidioc_dqbuf,
-#ifdef TUNER_FLAG
- .vidioc_s_std = cx25821_vidioc_s_std,
- .vidioc_querystd = cx25821_vidioc_querystd,
-#endif
- .vidioc_cropcap = cx25821_vidioc_cropcap,
- .vidioc_s_crop = cx25821_vidioc_s_crop,
- .vidioc_g_crop = cx25821_vidioc_g_crop,
- .vidioc_enum_input = cx25821_vidioc_enum_input,
- .vidioc_g_input = cx25821_vidioc_g_input,
- .vidioc_s_input = cx25821_vidioc_s_input,
- .vidioc_g_ctrl = cx25821_vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_queryctrl = cx25821_vidioc_queryctrl,
- .vidioc_streamon = vidioc_streamon,
- .vidioc_streamoff = vidioc_streamoff,
- .vidioc_log_status = vidioc_log_status,
- .vidioc_g_priority = cx25821_vidioc_g_priority,
- .vidioc_s_priority = cx25821_vidioc_s_priority,
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- .vidiocgmbuf = cx25821_vidiocgmbuf,
-#endif
-#ifdef TUNER_FLAG
- .vidioc_g_tuner = cx25821_vidioc_g_tuner,
- .vidioc_s_tuner = cx25821_vidioc_s_tuner,
- .vidioc_g_frequency = cx25821_vidioc_g_frequency,
- .vidioc_s_frequency = cx25821_vidioc_s_frequency,
-#endif
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- .vidioc_g_register = cx25821_vidioc_g_register,
- .vidioc_s_register = cx25821_vidioc_s_register,
-#endif
-};
-
-struct video_device cx25821_video_template9 = {
- .name = "cx25821-upstream9",
- .fops = &video_fops,
- .ioctl_ops = &video_ioctl_ops,
- .tvnorms = CX25821_NORMS,
- .current_norm = V4L2_STD_NTSC_M,
-};
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
index cf2286d83b6a..1b628f61578a 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/staging/cx25821/cx25821.h
@@ -61,7 +61,7 @@
#define FALSE 0
#define LINE_SIZE_D1 1440
-// Number of decoders and encoders
+/* Number of decoders and encoders */
#define MAX_DECODERS 8
#define MAX_ENCODERS 2
#define QUAD_DECODERS 4
@@ -139,6 +139,7 @@ struct cx25821_fh {
/* video capture */
struct cx25821_fmt *fmt;
unsigned int width, height;
+ int channel_id;
/* vbi capture */
struct videobuf_queue vidq;
@@ -236,13 +237,34 @@ struct cx25821_data {
struct sram_channel *channel;
};
+struct cx25821_channel {
+ struct v4l2_prio_state prio;
+
+ int ctl_bright;
+ int ctl_contrast;
+ int ctl_hue;
+ int ctl_saturation;
+
+ struct cx25821_data timeout_data;
+
+ struct video_device *video_dev;
+ struct cx25821_dmaqueue vidq;
+
+ struct sram_channel *sram_channels;
+
+ struct mutex lock;
+ int resources;
+
+ int pixel_formats;
+ int use_cif_resolution;
+ int cif_width;
+};
+
struct cx25821_dev {
struct list_head devlist;
atomic_t refcount;
struct v4l2_device v4l2_dev;
- struct v4l2_prio_state prio;
-
/* pci stuff */
struct pci_dev *pci;
unsigned char pci_rev, pci_lat;
@@ -261,13 +283,12 @@ struct cx25821_dev {
int nr;
struct mutex lock;
+ struct cx25821_channel channels[MAX_VID_CHANNEL_NUM];
+
/* board details */
unsigned int board;
char name[32];
- /* sram configuration */
- struct sram_channel *sram_channels;
-
/* Analog video */
u32 resources;
unsigned int input;
@@ -282,13 +303,6 @@ struct cx25821_dev {
unsigned char videc_addr;
unsigned short _max_num_decoders;
- int ctl_bright;
- int ctl_contrast;
- int ctl_hue;
- int ctl_saturation;
-
- struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
-
/* Analog Audio Upstream */
int _audio_is_running;
int _audiopixel_format;
@@ -297,7 +311,7 @@ struct cx25821_dev {
int _audio_lines_count;
int _audioframe_count;
int _audio_upstream_channel_select;
- int _last_index_irq; //The last interrupt index processed.
+ int _last_index_irq; /* The last interrupt index processed. */
__le32 *_risc_audio_jmp_addr;
__le32 *_risc_virt_start_addr;
@@ -313,12 +327,10 @@ struct cx25821_dev {
/* V4l */
u32 freq;
- struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
struct video_device *vbi_dev;
struct video_device *radio_dev;
struct video_device *ioctl_dev;
- struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
spinlock_t slock;
/* Video Upstream */
@@ -401,9 +413,6 @@ struct cx25821_dev {
int pixel_format;
int channel_select;
int command;
- int pixel_formats[VID_CHANNEL_NUM];
- int use_cif_resolution[VID_CHANNEL_NUM];
- int cif_width[VID_CHANNEL_NUM];
int channel_opened;
};
@@ -482,7 +491,7 @@ struct sram_channel {
u32 fld_aud_fifo_en;
u32 fld_aud_risc_en;
- //For Upstream Video
+ /* For Upstream Video */
u32 vid_fmt_ctl;
u32 vid_active_ctl1;
u32 vid_active_ctl2;
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
index 643b413d9f0f..e818f53ccfd7 100644
--- a/drivers/staging/pohmelfs/inode.c
+++ b/drivers/staging/pohmelfs/inode.c
@@ -968,12 +968,18 @@ int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
goto err_out_exit;
}
- err = inode_setattr(inode, attr);
- if (err) {
- dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
- goto err_out_exit;
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ err = vmtruncate(inode, attr->ia_size);
+ if (err) {
+ dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
+ goto err_out_exit;
+ }
}
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
__func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index 3657e33e8817..c725356cc346 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -26,8 +26,8 @@ config VIDEO_TM6000_ALSA
module will be called tm6000-alsa.
config VIDEO_TM6000_DVB
- bool "DVB Support for tm6000 based TV cards"
- depends on VIDEO_TM6000 && DVB_CORE && EXPERIMENTAL
+ tristate "DVB Support for tm6000 based TV cards"
+ depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL
select DVB_ZL10353
---help---
This adds support for DVB cards based on the tm5600/tm6000 chip.
diff --git a/drivers/staging/tm6000/Makefile b/drivers/staging/tm6000/Makefile
index 93370fccc073..77e06bfd2c46 100644
--- a/drivers/staging/tm6000/Makefile
+++ b/drivers/staging/tm6000/Makefile
@@ -2,14 +2,12 @@ tm6000-objs := tm6000-cards.o \
tm6000-core.o \
tm6000-i2c.o \
tm6000-video.o \
- tm6000-stds.o
-
-ifeq ($(CONFIG_VIDEO_TM6000_DVB),y)
-tm6000-objs += tm6000-dvb.o
-endif
+ tm6000-stds.o \
+ tm6000-input.o
obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
+obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
EXTRA_CFLAGS = -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 273e26ede650..3202309c1b0b 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
+#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/delay.h>
@@ -36,34 +37,11 @@
} while (0)
/****************************************************************************
- Data type declarations - Can be moded to a header file later
- ****************************************************************************/
-
-struct snd_tm6000_card {
- struct snd_card *card;
-
- spinlock_t reg_lock;
-
- atomic_t count;
-
- unsigned int period_size;
- unsigned int num_periods;
-
- struct tm6000_core *core;
- struct tm6000_buffer *buf;
-
- int bufsize;
-
- struct snd_pcm_substream *substream;
-};
-
-
-/****************************************************************************
Module global static vars
****************************************************************************/
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};
module_param_array(enable, bool, NULL, 0444);
@@ -100,11 +78,15 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
struct tm6000_core *core = chip->core;
int val;
+ dprintk(1, "Starting audio DMA\n");
+
/* Enables audio */
val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0);
val |= 0x20;
tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
+ tm6000_set_audio_bitrate(core, 48000);
+
tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0x80);
return 0;
@@ -129,19 +111,39 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
return 0;
}
-static int dsp_buffer_free(struct snd_tm6000_card *chip)
+static void dsp_buffer_free(struct snd_pcm_substream *substream)
{
- BUG_ON(!chip->bufsize);
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
dprintk(2, "Freeing buffer\n");
- /* FIXME: Frees buffer */
+ vfree(substream->runtime->dma_area);
+ substream->runtime->dma_area = NULL;
+ substream->runtime->dma_bytes = 0;
+}
- chip->bufsize = 0;
+static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size)
+{
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+
+ dprintk(2, "Allocating buffer\n");
+
+ if (substream->runtime->dma_area) {
+ if (substream->runtime->dma_bytes > size)
+ return 0;
+ dsp_buffer_free(substream);
+ }
- return 0;
+ substream->runtime->dma_area = vmalloc(size);
+ if (!substream->runtime->dma_area)
+ return -ENOMEM;
+
+ substream->runtime->dma_bytes = size;
+
+ return 0;
}
+
/****************************************************************************
ALSA PCM Interface
****************************************************************************/
@@ -158,16 +160,16 @@ static struct snd_pcm_hardware snd_tm6000_digital_hw = {
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
- .period_bytes_min = DEFAULT_FIFO_SIZE/4,
- .period_bytes_max = DEFAULT_FIFO_SIZE/4,
+ .period_bytes_min = 62720,
+ .period_bytes_max = 62720,
.periods_min = 1,
.periods_max = 1024,
- .buffer_bytes_max = (1024*1024),
+ .buffer_bytes_max = 62720 * 8,
};
/*
@@ -202,29 +204,64 @@ static int snd_tm6000_close(struct snd_pcm_substream *substream)
return 0;
}
+static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size)
+{
+ struct snd_tm6000_card *chip = core->adev;
+ struct snd_pcm_substream *substream = chip->substream;
+ struct snd_pcm_runtime *runtime;
+ int period_elapsed = 0;
+ unsigned int stride, buf_pos;
+
+ if (!size || !substream)
+ return -EINVAL;
+
+ runtime = substream->runtime;
+ if (!runtime || !runtime->dma_area)
+ return -EINVAL;
+
+ buf_pos = chip->buf_pos;
+ stride = runtime->frame_bits >> 3;
+
+ dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size,
+ runtime->dma_area, buf_pos,
+ (unsigned int)runtime->buffer_size, stride);
+
+ if (buf_pos + size >= runtime->buffer_size * stride) {
+ unsigned int cnt = runtime->buffer_size * stride - buf_pos;
+ memcpy(runtime->dma_area + buf_pos, buf, cnt);
+ memcpy(runtime->dma_area, buf + cnt, size - cnt);
+ } else
+ memcpy(runtime->dma_area + buf_pos, buf, size);
+
+ chip->buf_pos += size;
+ if (chip->buf_pos >= runtime->buffer_size * stride)
+ chip->buf_pos -= runtime->buffer_size * stride;
+
+ chip->period_pos += size;
+ if (chip->period_pos >= runtime->period_size) {
+ chip->period_pos -= runtime->period_size;
+ period_elapsed = 1;
+ }
+
+ if (period_elapsed)
+ snd_pcm_period_elapsed(substream);
+
+ return 0;
+}
+
/*
* hw_params callback
*/
static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- chip->period_size = params_period_bytes(hw_params);
- chip->num_periods = params_periods(hw_params);
- chip->bufsize = chip->period_size * params_periods(hw_params);
-
- BUG_ON(!chip->bufsize);
+ int size, rc;
- dprintk(1, "Setting buffer\n");
-
- /* FIXME: Allocate buffer for audio */
+ size = params_period_bytes(hw_params) * params_periods(hw_params);
+ rc = dsp_buffer_alloc(substream, size);
+ if (rc < 0)
+ return rc;
return 0;
}
@@ -234,13 +271,9 @@ static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
*/
static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
{
-
struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
+ _tm6000_stop_audio_dma(chip);
return 0;
}
@@ -250,6 +283,11 @@ static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
*/
static int snd_tm6000_prepare(struct snd_pcm_substream *substream)
{
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+
+ chip->buf_pos = 0;
+ chip->period_pos = 0;
+
return 0;
}
@@ -287,12 +325,8 @@ static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream)
{
struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 count;
-
- count = atomic_read(&chip->count);
- return runtime->period_size * (count & (runtime->periods-1));
+ return chip->buf_pos;
}
/*
@@ -312,21 +346,6 @@ static struct snd_pcm_ops snd_tm6000_pcm_ops = {
/*
* create a PCM device
*/
-static int __devinit snd_tm6000_pcm(struct snd_tm6000_card *chip,
- int device, char *name)
-{
- int err;
- struct snd_pcm *pcm;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
-
- return 0;
-}
/* FIXME: Control interface - How to control volume/mute? */
@@ -337,27 +356,41 @@ static int __devinit snd_tm6000_pcm(struct snd_tm6000_card *chip,
/*
* Alsa Constructor - Component probe
*/
-
-int tm6000_audio_init(struct tm6000_core *dev, int idx)
+int tm6000_audio_init(struct tm6000_core *dev)
{
- struct snd_card *card;
- struct snd_tm6000_card *chip;
- int rc, len;
- char component[14];
+ struct snd_card *card;
+ struct snd_tm6000_card *chip;
+ int rc;
+ static int devnr;
+ char component[14];
+ struct snd_pcm *pcm;
+
+ if (!dev)
+ return 0;
- if (idx >= SNDRV_CARDS)
+ if (devnr >= SNDRV_CARDS)
return -ENODEV;
- if (!enable[idx])
+ if (!enable[devnr])
return -ENOENT;
- rc = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
+ rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card);
if (rc < 0) {
- snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
+ snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
return rc;
}
+ strcpy(card->driver, "tm6000-alsa");
+ strcpy(card->shortname, "TM5600/60x0");
+ sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d",
+ dev->udev->bus->busnum, dev->udev->devnum);
+
+ sprintf(component, "USB%04x:%04x",
+ le16_to_cpu(dev->udev->descriptor.idVendor),
+ le16_to_cpu(dev->udev->descriptor.idProduct));
+ snd_component_add(card, component);
+ snd_card_set_dev(card, &dev->udev->dev);
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(struct snd_tm6000_card), GFP_KERNEL);
if (!chip) {
rc = -ENOMEM;
goto error;
@@ -365,45 +398,24 @@ int tm6000_audio_init(struct tm6000_core *dev, int idx)
chip->core = dev;
chip->card = card;
+ dev->adev = chip;
+ spin_lock_init(&chip->reg_lock);
- strcpy(card->driver, "tm6000-alsa");
- sprintf(component, "USB%04x:%04x",
- le16_to_cpu(dev->udev->descriptor.idVendor),
- le16_to_cpu(dev->udev->descriptor.idProduct));
- snd_component_add(card, component);
-
- if (dev->udev->descriptor.iManufacturer)
- len = usb_string(dev->udev,
- dev->udev->descriptor.iManufacturer,
- card->longname, sizeof(card->longname));
- else
- len = 0;
-
- if (len > 0)
- strlcat(card->longname, " ", sizeof(card->longname));
-
- strlcat(card->longname, card->shortname, sizeof(card->longname));
-
- len = strlcat(card->longname, " at ", sizeof(card->longname));
-
- if (len < sizeof(card->longname))
- usb_make_path(dev->udev, card->longname + len,
- sizeof(card->longname) - len);
-
- strlcat(card->longname,
- dev->udev->speed == USB_SPEED_LOW ? ", low speed" :
- dev->udev->speed == USB_SPEED_FULL ? ", full speed" :
- ", high speed",
- sizeof(card->longname));
-
- rc = snd_tm6000_pcm(chip, 0, "tm6000 Digital");
+ rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm);
if (rc < 0)
goto error;
+ pcm->info_flags = 0;
+ pcm->private_data = chip;
+ strcpy(pcm->name, "Trident TM5600/60x0");
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
+
rc = snd_card_register(card);
if (rc < 0)
goto error;
+ dprintk(1,"Registered audio driver for %s\n", card->longname);
return 0;
@@ -414,14 +426,31 @@ error:
static int tm6000_audio_fini(struct tm6000_core *dev)
{
+ struct snd_tm6000_card *chip = dev->adev;
+
+ if (!dev)
+ return 0;
+
+ if (!chip)
+ return 0;
+
+ if (!chip->card)
+ return 0;
+
+ snd_card_free(chip->card);
+ chip->card = NULL;
+ kfree(chip);
+ dev->adev = NULL;
+
return 0;
}
struct tm6000_ops audio_ops = {
- .id = TM6000_AUDIO,
+ .type = TM6000_AUDIO,
.name = "TM6000 Audio Extension",
.init = tm6000_audio_init,
.fini = tm6000_audio_fini,
+ .fillbuf = tm6000_fillbuf,
};
static int __init tm6000_alsa_register(void)
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 6a9ae40c7c6d..9d091c34991b 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -29,6 +29,7 @@
#include <media/tuner.h>
#include <media/tvaudio.h>
#include <media/i2c-addr.h>
+#include <media/rc-map.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -69,6 +70,8 @@ struct tm6000_board {
int demod_addr; /* demodulator address */
struct tm6000_gpio gpio;
+
+ char *ir_codes;
};
struct tm6000_board tm6000_boards[] = {
@@ -276,6 +279,7 @@ struct tm6000_board tm6000_boards[] = {
.dvb_led = TM6010_GPIO_5,
.ir = TM6010_GPIO_0,
},
+ .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
},
[TM6010_BOARD_TWINHAN_TU501] = {
.name = "Twinhan TU501(704D1)",
@@ -347,7 +351,7 @@ int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
}
return (rc);
}
-
+EXPORT_SYMBOL_GPL(tm6000_xc5000_callback);
/* Tuner callback to provide the proper gpio changes needed for xc2028 */
@@ -361,6 +365,8 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
switch (command) {
case XC2028_RESET_CLK:
+ tm6000_ir_wait(dev, 0);
+
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
0x02, arg);
msleep(10);
@@ -410,13 +416,14 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
msleep(130);
break;
}
+
+ tm6000_ir_wait(dev, 1);
break;
case 1:
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
0x02, 0x01);
msleep(10);
break;
-
case 2:
rc = tm6000_i2c_reset(dev, 100);
break;
@@ -424,6 +431,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
}
return rc;
}
+EXPORT_SYMBOL_GPL(tm6000_tuner_callback);
int tm6000_cards_setup(struct tm6000_core *dev)
{
@@ -635,6 +643,8 @@ static int tm6000_init_dev(struct tm6000_core *dev)
dev->gpio = tm6000_boards[dev->model].gpio;
+ dev->ir_codes = tm6000_boards[dev->model].ir_codes;
+
dev->demod_addr = tm6000_boards[dev->model].demod_addr;
dev->caps = tm6000_boards[dev->model].caps;
@@ -681,31 +691,13 @@ static int tm6000_init_dev(struct tm6000_core *dev)
goto err;
tm6000_add_into_devlist(dev);
-
tm6000_init_extension(dev);
- if (dev->caps.has_dvb) {
- dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
- if (!dev->dvb) {
- rc = -ENOMEM;
- goto err2;
- }
+ tm6000_ir_init(dev);
-#ifdef CONFIG_VIDEO_TM6000_DVB
- rc = tm6000_dvb_register(dev);
- if (rc < 0) {
- kfree(dev->dvb);
- dev->dvb = NULL;
- goto err2;
- }
-#endif
- }
mutex_unlock(&dev->lock);
return 0;
-err2:
- v4l2_device_unregister(&dev->v4l2_dev);
-
err:
mutex_unlock(&dev->lock);
return rc;
@@ -724,7 +716,7 @@ static void get_max_endpoint(struct usb_device *udev,
unsigned int size = tmp & 0x7ff;
if (udev->speed == USB_SPEED_HIGH)
- size = size * hb_mult (tmp);
+ size = size * hb_mult(tmp);
if (size > tm_ep->maxsize) {
tm_ep->endp = curr_e;
@@ -848,6 +840,19 @@ static int tm6000_usb_probe(struct usb_interface *interface,
&dev->isoc_out);
}
break;
+ case USB_ENDPOINT_XFER_INT:
+ if (!dir_out) {
+ get_max_endpoint(usbdev,
+ &interface->altsetting[i],
+ "INT IN", e,
+ &dev->int_in);
+ } else {
+ get_max_endpoint(usbdev,
+ &interface->altsetting[i],
+ "INT OUT", e,
+ &dev->int_out);
+ }
+ break;
}
}
}
@@ -906,12 +911,7 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
mutex_lock(&dev->lock);
-#ifdef CONFIG_VIDEO_TM6000_DVB
- if (dev->dvb) {
- tm6000_dvb_unregister(dev);
- kfree(dev->dvb);
- }
-#endif
+ tm6000_ir_fini(dev);
if (dev->gpio.power_led) {
switch (dev->model) {
@@ -942,8 +942,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
usb_put_dev(dev->udev);
- tm6000_remove_from_devlist(dev);
tm6000_close_extension(dev);
+ tm6000_remove_from_devlist(dev);
mutex_unlock(&dev->lock);
kfree(dev);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index c3690e3580da..2c38199c0539 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -32,66 +32,64 @@
#define USB_TIMEOUT 5*HZ /* ms */
-int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
- u16 value, u16 index, u8 *buf, u16 len)
+int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
+ u16 value, u16 index, u8 *buf, u16 len)
{
int ret, i;
unsigned int pipe;
- static int ini=0, last=0, n=0;
- u8 *data=NULL;
+ static int ini = 0, last = 0, n = 0;
+ u8 *data = NULL;
if (len)
data = kzalloc(len, GFP_KERNEL);
if (req_type & USB_DIR_IN)
- pipe=usb_rcvctrlpipe(dev->udev, 0);
+ pipe = usb_rcvctrlpipe(dev->udev, 0);
else {
- pipe=usb_sndctrlpipe(dev->udev, 0);
+ pipe = usb_sndctrlpipe(dev->udev, 0);
memcpy(data, buf, len);
}
if (tm6000_debug & V4L2_DEBUG_I2C) {
if (!ini)
- last=ini=jiffies;
+ last = ini = jiffies;
printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe);
- printk( "%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
- (req_type & USB_DIR_IN)?" IN":"OUT",
+ printk("%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
+ (req_type & USB_DIR_IN) ? " IN" : "OUT",
jiffies_to_msecs(jiffies-last),
jiffies_to_msecs(jiffies-ini),
- req_type, req,value&0xff,value>>8, index&0xff, index>>8,
- len&0xff, len>>8);
- last=jiffies;
+ req_type, req, value&0xff, value>>8, index&0xff,
+ index>>8, len&0xff, len>>8);
+ last = jiffies;
n++;
- if ( !(req_type & USB_DIR_IN) ) {
+ if (!(req_type & USB_DIR_IN)) {
printk(">>> ");
- for (i=0;i<len;i++) {
- printk(" %02x",buf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(" %02x", buf[i]);
printk("\n");
}
}
- ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, data,
- len, USB_TIMEOUT);
+ ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index,
+ data, len, USB_TIMEOUT);
if (req_type & USB_DIR_IN)
memcpy(buf, data, len);
if (tm6000_debug & V4L2_DEBUG_I2C) {
- if (ret<0) {
+ if (ret < 0) {
if (req_type & USB_DIR_IN)
- printk("<<< (len=%d)\n",len);
+ printk("<<< (len=%d)\n", len);
printk("%s: Error #%d\n", __FUNCTION__, ret);
} else if (req_type & USB_DIR_IN) {
printk("<<< ");
- for (i=0;i<len;i++) {
- printk(" %02x",buf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(" %02x", buf[i]);
printk("\n");
}
}
@@ -103,52 +101,52 @@ int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
return ret;
}
-int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
return
- tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
- req, value, index, NULL, 0);
+ tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
+ req, value, index, NULL, 0);
}
EXPORT_SYMBOL_GPL(tm6000_set_reg);
-int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[1];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 1);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 1);
- if (rc<0)
+ if (rc < 0)
return rc;
return *buf;
}
EXPORT_SYMBOL_GPL(tm6000_get_reg);
-int tm6000_get_reg16 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[2];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 2);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 2);
- if (rc<0)
+ if (rc < 0)
return rc;
return buf[1]|buf[0]<<8;
}
-int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[4];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 4);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 4);
- if (rc<0)
+ if (rc < 0)
return rc;
return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
@@ -188,7 +186,7 @@ void tm6000_set_fourcc_format(struct tm6000_core *dev)
}
}
-int tm6000_init_analog_mode (struct tm6000_core *dev)
+int tm6000_init_analog_mode(struct tm6000_core *dev)
{
if (dev->dev_type == TM6010) {
int val;
@@ -294,12 +292,10 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
/* Enables soft reset */
tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
- if (dev->scaler) {
+ if (dev->scaler)
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
- } else {
- /* Enable Hfilter and disable TS Drop err */
+ else /* Enable Hfilter and disable TS Drop err */
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
- }
tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23);
@@ -332,13 +328,19 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
/*FIXME: Hack!!! */
struct v4l2_frequency f;
mutex_lock(&dev->lock);
- f.frequency=dev->freq;
+ f.frequency = dev->freq;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
mutex_unlock(&dev->lock);
msleep(100);
- tm6000_set_standard (dev, &dev->norm);
- tm6000_set_audio_bitrate (dev,48000);
+ tm6000_set_standard(dev, &dev->norm);
+ tm6000_set_audio_bitrate(dev, 48000);
+
+ /* switch dvb led off */
+ if (dev->gpio.dvb_led) {
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.dvb_led, 0x01);
+ }
/* switch dvb led off */
if (dev->gpio.dvb_led) {
@@ -349,7 +351,7 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
return 0;
}
-int tm6000_init_digital_mode (struct tm6000_core *dev)
+int tm6000_init_digital_mode(struct tm6000_core *dev)
{
if (dev->dev_type == TM6010) {
int val;
@@ -366,10 +368,8 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
- tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
- printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
-
-
+ tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+ printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]);
} else {
tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
@@ -377,7 +377,7 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x08);
tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
@@ -388,14 +388,14 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
msleep(100);
}
@@ -407,6 +407,7 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
return 0;
}
+EXPORT_SYMBOL(tm6000_init_digital_mode);
struct reg_init {
u8 req;
@@ -566,9 +567,9 @@ struct reg_init tm6010_init_tab[] = {
{ TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff },
};
-int tm6000_init (struct tm6000_core *dev)
+int tm6000_init(struct tm6000_core *dev)
{
- int board, rc=0, i, size;
+ int board, rc = 0, i, size;
struct reg_init *tab;
if (dev->dev_type == TM6010) {
@@ -580,12 +581,12 @@ int tm6000_init (struct tm6000_core *dev)
}
/* Load board's initialization table */
- for (i=0; i< size; i++) {
- rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
- if (rc<0) {
- printk (KERN_ERR "Error %i while setting req %d, "
- "reg %d to value %d\n", rc,
- tab[i].req,tab[i].reg, tab[i].val);
+ for (i = 0; i < size; i++) {
+ rc = tm6000_set_reg(dev, tab[i].req, tab[i].reg, tab[i].val);
+ if (rc < 0) {
+ printk(KERN_ERR "Error %i while setting req %d, "
+ "reg %d to value %d\n", rc,
+ tab[i].req, tab[i].reg, tab[i].val);
return rc;
}
}
@@ -593,12 +594,11 @@ int tm6000_init (struct tm6000_core *dev)
msleep(5); /* Just to be conservative */
/* Check board version - maybe 10Moons specific */
- board=tm6000_get_reg32 (dev, REQ_40_GET_VERSION, 0, 0);
- if (board >=0) {
- printk (KERN_INFO "Board version = 0x%08x\n",board);
- } else {
- printk (KERN_ERR "Error %i while retrieving board version\n",board);
- }
+ board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
+ if (board >= 0)
+ printk(KERN_INFO "Board version = 0x%08x\n", board);
+ else
+ printk(KERN_ERR "Error %i while retrieving board version\n", board);
rc = tm6000_cards_setup(dev);
@@ -609,23 +609,32 @@ int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
{
int val;
- val=tm6000_get_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
-printk("Original value=%d\n",val);
- if (val<0)
+ if (dev->dev_type == TM6010) {
+ val = tm6000_get_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0);
+ if (val < 0)
+ return val;
+ val = (val & 0xf0) | 0x1; /* 48 kHz, not muted */
+ val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, val);
+ if (val < 0)
+ return val;
+ }
+
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
+ if (val < 0)
return val;
val &= 0x0f; /* Preserve the audio input control bits */
switch (bitrate) {
case 44100:
- val|=0xd0;
- dev->audio_bitrate=bitrate;
+ val |= 0xd0;
+ dev->audio_bitrate = bitrate;
break;
case 48000:
- val|=0x60;
- dev->audio_bitrate=bitrate;
+ val |= 0x60;
+ dev->audio_bitrate = bitrate;
break;
}
- val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);
+ val = tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, val);
return val;
}
@@ -659,6 +668,23 @@ void tm6000_add_into_devlist(struct tm6000_core *dev)
static LIST_HEAD(tm6000_extension_devlist);
static DEFINE_MUTEX(tm6000_extension_devlist_lock);
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+ char *buf, int size)
+{
+ struct tm6000_ops *ops = NULL;
+
+ /* FIXME: tm6000_extension_devlist_lock should be a spinlock */
+
+ if (!list_empty(&tm6000_extension_devlist)) {
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+ if (ops->fillbuf && ops->type == type)
+ ops->fillbuf(dev, buf, size);
+ }
+ }
+
+ return 0;
+}
+
int tm6000_register_extension(struct tm6000_ops *ops)
{
struct tm6000_core *dev = NULL;
@@ -667,10 +693,10 @@ int tm6000_register_extension(struct tm6000_ops *ops)
mutex_lock(&tm6000_extension_devlist_lock);
list_add_tail(&ops->next, &tm6000_extension_devlist);
list_for_each_entry(dev, &tm6000_devlist, devlist) {
- if (dev)
- ops->init(dev);
+ ops->init(dev);
+ printk(KERN_INFO "%s: Initialized (%s) extension\n",
+ dev->name, ops->name);
}
- printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
mutex_unlock(&tm6000_extension_devlist_lock);
mutex_unlock(&tm6000_devlist_mutex);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index 86c1c8b5f25a..f501edccf9c4 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -31,12 +31,25 @@
#include "tuner-xc2028.h"
#include "xc5000.h"
-static void inline print_err_status (struct tm6000_core *dev,
- int packet, int status)
+MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
+
+MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
+ "{{Trident, tm6000},"
+ "{{Trident, tm6010}");
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug message");
+
+static inline void print_err_status(struct tm6000_core *dev,
+ int packet, int status)
{
char *errmsg = "Unknown";
- switch(status) {
+ switch (status) {
case -ENOENT:
errmsg = "unlinked synchronuously";
break;
@@ -62,7 +75,7 @@ static void inline print_err_status (struct tm6000_core *dev,
errmsg = "Device does not respond";
break;
}
- if (packet<0) {
+ if (packet < 0) {
dprintk(dev, 1, "URB status %d [%s].\n",
status, errmsg);
} else {
@@ -74,19 +87,17 @@ static void inline print_err_status (struct tm6000_core *dev,
static void tm6000_urb_received(struct urb *urb)
{
int ret;
- struct tm6000_core* dev = urb->context;
+ struct tm6000_core *dev = urb->context;
- if(urb->status != 0) {
- print_err_status (dev,0,urb->status);
- }
- else if(urb->actual_length>0){
+ if (urb->status != 0)
+ print_err_status(dev, 0, urb->status);
+ else if (urb->actual_length > 0)
dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
- }
- if(dev->dvb->streams > 0) {
+ if (dev->dvb->streams > 0) {
ret = usb_submit_urb(urb, GFP_ATOMIC);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
@@ -100,7 +111,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start stream request %s\n", __FUNCTION__);
if (dev->mode != TM6000_MODE_DIGITAL) {
tm6000_init_digital_mode(dev);
@@ -108,7 +119,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
}
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if(dvb->bulk_urb == NULL) {
+ if (dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
@@ -120,7 +131,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
size = size * 15; /* 512 x 8 or 12 or 15 */
dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if(dvb->bulk_urb->transfer_buffer == NULL) {
+ if (dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
@@ -132,20 +143,20 @@ int tm6000_start_stream(struct tm6000_core *dev)
tm6000_urb_received, dev);
ret = usb_clear_halt(dev->udev, pipe);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",ret,__FUNCTION__);
+ if (ret < 0) {
+ printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
+ ret, __FUNCTION__);
return ret;
- }
- else {
+ } else
printk(KERN_ERR "tm6000: pipe resetted\n");
- }
/* mutex_lock(&tm6000_driver.open_close_mutex); */
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
if (ret) {
- printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
+ printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
+ ret);
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
@@ -159,10 +170,10 @@ void tm6000_stop_stream(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb) {
- printk (KERN_INFO "urb killing\n");
+ if (dvb->bulk_urb) {
+ printk(KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
- printk (KERN_INFO "urb buffer free\n");
+ printk(KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -174,35 +185,34 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- if(dvb->streams == 0) {
+ if (dvb->streams == 0) {
dvb->streams = 1;
/* mutex_init(&tm6000_dev->streming_mutex); */
tm6000_start_stream(dev);
- }
- else {
+ } else
++(dvb->streams);
- }
mutex_unlock(&dvb->mutex);
return 0;
}
-int tm6000_stop_feed(struct dvb_demux_feed *feed) {
+int tm6000_stop_feed(struct dvb_demux_feed *feed)
+{
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got stop feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- printk (KERN_INFO "stream %#x\n", dvb->streams);
+ printk(KERN_INFO "stream %#x\n", dvb->streams);
--(dvb->streams);
- if(dvb->streams == 0) {
- printk (KERN_INFO "stop stream\n");
+ if (dvb->streams == 0) {
+ printk(KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
/* mutex_destroy(&tm6000_dev->streaming_mutex); */
}
@@ -216,9 +226,9 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dev->caps.has_zl10353) {
- struct zl10353_config config =
- {.demod_address = dev->demod_addr,
+ if (dev->caps.has_zl10353) {
+ struct zl10353_config config = {
+ .demod_address = dev->demod_addr,
.no_tuner = 1,
.parallel_ts = 1,
.if2 = 45700,
@@ -227,8 +237,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
dvb->frontend = dvb_attach(zl10353_attach, &config,
&dev->i2c_adap);
- }
- else {
+ } else {
printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
return -1;
}
@@ -238,7 +247,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-int tm6000_dvb_register(struct tm6000_core *dev)
+int register_dvb(struct tm6000_core *dev)
{
int ret = -1;
struct tm6000_dvb *dvb = dev->dvb;
@@ -249,13 +258,13 @@ int tm6000_dvb_register(struct tm6000_core *dev)
/* attach the frontend */
ret = tm6000_dvb_attach_frontend(dev);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
goto err;
}
ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
- THIS_MODULE, &dev->udev->dev, adapter_nr);
+ THIS_MODULE, &dev->udev->dev, adapter_nr);
dvb->adapter.priv = dev;
if (dvb->frontend) {
@@ -308,9 +317,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
break;
}
}
- } else {
+ } else
printk(KERN_ERR "tm6000: no frontend found\n");
- }
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
@@ -321,7 +329,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
ret = dvb_dmx_init(&dvb->demux);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
goto frontend_err;
}
@@ -331,7 +339,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->dmxdev.capabilities = 0;
ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
goto dvb_dmx_err;
}
@@ -341,7 +349,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb_dmx_err:
dvb_dmx_release(&dvb->demux);
frontend_err:
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -351,11 +359,11 @@ err:
return ret;
}
-void tm6000_dvb_unregister(struct tm6000_core *dev)
+void unregister_dvb(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb != NULL) {
+ if (dvb->bulk_urb != NULL) {
struct urb *bulk_urb = dvb->bulk_urb;
kfree(bulk_urb->transfer_buffer);
@@ -365,7 +373,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
}
/* mutex_lock(&tm6000_driver.open_close_mutex); */
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -375,5 +383,70 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
+}
+static int dvb_init(struct tm6000_core *dev)
+{
+ struct tm6000_dvb *dvb;
+ int rc;
+
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
+ if (!dvb) {
+ printk(KERN_INFO "Cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ dev->dvb = dvb;
+
+ rc = register_dvb(dev);
+ if (rc < 0) {
+ kfree(dvb);
+ dev->dvb = NULL;
+ return 0;
+ }
+
+ return 0;
+}
+
+static int dvb_fini(struct tm6000_core *dev)
+{
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ if (dev->dvb) {
+ unregister_dvb(dev);
+ kfree(dev->dvb);
+ dev->dvb = NULL;
+ }
+
+ return 0;
}
+
+static struct tm6000_ops dvb_ops = {
+ .type = TM6000_DVB,
+ .name = "TM6000 dvb Extension",
+ .init = dvb_init,
+ .fini = dvb_fini,
+};
+
+static int __init tm6000_dvb_register(void)
+{
+ return tm6000_register_extension(&dvb_ops);
+}
+
+static void __exit tm6000_dvb_unregister(void)
+{
+ tm6000_unregister_extension(&dvb_ops);
+}
+
+module_init(tm6000_dvb_register);
+module_exit(tm6000_dvb_unregister);
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 94ff489a1bbb..79bc67f0311f 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -40,7 +40,7 @@ static unsigned int i2c_debug = 0;
module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-#define i2c_dprintk(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
+#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \
printk(KERN_DEBUG "%s at %s: " fmt, \
dev->name, __FUNCTION__ , ##args); } while (0)
@@ -171,7 +171,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
return 0;
for (i = 0; i < num; i++) {
addr = (msgs[i].addr << 1) & 0xff;
- i2c_dprintk(2,"%s %s addr=0x%x len=%d:",
+ i2c_dprintk(2, "%s %s addr=0x%x len=%d:",
(msgs[i].flags & I2C_M_RD) ? "read" : "write",
i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
if (msgs[i].flags & I2C_M_RD) {
@@ -235,7 +235,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
return num;
err:
- i2c_dprintk(2," ERROR: %i\n", rc);
+ i2c_dprintk(2, " ERROR: %i\n", rc);
return rc;
}
@@ -266,11 +266,10 @@ static int tm6000_i2c_eeprom(struct tm6000_core *dev,
if (0 == (i % 16))
printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
printk(" %02x", eedata[i]);
- if ((eedata[i] >= ' ') && (eedata[i] <= 'z')) {
+ if ((eedata[i] >= ' ') && (eedata[i] <= 'z'))
bytes[i%16] = eedata[i];
- } else {
- bytes[i%16]='.';
- }
+ else
+ bytes[i%16] = '.';
i++;
@@ -305,15 +304,15 @@ static u32 functionality(struct i2c_adapter *adap)
}
#define mass_write(addr, reg, data...) \
- { const static u8 _val[] = data; \
- rc=tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR, \
- REQ_16_SET_GET_I2C_WR1_RDN,(reg<<8)+addr, 0x00, (u8 *) _val, \
+ { static const u8 _val[] = data; \
+ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, \
+ REQ_16_SET_GET_I2C_WR1_RDN, (reg<<8)+addr, 0x00, (u8 *) _val, \
ARRAY_SIZE(_val)); \
- if (rc<0) { \
- printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc); \
+ if (rc < 0) { \
+ printk(KERN_ERR "Error on line %d: %d\n", __LINE__, rc); \
return rc; \
} \
- msleep (10); \
+ msleep(10); \
}
static struct i2c_algorithm tm6000_algo = {
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
new file mode 100644
index 000000000000..32f7a0af6938
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -0,0 +1,364 @@
+/*
+ tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+
+ Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation version 2
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include <media/ir-core.h>
+#include <media/ir-common.h>
+
+#include "tm6000.h"
+#include "tm6000-regs.h"
+
+static unsigned int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debug message [IR]");
+
+static unsigned int enable_ir = 1;
+module_param(enable_ir, int, 0644);
+MODULE_PARM_DESC(enable_ir, "enable ir (default is enable");
+
+#undef dprintk
+
+#define dprintk(fmt, arg...) \
+ if (ir_debug) { \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
+ }
+
+struct tm6000_ir_poll_result {
+ u8 rc_data[4];
+};
+
+struct tm6000_IR {
+ struct tm6000_core *dev;
+ struct ir_input_dev *input;
+ struct ir_input_state ir;
+ char name[32];
+ char phys[32];
+
+ /* poll expernal decoder */
+ int polling;
+ struct delayed_work work;
+ u8 wait:1;
+ struct urb *int_urb;
+ u8 *urb_data;
+ u8 key:1;
+
+ int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
+
+ /* IR device properties */
+ struct ir_dev_props props;
+};
+
+
+void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
+{
+ struct tm6000_IR *ir = dev->ir;
+
+ if (!dev->ir)
+ return;
+
+ if (state)
+ ir->wait = 1;
+ else
+ ir->wait = 0;
+}
+
+
+static int tm6000_ir_config(struct tm6000_IR *ir)
+{
+ struct tm6000_core *dev = ir->dev;
+ u8 buf[10];
+ int rc;
+
+ /* hack */
+ buf[0] = 0xff;
+ buf[1] = 0xff;
+ buf[2] = 0xf2;
+ buf[3] = 0x2b;
+ buf[4] = 0x20;
+ buf[5] = 0x35;
+ buf[6] = 0x60;
+ buf[7] = 0x04;
+ buf[8] = 0xc0;
+ buf[9] = 0x08;
+
+ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
+ msleep(100);
+
+ if (rc < 0) {
+ printk(KERN_INFO "IR configuration failed");
+ return rc;
+ }
+ return 0;
+}
+
+static void tm6000_ir_urb_received(struct urb *urb)
+{
+ struct tm6000_core *dev = urb->context;
+ struct tm6000_IR *ir = dev->ir;
+ int rc;
+
+ if (urb->status != 0)
+ printk(KERN_INFO "not ready\n");
+ else if (urb->actual_length > 0)
+ memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
+
+ dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
+ ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
+
+ ir->key = 1;
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int default_polling_getkey(struct tm6000_IR *ir,
+ struct tm6000_ir_poll_result *poll_result)
+{
+ struct tm6000_core *dev = ir->dev;
+ int rc;
+ u8 buf[2];
+
+ if (ir->wait && !&dev->int_in) {
+ poll_result->rc_data[0] = 0xff;
+ return 0;
+ }
+
+ if (&dev->int_in) {
+ poll_result->rc_data[0] = ir->urb_data[0];
+ poll_result->rc_data[1] = ir->urb_data[1];
+ } else {
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
+ msleep(10);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
+ msleep(10);
+
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1);
+
+ msleep(10);
+
+ dprintk("read data=%02x\n", buf[0]);
+ if (rc < 0)
+ return rc;
+
+ poll_result->rc_data[0] = buf[0];
+ }
+ return 0;
+}
+
+static void tm6000_ir_handle_key(struct tm6000_IR *ir)
+{
+ int result;
+ struct tm6000_ir_poll_result poll_result;
+
+ /* read the registers containing the IR status */
+ result = ir->get_key(ir, &poll_result);
+ if (result < 0) {
+ printk(KERN_INFO "ir->get_key() failed %d\n", result);
+ return;
+ }
+
+ dprintk("ir->get_key result data=%02x %02x\n",
+ poll_result.rc_data[0], poll_result.rc_data[1]);
+
+ if (poll_result.rc_data[0] != 0xff && ir->key == 1) {
+ ir_input_keydown(ir->input->input_dev, &ir->ir,
+ poll_result.rc_data[0] | poll_result.rc_data[1] << 8);
+
+ ir_input_nokey(ir->input->input_dev, &ir->ir);
+ ir->key = 0;
+ }
+ return;
+}
+
+static void tm6000_ir_work(struct work_struct *work)
+{
+ struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
+
+ tm6000_ir_handle_key(ir);
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+}
+
+static int tm6000_ir_start(void *priv)
+{
+ struct tm6000_IR *ir = priv;
+
+ INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
+ schedule_delayed_work(&ir->work, 0);
+
+ return 0;
+}
+
+static void tm6000_ir_stop(void *priv)
+{
+ struct tm6000_IR *ir = priv;
+
+ cancel_delayed_work_sync(&ir->work);
+}
+
+int tm6000_ir_change_protocol(void *priv, u64 ir_type)
+{
+ struct tm6000_IR *ir = priv;
+
+ ir->get_key = default_polling_getkey;
+
+ tm6000_ir_config(ir);
+ /* TODO */
+ return 0;
+}
+
+int tm6000_ir_init(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir;
+ struct ir_input_dev *ir_input_dev;
+ int err = -ENOMEM;
+ int pipe, size, rc;
+
+ if (!enable_ir)
+ return -ENODEV;
+
+ if (!dev->caps.has_remote)
+ return 0;
+
+ if (!dev->ir_codes)
+ return 0;
+
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL);
+ ir_input_dev->input_dev = input_allocate_device();
+ if (!ir || !ir_input_dev || !ir_input_dev->input_dev)
+ goto err_out_free;
+
+ /* record handles to ourself */
+ ir->dev = dev;
+ dev->ir = ir;
+
+ ir->input = ir_input_dev;
+
+ /* input einrichten */
+ ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+ ir->props.priv = ir;
+ ir->props.change_protocol = tm6000_ir_change_protocol;
+ ir->props.open = tm6000_ir_start;
+ ir->props.close = tm6000_ir_stop;
+ ir->props.driver_type = RC_DRIVER_SCANCODE;
+
+ ir->polling = 50;
+
+ snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
+ dev->name);
+
+ usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
+
+ tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
+ err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER);
+ if (err < 0)
+ goto err_out_free;
+
+ ir_input_dev->input_dev->name = ir->name;
+ ir_input_dev->input_dev->phys = ir->phys;
+ ir_input_dev->input_dev->id.bustype = BUS_USB;
+ ir_input_dev->input_dev->id.version = 1;
+ ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+ ir_input_dev->input_dev->dev.parent = &dev->udev->dev;
+
+ if (&dev->int_in) {
+ dprintk("IR over int\n");
+
+ ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ pipe = usb_rcvintpipe(dev->udev,
+ dev->int_in.endp->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ dprintk("IR max size: %d\n", size);
+
+ ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
+ if (ir->int_urb->transfer_buffer == NULL) {
+ usb_free_urb(ir->int_urb);
+ goto err_out_stop;
+ }
+ dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
+ usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
+ ir->int_urb->transfer_buffer, size,
+ tm6000_ir_urb_received, dev,
+ dev->int_in.endp->desc.bInterval);
+ rc = usb_submit_urb(ir->int_urb, GFP_KERNEL);
+ if (rc) {
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ err = rc;
+ goto err_out_stop;
+ }
+ ir->urb_data = kzalloc(size, GFP_KERNEL);
+ }
+
+ /* ir register */
+ err = ir_input_register(ir->input->input_dev, dev->ir_codes,
+ &ir->props, "tm6000");
+ if (err)
+ goto err_out_stop;
+
+ return 0;
+
+err_out_stop:
+ dev->ir = NULL;
+err_out_free:
+ kfree(ir_input_dev);
+ kfree(ir);
+ return err;
+}
+
+int tm6000_ir_fini(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir = dev->ir;
+
+ /* skip detach on non attached board */
+
+ if (!ir)
+ return 0;
+
+ ir_input_unregister(ir->input->input_dev);
+
+ if (ir->int_urb) {
+ usb_kill_urb(ir->int_urb);
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ ir->int_urb = NULL;
+ kfree(ir->urb_data);
+ ir->urb_data = NULL;
+ }
+
+ kfree(ir->input);
+ ir->input = NULL;
+ kfree(ir);
+ dev->ir = NULL;
+
+ return 0;
+}
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index b3564f611e5e..6bf4a73b320d 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -77,7 +77,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -135,7 +135,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -193,7 +193,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -251,7 +251,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -308,7 +308,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
@@ -354,7 +354,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -396,7 +396,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -438,7 +438,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -480,7 +480,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -521,7 +521,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
@@ -567,7 +567,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -609,7 +609,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -651,7 +651,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -693,7 +693,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -734,7 +734,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
{TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
@@ -763,11 +763,11 @@ static struct tm6000_std_settings svideo_stds[] = {
void tm6000_get_std_res(struct tm6000_core *dev)
{
/* Currently, those are the only supported resoltions */
- if (dev->norm & V4L2_STD_525_60) {
+ if (dev->norm & V4L2_STD_525_60)
dev->height = 480;
- } else {
+ else
dev->height = 576;
- }
+
dev->width = 720;
}
diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
index 5a5049acd4ec..138716a8f056 100644
--- a/drivers/staging/tm6000/tm6000-usb-isoc.h
+++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -39,7 +39,7 @@ struct usb_isoc_ctl {
int pos, size, pktsize;
/* Last field: ODD or EVEN? */
- int field;
+ int vfield;
/* Stores incomplete commands */
u32 tmp_buf;
@@ -47,7 +47,4 @@ struct usb_isoc_ctl {
/* Stores already requested buffers */
struct tm6000_buffer *buf;
-
- /* Stores the number of received fields */
- int nfields;
};
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 56fa371e08c8..ce0a089a0771 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -56,6 +56,7 @@ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
/* Debug level */
int tm6000_debug;
+EXPORT_SYMBOL_GPL(tm6000_debug);
/* supported controls */
static struct v4l2_queryctrl tm6000_qctrl[] = {
@@ -149,8 +150,6 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
/* Cleans up buffer - Usefull for testing for frame/URB loss */
outp = videobuf_to_vmalloc(&(*buf)->vb);
-// if (outp)
-// memset(outp, 0, (*buf)->vb.size);
return;
}
@@ -186,236 +185,152 @@ const char *tm6000_msg_type[] = {
/*
* Identify the tm5600/6000 buffer header type and properly handles
*/
-static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
- u8 *out_p, struct tm6000_buffer **buf)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- u8 c;
- unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
- int rc = 0;
- /* FIXME: move to tm6000-isoc */
- static int last_line = -2, start_line = -2, last_field = -2;
-
- /* FIXME: this is the hardcoded window size
- */
- unsigned int linewidth = (*buf)->vb.width << 1;
-
- if (!dev->isoc_ctl.cmd) {
- c = (header >> 24) & 0xff;
-
- /* split the header fields */
- size = ((header & 0x7e) << 1);
-
- if (size > 0)
- size -= 4;
-
- block = (header >> 7) & 0xf;
- field = (header >> 11) & 0x1;
- line = (header >> 12) & 0x1ff;
- cmd = (header >> 21) & 0x7;
-
- /* Validates header fields */
- if(size > TM6000_URB_MSG_LEN)
- size = TM6000_URB_MSG_LEN;
-
- if (cmd == TM6000_URB_MSG_VIDEO) {
- if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
- cmd = TM6000_URB_MSG_ERR;
-
- /* FIXME: Mounts the image as field0+field1
- * It should, instead, check if the user selected
- * entrelaced or non-entrelaced mode
- */
- pos = ((line << 1) - field - 1) * linewidth +
- block * TM6000_URB_MSG_LEN;
-
- /* Don't allow to write out of the buffer */
- if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
- dprintk(dev, V4L2_DEBUG_ISOC,
- "ERR: size=%d, num=%d, line=%d, "
- "field=%d\n",
- size, block, line, field);
-
- cmd = TM6000_URB_MSG_ERR;
- }
- } else {
- pos=0;
- }
-
- /* Prints debug info */
- dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
- " line=%d, field=%d\n",
- size, block, line, field);
-
- if ((last_line!=line)&&(last_line+1!=line) &&
- (cmd != TM6000_URB_MSG_ERR) ) {
- if (cmd != TM6000_URB_MSG_VIDEO) {
- dprintk(dev, V4L2_DEBUG_ISOC, "cmd=%d, "
- "size=%d, num=%d, line=%d, field=%d\n",
- cmd, size, block, line, field);
- }
- if (start_line<0)
- start_line=last_line;
- /* Prints debug info */
- dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
- "field=%d\n",
- start_line, last_line, field);
-
- if ((start_line<6 && last_line>200) &&
- (last_field != field) ) {
-
- dev->isoc_ctl.nfields++;
- if (dev->isoc_ctl.nfields>=2) {
- dev->isoc_ctl.nfields=0;
-
- /* Announces that a new buffer were filled */
- buffer_filled (dev, dma_q, *buf);
- dprintk(dev, V4L2_DEBUG_ISOC,
- "new buffer filled\n");
- get_next_buf (dma_q, buf);
- if (!*buf)
- return rc;
- out_p = videobuf_to_vmalloc(&((*buf)->vb));
- if (!out_p)
- return rc;
-
- pos = dev->isoc_ctl.pos = 0;
- }
- }
-
- start_line=line;
- last_field=field;
- }
- if (cmd == TM6000_URB_MSG_VIDEO)
- last_line = line;
-
- pktsize = TM6000_URB_MSG_LEN;
- } else {
- /* Continue the last copy */
- cmd = dev->isoc_ctl.cmd;
- size= dev->isoc_ctl.size;
- pos = dev->isoc_ctl.pos;
- pktsize = dev->isoc_ctl.pktsize;
- }
-
- cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
-
- if (cpysize) {
- /* handles each different URB message */
- switch(cmd) {
- case TM6000_URB_MSG_VIDEO:
- /* Fills video buffer */
- memcpy(&out_p[pos], *ptr, cpysize);
- break;
- case TM6000_URB_MSG_PTS:
- break;
- case TM6000_URB_MSG_AUDIO:
- /* Need some code to process audio */
- printk ("%ld: cmd=%s, size=%d\n", jiffies,
- tm6000_msg_type[cmd],size);
- break;
- case TM6000_URB_MSG_VBI:
- break;
- default:
- dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
- tm6000_msg_type[cmd],size);
- }
- }
- if (cpysize<size) {
- /* End of URB packet, but cmd processing is not
- * complete. Preserve the state for a next packet
- */
- dev->isoc_ctl.pos = pos+cpysize;
- dev->isoc_ctl.size= size-cpysize;
- dev->isoc_ctl.cmd = cmd;
- dev->isoc_ctl.pktsize = pktsize-cpysize;
- (*ptr)+=cpysize;
- } else {
- dev->isoc_ctl.cmd = 0;
- (*ptr)+=pktsize;
- }
-
- return rc;
-}
-
static int copy_streams(u8 *data, unsigned long len,
struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
- u8 *ptr=data, *endp=data+len;
+ u8 *ptr=data, *endp=data+len, c;
unsigned long header=0;
int rc=0;
- struct tm6000_buffer *buf;
- char *outp = NULL;
-
- get_next_buf(dma_q, &buf);
- if (buf)
- outp = videobuf_to_vmalloc(&buf->vb);
+ unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
+ struct tm6000_buffer *vbuf;
+ char *voutp = NULL;
+ unsigned int linewidth;
- if (!outp)
+ /* get video buffer */
+ get_next_buf (dma_q, &vbuf);
+ if (!vbuf)
+ return rc;
+ voutp = videobuf_to_vmalloc(&vbuf->vb);
+ if (!voutp)
return 0;
- for (ptr=data; ptr<endp;) {
+ for (ptr = data; ptr < endp;) {
if (!dev->isoc_ctl.cmd) {
- u8 *p=(u8 *)&dev->isoc_ctl.tmp_buf;
- /* FIXME: This seems very complex
- * It just recovers up to 3 bytes of the header that
- * might be at the previous packet
- */
- if (dev->isoc_ctl.tmp_buf_len) {
- while (dev->isoc_ctl.tmp_buf_len) {
- if ( *(ptr+3-dev->isoc_ctl.tmp_buf_len) == 0x47) {
- break;
- }
- p++;
- dev->isoc_ctl.tmp_buf_len--;
- }
- if (dev->isoc_ctl.tmp_buf_len) {
- memcpy(&header, p,
- dev->isoc_ctl.tmp_buf_len);
- memcpy((u8 *)&header +
+ /* Header */
+ if (dev->isoc_ctl.tmp_buf_len > 0) {
+ /* from last urb or packet */
+ header = dev->isoc_ctl.tmp_buf;
+ if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
+ memcpy ((u8 *)&header +
dev->isoc_ctl.tmp_buf_len,
ptr,
4 - dev->isoc_ctl.tmp_buf_len);
ptr += 4 - dev->isoc_ctl.tmp_buf_len;
- goto HEADER;
}
- }
- /* Seek for sync */
- for (;ptr<endp-3;ptr++) {
- if (*(ptr+3)==0x47)
- break;
+ dev->isoc_ctl.tmp_buf_len = 0;
+ } else {
+ if (ptr + 3 >= endp) {
+ /* have incomplete header */
+ dev->isoc_ctl.tmp_buf_len = endp - ptr;
+ memcpy (&dev->isoc_ctl.tmp_buf, ptr,
+ dev->isoc_ctl.tmp_buf_len);
+ return rc;
+ }
+ /* Seek for sync */
+ for (; ptr < endp - 3; ptr++) {
+ if (*(ptr + 3) == 0x47)
+ break;
+ }
+ /* Get message header */
+ header = *(unsigned long *)ptr;
+ ptr += 4;
}
- if (ptr+3>=endp) {
- dev->isoc_ctl.tmp_buf_len=endp-ptr;
- memcpy (&dev->isoc_ctl.tmp_buf,ptr,
- dev->isoc_ctl.tmp_buf_len);
- dev->isoc_ctl.cmd=0;
- return rc;
+ /* split the header fields */
+ c = (header >> 24) & 0xff;
+ size = ((header & 0x7e) << 1);
+ if (size > 0)
+ size -= 4;
+ block = (header >> 7) & 0xf;
+ field = (header >> 11) & 0x1;
+ line = (header >> 12) & 0x1ff;
+ cmd = (header >> 21) & 0x7;
+ /* Validates haeder fields */
+ if (size > TM6000_URB_MSG_LEN)
+ size = TM6000_URB_MSG_LEN;
+ pktsize = TM6000_URB_MSG_LEN;
+ /* calculate position in buffer
+ * and change the buffer
+ */
+ switch (cmd) {
+ case TM6000_URB_MSG_VIDEO:
+ if ((dev->isoc_ctl.vfield != field) &&
+ (field == 1)) {
+ /* Announces that a new buffer
+ * were filled
+ */
+ buffer_filled (dev, dma_q, vbuf);
+ dprintk (dev, V4L2_DEBUG_ISOC,
+ "new buffer filled\n");
+ get_next_buf (dma_q, &vbuf);
+ if (!vbuf)
+ return rc;
+ voutp = videobuf_to_vmalloc (&vbuf->vb);
+ if (!voutp)
+ return rc;
+ memset(voutp, 0, vbuf->vb.size);
+ }
+ linewidth = vbuf->vb.width << 1;
+ pos = ((line << 1) - field - 1) * linewidth +
+ block * TM6000_URB_MSG_LEN;
+ /* Don't allow to write out of the buffer */
+ if (pos + size > vbuf->vb.size)
+ cmd = TM6000_URB_MSG_ERR;
+ dev->isoc_ctl.vfield = field;
+ break;
+ case TM6000_URB_MSG_VBI:
+ break;
+ case TM6000_URB_MSG_AUDIO:
+ case TM6000_URB_MSG_PTS:
+ size = pktsize; /* Size is always 180 bytes */
+ break;
}
-
- /* Get message header */
- header=*(unsigned long *)ptr;
- ptr+=4;
+ } else {
+ /* Continue the last copy */
+ cmd = dev->isoc_ctl.cmd;
+ size = dev->isoc_ctl.size;
+ pos = dev->isoc_ctl.pos;
+ pktsize = dev->isoc_ctl.pktsize;
}
-HEADER:
- /* Copy or continue last copy */
- rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
- if (rc<0) {
- buf=NULL;
- printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
- jiffies);
- return rc;
+ cpysize = (endp - ptr > size) ? size : endp - ptr;
+ if (cpysize) {
+ /* copy data in different buffers */
+ switch (cmd) {
+ case TM6000_URB_MSG_VIDEO:
+ /* Fills video buffer */
+ if (vbuf)
+ memcpy (&voutp[pos], ptr, cpysize);
+ break;
+ case TM6000_URB_MSG_AUDIO:
+ tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
+ break;
+ case TM6000_URB_MSG_VBI:
+ /* Need some code to copy vbi buffer */
+ break;
+ case TM6000_URB_MSG_PTS:
+ /* Need some code to copy pts */
+ break;
+ }
+ }
+ if (ptr + pktsize > endp) {
+ /* End of URB packet, but cmd processing is not
+ * complete. Preserve the state for a next packet
+ */
+ dev->isoc_ctl.pos = pos + cpysize;
+ dev->isoc_ctl.size = size - cpysize;
+ dev->isoc_ctl.cmd = cmd;
+ dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
+ ptr += endp - ptr;
+ } else {
+ dev->isoc_ctl.cmd = 0;
+ ptr += pktsize;
}
- if (!buf)
- return 0;
}
-
return 0;
}
+
/*
* Identify the tm5600/6000 buffer header type and properly handles
*/
@@ -510,7 +425,6 @@ static inline int tm6000_isoc_copy(struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
- struct tm6000_buffer *buf;
int i, len=0, rc=1, status;
char *p;
@@ -585,7 +499,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
struct urb *urb;
int i;
- dev->isoc_ctl.nfields = -1;
dev->isoc_ctl.buf = NULL;
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
urb=dev->isoc_ctl.urb[i];
@@ -610,8 +523,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
dev->isoc_ctl.urb=NULL;
dev->isoc_ctl.transfer_buffer=NULL;
dev->isoc_ctl.num_bufs = 0;
-
- dev->isoc_ctl.num_bufs=0;
}
/*
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 7bbaf26dea14..1ec1bff9b294 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -20,8 +20,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-// Use the tm6000-hack, instead of the proper initialization code
-//#define HACK 1
+/* Use the tm6000-hack, instead of the proper initialization code i*/
+/* #define HACK 1 */
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
@@ -98,7 +98,7 @@ enum tm6000_io_method {
};
enum tm6000_mode {
- TM6000_MODE_UNKNOWN=0,
+ TM6000_MODE_UNKNOWN = 0,
TM6000_MODE_ANALOG,
TM6000_MODE_DIGITAL,
};
@@ -128,10 +128,21 @@ struct tm6000_dvb {
struct dvb_frontend *frontend;
struct dmxdev dmxdev;
unsigned int streams;
- struct urb *bulk_urb;
+ struct urb *bulk_urb;
struct mutex mutex;
};
+struct snd_tm6000_card {
+ struct snd_card *card;
+ spinlock_t reg_lock;
+ struct tm6000_core *core;
+ struct snd_pcm_substream *substream;
+
+ /* temporary data for buffer fill processing */
+ unsigned buf_pos;
+ unsigned period_pos;
+};
+
struct tm6000_endpoint {
struct usb_host_endpoint *endp;
__u8 bInterfaceNumber;
@@ -147,7 +158,7 @@ struct tm6000_core {
enum tm6000_devtype dev_type; /* type of device */
v4l2_std_id norm; /* Current norm */
- int width,height; /* Selected resolution */
+ int width, height; /* Selected resolution */
enum tm6000_core_state state;
@@ -160,6 +171,8 @@ struct tm6000_core {
struct tm6000_gpio gpio;
+ char *ir_codes;
+
/* Demodulator configuration */
int demod_addr; /* demodulator address */
@@ -190,6 +203,11 @@ struct tm6000_core {
/* DVB-T support */
struct tm6000_dvb *dvb;
+ /* audio support */
+ struct snd_tm6000_card *adev;
+
+ struct tm6000_IR *ir;
+
/* locks */
struct mutex lock;
@@ -197,6 +215,7 @@ struct tm6000_core {
struct usb_device *udev; /* the usb device */
struct tm6000_endpoint bulk_in, bulk_out, isoc_in, isoc_out;
+ struct tm6000_endpoint int_in, int_out;
/* scaler!=0 if scaler is active*/
int scaler;
@@ -207,14 +226,18 @@ struct tm6000_core {
spinlock_t slock;
};
-#define TM6000_AUDIO 0x10
+enum tm6000_ops_type {
+ TM6000_AUDIO = 0x10,
+ TM6000_DVB = 0x20,
+};
struct tm6000_ops {
struct list_head next;
char *name;
- int id;
+ enum tm6000_ops_type type;
int (*init)(struct tm6000_core *);
int (*fini)(struct tm6000_core *);
+ int (*fillbuf)(struct tm6000_core *, char *buf, int size);
};
struct tm6000_fh {
@@ -222,7 +245,7 @@ struct tm6000_fh {
/* video capture */
struct tm6000_fmt *fmt;
- unsigned int width,height;
+ unsigned int width, height;
struct videobuf_queue vb_vidq;
enum v4l2_buf_type type;
@@ -234,28 +257,24 @@ struct tm6000_fh {
/* In tm6000-cards.c */
-int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
-int tm6000_xc5000_callback (void *ptr, int component, int command, int arg);
+int tm6000_tuner_callback(void *ptr, int component, int command, int arg);
+int tm6000_xc5000_callback(void *ptr, int component, int command, int arg);
int tm6000_cards_setup(struct tm6000_core *dev);
/* In tm6000-core.c */
-int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
+int tm6000_read_write_usb(struct tm6000_core *dev, u8 reqtype, u8 req,
u16 value, u16 index, u8 *buf, u16 len);
-int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
+int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
+int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
+int tm6000_init(struct tm6000_core *dev);
-int tm6000_init (struct tm6000_core *dev);
-
-int tm6000_init_analog_mode (struct tm6000_core *dev);
-int tm6000_init_digital_mode (struct tm6000_core *dev);
-int tm6000_set_audio_bitrate (struct tm6000_core *dev, int bitrate);
-
-int tm6000_dvb_register(struct tm6000_core *dev);
-void tm6000_dvb_unregister(struct tm6000_core *dev);
+int tm6000_init_analog_mode(struct tm6000_core *dev);
+int tm6000_init_digital_mode(struct tm6000_core *dev);
+int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
int tm6000_v4l2_register(struct tm6000_core *dev);
int tm6000_v4l2_unregister(struct tm6000_core *dev);
@@ -268,10 +287,13 @@ int tm6000_register_extension(struct tm6000_ops *ops);
void tm6000_unregister_extension(struct tm6000_ops *ops);
void tm6000_init_extension(struct tm6000_core *dev);
void tm6000_close_extension(struct tm6000_core *dev);
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+ char *buf, int size);
+
/* In tm6000-stds.c */
void tm6000_get_std_res(struct tm6000_core *dev);
-int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
+int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id *norm);
/* In tm6000-i2c.c */
int tm6000_i2c_register(struct tm6000_core *dev);
@@ -285,14 +307,14 @@ int tm6000_vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type i);
int tm6000_vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type i);
-int tm6000_vidioc_reqbufs (struct file *file, void *priv,
- struct v4l2_requestbuffers *rb);
-int tm6000_vidioc_querybuf (struct file *file, void *priv,
- struct v4l2_buffer *b);
-int tm6000_vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *b);
-int tm6000_vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *b);
+int tm6000_vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb);
+int tm6000_vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b);
+int tm6000_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
+int tm6000_vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
ssize_t tm6000_v4l2_read(struct file *filp, char __user * buf, size_t count,
- loff_t * f_pos);
+ loff_t *f_pos);
unsigned int tm6000_v4l2_poll(struct file *file,
struct poll_table_struct *wait);
int tm6000_queue_init(struct tm6000_core *dev);
@@ -300,6 +322,10 @@ int tm6000_queue_init(struct tm6000_core *dev);
/* In tm6000-alsa.c */
/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
+/* In tm6000-input.c */
+int tm6000_ir_init(struct tm6000_core *dev);
+int tm6000_ir_fini(struct tm6000_core *dev);
+void tm6000_ir_wait(struct tm6000_core *dev, u8 state);
/* Debug stuff */
@@ -307,7 +333,7 @@ extern int tm6000_debug;
#define dprintk(dev, level, fmt, arg...) do {\
if (tm6000_debug & level) \
- printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
+ printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
dev->name, __FUNCTION__ , ##arg); } while (0)
#define V4L2_DEBUG_REG 0x0004
@@ -320,5 +346,3 @@ extern int tm6000_debug;
#define tm6000_err(fmt, arg...) do {\
printk(KERN_ERR "tm6000 %s :"fmt, \
__FUNCTION__ , ##arg); } while (0)
-
-
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 61d75507d5d0..162c95a088ed 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1596,6 +1596,7 @@ static const struct usb_device_id acm_ids[] = {
{ NOKIA_PCSUITE_ACM_INFO(0x00e9), }, /* Nokia 5320 XpressMusic */
{ NOKIA_PCSUITE_ACM_INFO(0x0108), }, /* Nokia 5320 XpressMusic 2G */
{ NOKIA_PCSUITE_ACM_INFO(0x01f5), }, /* Nokia N97, RM-505 */
+ { NOKIA_PCSUITE_ACM_INFO(0x02e3), }, /* Nokia 5230, RM-588 */
/* NOTE: non-Nokia COMM/ACM/0xff is likely MSFT RNDIS... NOT a modem! */
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 83e7bbbe97fa..70cccc75a362 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1982,6 +1982,8 @@ static int hub_port_wait_reset(struct usb_hub *hub, int port1,
(portstatus & USB_PORT_STAT_ENABLE)) {
if (hub_is_wusb(hub))
udev->speed = USB_SPEED_WIRELESS;
+ else if (portstatus & USB_PORT_STAT_SUPER_SPEED)
+ udev->speed = USB_SPEED_SUPER;
else if (portstatus & USB_PORT_STAT_HIGH_SPEED)
udev->speed = USB_SPEED_HIGH;
else if (portstatus & USB_PORT_STAT_LOW_SPEED)
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index f22d03df8b17..ba2620cd660d 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -41,6 +41,10 @@ static const struct usb_device_id usb_quirk_list[] = {
/* Philips PSC805 audio device */
{ USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
+ /* Artisman Watchdog Dongle */
+ { USB_DEVICE(0x04b4, 0x0526), .driver_info =
+ USB_QUIRK_CONFIG_INTF_STRINGS },
+
/* Roland SC-8820 */
{ USB_DEVICE(0x0582, 0x0007), .driver_info = USB_QUIRK_RESET_RESUME },
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index eaa79c8a9b8c..fd6a7577ad25 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -77,10 +77,10 @@ static const char driver_name [] = "at91_udc";
static const char ep0name[] = "ep0";
-#define at91_udp_read(dev, reg) \
- __raw_readl((dev)->udp_baseaddr + (reg))
-#define at91_udp_write(dev, reg, val) \
- __raw_writel((val), (dev)->udp_baseaddr + (reg))
+#define at91_udp_read(udc, reg) \
+ __raw_readl((udc)->udp_baseaddr + (reg))
+#define at91_udp_write(udc, reg, val) \
+ __raw_writel((val), (udc)->udp_baseaddr + (reg))
/*-------------------------------------------------------------------------*/
@@ -102,8 +102,9 @@ static void proc_ep_show(struct seq_file *s, struct at91_ep *ep)
u32 csr;
struct at91_request *req;
unsigned long flags;
+ struct at91_udc *udc = ep->udc;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
csr = __raw_readl(ep->creg);
@@ -147,7 +148,7 @@ static void proc_ep_show(struct seq_file *s, struct at91_ep *ep)
&req->req, length,
req->req.length, req->req.buf);
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
}
static void proc_irq_show(struct seq_file *s, const char *label, u32 mask)
@@ -272,7 +273,9 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status)
VDBG("%s done %p, status %d\n", ep->ep.name, req, status);
ep->stopped = 1;
+ spin_unlock(&udc->lock);
req->req.complete(&ep->ep, &req->req);
+ spin_lock(&udc->lock);
ep->stopped = stopped;
/* ep0 is always ready; other endpoints need a non-empty queue */
@@ -472,7 +475,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
const struct usb_endpoint_descriptor *desc)
{
struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
- struct at91_udc *dev = ep->udc;
+ struct at91_udc *udc = ep->udc;
u16 maxpacket;
u32 tmp;
unsigned long flags;
@@ -487,7 +490,7 @@ static int at91_ep_enable(struct usb_ep *_ep,
return -EINVAL;
}
- if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+ if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
DBG("bogus device state\n");
return -ESHUTDOWN;
}
@@ -521,7 +524,7 @@ bogus_max:
}
ok:
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
/* initialize endpoint to match this descriptor */
ep->is_in = usb_endpoint_dir_in(desc);
@@ -540,10 +543,10 @@ ok:
* reset/init endpoint fifo. NOTE: leaves fifo_bank alone,
* since endpoint resets don't reset hw pingpong state.
*/
- at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask);
- at91_udp_write(dev, AT91_UDP_RST_EP, 0);
+ at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_RST_EP, 0);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -556,7 +559,7 @@ static int at91_ep_disable (struct usb_ep * _ep)
if (ep == &ep->udc->ep[0])
return -EINVAL;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
nuke(ep, -ESHUTDOWN);
@@ -571,7 +574,7 @@ static int at91_ep_disable (struct usb_ep * _ep)
__raw_writel(0, ep->creg);
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -607,7 +610,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
{
struct at91_request *req;
struct at91_ep *ep;
- struct at91_udc *dev;
+ struct at91_udc *udc;
int status;
unsigned long flags;
@@ -625,9 +628,9 @@ static int at91_ep_queue(struct usb_ep *_ep,
return -EINVAL;
}
- dev = ep->udc;
+ udc = ep->udc;
- if (!dev || !dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) {
+ if (!udc || !udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
DBG("invalid device\n");
return -EINVAL;
}
@@ -635,7 +638,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
_req->status = -EINPROGRESS;
_req->actual = 0;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
/* try to kickstart any empty and idle queue */
if (list_empty(&ep->queue) && !ep->stopped) {
@@ -653,7 +656,7 @@ static int at91_ep_queue(struct usb_ep *_ep,
if (is_ep0) {
u32 tmp;
- if (!dev->req_pending) {
+ if (!udc->req_pending) {
status = -EINVAL;
goto done;
}
@@ -662,11 +665,11 @@ static int at91_ep_queue(struct usb_ep *_ep,
* defer changing CONFG until after the gadget driver
* reconfigures the endpoints.
*/
- if (dev->wait_for_config_ack) {
- tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT);
+ if (udc->wait_for_config_ack) {
+ tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT);
tmp ^= AT91_UDP_CONFG;
VDBG("toggle config\n");
- at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp);
+ at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp);
}
if (req->req.length == 0) {
ep0_in_status:
@@ -676,7 +679,7 @@ ep0_in_status:
tmp &= ~SET_FX;
tmp |= CLR_FX | AT91_UDP_TXPKTRDY;
__raw_writel(tmp, ep->creg);
- dev->req_pending = 0;
+ udc->req_pending = 0;
goto done;
}
}
@@ -695,31 +698,40 @@ ep0_in_status:
if (req && !status) {
list_add_tail (&req->queue, &ep->queue);
- at91_udp_write(dev, AT91_UDP_IER, ep->int_mask);
+ at91_udp_write(udc, AT91_UDP_IER, ep->int_mask);
}
done:
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return (status < 0) ? status : 0;
}
static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
{
- struct at91_ep *ep;
+ struct at91_ep *ep;
struct at91_request *req;
+ unsigned long flags;
+ struct at91_udc *udc;
ep = container_of(_ep, struct at91_ep, ep);
if (!_ep || ep->ep.name == ep0name)
return -EINVAL;
+ udc = ep->udc;
+
+ spin_lock_irqsave(&udc->lock, flags);
+
/* make sure it's actually queued on this endpoint */
list_for_each_entry (req, &ep->queue, queue) {
if (&req->req == _req)
break;
}
- if (&req->req != _req)
+ if (&req->req != _req) {
+ spin_unlock_irqrestore(&udc->lock, flags);
return -EINVAL;
+ }
done(ep, req, -ECONNRESET);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -736,7 +748,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
return -EINVAL;
creg = ep->creg;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
csr = __raw_readl(creg);
@@ -761,7 +773,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
__raw_writel(csr, creg);
}
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return status;
}
@@ -795,7 +807,7 @@ static int at91_wakeup(struct usb_gadget *gadget)
unsigned long flags;
DBG("%s\n", __func__ );
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
if (!udc->clocked || !udc->suspended)
goto done;
@@ -809,7 +821,7 @@ static int at91_wakeup(struct usb_gadget *gadget)
at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate);
done:
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return status;
}
@@ -851,8 +863,11 @@ static void stop_activity(struct at91_udc *udc)
ep->stopped = 1;
nuke(ep, -ESHUTDOWN);
}
- if (driver)
+ if (driver) {
+ spin_unlock(&udc->lock);
driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
udc_reinit(udc);
}
@@ -935,13 +950,13 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active)
unsigned long flags;
// VDBG("vbus %s\n", is_active ? "on" : "off");
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
udc->vbus = (is_active != 0);
if (udc->driver)
pullup(udc, is_active);
else
pullup(udc, 0);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -950,10 +965,10 @@ static int at91_pullup(struct usb_gadget *gadget, int is_on)
struct at91_udc *udc = to_udc(gadget);
unsigned long flags;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
udc->enabled = is_on = !!is_on;
pullup(udc, is_on);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -962,9 +977,9 @@ static int at91_set_selfpowered(struct usb_gadget *gadget, int is_on)
struct at91_udc *udc = to_udc(gadget);
unsigned long flags;
- local_irq_save(flags);
+ spin_lock_irqsave(&udc->lock, flags);
udc->selfpowered = (is_on != 0);
- local_irq_restore(flags);
+ spin_unlock_irqrestore(&udc->lock, flags);
return 0;
}
@@ -1226,8 +1241,11 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr)
#undef w_length
/* pass request up to the gadget driver */
- if (udc->driver)
+ if (udc->driver) {
+ spin_unlock(&udc->lock);
status = udc->driver->setup(&udc->gadget, &pkt.r);
+ spin_lock(&udc->lock);
+ }
else
status = -ENODEV;
if (status < 0) {
@@ -1378,6 +1396,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
struct at91_udc *udc = _udc;
u32 rescans = 5;
int disable_clock = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&udc->lock, flags);
if (!udc->clocked) {
clk_on(udc);
@@ -1433,8 +1454,11 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
* and then into standby to avoid drawing more than
* 500uA power (2500uA for some high-power configs).
*/
- if (udc->driver && udc->driver->suspend)
+ if (udc->driver && udc->driver->suspend) {
+ spin_unlock(&udc->lock);
udc->driver->suspend(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
/* host initiated resume */
} else if (status & AT91_UDP_RXRSM) {
@@ -1451,8 +1475,11 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
* would normally want to switch out of slow clock
* mode into normal mode.
*/
- if (udc->driver && udc->driver->resume)
+ if (udc->driver && udc->driver->resume) {
+ spin_unlock(&udc->lock);
udc->driver->resume(&udc->gadget);
+ spin_lock(&udc->lock);
+ }
/* endpoint IRQs are cleared by handling them */
} else {
@@ -1474,6 +1501,8 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
if (disable_clock)
clk_off(udc);
+ spin_unlock_irqrestore(&udc->lock, flags);
+
return IRQ_HANDLED;
}
@@ -1574,6 +1603,7 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
{
struct at91_udc *udc = &controller;
int retval;
+ unsigned long flags;
if (!driver
|| driver->speed < USB_SPEED_FULL
@@ -1605,9 +1635,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver)
return retval;
}
- local_irq_disable();
+ spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 1);
- local_irq_enable();
+ spin_unlock_irqrestore(&udc->lock, flags);
DBG("bound to %s\n", driver->driver.name);
return 0;
@@ -1617,15 +1647,16 @@ EXPORT_SYMBOL (usb_gadget_register_driver);
int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
{
struct at91_udc *udc = &controller;
+ unsigned long flags;
if (!driver || driver != udc->driver || !driver->unbind)
return -EINVAL;
- local_irq_disable();
+ spin_lock_irqsave(&udc->lock, flags);
udc->enabled = 0;
at91_udp_write(udc, AT91_UDP_IDR, ~0);
pullup(udc, 0);
- local_irq_enable();
+ spin_unlock_irqrestore(&udc->lock, flags);
driver->unbind(&udc->gadget);
udc->gadget.dev.driver = NULL;
@@ -1641,8 +1672,13 @@ EXPORT_SYMBOL (usb_gadget_unregister_driver);
static void at91udc_shutdown(struct platform_device *dev)
{
+ struct at91_udc *udc = platform_get_drvdata(dev);
+ unsigned long flags;
+
/* force disconnect on reboot */
+ spin_lock_irqsave(&udc->lock, flags);
pullup(platform_get_drvdata(dev), 0);
+ spin_unlock_irqrestore(&udc->lock, flags);
}
static int __init at91udc_probe(struct platform_device *pdev)
@@ -1683,6 +1719,7 @@ static int __init at91udc_probe(struct platform_device *pdev)
udc->board = *(struct at91_udc_data *) dev->platform_data;
udc->pdev = pdev;
udc->enabled = 0;
+ spin_lock_init(&udc->lock);
/* rm9200 needs manual D+ pullup; off by default */
if (cpu_is_at91rm9200()) {
@@ -1804,13 +1841,16 @@ static int __exit at91udc_remove(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
struct resource *res;
+ unsigned long flags;
DBG("remove\n");
if (udc->driver)
return -EBUSY;
+ spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 0);
+ spin_unlock_irqrestore(&udc->lock, flags);
device_init_wakeup(&pdev->dev, 0);
remove_debug_file(udc);
@@ -1840,6 +1880,7 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
int wake = udc->driver && device_may_wakeup(&pdev->dev);
+ unsigned long flags;
/* Unless we can act normally to the host (letting it wake us up
* whenever it has work for us) force disconnect. Wakeup requires
@@ -1849,8 +1890,10 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
if ((!udc->suspended && udc->addr)
|| !wake
|| at91_suspend_entering_slow_clock()) {
+ spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 0);
wake = 0;
+ spin_unlock_irqrestore(&udc->lock, flags);
} else
enable_irq_wake(udc->udp_irq);
@@ -1863,6 +1906,7 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
static int at91udc_resume(struct platform_device *pdev)
{
struct at91_udc *udc = platform_get_drvdata(pdev);
+ unsigned long flags;
if (udc->board.vbus_pin > 0 && udc->active_suspend)
disable_irq_wake(udc->board.vbus_pin);
@@ -1870,8 +1914,11 @@ static int at91udc_resume(struct platform_device *pdev)
/* maybe reconnect to host; if so, clocks on */
if (udc->active_suspend)
disable_irq_wake(udc->udp_irq);
- else
+ else {
+ spin_lock_irqsave(&udc->lock, flags);
pullup(udc, 1);
+ spin_unlock_irqrestore(&udc->lock, flags);
+ }
return 0;
}
#else
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h
index c65d62295890..bc76a39c2bb1 100644
--- a/drivers/usb/gadget/at91_udc.h
+++ b/drivers/usb/gadget/at91_udc.h
@@ -144,6 +144,7 @@ struct at91_udc {
struct proc_dir_entry *pde;
void __iomem *udp_baseaddr;
int udp_irq;
+ spinlock_t lock;
};
static inline struct at91_udc *to_udc(struct usb_gadget *g)
diff --git a/drivers/usb/gadget/fsl_mxc_udc.c b/drivers/usb/gadget/fsl_mxc_udc.c
index d0b8bde59e59..eafa6d2c5ed7 100644
--- a/drivers/usb/gadget/fsl_mxc_udc.c
+++ b/drivers/usb/gadget/fsl_mxc_udc.c
@@ -30,7 +30,7 @@ int fsl_udc_clk_init(struct platform_device *pdev)
pdata = pdev->dev.platform_data;
- if (!cpu_is_mx35()) {
+ if (!cpu_is_mx35() && !cpu_is_mx25()) {
mxc_ahb_clk = clk_get(&pdev->dev, "usb_ahb");
if (IS_ERR(mxc_ahb_clk))
return PTR_ERR(mxc_ahb_clk);
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c
index e724a051bfdd..ea2b3c7ebee5 100644
--- a/drivers/usb/gadget/s3c2410_udc.c
+++ b/drivers/usb/gadget/s3c2410_udc.c
@@ -735,6 +735,10 @@ static void s3c2410_udc_handle_ep0_idle(struct s3c2410_udc *dev,
else
dev->ep0state = EP0_OUT_DATA_PHASE;
+ if (!dev->driver)
+ return;
+
+ /* deliver the request to the gadget driver */
ret = dev->driver->setup(&dev->gadget, crq);
if (ret < 0) {
if (dev->req_config) {
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index bd4027745aa7..a8ad8ac120a2 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -182,7 +182,7 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
}
clk_enable(priv->usbclk);
- if (!cpu_is_mx35()) {
+ if (!cpu_is_mx35() && !cpu_is_mx25()) {
priv->ahbclk = clk_get(dev, "usb_ahb");
if (IS_ERR(priv->ahbclk)) {
ret = PTR_ERR(priv->ahbclk);
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c
index cd74bbdd007c..653d6a60edb5 100644
--- a/drivers/usb/host/ohci-pnx4008.c
+++ b/drivers/usb/host/ohci-pnx4008.c
@@ -329,7 +329,7 @@ static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
memset(&i2c_info, 0, sizeof(struct i2c_board_info));
strlcpy(i2c_info.type, "isp1301_pnx", I2C_NAME_SIZE);
isp1301_i2c_client = i2c_new_probed_device(i2c_adap, &i2c_info,
- normal_i2c);
+ normal_i2c, NULL);
i2c_put_adapter(i2c_adap);
if (!isp1301_i2c_client) {
err("failed to connect I2C to ISP1301 USB Transceiver");
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index fd9e03afd91c..8cc824bbc4ee 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -835,6 +835,27 @@ fail:
return 0;
}
+void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
+ struct usb_device *udev)
+{
+ struct xhci_virt_device *virt_dev;
+ struct xhci_ep_ctx *ep0_ctx;
+ struct xhci_ring *ep_ring;
+
+ virt_dev = xhci->devs[udev->slot_id];
+ ep0_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, 0);
+ ep_ring = virt_dev->eps[0].ring;
+ /*
+ * FIXME we don't keep track of the dequeue pointer very well after a
+ * Set TR dequeue pointer, so we're setting the dequeue pointer of the
+ * host to our enqueue pointer. This should only be called after a
+ * configured device has reset, so all control transfers should have
+ * been completed or cancelled before the reset.
+ */
+ ep0_ctx->deq = xhci_trb_virt_to_dma(ep_ring->enq_seg, ep_ring->enqueue);
+ ep0_ctx->deq |= ep_ring->cycle_state;
+}
+
/* Setup an xHCI virtual device for a Set Address command */
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev)
{
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 94e6934edb09..bfc99a939455 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2380,16 +2380,19 @@ static int queue_command(struct xhci_hcd *xhci, u32 field1, u32 field2,
u32 field3, u32 field4, bool command_must_succeed)
{
int reserved_trbs = xhci->cmd_ring_reserved_trbs;
+ int ret;
+
if (!command_must_succeed)
reserved_trbs++;
- if (!room_on_ring(xhci, xhci->cmd_ring, reserved_trbs)) {
- if (!in_interrupt())
- xhci_err(xhci, "ERR: No room for command on command ring\n");
+ ret = prepare_ring(xhci, xhci->cmd_ring, EP_STATE_RUNNING,
+ reserved_trbs, GFP_ATOMIC);
+ if (ret < 0) {
+ xhci_err(xhci, "ERR: No room for command on command ring\n");
if (command_must_succeed)
xhci_err(xhci, "ERR: Reserved TRB counting for "
"unfailable commands failed.\n");
- return -ENOMEM;
+ return ret;
}
queue_trb(xhci, xhci->cmd_ring, false, false, field1, field2, field3,
field4 | xhci->cmd_ring->cycle_state);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 27345cd04da0..3998f72cd0c4 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -2134,6 +2134,8 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
/* If this is a Set Address to an unconfigured device, setup ep 0 */
if (!udev->config)
xhci_setup_addressable_virt_dev(xhci, udev);
+ else
+ xhci_copy_ep0_dequeue_into_input_ctx(xhci, udev);
/* Otherwise, assume the core has the device configured how it wants */
xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 8b4b7d39f79c..6c7e3430ec93 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1292,6 +1292,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags);
void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id);
int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id, struct usb_device *udev, gfp_t flags);
int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *udev);
+void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
+ struct usb_device *udev);
unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index da7e334b0407..1d2a27b3ebb3 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -737,6 +737,14 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(FTDI_VID, MJSG_SR_RADIO_PID) },
{ USB_DEVICE(FTDI_VID, MJSG_HD_RADIO_PID) },
{ USB_DEVICE(FTDI_VID, MJSG_XM_RADIO_PID) },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_ST_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SLITE_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH2_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ { USB_DEVICE(FTDI_VID, XVERVE_SIGNALYZER_SH4_PID),
+ .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
{ }, /* Optional parameter entry */
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index bbc159a1df45..9c5d9cb25de1 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -1017,3 +1017,12 @@
#define MJSG_SR_RADIO_PID 0x9379
#define MJSG_XM_RADIO_PID 0x937A
#define MJSG_HD_RADIO_PID 0x937C
+
+/*
+ * Xverve Signalyzer tools (http://www.signalyzer.com/)
+ */
+#define XVERVE_SIGNALYZER_ST_PID 0xBCA0
+#define XVERVE_SIGNALYZER_SLITE_PID 0xBCA1
+#define XVERVE_SIGNALYZER_SH2_PID 0xBCA2
+#define XVERVE_SIGNALYZER_SH4_PID 0xBCA4
+
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index e280ad8e12f7..5cd30e4345c6 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -206,6 +206,7 @@ static void option_instat_callback(struct urb *urb);
#define AMOI_PRODUCT_H01 0x0800
#define AMOI_PRODUCT_H01A 0x7002
#define AMOI_PRODUCT_H02 0x0802
+#define AMOI_PRODUCT_SKYPEPHONE_S2 0x0407
#define DELL_VENDOR_ID 0x413C
@@ -302,6 +303,7 @@ static void option_instat_callback(struct urb *urb);
#define QISDA_PRODUCT_H21_4512 0x4512
#define QISDA_PRODUCT_H21_4523 0x4523
#define QISDA_PRODUCT_H20_4515 0x4515
+#define QISDA_PRODUCT_H20_4518 0x4518
#define QISDA_PRODUCT_H20_4519 0x4519
/* TLAYTECH PRODUCTS */
@@ -516,6 +518,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) },
+ { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_SKYPEPHONE_S2) },
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
@@ -852,6 +855,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4523) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4515) },
+ { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4518) },
{ USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H20_4519) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_G450) },
{ USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_HSDPA_MINICARD ) }, /* Toshiba 3G HSDPA == Novatel Expedite EU870D MiniCard */
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index 93d72eb8cafc..cde67cacb2c3 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -51,6 +51,8 @@ static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x1f45, 0x0001)}, /* Unknown Gobi QDL device */
{USB_DEVICE(0x413c, 0x8185)}, /* Dell Gobi 2000 QDL device (N0218, VU936) */
{USB_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */
+ {USB_DEVICE(0x05c6, 0x9208)}, /* Generic Gobi 2000 QDL device */
+ {USB_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */
{USB_DEVICE(0x05c6, 0x9224)}, /* Sony Gobi 2000 QDL device (N0279, VU730) */
{USB_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */
{USB_DEVICE(0x05c6, 0x9244)}, /* Samsung Gobi 2000 QDL device (VL176) */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ef0bdb08d788..d47b56e9e8ce 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -245,6 +245,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */
{ USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
{ USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */
+ { USB_DEVICE(0x1199, 0x0301) }, /* Sierra Wireless USB Dongle 250U */
/* Sierra Wireless C597 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0023, 0xFF, 0xFF, 0xFF) },
/* Sierra Wireless T598 */
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 3d94a1471724..a9f9e5eaa040 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1895,6 +1895,13 @@ config FB_W100
If unsure, say N.
+config SH_MIPI_DSI
+ tristate
+ depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+
+config SH_LCD_MIPI_DSI
+ bool
+
config FB_SH_MOBILE_LCDC
tristate "SuperH Mobile LCDC framebuffer support"
depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
@@ -1903,6 +1910,7 @@ config FB_SH_MOBILE_LCDC
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
select FB_DEFERRED_IO
+ select SH_MIPI_DSI if SH_LCD_MIPI_DSI
---help---
Frame buffer driver for the on-chip SH-Mobile LCD controller.
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ddc2af2ba45b..3c3bf867ef18 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -123,6 +123,7 @@ obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
obj-$(CONFIG_FB_PS3) += ps3fb.o
obj-$(CONFIG_FB_SM501) += sm501fb.o
obj-$(CONFIG_FB_XILINX) += xilinxfb.o
+obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
obj-$(CONFIG_FB_OMAP) += omap/
obj-y += omap2/
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
index 8e8f18d29d7a..5a35f22372b9 100644
--- a/drivers/video/console/Kconfig
+++ b/drivers/video/console/Kconfig
@@ -6,7 +6,7 @@ menu "Console display driver support"
config VGA_CONSOLE
bool "VGA text console" if EMBEDDED || !X86
- depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !ARCH_VERSATILE && !SUPERH && !BLACKFIN && !AVR32 && !MN10300
+ depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && !SUPERH && !BLACKFIN && !AVR32 && !MN10300 && (!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER)
default y
help
Saying Y here will allow you to use Linux in text mode through a
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/matrox/i2c-matroxfb.c
index 403b14445a78..0fb280ead3dc 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/matrox/i2c-matroxfb.c
@@ -191,7 +191,7 @@ static void* i2c_matroxfb_probe(struct matrox_fb_info* minfo) {
};
i2c_new_probed_device(&m2info->maven.adapter,
- &maven_info, addr_list);
+ &maven_info, addr_list, NULL);
}
}
return m2info;
diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c
index c1ff271017a9..844eff3ca8e6 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/msm/mddi.c
@@ -187,10 +187,8 @@ static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
{
- union mddi_rev *rev = mddi->rev_data;
uint32_t rev_data_count;
uint32_t rev_crc_err_count;
- int i;
struct reg_read_info *ri;
size_t prev_offset;
uint16_t length;
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 19c01c6208e8..3c28db03ad39 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -258,7 +258,6 @@ int get_img(struct mdp_img *img, struct fb_info *info,
{
int put_needed, ret = 0;
struct file *file;
- unsigned long vstart;
file = fget_light(img->memory_id, &put_needed);
if (file == NULL)
diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
index 2be94eb3bbf5..10459d8bd9a0 100644
--- a/drivers/video/omap/lcd_apollon.c
+++ b/drivers/video/omap/lcd_apollon.c
@@ -25,7 +25,6 @@
#include <linux/platform_device.h>
#include <mach/gpio.h>
-#include <plat/mux.h>
#include "omapfb.h"
@@ -34,8 +33,6 @@
static int apollon_panel_init(struct lcd_panel *panel,
struct omapfb_device *fbdev)
{
- /* configure LCD PWR_EN */
- omap_cfg_reg(M21_242X_GPIO11);
return 0;
}
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c
index 3b1237ad85ed..fe86194da1a9 100644
--- a/drivers/video/omap2/vram.c
+++ b/drivers/video/omap2/vram.c
@@ -25,7 +25,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
-#include <linux/bootmem.h>
+#include <linux/lmb.h>
#include <linux/completion.h>
#include <linux/debugfs.h>
#include <linux/jiffies.h>
@@ -525,10 +525,8 @@ early_param("vram", omap_vram_early_vram);
* Called from map_io. We need to call to this early enough so that we
* can reserve the fixed SDRAM regions before VM could get hold of them.
*/
-void __init omap_vram_reserve_sdram(void)
+void __init omap_vram_reserve_sdram_lmb(void)
{
- struct bootmem_data *bdata;
- unsigned long sdram_start, sdram_size;
u32 paddr;
u32 size = 0;
@@ -555,29 +553,28 @@ void __init omap_vram_reserve_sdram(void)
size = PAGE_ALIGN(size);
- bdata = NODE_DATA(0)->bdata;
- sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
- sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
-
if (paddr) {
- if ((paddr & ~PAGE_MASK) || paddr < sdram_start ||
- paddr + size > sdram_start + sdram_size) {
+ struct lmb_property res;
+
+ res.base = paddr;
+ res.size = size;
+ if ((paddr & ~PAGE_MASK) || lmb_find(&res) ||
+ res.base != paddr || res.size != size) {
pr_err("Illegal SDRAM region for VRAM\n");
return;
}
- if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) {
- pr_err("FB: failed to reserve VRAM\n");
+ if (lmb_is_region_reserved(paddr, size)) {
+ pr_err("FB: failed to reserve VRAM - busy\n");
return;
}
- } else {
- if (size > sdram_size) {
- pr_err("Illegal SDRAM size for VRAM\n");
+
+ if (lmb_reserve(paddr, size) < 0) {
+ pr_err("FB: failed to reserve VRAM - no memory\n");
return;
}
-
- paddr = virt_to_phys(alloc_bootmem_pages(size));
- BUG_ON(paddr & ~PAGE_MASK);
+ } else {
+ paddr = lmb_alloc_base(size, PAGE_SIZE, LMB_REAL_LIMIT);
}
omap_vram_add_region(paddr, size);
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
new file mode 100644
index 000000000000..017ae9f47d36
--- /dev/null
+++ b/drivers/video/sh_mipi_dsi.c
@@ -0,0 +1,505 @@
+/*
+ * Renesas SH-mobile MIPI DSI support
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <video/mipi_display.h>
+#include <video/sh_mipi_dsi.h>
+#include <video/sh_mobile_lcdc.h>
+
+#define CMTSRTCTR 0x80d0
+#define CMTSRTREQ 0x8070
+
+#define DSIINTE 0x0060
+
+/* E.g., sh7372 has 2 MIPI-DSIs - one for each LCDC */
+#define MAX_SH_MIPI_DSI 2
+
+struct sh_mipi {
+ void __iomem *base;
+ struct clk *dsit_clk;
+ struct clk *dsip_clk;
+};
+
+static struct sh_mipi *mipi_dsi[MAX_SH_MIPI_DSI];
+
+/* Protect the above array */
+static DEFINE_MUTEX(array_lock);
+
+static struct sh_mipi *sh_mipi_by_handle(int handle)
+{
+ if (handle >= ARRAY_SIZE(mipi_dsi) || handle < 0)
+ return NULL;
+
+ return mipi_dsi[handle];
+}
+
+static int sh_mipi_send_short(struct sh_mipi *mipi, u8 dsi_cmd,
+ u8 cmd, u8 param)
+{
+ u32 data = (dsi_cmd << 24) | (cmd << 16) | (param << 8);
+ int cnt = 100;
+
+ /* transmit a short packet to LCD panel */
+ iowrite32(1 | data, mipi->base + 0x80d0); /* CMTSRTCTR */
+ iowrite32(1, mipi->base + 0x8070); /* CMTSRTREQ */
+
+ while ((ioread32(mipi->base + 0x8070) & 1) && --cnt)
+ udelay(1);
+
+ return cnt ? 0 : -ETIMEDOUT;
+}
+
+#define LCD_CHAN2MIPI(c) ((c) < LCDC_CHAN_MAINLCD || (c) > LCDC_CHAN_SUBLCD ? \
+ -EINVAL : (c) - 1)
+
+static int sh_mipi_dcs(int handle, u8 cmd)
+{
+ struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
+ if (!mipi)
+ return -ENODEV;
+ return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE, cmd, 0);
+}
+
+static int sh_mipi_dcs_param(int handle, u8 cmd, u8 param)
+{
+ struct sh_mipi *mipi = sh_mipi_by_handle(LCD_CHAN2MIPI(handle));
+ if (!mipi)
+ return -ENODEV;
+ return sh_mipi_send_short(mipi, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd,
+ param);
+}
+
+static void sh_mipi_dsi_enable(struct sh_mipi *mipi, bool enable)
+{
+ /*
+ * enable LCDC data tx, transition to LPS after completion of each HS
+ * packet
+ */
+ iowrite32(0x00000002 | enable, mipi->base + 0x8000); /* DTCTR */
+}
+
+static void sh_mipi_shutdown(struct platform_device *pdev)
+{
+ struct sh_mipi *mipi = platform_get_drvdata(pdev);
+
+ sh_mipi_dsi_enable(mipi, false);
+}
+
+static void mipi_display_on(void *arg)
+{
+ struct sh_mipi *mipi = arg;
+
+ sh_mipi_dsi_enable(mipi, true);
+}
+
+static void mipi_display_off(void *arg)
+{
+ struct sh_mipi *mipi = arg;
+
+ sh_mipi_dsi_enable(mipi, false);
+}
+
+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;
+ u32 linelength;
+ bool yuv;
+
+ /* Select data format */
+ switch (pdata->data_format) {
+ case MIPI_RGB888:
+ pctype = 0;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+ pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
+ linelength = ch->lcd_cfg.xres * 3;
+ yuv = false;
+ break;
+ case MIPI_RGB565:
+ pctype = 1;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+ pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
+ linelength = ch->lcd_cfg.xres * 2;
+ yuv = false;
+ break;
+ case MIPI_RGB666_LP:
+ pctype = 2;
+ datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+ pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
+ linelength = ch->lcd_cfg.xres * 3;
+ yuv = false;
+ break;
+ case MIPI_RGB666:
+ pctype = 3;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+ pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
+ linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+ yuv = false;
+ break;
+ case MIPI_BGR888:
+ pctype = 8;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+ pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
+ linelength = ch->lcd_cfg.xres * 3;
+ yuv = false;
+ break;
+ case MIPI_BGR565:
+ pctype = 9;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+ pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
+ linelength = ch->lcd_cfg.xres * 2;
+ yuv = false;
+ break;
+ case MIPI_BGR666_LP:
+ pctype = 0xa;
+ datatype = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+ pixfmt = MIPI_DCS_PIXEL_FMT_24BIT;
+ linelength = ch->lcd_cfg.xres * 3;
+ yuv = false;
+ break;
+ case MIPI_BGR666:
+ pctype = 0xb;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+ pixfmt = MIPI_DCS_PIXEL_FMT_18BIT;
+ linelength = (ch->lcd_cfg.xres * 18 + 7) / 8;
+ yuv = false;
+ break;
+ case MIPI_YUYV:
+ pctype = 4;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
+ pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
+ linelength = ch->lcd_cfg.xres * 2;
+ yuv = true;
+ break;
+ case MIPI_UYVY:
+ pctype = 5;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16;
+ pixfmt = MIPI_DCS_PIXEL_FMT_16BIT;
+ linelength = ch->lcd_cfg.xres * 2;
+ yuv = true;
+ break;
+ case MIPI_YUV420_L:
+ pctype = 6;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
+ pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
+ linelength = (ch->lcd_cfg.xres * 12 + 7) / 8;
+ yuv = true;
+ break;
+ case MIPI_YUV420:
+ pctype = 7;
+ datatype = MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12;
+ pixfmt = MIPI_DCS_PIXEL_FMT_12BIT;
+ /* Length of U/V line */
+ linelength = (ch->lcd_cfg.xres + 1) / 2;
+ yuv = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if ((yuv && ch->interface_type != YUV422) ||
+ (!yuv && ch->interface_type != RGB24))
+ return -EINVAL;
+
+ /* reset DSI link */
+ iowrite32(0x00000001, base); /* SYSCTRL */
+ /* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
+ udelay(50);
+ iowrite32(0x00000000, base); /* SYSCTRL */
+
+ /* 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 + 0x04); /* SYSCONF */
+ /*
+ * T_wakeup = 0x7000
+ * T_hs-trail = 3
+ * T_hs-prepare = 3
+ * T_clk-trail = 3
+ * T_clk-prepare = 2
+ */
+ iowrite32(0x70003332, base + 0x08); /* TIMSET */
+ /* no responses requested */
+ iowrite32(0x00000000, base + 0x18); /* RESREQSET0 */
+ /* request response to packets of type 0x28 */
+ iowrite32(0x00000100, base + 0x1c); /* RESREQSET1 */
+ /* High-speed transmission timeout, default 0xffffffff */
+ iowrite32(0x0fffffff, base + 0x20); /* HSTTOVSET */
+ /* LP reception timeout, default 0xffffffff */
+ iowrite32(0x0fffffff, base + 0x24); /* LPRTOVSET */
+ /* Turn-around timeout, default 0xffffffff */
+ iowrite32(0x0fffffff, base + 0x28); /* TATOVSET */
+ /* Peripheral reset timeout, default 0xffffffff */
+ iowrite32(0x0fffffff, base + 0x2c); /* PRTOVSET */
+ /* Enable timeout counters */
+ iowrite32(0x00000f00, base + 0x30); /* DSICTRL */
+ /* Interrupts not used, disable all */
+ iowrite32(0, base + DSIINTE);
+ /* DSI-Tx bias on */
+ iowrite32(0x00000001, base + 0x70); /* PHYCTRL */
+ udelay(200);
+ /* Deassert resets, power on, set multiplier */
+ iowrite32(0x03070b01, base + 0x70); /* PHYCTRL */
+
+ /* setup l-bridge */
+
+ /*
+ * Enable transmission of all packets,
+ * transmit LPS after each HS packet completion
+ */
+ iowrite32(0x00000006, base + 0x8000); /* DTCTR */
+ /* VSYNC width = 2 (<< 17) */
+ iowrite32(0x00040000 | (pctype << 12) | datatype, base + 0x8020); /* VMCTR1 */
+ /*
+ * Non-burst mode with sync pulses: VSE and HSE are output,
+ * HSA period allowed, no commands in LP
+ */
+ iowrite32(0x00e00000, base + 0x8024); /* VMCTR2 */
+ /*
+ * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
+ * sh_mobile_lcdc_info.ch[0].lcd_cfg.xres), HSALEN = 1 - default
+ * (unused, since VMCTR2[HSABM] = 0)
+ */
+ iowrite32(1 | (linelength << 16), base + 0x8028); /* VMLEN1 */
+
+ msleep(5);
+
+ /* setup LCD panel */
+
+ /* cf. drivers/video/omap/lcd_mipid.c */
+ sh_mipi_dcs(ch->chan, MIPI_DCS_EXIT_SLEEP_MODE);
+ msleep(120);
+ /*
+ * [7] - Page Address Mode
+ * [6] - Column Address Mode
+ * [5] - Page / Column Address Mode
+ * [4] - Display Device Line Refresh Order
+ * [3] - RGB/BGR Order
+ * [2] - Display Data Latch Data Order
+ * [1] - Flip Horizontal
+ * [0] - Flip Vertical
+ */
+ sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_ADDRESS_MODE, 0x00);
+ /* cf. set_data_lines() */
+ sh_mipi_dcs_param(ch->chan, MIPI_DCS_SET_PIXEL_FORMAT,
+ pixfmt << 4);
+ sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
+
+ return 0;
+}
+
+static int __init sh_mipi_probe(struct platform_device *pdev)
+{
+ struct sh_mipi *mipi;
+ struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ unsigned long rate, f_current;
+ int idx = pdev->id, ret;
+ char dsip_clk[] = "dsi.p_clk";
+
+ if (!res || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
+ return -ENODEV;
+
+ mutex_lock(&array_lock);
+ if (idx < 0)
+ for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
+ ;
+
+ if (idx == ARRAY_SIZE(mipi_dsi)) {
+ ret = -EBUSY;
+ goto efindslot;
+ }
+
+ mipi = kzalloc(sizeof(*mipi), GFP_KERNEL);
+ if (!mipi) {
+ ret = -ENOMEM;
+ goto ealloc;
+ }
+
+ if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+ dev_err(&pdev->dev, "MIPI register region already claimed\n");
+ ret = -EBUSY;
+ goto ereqreg;
+ }
+
+ mipi->base = ioremap(res->start, resource_size(res));
+ if (!mipi->base) {
+ ret = -ENOMEM;
+ goto emap;
+ }
+
+ mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
+ if (IS_ERR(mipi->dsit_clk)) {
+ ret = PTR_ERR(mipi->dsit_clk);
+ goto eclktget;
+ }
+
+ f_current = clk_get_rate(mipi->dsit_clk);
+ /* 80MHz required by the datasheet */
+ rate = clk_round_rate(mipi->dsit_clk, 80000000);
+ if (rate > 0 && rate != f_current)
+ ret = clk_set_rate(mipi->dsit_clk, rate);
+ else
+ ret = rate;
+ if (ret < 0)
+ goto esettrate;
+
+ 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;
+
+ ret = sh_mipi_setup(mipi, pdata);
+ if (ret < 0)
+ goto emipisetup;
+
+ mutex_unlock(&array_lock);
+ platform_set_drvdata(pdev, mipi);
+
+ /* Set up LCDC callbacks */
+ pdata->lcd_chan->board_cfg.board_data = mipi;
+ pdata->lcd_chan->board_cfg.display_on = mipi_display_on;
+ pdata->lcd_chan->board_cfg.display_off = mipi_display_off;
+
+ return 0;
+
+emipisetup:
+ mipi_dsi[idx] = NULL;
+ 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:
+ iounmap(mipi->base);
+emap:
+ release_mem_region(res->start, resource_size(res));
+ereqreg:
+ kfree(mipi);
+ealloc:
+efindslot:
+ mutex_unlock(&array_lock);
+
+ return ret;
+}
+
+static int __exit sh_mipi_remove(struct platform_device *pdev)
+{
+ struct sh_mipi_dsi_info *pdata = pdev->dev.platform_data;
+ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ struct sh_mipi *mipi = platform_get_drvdata(pdev);
+ int i, ret;
+
+ mutex_lock(&array_lock);
+
+ for (i = 0; i < ARRAY_SIZE(mipi_dsi) && mipi_dsi[i] != mipi; i++)
+ ;
+
+ if (i == ARRAY_SIZE(mipi_dsi)) {
+ ret = -EINVAL;
+ } else {
+ ret = 0;
+ mipi_dsi[i] = NULL;
+ }
+
+ mutex_unlock(&array_lock);
+
+ if (ret < 0)
+ return ret;
+
+ pdata->lcd_chan->board_cfg.display_on = NULL;
+ pdata->lcd_chan->board_cfg.display_off = NULL;
+ pdata->lcd_chan->board_cfg.board_data = NULL;
+
+ clk_disable(mipi->dsip_clk);
+ clk_disable(mipi->dsit_clk);
+ clk_put(mipi->dsit_clk);
+ clk_put(mipi->dsip_clk);
+ iounmap(mipi->base);
+ if (res)
+ release_mem_region(res->start, resource_size(res));
+ platform_set_drvdata(pdev, NULL);
+ kfree(mipi);
+
+ return 0;
+}
+
+static struct platform_driver sh_mipi_driver = {
+ .remove = __exit_p(sh_mipi_remove),
+ .shutdown = sh_mipi_shutdown,
+ .driver = {
+ .name = "sh-mipi-dsi",
+ },
+};
+
+static int __init sh_mipi_init(void)
+{
+ return platform_driver_probe(&sh_mipi_driver, sh_mipi_probe);
+}
+module_init(sh_mipi_init);
+
+static void __exit sh_mipi_exit(void)
+{
+ platform_driver_unregister(&sh_mipi_driver);
+}
+module_exit(sh_mipi_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
+MODULE_DESCRIPTION("SuperH / ARM-shmobile MIPI DSI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 980548390048..3ee5e63cfa4f 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1571,8 +1571,8 @@ out_err_iobase:
if (default_par->mtrr_handle >= 0)
mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
info->fix.smem_len);
- release_mem_region(pci_resource_start(pdev, 2),
- pci_resource_len(pdev, 2));
+ release_region(pci_resource_start(pdev, 2),
+ pci_resource_len(pdev, 2));
out_err_screenbase:
if (info->screen_base)
iounmap(info->screen_base);
diff --git a/drivers/zorro/proc.c b/drivers/zorro/proc.c
index 3c7046d79654..cafc50454292 100644
--- a/drivers/zorro/proc.c
+++ b/drivers/zorro/proc.c
@@ -22,8 +22,9 @@ static loff_t
proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
{
loff_t new = -1;
+ struct inode *inode = file->f_path.dentry->d_inode;
- lock_kernel();
+ mutex_lock(&inode->i_mutex);
switch (whence) {
case 0:
new = off;
@@ -35,12 +36,12 @@ proc_bus_zorro_lseek(struct file *file, loff_t off, int whence)
new = sizeof(struct ConfigDev) + off;
break;
}
- if (new < 0 || new > sizeof(struct ConfigDev)) {
- unlock_kernel();
- return -EINVAL;
- }
- unlock_kernel();
- return (file->f_pos = new);
+ if (new < 0 || new > sizeof(struct ConfigDev))
+ new = -EINVAL;
+ else
+ file->f_pos = new;
+ mutex_unlock(&inode->i_mutex);
+ return new;
}
static ssize_t
@@ -67,7 +68,7 @@ proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *
cd.cd_BoardAddr = (void *)zorro_resource_start(z);
cd.cd_BoardSize = zorro_resource_len(z);
- if (copy_to_user(buf, &cd, nbytes))
+ if (copy_to_user(buf, (void *)&cd + pos, nbytes))
return -EFAULT;
*ppos += nbytes;
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 7317b39b2815..5d6cfcbf73e7 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -152,7 +152,8 @@ struct p9_fid *v9fs_fid_lookup(struct dentry *dentry)
if (access == V9FS_ACCESS_SINGLE)
return ERR_PTR(-EPERM);
- if (v9fs_proto_dotu(v9ses))
+ if (v9fs_proto_dotu(v9ses) ||
+ v9fs_proto_dotl(v9ses))
uname = NULL;
else
uname = v9ses->uname;
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index f8b86e92cd66..3c492011221c 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -278,7 +278,7 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
v9ses->maxdata = v9ses->clnt->msize - P9_IOHDRSZ;
/* for legacy mode, fall back to V9FS_ACCESS_ANY */
- if (!v9fs_proto_dotu(v9ses) &&
+ if (!(v9fs_proto_dotu(v9ses) || v9fs_proto_dotl(v9ses)) &&
((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
v9ses->flags &= ~V9FS_ACCESS_MASK;
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index 32ef4009d030..88418c419ea7 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -52,9 +52,10 @@ void v9fs_destroy_inode(struct inode *inode);
#endif
struct inode *v9fs_get_inode(struct super_block *sb, int mode);
-void v9fs_clear_inode(struct inode *inode);
+void v9fs_evict_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
+void v9fs_stat2inode_dotl(struct p9_stat_dotl *, struct inode *);
int v9fs_dir_release(struct inode *inode, struct file *filp);
int v9fs_file_open(struct inode *inode, struct file *file);
void v9fs_inode2stat(struct inode *inode, struct p9_wstat *stat);
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index d61e3b28ce37..aa1852d7c98e 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -87,29 +87,19 @@ static void p9stat_init(struct p9_wstat *stbuf)
}
/**
- * v9fs_dir_readdir - read a directory
+ * v9fs_alloc_rdir_buf - Allocate buffer used for read and readdir
* @filp: opened file structure
- * @dirent: directory structure ???
- * @filldir: function to populate directory structure ???
+ * @buflen: Length in bytes of buffer to allocate
*
*/
-static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int v9fs_alloc_rdir_buf(struct file *filp, int buflen)
{
- int over;
- struct p9_wstat st;
- int err = 0;
- struct p9_fid *fid;
- int buflen;
- int reclen = 0;
struct p9_rdir *rdir;
+ struct p9_fid *fid;
+ int err = 0;
- P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
fid = filp->private_data;
-
- buflen = fid->clnt->msize - P9_IOHDRSZ;
-
- /* allocate rdir on demand */
if (!fid->rdir) {
rdir = kmalloc(sizeof(struct p9_rdir) + buflen, GFP_KERNEL);
@@ -128,6 +118,36 @@ static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
spin_unlock(&filp->f_dentry->d_lock);
kfree(rdir);
}
+exit:
+ return err;
+}
+
+/**
+ * v9fs_dir_readdir - read a directory
+ * @filp: opened file structure
+ * @dirent: directory structure ???
+ * @filldir: function to populate directory structure ???
+ *
+ */
+
+static int v9fs_dir_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ int over;
+ struct p9_wstat st;
+ int err = 0;
+ struct p9_fid *fid;
+ int buflen;
+ int reclen = 0;
+ struct p9_rdir *rdir;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
+ fid = filp->private_data;
+
+ buflen = fid->clnt->msize - P9_IOHDRSZ;
+
+ err = v9fs_alloc_rdir_buf(filp, buflen);
+ if (err)
+ goto exit;
rdir = (struct p9_rdir *) fid->rdir;
err = mutex_lock_interruptible(&rdir->mutex);
@@ -176,6 +196,88 @@ exit:
return err;
}
+/**
+ * v9fs_dir_readdir_dotl - read a directory
+ * @filp: opened file structure
+ * @dirent: buffer to fill dirent structures
+ * @filldir: function to populate dirent structures
+ *
+ */
+static int v9fs_dir_readdir_dotl(struct file *filp, void *dirent,
+ filldir_t filldir)
+{
+ int over;
+ int err = 0;
+ struct p9_fid *fid;
+ int buflen;
+ struct p9_rdir *rdir;
+ struct p9_dirent curdirent;
+ u64 oldoffset = 0;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "name %s\n", filp->f_path.dentry->d_name.name);
+ fid = filp->private_data;
+
+ buflen = fid->clnt->msize - P9_READDIRHDRSZ;
+
+ err = v9fs_alloc_rdir_buf(filp, buflen);
+ if (err)
+ goto exit;
+ rdir = (struct p9_rdir *) fid->rdir;
+
+ err = mutex_lock_interruptible(&rdir->mutex);
+ if (err)
+ return err;
+
+ while (err == 0) {
+ if (rdir->tail == rdir->head) {
+ err = p9_client_readdir(fid, rdir->buf, buflen,
+ filp->f_pos);
+ if (err <= 0)
+ goto unlock_and_exit;
+
+ rdir->head = 0;
+ rdir->tail = err;
+ }
+
+ while (rdir->head < rdir->tail) {
+
+ err = p9dirent_read(rdir->buf + rdir->head,
+ buflen - rdir->head, &curdirent,
+ fid->clnt->proto_version);
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS, "returned %d\n", err);
+ err = -EIO;
+ goto unlock_and_exit;
+ }
+
+ /* d_off in dirent structure tracks the offset into
+ * the next dirent in the dir. However, filldir()
+ * expects offset into the current dirent. Hence
+ * while calling filldir send the offset from the
+ * previous dirent structure.
+ */
+ over = filldir(dirent, curdirent.d_name,
+ strlen(curdirent.d_name),
+ oldoffset, v9fs_qid2ino(&curdirent.qid),
+ curdirent.d_type);
+ oldoffset = curdirent.d_off;
+
+ if (over) {
+ err = 0;
+ goto unlock_and_exit;
+ }
+
+ filp->f_pos = curdirent.d_off;
+ rdir->head += err;
+ }
+ }
+
+unlock_and_exit:
+ mutex_unlock(&rdir->mutex);
+exit:
+ return err;
+}
+
/**
* v9fs_dir_release - close a directory
@@ -207,7 +309,7 @@ const struct file_operations v9fs_dir_operations = {
const struct file_operations v9fs_dir_operations_dotl = {
.read = generic_read_dir,
.llseek = generic_file_llseek,
- .readdir = v9fs_dir_readdir,
+ .readdir = v9fs_dir_readdir_dotl,
.open = v9fs_file_open,
.release = v9fs_dir_release,
};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 2bedc6c94fc2..2d686ec322a0 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -139,7 +139,7 @@ ssize_t
v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
u64 offset)
{
- int n, total;
+ int n, total, size;
struct p9_fid *fid = filp->private_data;
P9_DPRINTK(P9_DEBUG_VFS, "fid %d offset %llu count %d\n", fid->fid,
@@ -147,6 +147,7 @@ v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
n = 0;
total = 0;
+ size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
do {
n = p9_client_read(fid, data, udata, offset, count);
if (n <= 0)
@@ -160,7 +161,7 @@ v9fs_file_readn(struct file *filp, char *data, char __user *udata, u32 count,
offset += n;
count -= n;
total += n;
- } while (count > 0 && n == (fid->clnt->msize - P9_IOHDRSZ));
+ } while (count > 0 && n == size);
if (n < 0)
total = n;
@@ -183,11 +184,13 @@ v9fs_file_read(struct file *filp, char __user *udata, size_t count,
{
int ret;
struct p9_fid *fid;
+ size_t size;
P9_DPRINTK(P9_DEBUG_VFS, "count %zu offset %lld\n", count, *offset);
fid = filp->private_data;
- if (count > (fid->clnt->msize - P9_IOHDRSZ))
+ size = fid->iounit ? fid->iounit : fid->clnt->msize - P9_IOHDRSZ;
+ if (count > size)
ret = v9fs_file_readn(filp, NULL, udata, count, *offset);
else
ret = p9_client_read(fid, NULL, udata, *offset, count);
@@ -224,9 +227,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
fid = filp->private_data;
clnt = fid->clnt;
- rsize = fid->iounit;
- if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
- rsize = clnt->msize - P9_IOHDRSZ;
+ rsize = fid->iounit ? fid->iounit : clnt->msize - P9_IOHDRSZ;
do {
if (count < rsize)
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 4331b3b5ee1c..72463fac48b0 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -236,6 +236,23 @@ void v9fs_destroy_inode(struct inode *inode)
#endif
/**
+ * v9fs_get_fsgid_for_create - Helper function to get the gid for creating a
+ * new file system object. This checks the S_ISGID to determine the owning
+ * group of the new file system object.
+ */
+
+static gid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
+{
+ BUG_ON(dir_inode == NULL);
+
+ if (dir_inode->i_mode & S_ISGID) {
+ /* set_gid bit is set.*/
+ return dir_inode->i_gid;
+ }
+ return current_fsgid();
+}
+
+/**
* v9fs_get_inode - helper function to setup an inode
* @sb: superblock
* @mode: mode to setup inode with
@@ -387,8 +404,10 @@ error:
* @inode: inode to release
*
*/
-void v9fs_clear_inode(struct inode *inode)
+void v9fs_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(inode->i_mapping, 0);
+ end_writeback(inode);
filemap_fdatawrite(inode->i_mapping);
#ifdef CONFIG_9P_FSCACHE
@@ -396,23 +415,14 @@ void v9fs_clear_inode(struct inode *inode)
#endif
}
-/**
- * v9fs_inode_from_fid - populate an inode by issuing a attribute request
- * @v9ses: session information
- * @fid: fid to issue attribute request for
- * @sb: superblock on which to create inode
- *
- */
-
static struct inode *
-v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
int err, umode;
- struct inode *ret;
+ struct inode *ret = NULL;
struct p9_wstat *st;
- ret = NULL;
st = p9_client_stat(fid);
if (IS_ERR(st))
return ERR_CAST(st);
@@ -433,15 +443,62 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
#endif
p9stat_free(st);
kfree(st);
-
return ret;
-
error:
p9stat_free(st);
kfree(st);
return ERR_PTR(err);
}
+static struct inode *
+v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ struct super_block *sb)
+{
+ struct inode *ret = NULL;
+ int err;
+ struct p9_stat_dotl *st;
+
+ st = p9_client_getattr_dotl(fid);
+ if (IS_ERR(st))
+ return ERR_CAST(st);
+
+ ret = v9fs_get_inode(sb, st->st_mode);
+ if (IS_ERR(ret)) {
+ err = PTR_ERR(ret);
+ goto error;
+ }
+
+ v9fs_stat2inode_dotl(st, ret);
+ ret->i_ino = v9fs_qid2ino(&st->qid);
+#ifdef CONFIG_9P_FSCACHE
+ v9fs_vcookie_set_qid(ret, &st->qid);
+ v9fs_cache_inode_get_cookie(ret);
+#endif
+ kfree(st);
+ return ret;
+error:
+ kfree(st);
+ return ERR_PTR(err);
+}
+
+/**
+ * v9fs_inode_from_fid - Helper routine to populate an inode by
+ * issuing a attribute request
+ * @v9ses: session information
+ * @fid: fid to issue attribute request for
+ * @sb: superblock on which to create inode
+ *
+ */
+static inline struct inode *
+v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
+ struct super_block *sb)
+{
+ if (v9fs_proto_dotl(v9ses))
+ return v9fs_inode_dotl(v9ses, fid, sb);
+ else
+ return v9fs_inode(v9ses, fid, sb);
+}
+
/**
* v9fs_remove - helper function to remove files and directories
* @dir: directory inode that is being deleted
@@ -532,6 +589,23 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
goto error;
}
+ /* Server grabs uid information from the fid but we need to fix
+ * gid as dotu doesn't support sending gid on the wire with Tcreate.
+ * hardlink is an exception as it inherits all credentials.
+ */
+ if (v9fs_proto_dotu(v9ses) && !(perm & P9_DMLINK)) {
+ struct p9_wstat wstat;
+
+ v9fs_blank_wstat(&wstat);
+ wstat.n_gid = v9fs_get_fsgid_for_create(dir);
+ err = p9_client_wstat(fid, &wstat);
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS, "p9_client_wstat failed %d\n",
+ err);
+ goto error;
+ }
+ }
+
/* instantiate inode and assign the unopened fid to the dentry */
inode = v9fs_inode_from_fid(v9ses, fid, dir->i_sb);
if (IS_ERR(inode)) {
@@ -853,6 +927,38 @@ v9fs_vfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
return 0;
}
+static int
+v9fs_vfs_getattr_dotl(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ int err;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid;
+ struct p9_stat_dotl *st;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "dentry: %p\n", dentry);
+ err = -EPERM;
+ v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE)
+ return simple_getattr(mnt, dentry, stat);
+
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ st = p9_client_getattr_dotl(fid);
+ if (IS_ERR(st))
+ return PTR_ERR(st);
+
+ v9fs_stat2inode_dotl(st, dentry->d_inode);
+ generic_fillattr(dentry->d_inode, stat);
+ /* Change block size to what the server returned */
+ stat->blksize = st->st_blksize;
+
+ kfree(st);
+ return 0;
+}
+
/**
* v9fs_vfs_setattr - set file metadata
* @dentry: file whose metadata to set
@@ -896,10 +1002,71 @@ static int v9fs_vfs_setattr(struct dentry *dentry, struct iattr *iattr)
}
retval = p9_client_wstat(fid, &wstat);
- if (retval >= 0)
- retval = inode_setattr(dentry->d_inode, iattr);
+ if (retval < 0)
+ return retval;
+
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(dentry->d_inode)) {
+ retval = vmtruncate(dentry->d_inode, iattr->ia_size);
+ if (retval)
+ return retval;
+ }
- return retval;
+ setattr_copy(dentry->d_inode, iattr);
+ mark_inode_dirty(dentry->d_inode);
+ return 0;
+}
+
+/**
+ * v9fs_vfs_setattr_dotl - set file metadata
+ * @dentry: file whose metadata to set
+ * @iattr: metadata assignment structure
+ *
+ */
+
+static int v9fs_vfs_setattr_dotl(struct dentry *dentry, struct iattr *iattr)
+{
+ int retval;
+ struct v9fs_session_info *v9ses;
+ struct p9_fid *fid;
+ struct p9_iattr_dotl p9attr;
+
+ P9_DPRINTK(P9_DEBUG_VFS, "\n");
+
+ retval = inode_change_ok(dentry->d_inode, iattr);
+ if (retval)
+ return retval;
+
+ p9attr.valid = iattr->ia_valid;
+ p9attr.mode = iattr->ia_mode;
+ p9attr.uid = iattr->ia_uid;
+ p9attr.gid = iattr->ia_gid;
+ p9attr.size = iattr->ia_size;
+ p9attr.atime_sec = iattr->ia_atime.tv_sec;
+ p9attr.atime_nsec = iattr->ia_atime.tv_nsec;
+ p9attr.mtime_sec = iattr->ia_mtime.tv_sec;
+ p9attr.mtime_nsec = iattr->ia_mtime.tv_nsec;
+
+ retval = -EPERM;
+ v9ses = v9fs_inode2v9ses(dentry->d_inode);
+ fid = v9fs_fid_lookup(dentry);
+ if (IS_ERR(fid))
+ return PTR_ERR(fid);
+
+ retval = p9_client_setattr(fid, &p9attr);
+ if (retval < 0)
+ return retval;
+
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(dentry->d_inode)) {
+ retval = vmtruncate(dentry->d_inode, iattr->ia_size);
+ if (retval)
+ return retval;
+ }
+
+ setattr_copy(dentry->d_inode, iattr);
+ mark_inode_dirty(dentry->d_inode);
+ return 0;
}
/**
@@ -980,6 +1147,36 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
}
/**
+ * v9fs_stat2inode_dotl - populate an inode structure with stat info
+ * @stat: stat structure
+ * @inode: inode to populate
+ * @sb: superblock of filesystem
+ *
+ */
+
+void
+v9fs_stat2inode_dotl(struct p9_stat_dotl *stat, struct inode *inode)
+{
+ inode->i_atime.tv_sec = stat->st_atime_sec;
+ inode->i_atime.tv_nsec = stat->st_atime_nsec;
+ inode->i_mtime.tv_sec = stat->st_mtime_sec;
+ inode->i_mtime.tv_nsec = stat->st_mtime_nsec;
+ inode->i_ctime.tv_sec = stat->st_ctime_sec;
+ inode->i_ctime.tv_nsec = stat->st_ctime_nsec;
+ inode->i_uid = stat->st_uid;
+ inode->i_gid = stat->st_gid;
+ inode->i_nlink = stat->st_nlink;
+ inode->i_mode = stat->st_mode;
+ inode->i_rdev = new_decode_dev(stat->st_rdev);
+
+ if ((S_ISBLK(inode->i_mode)) || (S_ISCHR(inode->i_mode)))
+ init_special_inode(inode, inode->i_mode, inode->i_rdev);
+
+ i_size_write(inode, stat->st_size);
+ inode->i_blocks = stat->st_blocks;
+}
+
+/**
* v9fs_qid2ino - convert qid into inode number
* @qid: qid to hash
*
@@ -1254,8 +1451,8 @@ static const struct inode_operations v9fs_dir_inode_operations_dotl = {
.rmdir = v9fs_vfs_rmdir,
.mknod = v9fs_vfs_mknod,
.rename = v9fs_vfs_rename,
- .getattr = v9fs_vfs_getattr,
- .setattr = v9fs_vfs_setattr,
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
};
static const struct inode_operations v9fs_dir_inode_operations = {
@@ -1276,8 +1473,8 @@ static const struct inode_operations v9fs_file_inode_operations = {
};
static const struct inode_operations v9fs_file_inode_operations_dotl = {
- .getattr = v9fs_vfs_getattr,
- .setattr = v9fs_vfs_setattr,
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
};
static const struct inode_operations v9fs_symlink_inode_operations = {
@@ -1292,6 +1489,6 @@ static const struct inode_operations v9fs_symlink_inode_operations_dotl = {
.readlink = generic_readlink,
.follow_link = v9fs_vfs_follow_link,
.put_link = v9fs_vfs_put_link,
- .getattr = v9fs_vfs_getattr,
- .setattr = v9fs_vfs_setattr,
+ .getattr = v9fs_vfs_getattr_dotl,
+ .setattr = v9fs_vfs_setattr_dotl,
};
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index be74d020436e..2eaf6f82ff8f 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -107,7 +107,6 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
struct inode *inode = NULL;
struct dentry *root = NULL;
struct v9fs_session_info *v9ses = NULL;
- struct p9_wstat *st = NULL;
int mode = S_IRWXUGO | S_ISVTX;
struct p9_fid *fid;
int retval = 0;
@@ -124,16 +123,10 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
goto close_session;
}
- st = p9_client_stat(fid);
- if (IS_ERR(st)) {
- retval = PTR_ERR(st);
- goto clunk_fid;
- }
-
sb = sget(fs_type, NULL, v9fs_set_super, v9ses);
if (IS_ERR(sb)) {
retval = PTR_ERR(sb);
- goto free_stat;
+ goto clunk_fid;
}
v9fs_fill_super(sb, v9ses, flags, data);
@@ -151,22 +144,38 @@ static int v9fs_get_sb(struct file_system_type *fs_type, int flags,
}
sb->s_root = root;
- root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
- v9fs_stat2inode(st, root->d_inode, sb);
+ if (v9fs_proto_dotl(v9ses)) {
+ struct p9_stat_dotl *st = NULL;
+ st = p9_client_getattr_dotl(fid);
+ if (IS_ERR(st)) {
+ retval = PTR_ERR(st);
+ goto clunk_fid;
+ }
+
+ v9fs_stat2inode_dotl(st, root->d_inode);
+ kfree(st);
+ } else {
+ struct p9_wstat *st = NULL;
+ st = p9_client_stat(fid);
+ if (IS_ERR(st)) {
+ retval = PTR_ERR(st);
+ goto clunk_fid;
+ }
+
+ root->d_inode->i_ino = v9fs_qid2ino(&st->qid);
+ v9fs_stat2inode(st, root->d_inode, sb);
+
+ p9stat_free(st);
+ kfree(st);
+ }
v9fs_fid_add(root, fid);
- p9stat_free(st);
- kfree(st);
P9_DPRINTK(P9_DEBUG_VFS, " simple set mount, return 0\n");
simple_set_mnt(mnt, sb);
return 0;
-free_stat:
- p9stat_free(st);
- kfree(st);
-
clunk_fid:
p9_client_clunk(fid);
@@ -176,8 +185,6 @@ close_session:
return retval;
release_sb:
- p9stat_free(st);
- kfree(st);
deactivate_locked_super(sb);
return retval;
}
@@ -257,7 +264,7 @@ static const struct super_operations v9fs_super_ops = {
.destroy_inode = v9fs_destroy_inode,
#endif
.statfs = simple_statfs,
- .clear_inode = v9fs_clear_inode,
+ .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
};
@@ -268,7 +275,7 @@ static const struct super_operations v9fs_super_ops_dotl = {
.destroy_inode = v9fs_destroy_inode,
#endif
.statfs = v9fs_statfs,
- .clear_inode = v9fs_clear_inode,
+ .evict_inode = v9fs_evict_inode,
.show_options = generic_show_options,
.umount_begin = v9fs_umount_begin,
};
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 6f850b06ab62..65794b8fe79e 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -50,10 +50,19 @@ static int adfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
adfs_get_block,
&ADFS_I(mapping->host)->mmu_private);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
@@ -324,10 +333,7 @@ adfs_notify_change(struct dentry *dentry, struct iattr *attr)
/* XXX: this is missing some actual on-disk truncation.. */
if (ia_valid & ATTR_SIZE)
- error = simple_setsize(inode, attr->ia_size);
-
- if (error)
- goto out;
+ truncate_setsize(inode, attr->ia_size);
if (ia_valid & ATTR_MTIME) {
inode->i_mtime = attr->ia_mtime;
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index f05b6155ccc8..a8cbdeb34025 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -171,8 +171,7 @@ extern int affs_rename(struct inode *old_dir, struct dentry *old_dentry,
extern unsigned long affs_parent_ino(struct inode *dir);
extern struct inode *affs_new_inode(struct inode *dir);
extern int affs_notify_change(struct dentry *dentry, struct iattr *attr);
-extern void affs_delete_inode(struct inode *inode);
-extern void affs_clear_inode(struct inode *inode);
+extern void affs_evict_inode(struct inode *inode);
extern struct inode *affs_iget(struct super_block *sb,
unsigned long ino);
extern int affs_write_inode(struct inode *inode,
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 322710c3eedf..c4a9875bd1a6 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -406,10 +406,19 @@ static int affs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
affs_get_block,
&AFFS_I(mapping->host)->mmu_private);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/affs/inode.c b/fs/affs/inode.c
index f4b2a4ee4f91..3a0fdec175ba 100644
--- a/fs/affs/inode.c
+++ b/fs/affs/inode.c
@@ -235,31 +235,36 @@ affs_notify_change(struct dentry *dentry, struct iattr *attr)
goto out;
}
- error = inode_setattr(inode, attr);
- if (!error && (attr->ia_valid & ATTR_MODE))
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
+ if (attr->ia_valid & ATTR_MODE)
mode_to_prot(inode);
out:
return error;
}
void
-affs_delete_inode(struct inode *inode)
-{
- pr_debug("AFFS: delete_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
- truncate_inode_pages(&inode->i_data, 0);
- inode->i_size = 0;
- affs_truncate(inode);
- clear_inode(inode);
- affs_free_block(inode->i_sb, inode->i_ino);
-}
-
-void
-affs_clear_inode(struct inode *inode)
+affs_evict_inode(struct inode *inode)
{
unsigned long cache_page;
+ pr_debug("AFFS: evict_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
+ truncate_inode_pages(&inode->i_data, 0);
- pr_debug("AFFS: clear_inode(ino=%lu, nlink=%u)\n", inode->i_ino, inode->i_nlink);
+ if (!inode->i_nlink) {
+ inode->i_size = 0;
+ affs_truncate(inode);
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
affs_free_prealloc(inode);
cache_page = (unsigned long)AFFS_I(inode)->i_lc;
if (cache_page) {
@@ -271,6 +276,9 @@ affs_clear_inode(struct inode *inode)
affs_brelse(AFFS_I(inode)->i_ext_bh);
AFFS_I(inode)->i_ext_last = ~1;
AFFS_I(inode)->i_ext_bh = NULL;
+
+ if (!inode->i_nlink)
+ affs_free_block(inode->i_sb, inode->i_ino);
}
struct inode *
diff --git a/fs/affs/super.c b/fs/affs/super.c
index 16a3e4765f68..2c804a87c142 100644
--- a/fs/affs/super.c
+++ b/fs/affs/super.c
@@ -140,8 +140,7 @@ static const struct super_operations affs_sops = {
.alloc_inode = affs_alloc_inode,
.destroy_inode = affs_destroy_inode,
.write_inode = affs_write_inode,
- .delete_inode = affs_delete_inode,
- .clear_inode = affs_clear_inode,
+ .evict_inode = affs_evict_inode,
.put_super = affs_put_super,
.write_super = affs_write_super,
.sync_fs = affs_sync_fs,
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index d00b312e3110..320ffef11574 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -316,7 +316,7 @@ int afs_getattr(struct vfsmount *mnt, struct dentry *dentry,
/*
* clear an AFS inode
*/
-void afs_clear_inode(struct inode *inode)
+void afs_evict_inode(struct inode *inode)
{
struct afs_permits *permits;
struct afs_vnode *vnode;
@@ -335,6 +335,9 @@ void afs_clear_inode(struct inode *inode)
ASSERTCMP(inode->i_ino, ==, vnode->fid.vnode);
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
+
afs_give_up_callback(vnode);
if (vnode->server) {
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 5f679b77ce24..8679089ce9a1 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -565,7 +565,7 @@ extern void afs_zap_data(struct afs_vnode *);
extern int afs_validate(struct afs_vnode *, struct key *);
extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int afs_setattr(struct dentry *, struct iattr *);
-extern void afs_clear_inode(struct inode *);
+extern void afs_evict_inode(struct inode *);
/*
* main.c
diff --git a/fs/afs/super.c b/fs/afs/super.c
index e932e5a3a0c1..9cf80f02da16 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -49,7 +49,7 @@ static const struct super_operations afs_super_ops = {
.statfs = afs_statfs,
.alloc_inode = afs_alloc_inode,
.destroy_inode = afs_destroy_inode,
- .clear_inode = afs_clear_inode,
+ .evict_inode = afs_evict_inode,
.put_super = afs_put_super,
.show_options = generic_show_options,
};
diff --git a/fs/aio.c b/fs/aio.c
index 1ccf25cef1f0..3006b5bc33d6 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1277,7 +1277,7 @@ out:
/* sys_io_destroy:
* Destroy the aio_context specified. May cancel any outstanding
* AIOs and block on completion. Will fail with -ENOSYS if not
- * implemented. May fail with -EFAULT if the context pointed to
+ * implemented. May fail with -EINVAL if the context pointed to
* is invalid.
*/
SYSCALL_DEFINE1(io_destroy, aio_context_t, ctx)
@@ -1795,15 +1795,16 @@ SYSCALL_DEFINE3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb,
/* io_getevents:
* Attempts to read at least min_nr events and up to nr events from
- * the completion queue for the aio_context specified by ctx_id. May
- * fail with -EINVAL if ctx_id is invalid, if min_nr is out of range,
- * if nr is out of range, if when is out of range. May fail with
- * -EFAULT if any of the memory specified to is invalid. May return
- * 0 or < min_nr if no events are available and the timeout specified
- * by when has elapsed, where when == NULL specifies an infinite
- * timeout. Note that the timeout pointed to by when is relative and
- * will be updated if not NULL and the operation blocks. Will fail
- * with -ENOSYS if not implemented.
+ * the completion queue for the aio_context specified by ctx_id. If
+ * it succeeds, the number of read events is returned. May fail with
+ * -EINVAL if ctx_id is invalid, if min_nr is out of range, if nr is
+ * out of range, if timeout is out of range. May fail with -EFAULT
+ * if any of the memory specified is invalid. May return 0 or
+ * < min_nr if the timeout specified by timeout has elapsed
+ * before sufficient events are available, where timeout == NULL
+ * specifies an infinite timeout. Note that the timeout pointed to by
+ * timeout is relative and will be updated if not NULL and the
+ * operation blocks. Will fail with -ENOSYS if not implemented.
*/
SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id,
long, min_nr,
diff --git a/fs/attr.c b/fs/attr.c
index b4fa3b0aa596..7ca41811afa1 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -14,35 +14,53 @@
#include <linux/fcntl.h>
#include <linux/security.h>
-/* Taken over from the old code... */
-
-/* POSIX UID/GID verification for setting inode attributes. */
+/**
+ * inode_change_ok - check if attribute changes to an inode are allowed
+ * @inode: inode to check
+ * @attr: attributes to change
+ *
+ * Check if we are allowed to change the attributes contained in @attr
+ * in the given inode. This includes the normal unix access permission
+ * checks, as well as checks for rlimits and others.
+ *
+ * Should be called as the first thing in ->setattr implementations,
+ * possibly after taking additional locks.
+ */
int inode_change_ok(const struct inode *inode, struct iattr *attr)
{
- int retval = -EPERM;
unsigned int ia_valid = attr->ia_valid;
+ /*
+ * First check size constraints. These can't be overriden using
+ * ATTR_FORCE.
+ */
+ if (ia_valid & ATTR_SIZE) {
+ int error = inode_newsize_ok(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
/* If force is set do it anyway. */
if (ia_valid & ATTR_FORCE)
- goto fine;
+ return 0;
/* Make sure a caller can chown. */
if ((ia_valid & ATTR_UID) &&
(current_fsuid() != inode->i_uid ||
attr->ia_uid != inode->i_uid) && !capable(CAP_CHOWN))
- goto error;
+ return -EPERM;
/* Make sure caller can chgrp. */
if ((ia_valid & ATTR_GID) &&
(current_fsuid() != inode->i_uid ||
(!in_group_p(attr->ia_gid) && attr->ia_gid != inode->i_gid)) &&
!capable(CAP_CHOWN))
- goto error;
+ return -EPERM;
/* Make sure a caller can chmod. */
if (ia_valid & ATTR_MODE) {
if (!is_owner_or_cap(inode))
- goto error;
+ return -EPERM;
/* Also check the setgid bit! */
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
inode->i_gid) && !capable(CAP_FSETID))
@@ -52,12 +70,10 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
/* Check for setting the inode time. */
if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
if (!is_owner_or_cap(inode))
- goto error;
+ return -EPERM;
}
-fine:
- retval = 0;
-error:
- return retval;
+
+ return 0;
}
EXPORT_SYMBOL(inode_change_ok);
@@ -105,21 +121,21 @@ out_big:
EXPORT_SYMBOL(inode_newsize_ok);
/**
- * generic_setattr - copy simple metadata updates into the generic inode
+ * setattr_copy - copy simple metadata updates into the generic inode
* @inode: the inode to be updated
* @attr: the new attributes
*
- * generic_setattr must be called with i_mutex held.
+ * setattr_copy must be called with i_mutex held.
*
- * generic_setattr updates the inode's metadata with that specified
+ * setattr_copy updates the inode's metadata with that specified
* in attr. Noticably missing is inode size update, which is more complex
- * as it requires pagecache updates. See simple_setsize.
+ * as it requires pagecache updates.
*
* The inode is not marked as dirty after this operation. The rationale is
* that for "simple" filesystems, the struct inode is the inode storage.
* The caller is free to mark the inode dirty afterwards if needed.
*/
-void generic_setattr(struct inode *inode, const struct iattr *attr)
+void setattr_copy(struct inode *inode, const struct iattr *attr)
{
unsigned int ia_valid = attr->ia_valid;
@@ -144,32 +160,7 @@ void generic_setattr(struct inode *inode, const struct iattr *attr)
inode->i_mode = mode;
}
}
-EXPORT_SYMBOL(generic_setattr);
-
-/*
- * note this function is deprecated, the new truncate sequence should be
- * used instead -- see eg. simple_setsize, generic_setattr.
- */
-int inode_setattr(struct inode *inode, const struct iattr *attr)
-{
- unsigned int ia_valid = attr->ia_valid;
-
- if (ia_valid & ATTR_SIZE &&
- attr->ia_size != i_size_read(inode)) {
- int error;
-
- error = vmtruncate(inode, attr->ia_size);
- if (error)
- return error;
- }
-
- generic_setattr(inode, attr);
-
- mark_inode_dirty(inode);
-
- return 0;
-}
-EXPORT_SYMBOL(inode_setattr);
+EXPORT_SYMBOL(setattr_copy);
int notify_change(struct dentry * dentry, struct iattr * attr)
{
@@ -237,13 +228,10 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
if (ia_valid & ATTR_SIZE)
down_write(&dentry->d_inode->i_alloc_sem);
- if (inode->i_op && inode->i_op->setattr) {
+ if (inode->i_op->setattr)
error = inode->i_op->setattr(dentry, attr);
- } else {
- error = inode_change_ok(inode, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- }
+ else
+ error = simple_setattr(dentry, attr);
if (ia_valid & ATTR_SIZE)
up_write(&dentry->d_inode->i_alloc_sem);
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 88b9a3ff44e4..8fc2e9c9739d 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -168,9 +168,17 @@ static int bfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return block_write_begin(file, mapping, pos, len, flags,
- pagep, fsdata, bfs_get_block);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ bfs_get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c
index f22a7d3dc362..0499822b1568 100644
--- a/fs/bfs/inode.c
+++ b/fs/bfs/inode.c
@@ -99,6 +99,24 @@ error:
return ERR_PTR(-EIO);
}
+static struct bfs_inode *find_inode(struct super_block *sb, u16 ino, struct buffer_head **p)
+{
+ if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(sb)->si_lasti)) {
+ printf("Bad inode number %s:%08x\n", sb->s_id, ino);
+ return ERR_PTR(-EIO);
+ }
+
+ ino -= BFS_ROOT_INO;
+
+ *p = sb_bread(sb, 1 + ino / BFS_INODES_PER_BLOCK);
+ if (!*p) {
+ printf("Unable to read inode %s:%08x\n", sb->s_id, ino);
+ return ERR_PTR(-EIO);
+ }
+
+ return (struct bfs_inode *)(*p)->b_data + ino % BFS_INODES_PER_BLOCK;
+}
+
static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
{
struct bfs_sb_info *info = BFS_SB(inode->i_sb);
@@ -106,28 +124,15 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
unsigned long i_sblock;
struct bfs_inode *di;
struct buffer_head *bh;
- int block, off;
int err = 0;
dprintf("ino=%08x\n", ino);
- if ((ino < BFS_ROOT_INO) || (ino > BFS_SB(inode->i_sb)->si_lasti)) {
- printf("Bad inode number %s:%08x\n", inode->i_sb->s_id, ino);
- return -EIO;
- }
+ di = find_inode(inode->i_sb, ino, &bh);
+ if (IS_ERR(di))
+ return PTR_ERR(di);
mutex_lock(&info->bfs_lock);
- block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
- bh = sb_bread(inode->i_sb, block);
- if (!bh) {
- printf("Unable to read inode %s:%08x\n",
- inode->i_sb->s_id, ino);
- mutex_unlock(&info->bfs_lock);
- return -EIO;
- }
-
- off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
- di = (struct bfs_inode *)bh->b_data + off;
if (ino == BFS_ROOT_INO)
di->i_vtype = cpu_to_le32(BFS_VDIR);
@@ -158,12 +163,11 @@ static int bfs_write_inode(struct inode *inode, struct writeback_control *wbc)
return err;
}
-static void bfs_delete_inode(struct inode *inode)
+static void bfs_evict_inode(struct inode *inode)
{
unsigned long ino = inode->i_ino;
struct bfs_inode *di;
struct buffer_head *bh;
- int block, off;
struct super_block *s = inode->i_sb;
struct bfs_sb_info *info = BFS_SB(s);
struct bfs_inode_info *bi = BFS_I(inode);
@@ -171,28 +175,19 @@ static void bfs_delete_inode(struct inode *inode)
dprintf("ino=%08lx\n", ino);
truncate_inode_pages(&inode->i_data, 0);
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
- if ((ino < BFS_ROOT_INO) || (ino > info->si_lasti)) {
- printf("invalid ino=%08lx\n", ino);
+ if (inode->i_nlink)
return;
- }
-
- inode->i_size = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
- mutex_lock(&info->bfs_lock);
- mark_inode_dirty(inode);
- block = (ino - BFS_ROOT_INO) / BFS_INODES_PER_BLOCK + 1;
- bh = sb_bread(s, block);
- if (!bh) {
- printf("Unable to read inode %s:%08lx\n",
- inode->i_sb->s_id, ino);
- mutex_unlock(&info->bfs_lock);
+ di = find_inode(s, inode->i_ino, &bh);
+ if (IS_ERR(di))
return;
- }
- off = (ino - BFS_ROOT_INO) % BFS_INODES_PER_BLOCK;
- di = (struct bfs_inode *)bh->b_data + off;
- memset((void *)di, 0, sizeof(struct bfs_inode));
+
+ mutex_lock(&info->bfs_lock);
+ /* clear on-disk inode */
+ memset(di, 0, sizeof(struct bfs_inode));
mark_buffer_dirty(bh);
brelse(bh);
@@ -214,7 +209,6 @@ static void bfs_delete_inode(struct inode *inode)
mark_buffer_dirty(info->si_sbh);
}
mutex_unlock(&info->bfs_lock);
- clear_inode(inode);
}
static int bfs_sync_fs(struct super_block *sb, int wait)
@@ -319,7 +313,7 @@ static const struct super_operations bfs_sops = {
.alloc_inode = bfs_alloc_inode,
.destroy_inode = bfs_destroy_inode,
.write_inode = bfs_write_inode,
- .delete_inode = bfs_delete_inode,
+ .evict_inode = bfs_evict_inode,
.put_super = bfs_put_super,
.write_super = bfs_write_super,
.sync_fs = bfs_sync_fs,
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index c4e83537ead7..9e60fd201716 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -502,8 +502,9 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode)
return inode;
}
-static void bm_clear_inode(struct inode *inode)
+static void bm_evict_inode(struct inode *inode)
{
+ end_writeback(inode);
kfree(inode->i_private);
}
@@ -685,7 +686,7 @@ static const struct file_operations bm_status_operations = {
static const struct super_operations s_ops = {
.statfs = simple_statfs,
- .clear_inode = bm_clear_inode,
+ .evict_inode = bm_evict_inode,
};
static int bm_fill_super(struct super_block * sb, void * data, int silent)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 99d6af811747..de7b4d0c7e30 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -172,9 +172,8 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
- return blockdev_direct_IO_no_locking_newtrunc(rw, iocb, inode,
- I_BDEV(inode), iov, offset, nr_segs,
- blkdev_get_blocks, NULL);
+ return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
+ nr_segs, blkdev_get_blocks, NULL, NULL, 0);
}
int __sync_blockdev(struct block_device *bdev, int wait)
@@ -309,9 +308,8 @@ static int blkdev_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return block_write_begin_newtrunc(file, mapping, pos, len, flags,
- pagep, fsdata, blkdev_get_block);
+ return block_write_begin(mapping, pos, len, flags, pagep,
+ blkdev_get_block);
}
static int blkdev_write_end(struct file *file, struct address_space *mapping,
@@ -428,10 +426,13 @@ static inline void __bd_forget(struct inode *inode)
inode->i_mapping = &inode->i_data;
}
-static void bdev_clear_inode(struct inode *inode)
+static void bdev_evict_inode(struct inode *inode)
{
struct block_device *bdev = &BDEV_I(inode)->bdev;
struct list_head *p;
+ truncate_inode_pages(&inode->i_data, 0);
+ invalidate_inode_buffers(inode); /* is it needed here? */
+ end_writeback(inode);
spin_lock(&bdev_lock);
while ( (p = bdev->bd_inodes.next) != &bdev->bd_inodes ) {
__bd_forget(list_entry(p, struct inode, i_devices));
@@ -445,7 +446,7 @@ static const struct super_operations bdev_sops = {
.alloc_inode = bdev_alloc_inode,
.destroy_inode = bdev_destroy_inode,
.drop_inode = generic_delete_inode,
- .clear_inode = bdev_clear_inode,
+ .evict_inode = bdev_evict_inode,
};
static int bd_get_sb(struct file_system_type *fs_type,
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 29c20092847e..394d5422ab6a 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2389,7 +2389,7 @@ unsigned long btrfs_force_ra(struct address_space *mapping,
pgoff_t offset, pgoff_t last_index);
int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
int btrfs_readpage(struct file *file, struct page *page);
-void btrfs_delete_inode(struct inode *inode);
+void btrfs_evict_inode(struct inode *inode);
void btrfs_put_inode(struct inode *inode);
int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
void btrfs_dirty_inode(struct inode *inode);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1bff92ad4744..ce02199ec4e5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3656,17 +3656,19 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
if (err)
return err;
}
- attr->ia_valid &= ~ATTR_SIZE;
- if (attr->ia_valid)
- err = inode_setattr(inode, attr);
+ if (attr->ia_valid) {
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
+ if (attr->ia_valid & ATTR_MODE)
+ err = btrfs_acl_chmod(inode);
+ }
- if (!err && ((attr->ia_valid & ATTR_MODE)))
- err = btrfs_acl_chmod(inode);
return err;
}
-void btrfs_delete_inode(struct inode *inode)
+void btrfs_evict_inode(struct inode *inode)
{
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3674,10 +3676,14 @@ void btrfs_delete_inode(struct inode *inode)
int ret;
truncate_inode_pages(&inode->i_data, 0);
+ if (inode->i_nlink && btrfs_root_refs(&root->root_item) != 0)
+ goto no_delete;
+
if (is_bad_inode(inode)) {
btrfs_orphan_del(NULL, inode);
goto no_delete;
}
+ /* do we really want it for ->i_nlink > 0 and zero btrfs_root_refs? */
btrfs_wait_ordered_range(inode, 0, (u64)-1);
if (root->fs_info->log_root_recovering) {
@@ -3727,7 +3733,7 @@ void btrfs_delete_inode(struct inode *inode)
btrfs_end_transaction(trans, root);
btrfs_btree_balance_dirty(root, nr);
no_delete:
- clear_inode(inode);
+ end_writeback(inode);
return;
}
@@ -3858,7 +3864,7 @@ again:
p = &parent->rb_right;
else {
WARN_ON(!(entry->vfs_inode.i_state &
- (I_WILL_FREE | I_FREEING | I_CLEAR)));
+ (I_WILL_FREE | I_FREEING)));
rb_erase(parent, &root->inode_tree);
RB_CLEAR_NODE(parent);
spin_unlock(&root->inode_lock);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index f2393b390318..1776dbd8dc98 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -797,7 +797,7 @@ static int btrfs_unfreeze(struct super_block *sb)
static const struct super_operations btrfs_super_ops = {
.drop_inode = btrfs_drop_inode,
- .delete_inode = btrfs_delete_inode,
+ .evict_inode = btrfs_evict_inode,
.put_super = btrfs_put_super,
.sync_fs = btrfs_sync_fs,
.show_options = btrfs_show_options,
diff --git a/fs/buffer.c b/fs/buffer.c
index d54812b198e9..50efa339e051 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1833,9 +1833,10 @@ void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
}
EXPORT_SYMBOL(page_zero_new_buffers);
-static int __block_prepare_write(struct inode *inode, struct page *page,
- unsigned from, unsigned to, get_block_t *get_block)
+int block_prepare_write(struct page *page, unsigned from, unsigned to,
+ get_block_t *get_block)
{
+ struct inode *inode = page->mapping->host;
unsigned block_start, block_end;
sector_t block;
int err = 0;
@@ -1908,10 +1909,13 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
if (!buffer_uptodate(*wait_bh))
err = -EIO;
}
- if (unlikely(err))
+ if (unlikely(err)) {
page_zero_new_buffers(page, from, to);
+ ClearPageUptodate(page);
+ }
return err;
}
+EXPORT_SYMBOL(block_prepare_write);
static int __block_commit_write(struct inode *inode, struct page *page,
unsigned from, unsigned to)
@@ -1948,90 +1952,41 @@ static int __block_commit_write(struct inode *inode, struct page *page,
return 0;
}
-/*
- * Filesystems implementing the new truncate sequence should use the
- * _newtrunc postfix variant which won't incorrectly call vmtruncate.
- * The filesystem needs to handle block truncation upon failure.
- */
-int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata,
- get_block_t *get_block)
+int __block_write_begin(struct page *page, loff_t pos, unsigned len,
+ get_block_t *get_block)
{
- struct inode *inode = mapping->host;
- int status = 0;
- struct page *page;
- pgoff_t index;
- unsigned start, end;
- int ownpage = 0;
-
- index = pos >> PAGE_CACHE_SHIFT;
- start = pos & (PAGE_CACHE_SIZE - 1);
- end = start + len;
-
- page = *pagep;
- if (page == NULL) {
- ownpage = 1;
- page = grab_cache_page_write_begin(mapping, index, flags);
- if (!page) {
- status = -ENOMEM;
- goto out;
- }
- *pagep = page;
- } else
- BUG_ON(!PageLocked(page));
-
- status = __block_prepare_write(inode, page, start, end, get_block);
- if (unlikely(status)) {
- ClearPageUptodate(page);
+ unsigned start = pos & (PAGE_CACHE_SIZE - 1);
- if (ownpage) {
- unlock_page(page);
- page_cache_release(page);
- *pagep = NULL;
- }
- }
-
-out:
- return status;
+ return block_prepare_write(page, start, start + len, get_block);
}
-EXPORT_SYMBOL(block_write_begin_newtrunc);
+EXPORT_SYMBOL(__block_write_begin);
/*
* block_write_begin takes care of the basic task of block allocation and
* bringing partial write blocks uptodate first.
*
- * If *pagep is not NULL, then block_write_begin uses the locked page
- * at *pagep rather than allocating its own. In this case, the page will
- * not be unlocked or deallocated on failure.
+ * The filesystem needs to handle block truncation upon failure.
*/
-int block_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata,
- get_block_t *get_block)
+int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
+ unsigned flags, struct page **pagep, get_block_t *get_block)
{
- int ret;
+ pgoff_t index = pos >> PAGE_CACHE_SHIFT;
+ struct page *page;
+ int status;
- ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
- pagep, fsdata, get_block);
+ page = grab_cache_page_write_begin(mapping, index, flags);
+ if (!page)
+ return -ENOMEM;
- /*
- * prepare_write() may have instantiated a few blocks
- * outside i_size. Trim these off again. Don't need
- * i_size_read because we hold i_mutex.
- *
- * Filesystems which pass down their own page also cannot
- * call into vmtruncate here because it would lead to lock
- * inversion problems (*pagep is locked). This is a further
- * example of where the old truncate sequence is inadequate.
- */
- if (unlikely(ret) && *pagep == NULL) {
- loff_t isize = mapping->host->i_size;
- if (pos + len > isize)
- vmtruncate(mapping->host, isize);
+ status = __block_write_begin(page, pos, len, get_block);
+ if (unlikely(status)) {
+ unlock_page(page);
+ page_cache_release(page);
+ page = NULL;
}
- return ret;
+ *pagep = page;
+ return status;
}
EXPORT_SYMBOL(block_write_begin);
@@ -2351,7 +2306,7 @@ out:
* For moronic filesystems that do not allow holes in file.
* We may have to extend the file.
*/
-int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
+int cont_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
get_block_t *get_block, loff_t *bytes)
@@ -2363,7 +2318,7 @@ int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
err = cont_expand_zero(file, mapping, pos, bytes);
if (err)
- goto out;
+ return err;
zerofrom = *bytes & ~PAGE_CACHE_MASK;
if (pos+len > *bytes && zerofrom & (blocksize-1)) {
@@ -2371,44 +2326,10 @@ int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
(*bytes)++;
}
- *pagep = NULL;
- err = block_write_begin_newtrunc(file, mapping, pos, len,
- flags, pagep, fsdata, get_block);
-out:
- return err;
-}
-EXPORT_SYMBOL(cont_write_begin_newtrunc);
-
-int cont_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata,
- get_block_t *get_block, loff_t *bytes)
-{
- int ret;
-
- ret = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
- pagep, fsdata, get_block, bytes);
- if (unlikely(ret)) {
- loff_t isize = mapping->host->i_size;
- if (pos + len > isize)
- vmtruncate(mapping->host, isize);
- }
-
- return ret;
+ return block_write_begin(mapping, pos, len, flags, pagep, get_block);
}
EXPORT_SYMBOL(cont_write_begin);
-int block_prepare_write(struct page *page, unsigned from, unsigned to,
- get_block_t *get_block)
-{
- struct inode *inode = page->mapping->host;
- int err = __block_prepare_write(inode, page, from, to, get_block);
- if (err)
- ClearPageUptodate(page);
- return err;
-}
-EXPORT_SYMBOL(block_prepare_write);
-
int block_commit_write(struct page *page, unsigned from, unsigned to)
{
struct inode *inode = page->mapping->host;
@@ -2510,11 +2431,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
}
/*
- * Filesystems implementing the new truncate sequence should use the
- * _newtrunc postfix variant which won't incorrectly call vmtruncate.
+ * On entry, the page is fully not uptodate.
+ * On exit the page is fully uptodate in the areas outside (from,to)
* The filesystem needs to handle block truncation upon failure.
*/
-int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
+int nobh_write_begin(struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
get_block_t *get_block)
@@ -2547,8 +2468,8 @@ int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
unlock_page(page);
page_cache_release(page);
*pagep = NULL;
- return block_write_begin_newtrunc(file, mapping, pos, len,
- flags, pagep, fsdata, get_block);
+ return block_write_begin(mapping, pos, len, flags, pagep,
+ get_block);
}
if (PageMappedToDisk(page))
@@ -2654,35 +2575,6 @@ out_release:
return ret;
}
-EXPORT_SYMBOL(nobh_write_begin_newtrunc);
-
-/*
- * On entry, the page is fully not uptodate.
- * On exit the page is fully uptodate in the areas outside (from,to)
- */
-int nobh_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata,
- get_block_t *get_block)
-{
- int ret;
-
- ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags,
- pagep, fsdata, get_block);
-
- /*
- * prepare_write() may have instantiated a few blocks
- * outside i_size. Trim these off again. Don't need
- * i_size_read because we hold i_mutex.
- */
- if (unlikely(ret)) {
- loff_t isize = mapping->host->i_size;
- if (pos + len > isize)
- vmtruncate(mapping->host, isize);
- }
-
- return ret;
-}
EXPORT_SYMBOL(nobh_write_begin);
int nobh_write_end(struct file *file, struct address_space *mapping,
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index d9c60b84949a..e00797eed29c 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -552,7 +552,7 @@ static void writepages_finish(struct ceph_osd_request *req,
* page truncation thread, possibly losing some data that
* raced its way in
*/
- if ((issued & CEPH_CAP_FILE_CACHE) == 0)
+ if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0)
generic_error_remove_page(inode->i_mapping, page);
unlock_page(page);
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 74144d6389f0..f25365cbe95a 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -337,8 +337,7 @@ static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
}
/*
- * Return id of any MDS with a cap, preferably FILE_WR|WRBUFFER|EXCL, else
- * -1.
+ * Return id of any MDS with a cap, preferably FILE_WR|BUFFER|EXCL, else -1.
*/
static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
{
@@ -346,7 +345,7 @@ static int __ceph_get_cap_mds(struct ceph_inode_info *ci, u32 *mseq)
int mds = -1;
struct rb_node *p;
- /* prefer mds with WR|WRBUFFER|EXCL caps */
+ /* prefer mds with WR|BUFFER|EXCL caps */
for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
cap = rb_entry(p, struct ceph_cap, ci_node);
mds = cap->mds;
@@ -483,8 +482,8 @@ static void __check_cap_issue(struct ceph_inode_info *ci, struct ceph_cap *cap,
* Each time we receive FILE_CACHE anew, we increment
* i_rdcache_gen.
*/
- if ((issued & CEPH_CAP_FILE_CACHE) &&
- (had & CEPH_CAP_FILE_CACHE) == 0)
+ if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) &&
+ (had & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0)
ci->i_rdcache_gen++;
/*
@@ -831,7 +830,7 @@ int __ceph_caps_file_wanted(struct ceph_inode_info *ci)
{
int want = 0;
int mode;
- for (mode = 0; mode < 4; mode++)
+ for (mode = 0; mode < CEPH_FILE_MODE_NUM; mode++)
if (ci->i_nr_by_mode[mode])
want |= ceph_caps_for_mode(mode);
return want;
@@ -1347,7 +1346,7 @@ void __ceph_mark_dirty_caps(struct ceph_inode_info *ci, int mask)
* Add dirty inode to the flushing list. Assigned a seq number so we
* can wait for caps to flush without starving.
*
- * Called under i_lock.
+ * Called under i_lock, s_mutex
*/
static int __mark_caps_flushing(struct inode *inode,
struct ceph_mds_session *session)
@@ -1510,11 +1509,13 @@ retry_locked:
ci->i_wrbuffer_ref == 0 && /* no dirty pages... */
ci->i_rdcache_gen && /* may have cached pages */
(file_wanted == 0 || /* no open files */
- (revoking & CEPH_CAP_FILE_CACHE)) && /* or revoking cache */
+ (revoking & (CEPH_CAP_FILE_CACHE|
+ CEPH_CAP_FILE_LAZYIO))) && /* or revoking cache */
!tried_invalidate) {
dout("check_caps trying to invalidate on %p\n", inode);
if (try_nonblocking_invalidate(inode) < 0) {
- if (revoking & CEPH_CAP_FILE_CACHE) {
+ if (revoking & (CEPH_CAP_FILE_CACHE|
+ CEPH_CAP_FILE_LAZYIO)) {
dout("check_caps queuing invalidate\n");
queue_invalidate = 1;
ci->i_rdcache_revoking = ci->i_rdcache_gen;
@@ -1880,8 +1881,16 @@ static void kick_flushing_capsnaps(struct ceph_mds_client *mdsc,
cap, capsnap);
__ceph_flush_snaps(ci, &session);
} else {
+ struct rb_node *p;
+
pr_err("%p auth cap %p not mds%d ???\n", inode,
cap, session->s_mds);
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ struct ceph_cap *t =
+ rb_entry(p, struct ceph_cap, ci_node);
+ pr_info(" %p cap %p mds%d\n", inode, t,
+ t->session ? t->session->s_mds : -1);
+ }
}
spin_unlock(&inode->i_lock);
}
@@ -1916,8 +1925,15 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc,
spin_unlock(&inode->i_lock);
}
} else {
+ struct rb_node *p;
pr_err("%p auth cap %p not mds%d ???\n", inode,
cap, session->s_mds);
+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
+ struct ceph_cap *t =
+ rb_entry(p, struct ceph_cap, ci_node);
+ pr_info(" %p cap %p mds%d\n", inode, t,
+ t->session ? t->session->s_mds : -1);
+ }
spin_unlock(&inode->i_lock);
}
}
@@ -2277,7 +2293,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
* try to invalidate (once). (If there are dirty buffers, we
* will invalidate _after_ writeback.)
*/
- if (((cap->issued & ~newcaps) & CEPH_CAP_FILE_CACHE) &&
+ if (((cap->issued & ~newcaps) & (CEPH_CAP_FILE_CACHE|
+ CEPH_CAP_FILE_LAZYIO)) &&
!ci->i_wrbuffer_ref) {
if (try_nonblocking_invalidate(inode) == 0) {
revoked_rdcache = 1;
@@ -2375,7 +2392,8 @@ static void handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
writeback = 1; /* will delay ack */
else if (dirty & ~newcaps)
check_caps = 1; /* initiate writeback in check_caps */
- else if (((used & ~newcaps) & CEPH_CAP_FILE_CACHE) == 0 ||
+ else if (((used & ~newcaps) & (CEPH_CAP_FILE_CACHE|
+ CEPH_CAP_FILE_LAZYIO)) == 0 ||
revoked_rdcache)
check_caps = 2; /* send revoke ack in check_caps */
cap->issued = newcaps;
diff --git a/fs/ceph/ceph_fs.c b/fs/ceph/ceph_fs.c
index 79d76bc4303f..3ac6cc7c1156 100644
--- a/fs/ceph/ceph_fs.c
+++ b/fs/ceph/ceph_fs.c
@@ -29,46 +29,44 @@ int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
int ceph_flags_to_mode(int flags)
{
+ int mode;
+
#ifdef O_DIRECTORY /* fixme */
if ((flags & O_DIRECTORY) == O_DIRECTORY)
return CEPH_FILE_MODE_PIN;
#endif
+ if ((flags & O_APPEND) == O_APPEND)
+ flags |= O_WRONLY;
+
+ if ((flags & O_ACCMODE) == O_RDWR)
+ mode = CEPH_FILE_MODE_RDWR;
+ else if ((flags & O_ACCMODE) == O_WRONLY)
+ mode = CEPH_FILE_MODE_WR;
+ else
+ mode = CEPH_FILE_MODE_RD;
+
#ifdef O_LAZY
if (flags & O_LAZY)
- return CEPH_FILE_MODE_LAZY;
+ mode |= CEPH_FILE_MODE_LAZY;
#endif
- if ((flags & O_APPEND) == O_APPEND)
- flags |= O_WRONLY;
- flags &= O_ACCMODE;
- if ((flags & O_RDWR) == O_RDWR)
- return CEPH_FILE_MODE_RDWR;
- if ((flags & O_WRONLY) == O_WRONLY)
- return CEPH_FILE_MODE_WR;
- return CEPH_FILE_MODE_RD;
+ return mode;
}
int ceph_caps_for_mode(int mode)
{
- switch (mode) {
- case CEPH_FILE_MODE_PIN:
- return CEPH_CAP_PIN;
- case CEPH_FILE_MODE_RD:
- return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
+ int caps = CEPH_CAP_PIN;
+
+ if (mode & CEPH_FILE_MODE_RD)
+ caps |= CEPH_CAP_FILE_SHARED |
CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE;
- case CEPH_FILE_MODE_RDWR:
- return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
- CEPH_CAP_FILE_EXCL |
- CEPH_CAP_FILE_RD | CEPH_CAP_FILE_CACHE |
- CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
- CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
- CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
- case CEPH_FILE_MODE_WR:
- return CEPH_CAP_PIN | CEPH_CAP_FILE_SHARED |
- CEPH_CAP_FILE_EXCL |
+ if (mode & CEPH_FILE_MODE_WR)
+ caps |= CEPH_CAP_FILE_EXCL |
CEPH_CAP_FILE_WR | CEPH_CAP_FILE_BUFFER |
CEPH_CAP_AUTH_SHARED | CEPH_CAP_AUTH_EXCL |
CEPH_CAP_XATTR_SHARED | CEPH_CAP_XATTR_EXCL;
- }
- return 0;
+ if (mode & CEPH_FILE_MODE_LAZY)
+ caps |= CEPH_CAP_FILE_LAZYIO;
+
+ return caps;
}
diff --git a/fs/ceph/ceph_fs.h b/fs/ceph/ceph_fs.h
index 2fa992eaf7da..c2e4c61a99a3 100644
--- a/fs/ceph/ceph_fs.h
+++ b/fs/ceph/ceph_fs.h
@@ -563,7 +563,8 @@ int ceph_flags_to_mode(int flags);
CEPH_CAP_FILE_EXCL)
#define CEPH_CAP_ANY_WR (CEPH_CAP_ANY_EXCL | CEPH_CAP_ANY_FILE_WR)
#define CEPH_CAP_ANY (CEPH_CAP_ANY_RD | CEPH_CAP_ANY_EXCL | \
- CEPH_CAP_ANY_FILE_WR | CEPH_CAP_PIN)
+ CEPH_CAP_ANY_FILE_WR | CEPH_CAP_FILE_LAZYIO | \
+ CEPH_CAP_PIN)
#define CEPH_CAP_LOCKS (CEPH_LOCK_IFILE | CEPH_LOCK_IAUTH | CEPH_LOCK_ILINK | \
CEPH_LOCK_IXATTR)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 6251a1574b94..2261d52279ed 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -740,28 +740,32 @@ static ssize_t ceph_aio_read(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *filp = iocb->ki_filp;
+ struct ceph_file_info *fi = filp->private_data;
loff_t *ppos = &iocb->ki_pos;
size_t len = iov->iov_len;
struct inode *inode = filp->f_dentry->d_inode;
struct ceph_inode_info *ci = ceph_inode(inode);
void *base = iov->iov_base;
ssize_t ret;
- int got = 0;
+ int want, got = 0;
int checkeof = 0, read = 0;
dout("aio_read %p %llx.%llx %llu~%u trying to get caps on %p\n",
inode, ceph_vinop(inode), pos, (unsigned)len, inode);
again:
__ceph_do_pending_vmtruncate(inode);
- ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, CEPH_CAP_FILE_CACHE,
- &got, -1);
+ if (fi->fmode & CEPH_FILE_MODE_LAZY)
+ want = CEPH_CAP_FILE_CACHE | CEPH_CAP_FILE_LAZYIO;
+ else
+ want = CEPH_CAP_FILE_CACHE;
+ ret = ceph_get_caps(ci, CEPH_CAP_FILE_RD, want, &got, -1);
if (ret < 0)
goto out;
dout("aio_read %p %llx.%llx %llu~%u got cap refs on %s\n",
inode, ceph_vinop(inode), pos, (unsigned)len,
ceph_cap_string(got));
- if ((got & CEPH_CAP_FILE_CACHE) == 0 ||
+ if ((got & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_LAZYIO)) == 0 ||
(iocb->ki_filp->f_flags & O_DIRECT) ||
(inode->i_sb->s_flags & MS_SYNCHRONOUS))
/* hmm, this isn't really async... */
@@ -807,11 +811,12 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct file *file = iocb->ki_filp;
+ struct ceph_file_info *fi = file->private_data;
struct inode *inode = file->f_dentry->d_inode;
struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_osd_client *osdc = &ceph_sb_to_client(inode->i_sb)->osdc;
loff_t endoff = pos + iov->iov_len;
- int got = 0;
+ int want, got = 0;
int ret, err;
if (ceph_snap(inode) != CEPH_NOSNAP)
@@ -824,8 +829,11 @@ retry_snap:
dout("aio_write %p %llx.%llx %llu~%u getting caps. i_size %llu\n",
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
inode->i_size);
- ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, CEPH_CAP_FILE_BUFFER,
- &got, endoff);
+ if (fi->fmode & CEPH_FILE_MODE_LAZY)
+ want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
+ else
+ want = CEPH_CAP_FILE_BUFFER;
+ ret = ceph_get_caps(ci, CEPH_CAP_FILE_WR, want, &got, endoff);
if (ret < 0)
goto out;
@@ -833,7 +841,7 @@ retry_snap:
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len,
ceph_cap_string(got));
- if ((got & CEPH_CAP_FILE_BUFFER) == 0 ||
+ if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
(iocb->ki_filp->f_flags & O_DIRECT) ||
(inode->i_sb->s_flags & MS_SYNCHRONOUS)) {
ret = ceph_sync_write(file, iov->iov_base, iov->iov_len,
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 8f9b9fe8ef9f..6ce61c350934 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -442,8 +442,9 @@ int ceph_fill_file_size(struct inode *inode, int issued,
* the file is either opened or mmaped
*/
if ((issued & (CEPH_CAP_FILE_CACHE|CEPH_CAP_FILE_RD|
- CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER|
- CEPH_CAP_FILE_EXCL)) ||
+ CEPH_CAP_FILE_WR|CEPH_CAP_FILE_BUFFER|
+ CEPH_CAP_FILE_EXCL|
+ CEPH_CAP_FILE_LAZYIO)) ||
mapping_mapped(inode->i_mapping) ||
__ceph_caps_file_wanted(ci)) {
ci->i_truncate_pending++;
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c
index d085f07756b4..76e307d2aba1 100644
--- a/fs/ceph/ioctl.c
+++ b/fs/ceph/ioctl.c
@@ -143,6 +143,27 @@ static long ceph_ioctl_get_dataloc(struct file *file, void __user *arg)
return 0;
}
+static long ceph_ioctl_lazyio(struct file *file)
+{
+ struct ceph_file_info *fi = file->private_data;
+ struct inode *inode = file->f_dentry->d_inode;
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) {
+ spin_lock(&inode->i_lock);
+ ci->i_nr_by_mode[fi->fmode]--;
+ fi->fmode |= CEPH_FILE_MODE_LAZY;
+ ci->i_nr_by_mode[fi->fmode]++;
+ spin_unlock(&inode->i_lock);
+ dout("ioctl_layzio: file %p marked lazy\n", file);
+
+ ceph_check_caps(ci, 0, NULL);
+ } else {
+ dout("ioctl_layzio: file %p already lazy\n", file);
+ }
+ return 0;
+}
+
long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
dout("ioctl file %p cmd %u arg %lu\n", file, cmd, arg);
@@ -155,6 +176,9 @@ long ceph_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case CEPH_IOC_GET_DATALOC:
return ceph_ioctl_get_dataloc(file, (void __user *)arg);
+
+ case CEPH_IOC_LAZYIO:
+ return ceph_ioctl_lazyio(file);
}
return -ENOTTY;
}
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h
index 25e4f1a9d059..88451a3b6857 100644
--- a/fs/ceph/ioctl.h
+++ b/fs/ceph/ioctl.h
@@ -37,4 +37,6 @@ struct ceph_ioctl_dataloc {
#define CEPH_IOC_GET_DATALOC _IOWR(CEPH_IOCTL_MAGIC, 3, \
struct ceph_ioctl_dataloc)
+#define CEPH_IOC_LAZYIO _IO(CEPH_IOCTL_MAGIC, 4)
+
#endif
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 80f352596807..5739fd7f88b4 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -131,6 +131,15 @@ config CIFS_DFS_UPCALL
IP addresses) which is needed for implicit mounts of DFS junction
points. If unsure, say N.
+config CIFS_FSCACHE
+ bool "Provide CIFS client caching support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL
+ depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
+ help
+ Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
+ to be cached locally on disk through the general filesystem cache
+ manager. If unsure, say N.
+
config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index a88479ceaad5..6113427651c4 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -16,6 +16,9 @@
* the GNU Lesser General Public License for more details.
*
*/
+#ifndef _CIFS_GLOB_H
+#define _CIFS_GLOB_H
+
#include <linux/in.h>
#include <linux/in6.h>
#include <linux/slab.h>
@@ -142,7 +145,6 @@ struct TCP_Server_Info {
struct list_head pending_mid_q;
void *Server_NlsInfo; /* BB - placeholder for future NLS info */
unsigned short server_codepage; /* codepage for the server */
- unsigned long ip_address; /* IP addr for the server if known */
enum protocolEnum protocolType;
char versionMajor;
char versionMinor;
@@ -733,3 +735,5 @@ GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
extern const struct slow_work_ops cifs_oplock_break_ops;
+
+#endif /* _CIFS_GLOB_H */
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index e7ae78b66fa1..a7de5e9fff11 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -130,12 +130,6 @@ cifs_bp_rename_retry:
return full_path;
}
-/*
- * When called with struct file pointer set to NULL, there is no way we could
- * update file->private_data, but getting it stuck on openFileList provides a
- * way to access it from cifs_fill_filedata and thereby set file->private_data
- * from cifs_open.
- */
struct cifsFileInfo *
cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
struct file *file, struct vfsmount *mnt, unsigned int oflags)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 6f0683c68952..107c84dc607b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1780,14 +1780,12 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
xid = GetXid();
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
- /* check if we have permission to change attrs */
- rc = inode_change_ok(inode, attrs);
- if (rc < 0)
- goto out;
- else
- rc = 0;
- }
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
+ attrs->ia_valid |= ATTR_FORCE;
+
+ rc = inode_change_ok(inode, attrs);
+ if (rc < 0)
+ goto out;
full_path = build_path_from_dentry(direntry);
if (full_path == NULL) {
@@ -1873,18 +1871,27 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
CIFS_MOUNT_MAP_SPECIAL_CHR);
}
- if (!rc) {
- rc = inode_setattr(inode, attrs);
+ if (rc)
+ goto out;
- /* force revalidate when any of these times are set since some
- of the fs types (eg ext3, fat) do not have fine enough
- time granularity to match protocol, and we do not have a
- a way (yet) to query the server fs's time granularity (and
- whether it rounds times down).
- */
- if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
- cifsInode->time = 0;
+ if ((attrs->ia_valid & ATTR_SIZE) &&
+ attrs->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, attrs->ia_size);
+ if (rc)
+ goto out;
}
+
+ setattr_copy(inode, attrs);
+ mark_inode_dirty(inode);
+
+ /* force revalidate when any of these times are set since some
+ of the fs types (eg ext3, fat) do not have fine enough
+ time granularity to match protocol, and we do not have a
+ a way (yet) to query the server fs's time granularity (and
+ whether it rounds times down).
+ */
+ if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
+ cifsInode->time = 0;
out:
kfree(args);
kfree(full_path);
@@ -1909,14 +1916,13 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
direntry->d_name.name, attrs->ia_valid);
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
- /* check if we have permission to change attrs */
- rc = inode_change_ok(inode, attrs);
- if (rc < 0) {
- FreeXid(xid);
- return rc;
- } else
- rc = 0;
+ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
+ attrs->ia_valid |= ATTR_FORCE;
+
+ rc = inode_change_ok(inode, attrs);
+ if (rc < 0) {
+ FreeXid(xid);
+ return rc;
}
full_path = build_path_from_dentry(direntry);
@@ -2024,8 +2030,20 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
/* do not need local check to inode_check_ok since the server does
that */
- if (!rc)
- rc = inode_setattr(inode, attrs);
+ if (rc)
+ goto cifs_setattr_exit;
+
+ if ((attrs->ia_valid & ATTR_SIZE) &&
+ attrs->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, attrs->ia_size);
+ if (rc)
+ goto cifs_setattr_exit;
+ }
+
+ setattr_copy(inode, attrs);
+ mark_inode_dirty(inode);
+ return 0;
+
cifs_setattr_exit:
kfree(full_path);
FreeXid(xid);
diff --git a/fs/coda/inode.c b/fs/coda/inode.c
index d97f9935a028..6526e6f21ecf 100644
--- a/fs/coda/inode.c
+++ b/fs/coda/inode.c
@@ -35,7 +35,7 @@
#include "coda_int.h"
/* VFS super_block ops */
-static void coda_clear_inode(struct inode *);
+static void coda_evict_inode(struct inode *);
static void coda_put_super(struct super_block *);
static int coda_statfs(struct dentry *dentry, struct kstatfs *buf);
@@ -93,7 +93,7 @@ static const struct super_operations coda_super_operations =
{
.alloc_inode = coda_alloc_inode,
.destroy_inode = coda_destroy_inode,
- .clear_inode = coda_clear_inode,
+ .evict_inode = coda_evict_inode,
.put_super = coda_put_super,
.statfs = coda_statfs,
.remount_fs = coda_remount,
@@ -224,8 +224,10 @@ static void coda_put_super(struct super_block *sb)
printk("Coda: Bye bye.\n");
}
-static void coda_clear_inode(struct inode *inode)
+static void coda_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
coda_cache_clear_inode(inode);
}
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index dd3634e4c967..a53b130b366c 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -39,66 +39,55 @@ static DEFINE_MUTEX(read_mutex);
#define CRAMINO(x) (((x)->offset && (x)->size)?(x)->offset<<2:1)
#define OFFSET(x) ((x)->i_ino)
-
-static int cramfs_iget5_test(struct inode *inode, void *opaque)
-{
- struct cramfs_inode *cramfs_inode = opaque;
- return inode->i_ino == CRAMINO(cramfs_inode) && inode->i_ino != 1;
-}
-
-static int cramfs_iget5_set(struct inode *inode, void *opaque)
+static void setup_inode(struct inode *inode, struct cramfs_inode * cramfs_inode)
{
- struct cramfs_inode *cramfs_inode = opaque;
- inode->i_ino = CRAMINO(cramfs_inode);
- return 0;
+ static struct timespec zerotime;
+ inode->i_mode = cramfs_inode->mode;
+ inode->i_uid = cramfs_inode->uid;
+ inode->i_size = cramfs_inode->size;
+ inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
+ inode->i_gid = cramfs_inode->gid;
+ /* Struct copy intentional */
+ inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
+ /* inode->i_nlink is left 1 - arguably wrong for directories,
+ but it's the best we can do without reading the directory
+ contents. 1 yields the right result in GNU find, even
+ without -noleaf option. */
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_fop = &generic_ro_fops;
+ inode->i_data.a_ops = &cramfs_aops;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_op = &cramfs_dir_inode_operations;
+ inode->i_fop = &cramfs_directory_operations;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &page_symlink_inode_operations;
+ inode->i_data.a_ops = &cramfs_aops;
+ } else {
+ init_special_inode(inode, inode->i_mode,
+ old_decode_dev(cramfs_inode->size));
+ }
}
static struct inode *get_cramfs_inode(struct super_block *sb,
struct cramfs_inode * cramfs_inode)
{
- struct inode *inode = iget5_locked(sb, CRAMINO(cramfs_inode),
- cramfs_iget5_test, cramfs_iget5_set,
- cramfs_inode);
- static struct timespec zerotime;
-
- if (inode && (inode->i_state & I_NEW)) {
- inode->i_mode = cramfs_inode->mode;
- inode->i_uid = cramfs_inode->uid;
- inode->i_size = cramfs_inode->size;
- inode->i_blocks = (cramfs_inode->size - 1) / 512 + 1;
- inode->i_gid = cramfs_inode->gid;
- /* Struct copy intentional */
- inode->i_mtime = inode->i_atime = inode->i_ctime = zerotime;
- /* inode->i_nlink is left 1 - arguably wrong for directories,
- but it's the best we can do without reading the directory
- contents. 1 yields the right result in GNU find, even
- without -noleaf option. */
- if (S_ISREG(inode->i_mode)) {
- inode->i_fop = &generic_ro_fops;
- inode->i_data.a_ops = &cramfs_aops;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &cramfs_dir_inode_operations;
- inode->i_fop = &cramfs_directory_operations;
- } else if (S_ISLNK(inode->i_mode)) {
- inode->i_op = &page_symlink_inode_operations;
- inode->i_data.a_ops = &cramfs_aops;
- } else {
- init_special_inode(inode, inode->i_mode,
- old_decode_dev(cramfs_inode->size));
+ struct inode *inode;
+ if (CRAMINO(cramfs_inode) == 1) {
+ inode = new_inode(sb);
+ if (inode) {
+ inode->i_ino = 1;
+ setup_inode(inode, cramfs_inode);
+ }
+ } else {
+ inode = iget_locked(sb, CRAMINO(cramfs_inode));
+ if (inode) {
+ setup_inode(inode, cramfs_inode);
+ unlock_new_inode(inode);
}
- unlock_new_inode(inode);
}
return inode;
}
-static void cramfs_drop_inode(struct inode *inode)
-{
- if (inode->i_ino == 1)
- generic_delete_inode(inode);
- else
- generic_drop_inode(inode);
-}
-
/*
* We have our own block cache: don't fill up the buffer cache
* with the rom-image, because the way the filesystem is set
@@ -542,7 +531,6 @@ static const struct super_operations cramfs_ops = {
.put_super = cramfs_put_super,
.remount_fs = cramfs_remount,
.statfs = cramfs_statfs,
- .drop_inode = cramfs_drop_inode,
};
static int cramfs_get_sb(struct file_system_type *fs_type,
diff --git a/fs/dcache.c b/fs/dcache.c
index c8c78ba07827..c0165e4632b2 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -2049,16 +2049,12 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen,
/*
* Write full pathname from the root of the filesystem into the buffer.
*/
-char *dentry_path(struct dentry *dentry, char *buf, int buflen)
+char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
{
char *end = buf + buflen;
char *retval;
- spin_lock(&dcache_lock);
prepend(&end, &buflen, "\0", 1);
- if (d_unlinked(dentry) &&
- (prepend(&end, &buflen, "//deleted", 9) != 0))
- goto Elong;
if (buflen < 1)
goto Elong;
/* Get '/' right */
@@ -2076,7 +2072,28 @@ char *dentry_path(struct dentry *dentry, char *buf, int buflen)
retval = end;
dentry = parent;
}
+ return retval;
+Elong:
+ return ERR_PTR(-ENAMETOOLONG);
+}
+EXPORT_SYMBOL(__dentry_path);
+
+char *dentry_path(struct dentry *dentry, char *buf, int buflen)
+{
+ char *p = NULL;
+ char *retval;
+
+ spin_lock(&dcache_lock);
+ if (d_unlinked(dentry)) {
+ p = buf + buflen;
+ if (prepend(&p, &buflen, "//deleted", 10) != 0)
+ goto Elong;
+ buflen++;
+ }
+ retval = __dentry_path(dentry, buf, buflen);
spin_unlock(&dcache_lock);
+ if (!IS_ERR(retval) && p)
+ *p = '/'; /* restore '/' overriden with '\0' */
return retval;
Elong:
spin_unlock(&dcache_lock);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 7600aacf531d..88b1ab2354fa 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1134,8 +1134,27 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
return ret;
}
+/*
+ * This is a library function for use by filesystem drivers.
+ *
+ * The locking rules are governed by the flags parameter:
+ * - if the flags value contains DIO_LOCKING we use a fancy locking
+ * scheme for dumb filesystems.
+ * For writes this function is called under i_mutex and returns with
+ * i_mutex held, for reads, i_mutex is not held on entry, but it is
+ * taken and dropped again before returning.
+ * For reads and writes i_alloc_sem is taken in shared mode and released
+ * on I/O completion (which may happen asynchronously after returning to
+ * the caller).
+ *
+ * - if the flags value does NOT contain DIO_LOCKING we don't use any
+ * internal locking but rather rely on the filesystem to synchronize
+ * direct I/O reads/writes versus each other and truncate.
+ * For reads and writes both i_mutex and i_alloc_sem are not held on
+ * entry and are never taken.
+ */
ssize_t
-__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
+__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
struct block_device *bdev, const struct iovec *iov, loff_t offset,
unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
dio_submit_t submit_io, int flags)
@@ -1231,57 +1250,4 @@ __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
out:
return retval;
}
-EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc);
-
-/*
- * This is a library function for use by filesystem drivers.
- *
- * The locking rules are governed by the flags parameter:
- * - if the flags value contains DIO_LOCKING we use a fancy locking
- * scheme for dumb filesystems.
- * For writes this function is called under i_mutex and returns with
- * i_mutex held, for reads, i_mutex is not held on entry, but it is
- * taken and dropped again before returning.
- * For reads and writes i_alloc_sem is taken in shared mode and released
- * on I/O completion (which may happen asynchronously after returning to
- * the caller).
- *
- * - if the flags value does NOT contain DIO_LOCKING we don't use any
- * internal locking but rather rely on the filesystem to synchronize
- * direct I/O reads/writes versus each other and truncate.
- * For reads and writes both i_mutex and i_alloc_sem are not held on
- * entry and are never taken.
- */
-ssize_t
-__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
- struct block_device *bdev, const struct iovec *iov, loff_t offset,
- unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
- dio_submit_t submit_io, int flags)
-{
- ssize_t retval;
-
- retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov,
- offset, nr_segs, get_block, end_io, submit_io, flags);
- /*
- * In case of error extending write may have instantiated a few
- * blocks outside i_size. Trim these off again for DIO_LOCKING.
- * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in
- * their own manner. This is a further example of where the old
- * truncate sequence is inadequate.
- *
- * NOTE: filesystems with their own locking have to handle this
- * on their own.
- */
- if (flags & DIO_LOCKING) {
- if (unlikely((rw & WRITE) && retval < 0)) {
- loff_t isize = i_size_read(inode);
- loff_t end = offset + iov_length(iov, nr_segs);
-
- if (end > isize)
- vmtruncate(inode, isize);
- }
- }
-
- return retval;
-}
EXPORT_SYMBOL(__blockdev_direct_IO);
diff --git a/fs/drop_caches.c b/fs/drop_caches.c
index 83c4f600786a..2195c213ab2f 100644
--- a/fs/drop_caches.c
+++ b/fs/drop_caches.c
@@ -18,7 +18,7 @@ static void drop_pagecache_sb(struct super_block *sb, void *unused)
spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
+ if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue;
if (inode->i_mapping->nrpages == 0)
continue;
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index e8fcf4e2ed7d..6e4f84cf73e8 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -292,12 +292,40 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
return rc;
}
-static int ecryptfs_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
+static long
+ecryptfs_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct file *lower_file = NULL;
+ long rc = -ENOTTY;
+
+ if (ecryptfs_file_to_private(file))
+ lower_file = ecryptfs_file_to_lower(file);
+ if (lower_file && lower_file->f_op && lower_file->f_op->unlocked_ioctl)
+ rc = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
+ return rc;
+}
+
+#ifdef CONFIG_COMPAT
+static long
+ecryptfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct file *lower_file = NULL;
+ long rc = -ENOIOCTLCMD;
+
+ if (ecryptfs_file_to_private(file))
+ lower_file = ecryptfs_file_to_lower(file);
+ if (lower_file && lower_file->f_op && lower_file->f_op->compat_ioctl)
+ rc = lower_file->f_op->compat_ioctl(lower_file, cmd, arg);
+ return rc;
+}
+#endif
const struct file_operations ecryptfs_dir_fops = {
.readdir = ecryptfs_readdir,
- .ioctl = ecryptfs_ioctl,
+ .unlocked_ioctl = ecryptfs_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ecryptfs_compat_ioctl,
+#endif
.open = ecryptfs_open,
.flush = ecryptfs_flush,
.release = ecryptfs_release,
@@ -313,7 +341,10 @@ const struct file_operations ecryptfs_main_fops = {
.write = do_sync_write,
.aio_write = generic_file_aio_write,
.readdir = ecryptfs_readdir,
- .ioctl = ecryptfs_ioctl,
+ .unlocked_ioctl = ecryptfs_unlocked_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = ecryptfs_compat_ioctl,
+#endif
.mmap = generic_file_mmap,
.open = ecryptfs_open,
.flush = ecryptfs_flush,
@@ -322,20 +353,3 @@ const struct file_operations ecryptfs_main_fops = {
.fasync = ecryptfs_fasync,
.splice_read = generic_file_splice_read,
};
-
-static int
-ecryptfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- int rc = 0;
- struct file *lower_file = NULL;
-
- if (ecryptfs_file_to_private(file))
- lower_file = ecryptfs_file_to_lower(file);
- if (lower_file && lower_file->f_op && lower_file->f_op->ioctl)
- rc = lower_file->f_op->ioctl(ecryptfs_inode_to_lower(inode),
- lower_file, cmd, arg);
- else
- rc = -ENOTTY;
- return rc;
-}
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 31ef5252f0fe..82900b063b1e 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -804,10 +804,20 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
size_t num_zeros = (PAGE_CACHE_SIZE
- (ia->ia_size & ~PAGE_CACHE_MASK));
+
+ /*
+ * XXX(truncate) this should really happen at the begginning
+ * of ->setattr. But the code is too messy to that as part
+ * of a larger patch. ecryptfs is also totally missing out
+ * on the inode_change_ok check at the beginning of
+ * ->setattr while would include this.
+ */
+ rc = inode_newsize_ok(inode, ia->ia_size);
+ if (rc)
+ goto out;
+
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
- rc = simple_setsize(inode, ia->ia_size);
- if (rc)
- goto out;
+ truncate_setsize(inode, ia->ia_size);
lower_ia->ia_size = ia->ia_size;
lower_ia->ia_valid |= ATTR_SIZE;
goto out;
@@ -830,7 +840,7 @@ static int truncate_upper(struct dentry *dentry, struct iattr *ia,
goto out;
}
}
- simple_setsize(inode, ia->ia_size);
+ truncate_setsize(inode, ia->ia_size);
rc = ecryptfs_write_inode_size_to_metadata(inode);
if (rc) {
printk(KERN_ERR "Problem with "
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index 2d8dbce9d485..5cd806258d59 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -274,7 +274,7 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid,
struct user_namespace *user_ns, struct pid *pid,
u32 seq)
{
- struct ecryptfs_daemon *daemon;
+ struct ecryptfs_daemon *uninitialized_var(daemon);
struct ecryptfs_msg_ctx *msg_ctx;
size_t msg_size;
struct nsproxy *nsproxy;
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 0435886e4a9f..4b5de6c6e0fa 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -122,7 +122,7 @@ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
}
/**
- * ecryptfs_clear_inode
+ * ecryptfs_evict_inode
* @inode - The ecryptfs inode
*
* Called by iput() when the inode reference count reached zero
@@ -131,8 +131,10 @@ static int ecryptfs_statfs(struct dentry *dentry, struct kstatfs *buf)
* on the inode free list. We use this to drop out reference to the
* lower inode.
*/
-static void ecryptfs_clear_inode(struct inode *inode)
+static void ecryptfs_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
iput(ecryptfs_inode_to_lower(inode));
}
@@ -184,6 +186,6 @@ const struct super_operations ecryptfs_sops = {
.drop_inode = generic_delete_inode,
.statfs = ecryptfs_statfs,
.remount_fs = NULL,
- .clear_inode = ecryptfs_clear_inode,
+ .evict_inode = ecryptfs_evict_inode,
.show_options = ecryptfs_show_options
};
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h
index 22721b2fd890..2dc925fa1010 100644
--- a/fs/exofs/exofs.h
+++ b/fs/exofs/exofs.h
@@ -256,7 +256,6 @@ static inline int exofs_oi_read(struct exofs_i_info *oi,
}
/* inode.c */
-void exofs_truncate(struct inode *inode);
int exofs_setattr(struct dentry *, struct iattr *);
int exofs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
@@ -264,7 +263,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
extern struct inode *exofs_iget(struct super_block *, unsigned long);
struct inode *exofs_new_inode(struct inode *, int);
extern int exofs_write_inode(struct inode *, struct writeback_control *wbc);
-extern void exofs_delete_inode(struct inode *);
+extern void exofs_evict_inode(struct inode *);
/* dir.c: */
int exofs_add_link(struct dentry *, struct inode *);
diff --git a/fs/exofs/file.c b/fs/exofs/file.c
index fef6899be397..f9bfe2b501d5 100644
--- a/fs/exofs/file.c
+++ b/fs/exofs/file.c
@@ -86,6 +86,5 @@ const struct file_operations exofs_file_operations = {
};
const struct inode_operations exofs_file_inode_operations = {
- .truncate = exofs_truncate,
.setattr = exofs_setattr,
};
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c
index 4bb6ef822e46..088cb476b68a 100644
--- a/fs/exofs/inode.c
+++ b/fs/exofs/inode.c
@@ -697,6 +697,13 @@ static int exofs_writepage(struct page *page, struct writeback_control *wbc)
return write_exec(&pcol);
}
+/* i_mutex held using inode->i_size directly */
+static void _write_failed(struct inode *inode, loff_t to)
+{
+ if (to > inode->i_size)
+ truncate_pagecache(inode, to, inode->i_size);
+}
+
int exofs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
@@ -710,7 +717,7 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
fsdata);
if (ret) {
EXOFS_DBGMSG("simple_write_begin faild\n");
- return ret;
+ goto out;
}
page = *pagep;
@@ -725,6 +732,9 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,
EXOFS_DBGMSG("__readpage_filler faild\n");
}
}
+out:
+ if (unlikely(ret))
+ _write_failed(mapping->host, pos + len);
return ret;
}
@@ -750,6 +760,10 @@ static int exofs_write_end(struct file *file, struct address_space *mapping,
int ret;
ret = simple_write_end(file, mapping,pos, len, copied, page, fsdata);
+ if (unlikely(ret))
+ _write_failed(inode, pos + len);
+
+ /* TODO: once simple_write_end marks inode dirty remove */
if (i_size != inode->i_size)
mark_inode_dirty(inode);
return ret;
@@ -808,87 +822,55 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode)
return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);
}
-/*
- * get_block_t - Fill in a buffer_head
- * An OSD takes care of block allocation so we just fake an allocation by
- * putting in the inode's sector_t in the buffer_head.
- * TODO: What about the case of create==0 and @iblock does not exist in the
- * object?
- */
-static int exofs_get_block(struct inode *inode, sector_t iblock,
- struct buffer_head *bh_result, int create)
-{
- map_bh(bh_result, inode->i_sb, iblock);
- return 0;
-}
-
const struct osd_attr g_attr_logical_length = ATTR_DEF(
OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8);
-static int _do_truncate(struct inode *inode)
+static int _do_truncate(struct inode *inode, loff_t newsize)
{
struct exofs_i_info *oi = exofs_i(inode);
- loff_t isize = i_size_read(inode);
int ret;
inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- nobh_truncate_page(inode->i_mapping, isize, exofs_get_block);
+ ret = exofs_oi_truncate(oi, (u64)newsize);
+ if (likely(!ret))
+ truncate_setsize(inode, newsize);
- ret = exofs_oi_truncate(oi, (u64)isize);
- EXOFS_DBGMSG("(0x%lx) size=0x%llx\n", inode->i_ino, isize);
+ EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n",
+ inode->i_ino, newsize, ret);
return ret;
}
/*
- * Truncate a file to the specified size - all we have to do is set the size
- * attribute. We make sure the object exists first.
- */
-void exofs_truncate(struct inode *inode)
-{
- struct exofs_i_info *oi = exofs_i(inode);
- int ret;
-
- if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
- || S_ISLNK(inode->i_mode)))
- return;
- if (exofs_inode_is_fast_symlink(inode))
- return;
- if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
- return;
-
- /* if we are about to truncate an object, and it hasn't been
- * created yet, wait
- */
- if (unlikely(wait_obj_created(oi)))
- goto fail;
-
- ret = _do_truncate(inode);
- if (ret)
- goto fail;
-
-out:
- mark_inode_dirty(inode);
- return;
-fail:
- make_bad_inode(inode);
- goto out;
-}
-
-/*
- * Set inode attributes - just call generic functions.
+ * Set inode attributes - update size attribute on OSD if needed,
+ * otherwise just call generic functions.
*/
int exofs_setattr(struct dentry *dentry, struct iattr *iattr)
{
struct inode *inode = dentry->d_inode;
int error;
+ /* if we are about to modify an object, and it hasn't been
+ * created yet, wait
+ */
+ error = wait_obj_created(exofs_i(inode));
+ if (unlikely(error))
+ return error;
+
error = inode_change_ok(inode, iattr);
- if (error)
+ if (unlikely(error))
return error;
- error = inode_setattr(inode, iattr);
- return error;
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(inode)) {
+ error = _do_truncate(inode, iattr->ia_size);
+ if (unlikely(error))
+ return error;
+ }
+
+ setattr_copy(inode, iattr);
+ mark_inode_dirty(inode);
+ return 0;
}
static const struct osd_attr g_attr_inode_file_layout = ATTR_DEF(
@@ -1325,7 +1307,7 @@ static void delete_done(struct exofs_io_state *ios, void *p)
* from the OSD here. We make sure the object was created before we try and
* delete it.
*/
-void exofs_delete_inode(struct inode *inode)
+void exofs_evict_inode(struct inode *inode)
{
struct exofs_i_info *oi = exofs_i(inode);
struct super_block *sb = inode->i_sb;
@@ -1335,30 +1317,27 @@ void exofs_delete_inode(struct inode *inode)
truncate_inode_pages(&inode->i_data, 0);
- if (is_bad_inode(inode))
+ /* TODO: should do better here */
+ if (inode->i_nlink || is_bad_inode(inode))
goto no_delete;
- mark_inode_dirty(inode);
- exofs_update_inode(inode, inode_needs_sync(inode));
-
inode->i_size = 0;
- if (inode->i_blocks)
- exofs_truncate(inode);
+ end_writeback(inode);
- clear_inode(inode);
+ /* if we are deleting an obj that hasn't been created yet, wait */
+ if (!obj_created(oi)) {
+ BUG_ON(!obj_2bcreated(oi));
+ wait_event(oi->i_wq, obj_created(oi));
+ /* ignore the error attempt a remove anyway */
+ }
+ /* Now Remove the OSD objects */
ret = exofs_get_io_state(&sbi->layout, &ios);
if (unlikely(ret)) {
EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__);
return;
}
- /* if we are deleting an obj that hasn't been created yet, wait */
- if (!obj_created(oi)) {
- BUG_ON(!obj_2bcreated(oi));
- wait_event(oi->i_wq, obj_created(oi));
- }
-
ios->obj.id = exofs_oi_objno(oi);
ios->done = delete_done;
ios->private = sbi;
@@ -1374,5 +1353,5 @@ void exofs_delete_inode(struct inode *inode)
return;
no_delete:
- clear_inode(inode);
+ end_writeback(inode);
}
diff --git a/fs/exofs/super.c b/fs/exofs/super.c
index 03149b9a5178..32cfd61def5f 100644
--- a/fs/exofs/super.c
+++ b/fs/exofs/super.c
@@ -743,7 +743,7 @@ static const struct super_operations exofs_sops = {
.alloc_inode = exofs_alloc_inode,
.destroy_inode = exofs_destroy_inode,
.write_inode = exofs_write_inode,
- .delete_inode = exofs_delete_inode,
+ .evict_inode = exofs_evict_inode,
.put_super = exofs_put_super,
.write_super = exofs_write_super,
.sync_fs = exofs_sync_fs,
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 7516957273ed..764109886ec0 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -448,6 +448,11 @@ ino_t ext2_inode_by_name(struct inode *dir, struct qstr *child)
return res;
}
+static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
+{
+ return __block_write_begin(page, pos, len, ext2_get_block);
+}
+
/* Releases the page */
void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
struct page *page, struct inode *inode, int update_times)
@@ -458,8 +463,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
int err;
lock_page(page);
- err = __ext2_write_begin(NULL, page->mapping, pos, len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = ext2_prepare_chunk(page, pos, len);
BUG_ON(err);
de->inode = cpu_to_le32(inode->i_ino);
ext2_set_de_type(de, inode);
@@ -542,8 +546,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
got_it:
pos = page_offset(page) +
(char*)de - (char*)page_address(page);
- err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
- &page, NULL);
+ err = ext2_prepare_chunk(page, pos, rec_len);
if (err)
goto out_unlock;
if (de->inode) {
@@ -576,8 +579,7 @@ out_unlock:
*/
int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = mapping->host;
+ struct inode *inode = page->mapping->host;
char *kaddr = page_address(page);
unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
unsigned to = ((char *)dir - kaddr) +
@@ -601,8 +603,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
from = (char*)pde - (char*)page_address(page);
pos = page_offset(page) + from;
lock_page(page);
- err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
- &page, NULL);
+ err = ext2_prepare_chunk(page, pos, to - from);
BUG_ON(err);
if (pde)
pde->rec_len = ext2_rec_len_to_disk(to - from);
@@ -621,8 +622,7 @@ out:
*/
int ext2_make_empty(struct inode *inode, struct inode *parent)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct page *page = grab_cache_page(inode->i_mapping, 0);
unsigned chunk_size = ext2_chunk_size(inode);
struct ext2_dir_entry_2 * de;
int err;
@@ -631,8 +631,7 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
if (!page)
return -ENOMEM;
- err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
- &page, NULL);
+ err = ext2_prepare_chunk(page, 0, chunk_size);
if (err) {
unlock_page(page);
goto fail;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 52b34f1d2738..416daa62242c 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -119,7 +119,7 @@ extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
/* inode.c */
extern struct inode *ext2_iget (struct super_block *, unsigned long);
extern int ext2_write_inode (struct inode *, struct writeback_control *);
-extern void ext2_delete_inode (struct inode *);
+extern void ext2_evict_inode(struct inode *);
extern int ext2_sync_inode (struct inode *);
extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int);
extern int ext2_setattr (struct dentry *, struct iattr *);
@@ -127,9 +127,6 @@ extern void ext2_set_inode_flags(struct inode *inode);
extern void ext2_get_inode_flags(struct ext2_inode_info *);
extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len);
-int __ext2_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
/* ioctl.c */
extern long ext2_ioctl(struct file *, unsigned int, unsigned long);
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 938dbc739d00..ad70479aabff 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -118,19 +118,14 @@ void ext2_free_inode (struct inode * inode)
* Note: we must free any quota before locking the superblock,
* as writing the quota to disk may need the lock as well.
*/
- if (!is_bad_inode(inode)) {
- /* Quota is already initialized in iput() */
- ext2_xattr_delete_inode(inode);
- dquot_free_inode(inode);
- dquot_drop(inode);
- }
+ /* Quota is already initialized in iput() */
+ ext2_xattr_delete_inode(inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
es = EXT2_SB(sb)->s_es;
is_directory = S_ISDIR(inode->i_mode);
- /* Do this BEFORE marking the inode not in use or returning an error */
- clear_inode (inode);
-
if (ino < EXT2_FIRST_INO(sb) ||
ino > le32_to_cpu(es->s_inodes_count)) {
ext2_error (sb, "ext2_free_inode",
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 3675088cb88c..7e4a4554de08 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -69,26 +69,42 @@ static void ext2_write_failed(struct address_space *mapping, loff_t to)
/*
* Called at the last iput() if i_nlink is zero.
*/
-void ext2_delete_inode (struct inode * inode)
+void ext2_evict_inode(struct inode * inode)
{
- if (!is_bad_inode(inode))
+ struct ext2_block_alloc_info *rsv;
+ int want_delete = 0;
+
+ if (!inode->i_nlink && !is_bad_inode(inode)) {
+ want_delete = 1;
dquot_initialize(inode);
+ } else {
+ dquot_drop(inode);
+ }
+
truncate_inode_pages(&inode->i_data, 0);
- if (is_bad_inode(inode))
- goto no_delete;
- EXT2_I(inode)->i_dtime = get_seconds();
- mark_inode_dirty(inode);
- __ext2_write_inode(inode, inode_needs_sync(inode));
+ if (want_delete) {
+ /* set dtime */
+ EXT2_I(inode)->i_dtime = get_seconds();
+ mark_inode_dirty(inode);
+ __ext2_write_inode(inode, inode_needs_sync(inode));
+ /* truncate to 0 */
+ inode->i_size = 0;
+ if (inode->i_blocks)
+ ext2_truncate_blocks(inode, 0);
+ }
- inode->i_size = 0;
- if (inode->i_blocks)
- ext2_truncate_blocks(inode, 0);
- ext2_free_inode (inode);
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
- return;
-no_delete:
- clear_inode(inode); /* We must guarantee clearing of inode... */
+ ext2_discard_reservation(inode);
+ rsv = EXT2_I(inode)->i_block_alloc_info;
+ EXT2_I(inode)->i_block_alloc_info = NULL;
+ if (unlikely(rsv))
+ kfree(rsv);
+
+ if (want_delete)
+ ext2_free_inode(inode);
}
typedef struct {
@@ -765,14 +781,6 @@ ext2_readpages(struct file *file, struct address_space *mapping,
return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
}
-int __ext2_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
- return block_write_begin_newtrunc(file, mapping, pos, len, flags,
- pagep, fsdata, ext2_get_block);
-}
-
static int
ext2_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
@@ -780,8 +788,8 @@ ext2_write_begin(struct file *file, struct address_space *mapping,
{
int ret;
- *pagep = NULL;
- ret = __ext2_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ ext2_get_block);
if (ret < 0)
ext2_write_failed(mapping, pos + len);
return ret;
@@ -806,13 +814,8 @@ ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
{
int ret;
- /*
- * Dir-in-pagecache still uses ext2_write_begin. Would have to rework
- * directory handling code to pass around offsets rather than struct
- * pages in order to make this work easily.
- */
- ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags, pagep,
- fsdata, ext2_get_block);
+ ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
+ ext2_get_block);
if (ret < 0)
ext2_write_failed(mapping, pos + len);
return ret;
@@ -838,7 +841,7 @@ ext2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
struct inode *inode = mapping->host;
ssize_t ret;
- ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev,
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
iov, offset, nr_segs, ext2_get_block, NULL);
if (ret < 0 && (rw & WRITE))
ext2_write_failed(mapping, offset + iov_length(iov, nr_segs));
@@ -1169,15 +1172,10 @@ static void ext2_truncate_blocks(struct inode *inode, loff_t offset)
__ext2_truncate_blocks(inode, offset);
}
-int ext2_setsize(struct inode *inode, loff_t newsize)
+static int ext2_setsize(struct inode *inode, loff_t newsize)
{
- loff_t oldsize;
int error;
- error = inode_newsize_ok(inode, newsize);
- if (error)
- return error;
-
if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
S_ISLNK(inode->i_mode)))
return -EINVAL;
@@ -1197,10 +1195,7 @@ int ext2_setsize(struct inode *inode, loff_t newsize)
if (error)
return error;
- oldsize = inode->i_size;
- i_size_write(inode, newsize);
- truncate_pagecache(inode, oldsize, newsize);
-
+ truncate_setsize(inode, newsize);
__ext2_truncate_blocks(inode, newsize);
inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
@@ -1557,7 +1552,7 @@ int ext2_setattr(struct dentry *dentry, struct iattr *iattr)
if (error)
return error;
}
- generic_setattr(inode, iattr);
+ setattr_copy(inode, iattr);
if (iattr->ia_valid & ATTR_MODE)
error = ext2_acl_chmod(inode);
mark_inode_dirty(inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 7ff43f4a59cd..1ec602673ea8 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -195,17 +195,6 @@ static void destroy_inodecache(void)
kmem_cache_destroy(ext2_inode_cachep);
}
-static void ext2_clear_inode(struct inode *inode)
-{
- struct ext2_block_alloc_info *rsv = EXT2_I(inode)->i_block_alloc_info;
-
- dquot_drop(inode);
- ext2_discard_reservation(inode);
- EXT2_I(inode)->i_block_alloc_info = NULL;
- if (unlikely(rsv))
- kfree(rsv);
-}
-
static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct super_block *sb = vfs->mnt_sb;
@@ -299,13 +288,12 @@ static const struct super_operations ext2_sops = {
.alloc_inode = ext2_alloc_inode,
.destroy_inode = ext2_destroy_inode,
.write_inode = ext2_write_inode,
- .delete_inode = ext2_delete_inode,
+ .evict_inode = ext2_evict_inode,
.put_super = ext2_put_super,
.write_super = ext2_write_super,
.sync_fs = ext2_sync_fs,
.statfs = ext2_statfs,
.remount_fs = ext2_remount,
- .clear_inode = ext2_clear_inode,
.show_options = ext2_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ext2_quota_read,
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
index 498021eb88fb..4ab72db3559e 100644
--- a/fs/ext3/ialloc.c
+++ b/fs/ext3/ialloc.c
@@ -119,20 +119,8 @@ void ext3_free_inode (handle_t *handle, struct inode * inode)
ino = inode->i_ino;
ext3_debug ("freeing inode %lu\n", ino);
- /*
- * Note: we must free any quota before locking the superblock,
- * as writing the quota to disk may need the lock as well.
- */
- dquot_initialize(inode);
- ext3_xattr_delete_inode(handle, inode);
- dquot_free_inode(inode);
- dquot_drop(inode);
-
is_directory = S_ISDIR(inode->i_mode);
- /* Do this BEFORE marking the inode not in use or returning an error */
- clear_inode (inode);
-
es = EXT3_SB(sb)->s_es;
if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
ext3_error (sb, "ext3_free_inode",
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 735f0190ec2a..a8d52802f55c 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -190,18 +190,28 @@ static int truncate_restart_transaction(handle_t *handle, struct inode *inode)
}
/*
- * Called at the last iput() if i_nlink is zero.
+ * Called at inode eviction from icache
*/
-void ext3_delete_inode (struct inode * inode)
+void ext3_evict_inode (struct inode *inode)
{
+ struct ext3_block_alloc_info *rsv;
handle_t *handle;
+ int want_delete = 0;
- if (!is_bad_inode(inode))
+ if (!inode->i_nlink && !is_bad_inode(inode)) {
dquot_initialize(inode);
+ want_delete = 1;
+ }
truncate_inode_pages(&inode->i_data, 0);
- if (is_bad_inode(inode))
+ ext3_discard_reservation(inode);
+ rsv = EXT3_I(inode)->i_block_alloc_info;
+ EXT3_I(inode)->i_block_alloc_info = NULL;
+ if (unlikely(rsv))
+ kfree(rsv);
+
+ if (!want_delete)
goto no_delete;
handle = start_transaction(inode);
@@ -220,6 +230,7 @@ void ext3_delete_inode (struct inode * inode)
inode->i_size = 0;
if (inode->i_blocks)
ext3_truncate(inode);
+ end_writeback(inode);
/*
* Kill off the orphan record which ext3_truncate created.
* AKPM: I think this can be inside the above `if'.
@@ -238,15 +249,20 @@ void ext3_delete_inode (struct inode * inode)
* having errors), but we can't free the inode if the mark_dirty
* fails.
*/
- if (ext3_mark_inode_dirty(handle, inode))
- /* If that failed, just do the required in-core inode clear. */
- clear_inode(inode);
- else
+ if (ext3_mark_inode_dirty(handle, inode)) {
+ /* If that failed, just dquot_drop() and be done with that */
+ dquot_drop(inode);
+ } else {
+ ext3_xattr_delete_inode(handle, inode);
+ dquot_free_inode(inode);
+ dquot_drop(inode);
ext3_free_inode(handle, inode);
+ }
ext3_journal_stop(handle);
return;
no_delete:
- clear_inode(inode); /* We must guarantee clearing of inode... */
+ end_writeback(inode);
+ dquot_drop(inode);
}
typedef struct {
@@ -1196,8 +1212,7 @@ retry:
ret = PTR_ERR(handle);
goto out;
}
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext3_get_block);
+ ret = __block_write_begin(page, pos, len, ext3_get_block);
if (ret)
goto write_begin_failed;
@@ -1625,10 +1640,7 @@ static int ext3_writeback_writepage(struct page *page,
goto out_fail;
}
- if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode))
- ret = nobh_writepage(page, ext3_get_block, wbc);
- else
- ret = block_write_full_page(page, ext3_get_block, wbc);
+ ret = block_write_full_page(page, ext3_get_block, wbc);
err = ext3_journal_stop(handle);
if (!ret)
@@ -1785,6 +1797,17 @@ retry:
ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext3_get_block, NULL);
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
goto retry;
@@ -1922,17 +1945,6 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page,
length = blocksize - (offset & (blocksize - 1));
iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits);
- /*
- * For "nobh" option, we can only work if we don't need to
- * read-in the page - otherwise we create buffers to do the IO.
- */
- if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) &&
- ext3_should_writeback_data(inode) && PageUptodate(page)) {
- zero_user(page, offset, length);
- set_page_dirty(page);
- goto unlock;
- }
-
if (!page_has_buffers(page))
create_empty_buffers(page, blocksize, 0);
@@ -2554,7 +2566,7 @@ out_stop:
* If this was a simple ftruncate(), and the file will remain alive
* then we need to clear up the orphan record which we created above.
* However, if this was a real unlink then we were called by
- * ext3_delete_inode(), and we allow that function to clean up the
+ * ext3_evict_inode(), and we allow that function to clean up the
* orphan info for us.
*/
if (inode->i_nlink)
@@ -3198,9 +3210,17 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr)
ext3_journal_stop(handle);
}
- rc = inode_setattr(inode, attr);
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, attr->ia_size);
+ if (rc)
+ goto err_out;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
- if (!rc && (ia_valid & ATTR_MODE))
+ if (ia_valid & ATTR_MODE)
rc = ext3_acl_chmod(inode);
err_out:
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index ee184084ca42..2b35ddb70d65 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1447,7 +1447,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
struct inode *inode)
{
struct inode *dir = dentry->d_parent->d_inode;
- unsigned long offset;
struct buffer_head * bh;
struct ext3_dir_entry_2 *de;
struct super_block * sb;
@@ -1469,7 +1468,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry,
ext3_mark_inode_dirty(handle, dir);
}
blocks = dir->i_size >> sb->s_blocksize_bits;
- for (block = 0, offset = 0; block < blocks; block++) {
+ for (block = 0; block < blocks; block++) {
bh = ext3_bread(handle, dir, block, 0, &retval);
if(!bh)
return retval;
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index 54351ac7cef9..0ccd7b12b73c 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -964,7 +964,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
ext3_fsblk_t n_blocks_count)
{
ext3_fsblk_t o_blocks_count;
- unsigned long o_groups_count;
ext3_grpblk_t last;
ext3_grpblk_t add;
struct buffer_head * bh;
@@ -976,7 +975,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es,
* yet: we're going to revalidate es->s_blocks_count after
* taking the s_resize_lock below. */
o_blocks_count = le32_to_cpu(es->s_blocks_count);
- o_groups_count = EXT3_SB(sb)->s_groups_count;
if (test_opt(sb, DEBUG))
printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n",
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 6c953bb255e7..5dbf4dba03c4 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -527,17 +527,6 @@ static void destroy_inodecache(void)
kmem_cache_destroy(ext3_inode_cachep);
}
-static void ext3_clear_inode(struct inode *inode)
-{
- struct ext3_block_alloc_info *rsv = EXT3_I(inode)->i_block_alloc_info;
-
- dquot_drop(inode);
- ext3_discard_reservation(inode);
- EXT3_I(inode)->i_block_alloc_info = NULL;
- if (unlikely(rsv))
- kfree(rsv);
-}
-
static inline void ext3_show_quota_options(struct seq_file *seq, struct super_block *sb)
{
#if defined(CONFIG_QUOTA)
@@ -661,9 +650,6 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
*/
seq_puts(seq, ",barrier=");
seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0");
- if (test_opt(sb, NOBH))
- seq_puts(seq, ",nobh");
-
seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS)));
if (test_opt(sb, DATA_ERR_ABORT))
seq_puts(seq, ",data_err=abort");
@@ -783,14 +769,13 @@ static const struct super_operations ext3_sops = {
.destroy_inode = ext3_destroy_inode,
.write_inode = ext3_write_inode,
.dirty_inode = ext3_dirty_inode,
- .delete_inode = ext3_delete_inode,
+ .evict_inode = ext3_evict_inode,
.put_super = ext3_put_super,
.sync_fs = ext3_sync_fs,
.freeze_fs = ext3_freeze,
.unfreeze_fs = ext3_unfreeze,
.statfs = ext3_statfs,
.remount_fs = ext3_remount,
- .clear_inode = ext3_clear_inode,
.show_options = ext3_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ext3_quota_read,
@@ -1255,10 +1240,12 @@ set_qf_format:
*n_blocks_count = option;
break;
case Opt_nobh:
- set_opt(sbi->s_mount_opt, NOBH);
+ ext3_msg(sb, KERN_WARNING,
+ "warning: ignoring deprecated nobh option");
break;
case Opt_bh:
- clear_opt(sbi->s_mount_opt, NOBH);
+ ext3_msg(sb, KERN_WARNING,
+ "warning: ignoring deprecated bh option");
break;
default:
ext3_msg(sb, KERN_ERR,
@@ -2001,14 +1988,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
break;
}
- if (test_opt(sb, NOBH)) {
- if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) {
- ext3_msg(sb, KERN_WARNING,
- "warning: ignoring nobh option - "
- "it is supported only with writeback mode");
- clear_opt(sbi->s_mount_opt, NOBH);
- }
- }
/*
* The journal_load will have done any necessary log recovery,
* so we can safely mount the rest of the filesystem now.
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 19a4de57128a..6a0d52ca1434 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1571,7 +1571,8 @@ extern int ext4_write_inode(struct inode *, struct writeback_control *);
extern int ext4_setattr(struct dentry *, struct iattr *);
extern int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
-extern void ext4_delete_inode(struct inode *);
+extern void ext4_evict_inode(struct inode *);
+extern void ext4_clear_inode(struct inode *);
extern int ext4_sync_inode(handle_t *, struct inode *);
extern void ext4_dirty_inode(struct inode *);
extern int ext4_change_inode_journal_flag(struct inode *, int);
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index 25c4b3173fd9..07e791a856da 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -222,7 +222,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode)
is_directory = S_ISDIR(inode->i_mode);
/* Do this BEFORE marking the inode not in use or returning an error */
- clear_inode(inode);
+ ext4_clear_inode(inode);
es = EXT4_SB(sb)->s_es;
if (ino < EXT4_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 42272d67955a..810ee22f1ea1 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -167,11 +167,16 @@ int ext4_truncate_restart_trans(handle_t *handle, struct inode *inode,
/*
* Called at the last iput() if i_nlink is zero.
*/
-void ext4_delete_inode(struct inode *inode)
+void ext4_evict_inode(struct inode *inode)
{
handle_t *handle;
int err;
+ if (inode->i_nlink) {
+ truncate_inode_pages(&inode->i_data, 0);
+ goto no_delete;
+ }
+
if (!is_bad_inode(inode))
dquot_initialize(inode);
@@ -245,13 +250,13 @@ void ext4_delete_inode(struct inode *inode)
*/
if (ext4_mark_inode_dirty(handle, inode))
/* If that failed, just do the required in-core inode clear. */
- clear_inode(inode);
+ ext4_clear_inode(inode);
else
ext4_free_inode(handle, inode);
ext4_journal_stop(handle);
return;
no_delete:
- clear_inode(inode); /* We must guarantee clearing of inode... */
+ ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
}
typedef struct {
@@ -1578,11 +1583,9 @@ retry:
*pagep = page;
if (ext4_should_dioread_nolock(inode))
- ret = block_write_begin(file, mapping, pos, len, flags, pagep,
- fsdata, ext4_get_block_write);
+ ret = __block_write_begin(page, pos, len, ext4_get_block_write);
else
- ret = block_write_begin(file, mapping, pos, len, flags, pagep,
- fsdata, ext4_get_block);
+ ret = __block_write_begin(page, pos, len, ext4_get_block);
if (!ret && ext4_should_journal_data(inode)) {
ret = walk_page_buffers(handle, page_buffers(page),
@@ -1593,7 +1596,7 @@ retry:
unlock_page(page);
page_cache_release(page);
/*
- * block_write_begin may have instantiated a few blocks
+ * __block_write_begin may have instantiated a few blocks
* outside i_size. Trim these off again. Don't need
* i_size_read because we hold i_mutex.
*
@@ -3185,8 +3188,7 @@ retry:
}
*pagep = page;
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ext4_da_get_block_prep);
+ ret = __block_write_begin(page, pos, len, ext4_da_get_block_prep);
if (ret < 0) {
unlock_page(page);
ext4_journal_stop(handle);
@@ -3545,15 +3547,24 @@ static ssize_t ext4_ind_direct_IO(int rw, struct kiocb *iocb,
retry:
if (rw == READ && ext4_should_dioread_nolock(inode))
- ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
+ ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
- ext4_get_block, NULL);
- else
+ ext4_get_block, NULL, NULL, 0);
+ else {
ret = blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL);
+
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+ }
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
goto retry;
@@ -5529,11 +5540,19 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
ext4_truncate(inode);
}
- rc = inode_setattr(inode, attr);
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode))
+ rc = vmtruncate(inode, attr->ia_size);
- /* If inode_setattr's call to ext4_truncate failed to get a
- * transaction handle at all, we need to clean up the in-core
- * orphan list manually. */
+ if (!rc) {
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ }
+
+ /*
+ * If the call to ext4_truncate failed to get a transaction handle at
+ * all, we need to clean up the in-core orphan list manually.
+ */
if (inode->i_nlink)
ext4_orphan_del(NULL, inode);
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 4e8983a9811b..f627a6a4c317 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -813,8 +813,10 @@ static void destroy_inodecache(void)
kmem_cache_destroy(ext4_inode_cachep);
}
-static void ext4_clear_inode(struct inode *inode)
+void ext4_clear_inode(struct inode *inode)
{
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
dquot_drop(inode);
ext4_discard_preallocations(inode);
if (EXT4_JOURNAL(inode))
@@ -1100,14 +1102,13 @@ static const struct super_operations ext4_sops = {
.destroy_inode = ext4_destroy_inode,
.write_inode = ext4_write_inode,
.dirty_inode = ext4_dirty_inode,
- .delete_inode = ext4_delete_inode,
+ .evict_inode = ext4_evict_inode,
.put_super = ext4_put_super,
.sync_fs = ext4_sync_fs,
.freeze_fs = ext4_freeze,
.unfreeze_fs = ext4_unfreeze,
.statfs = ext4_statfs,
.remount_fs = ext4_remount,
- .clear_inode = ext4_clear_inode,
.show_options = ext4_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ext4_quota_read,
@@ -1121,12 +1122,11 @@ static const struct super_operations ext4_nojournal_sops = {
.destroy_inode = ext4_destroy_inode,
.write_inode = ext4_write_inode,
.dirty_inode = ext4_dirty_inode,
- .delete_inode = ext4_delete_inode,
+ .evict_inode = ext4_evict_inode,
.write_super = ext4_write_super,
.put_super = ext4_put_super,
.statfs = ext4_statfs,
.remount_fs = ext4_remount,
- .clear_inode = ext4_clear_inode,
.show_options = ext4_show_options,
#ifdef CONFIG_QUOTA
.quota_read = ext4_quota_read,
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index 27ac25725954..d75a77f85c28 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -306,7 +306,6 @@ extern long fat_generic_ioctl(struct file *filp, unsigned int cmd,
extern const struct file_operations fat_file_operations;
extern const struct inode_operations fat_file_inode_operations;
extern int fat_setattr(struct dentry * dentry, struct iattr * attr);
-extern int fat_setsize(struct inode *inode, loff_t offset);
extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
extern int fat_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 990dfae022e5..7257752b6d5d 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -364,18 +364,6 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
return 0;
}
-int fat_setsize(struct inode *inode, loff_t offset)
-{
- int error;
-
- error = simple_setsize(inode, offset);
- if (error)
- return error;
- fat_truncate_blocks(inode, offset);
-
- return error;
-}
-
#define TIMES_SET_FLAGS (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
/* valid file mode bits */
#define FAT_VALID_MODE (S_IFREG | S_IFDIR | S_IRWXUGO)
@@ -387,21 +375,6 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
unsigned int ia_valid;
int error;
- /*
- * Expand the file. Since inode_setattr() updates ->i_size
- * before calling the ->truncate(), but FAT needs to fill the
- * hole before it. XXX: this is no longer true with new truncate
- * sequence.
- */
- if (attr->ia_valid & ATTR_SIZE) {
- if (attr->ia_size > inode->i_size) {
- error = fat_cont_expand(inode, attr->ia_size);
- if (error || attr->ia_valid == ATTR_SIZE)
- goto out;
- attr->ia_valid &= ~ATTR_SIZE;
- }
- }
-
/* Check for setting the inode time. */
ia_valid = attr->ia_valid;
if (ia_valid & TIMES_SET_FLAGS) {
@@ -417,6 +390,21 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
goto out;
}
+ /*
+ * Expand the file. Since inode_setattr() updates ->i_size
+ * before calling the ->truncate(), but FAT needs to fill the
+ * hole before it. XXX: this is no longer true with new truncate
+ * sequence.
+ */
+ if (attr->ia_valid & ATTR_SIZE) {
+ if (attr->ia_size > inode->i_size) {
+ error = fat_cont_expand(inode, attr->ia_size);
+ if (error || attr->ia_valid == ATTR_SIZE)
+ goto out;
+ attr->ia_valid &= ~ATTR_SIZE;
+ }
+ }
+
if (((attr->ia_valid & ATTR_UID) &&
(attr->ia_uid != sbi->options.fs_uid)) ||
((attr->ia_valid & ATTR_GID) &&
@@ -441,12 +429,11 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
}
if (attr->ia_valid & ATTR_SIZE) {
- error = fat_setsize(inode, attr->ia_size);
- if (error)
- goto out;
+ truncate_setsize(inode, attr->ia_size);
+ fat_truncate_blocks(inode, attr->ia_size);
}
- generic_setattr(inode, attr);
+ setattr_copy(inode, attr);
mark_inode_dirty(inode);
out:
return error;
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7bf45aee56d7..830058057d33 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -159,7 +159,7 @@ static int fat_write_begin(struct file *file, struct address_space *mapping,
int err;
*pagep = NULL;
- err = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
+ err = cont_write_begin(file, mapping, pos, len, flags,
pagep, fsdata, fat_get_block,
&MSDOS_I(mapping->host)->mmu_private);
if (err < 0)
@@ -212,8 +212,8 @@ static ssize_t fat_direct_IO(int rw, struct kiocb *iocb,
* FAT need to use the DIO_LOCKING for avoiding the race
* condition of fat_get_block() and ->truncate().
*/
- ret = blockdev_direct_IO_newtrunc(rw, iocb, inode, inode->i_sb->s_bdev,
- iov, offset, nr_segs, fat_get_block, NULL);
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
+ iov, offset, nr_segs, fat_get_block, NULL);
if (ret < 0 && (rw & WRITE))
fat_write_failed(mapping, offset + iov_length(iov, nr_segs));
@@ -263,7 +263,7 @@ static const struct address_space_operations fat_aops = {
* check if the location is still valid and retry if it
* isn't. Otherwise we do changes.
* 5. Spinlock is used to protect hash/unhash/location check/lookup
- * 6. fat_clear_inode() unhashes the F-d-c entry.
+ * 6. fat_evict_inode() unhashes the F-d-c entry.
* 7. lookup() and readdir() do igrab() if they find a F-d-c entry
* and consider negative result as cache miss.
*/
@@ -448,16 +448,15 @@ out:
EXPORT_SYMBOL_GPL(fat_build_inode);
-static void fat_delete_inode(struct inode *inode)
+static void fat_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- inode->i_size = 0;
- fat_truncate_blocks(inode, 0);
- clear_inode(inode);
-}
-
-static void fat_clear_inode(struct inode *inode)
-{
+ if (!inode->i_nlink) {
+ inode->i_size = 0;
+ fat_truncate_blocks(inode, 0);
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
fat_cache_inval_inode(inode);
fat_detach(inode);
}
@@ -674,12 +673,11 @@ static const struct super_operations fat_sops = {
.alloc_inode = fat_alloc_inode,
.destroy_inode = fat_destroy_inode,
.write_inode = fat_write_inode,
- .delete_inode = fat_delete_inode,
+ .evict_inode = fat_evict_inode,
.put_super = fat_put_super,
.write_super = fat_write_super,
.sync_fs = fat_sync_fs,
.statfs = fat_statfs,
- .clear_inode = fat_clear_inode,
.remount_fs = fat_remount,
.show_options = fat_show_options,
diff --git a/fs/freevxfs/vxfs_extern.h b/fs/freevxfs/vxfs_extern.h
index 50ab5eecb99b..881aa3d217f0 100644
--- a/fs/freevxfs/vxfs_extern.h
+++ b/fs/freevxfs/vxfs_extern.h
@@ -63,7 +63,7 @@ extern void vxfs_put_fake_inode(struct inode *);
extern struct vxfs_inode_info * vxfs_blkiget(struct super_block *, u_long, ino_t);
extern struct vxfs_inode_info * vxfs_stiget(struct super_block *, ino_t);
extern struct inode * vxfs_iget(struct super_block *, ino_t);
-extern void vxfs_clear_inode(struct inode *);
+extern void vxfs_evict_inode(struct inode *);
/* vxfs_lookup.c */
extern const struct inode_operations vxfs_dir_inode_ops;
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 03a6ea5e99f7..79d1b4ea13e7 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -337,15 +337,17 @@ vxfs_iget(struct super_block *sbp, ino_t ino)
}
/**
- * vxfs_clear_inode - remove inode from main memory
+ * vxfs_evict_inode - remove inode from main memory
* @ip: inode to discard.
*
* Description:
- * vxfs_clear_inode() is called on the final iput and frees the private
+ * vxfs_evict_inode() is called on the final iput and frees the private
* inode area.
*/
void
-vxfs_clear_inode(struct inode *ip)
+vxfs_evict_inode(struct inode *ip)
{
+ truncate_inode_pages(&ip->i_data, 0);
+ end_writeback(ip);
kmem_cache_free(vxfs_inode_cachep, ip->i_private);
}
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c
index 1e8af939b3e4..1f3ffd93b357 100644
--- a/fs/freevxfs/vxfs_super.c
+++ b/fs/freevxfs/vxfs_super.c
@@ -61,7 +61,7 @@ static int vxfs_statfs(struct dentry *, struct kstatfs *);
static int vxfs_remount(struct super_block *, int *, char *);
static const struct super_operations vxfs_super_ops = {
- .clear_inode = vxfs_clear_inode,
+ .evict_inode = vxfs_evict_inode,
.put_super = vxfs_put_super,
.statfs = vxfs_statfs,
.remount_fs = vxfs_remount,
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d5be1693ac93..7608880b5c58 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -352,7 +352,7 @@ writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
spin_lock(&inode_lock);
inode->i_state &= ~I_SYNC;
- if (!(inode->i_state & (I_FREEING | I_CLEAR))) {
+ if (!(inode->i_state & I_FREEING)) {
if ((inode->i_state & I_DIRTY_PAGES) && wbc->for_kupdate) {
/*
* More pages get dirtied by a fast dirtier.
@@ -499,7 +499,7 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
if (inode_dirtied_after(inode, wbc->wb_start))
return 1;
- BUG_ON(inode->i_state & (I_FREEING | I_CLEAR));
+ BUG_ON(inode->i_state & I_FREEING);
__iget(inode);
pages_skipped = wbc->pages_skipped;
writeback_single_inode(inode, wbc);
@@ -935,7 +935,7 @@ void __mark_inode_dirty(struct inode *inode, int flags)
if (hlist_unhashed(&inode->i_hash))
goto out;
}
- if (inode->i_state & (I_FREEING|I_CLEAR))
+ if (inode->i_state & I_FREEING)
goto out;
/*
@@ -1001,7 +1001,7 @@ static void wait_sb_inodes(struct super_block *sb)
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
struct address_space *mapping;
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
+ if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue;
mapping = inode->i_mapping;
if (mapping->nrpages == 0)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 9424796d6634..69ad053ffd78 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -239,7 +239,6 @@ static u64 fuse_get_unique(struct fuse_conn *fc)
static void queue_request(struct fuse_conn *fc, struct fuse_req *req)
{
- req->in.h.unique = fuse_get_unique(fc);
req->in.h.len = sizeof(struct fuse_in_header) +
len_args(req->in.numargs, (struct fuse_arg *) req->in.args);
list_add_tail(&req->list, &fc->pending);
@@ -261,6 +260,7 @@ static void flush_bg_queue(struct fuse_conn *fc)
req = list_entry(fc->bg_queue.next, struct fuse_req, list);
list_del(&req->list);
fc->active_background++;
+ req->in.h.unique = fuse_get_unique(fc);
queue_request(fc, req);
}
}
@@ -398,6 +398,7 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
else if (fc->conn_error)
req->out.h.error = -ECONNREFUSED;
else {
+ req->in.h.unique = fuse_get_unique(fc);
queue_request(fc, req);
/* acquire extra reference, since request is still needed
after request_end() */
@@ -450,6 +451,23 @@ void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req)
}
EXPORT_SYMBOL_GPL(fuse_request_send_background);
+static int fuse_request_send_notify_reply(struct fuse_conn *fc,
+ struct fuse_req *req, u64 unique)
+{
+ int err = -ENODEV;
+
+ req->isreply = 0;
+ req->in.h.unique = unique;
+ spin_lock(&fc->lock);
+ if (fc->connected) {
+ queue_request(fc, req);
+ err = 0;
+ }
+ spin_unlock(&fc->lock);
+
+ return err;
+}
+
/*
* Called under fc->lock
*
@@ -535,13 +553,13 @@ static void fuse_copy_finish(struct fuse_copy_state *cs)
if (!cs->write) {
buf->ops->unmap(cs->pipe, buf, cs->mapaddr);
} else {
- kunmap_atomic(cs->mapaddr, KM_USER0);
+ kunmap(buf->page);
buf->len = PAGE_SIZE - cs->len;
}
cs->currbuf = NULL;
cs->mapaddr = NULL;
} else if (cs->mapaddr) {
- kunmap_atomic(cs->mapaddr, KM_USER0);
+ kunmap(cs->pg);
if (cs->write) {
flush_dcache_page(cs->pg);
set_page_dirty_lock(cs->pg);
@@ -572,7 +590,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
BUG_ON(!cs->nr_segs);
cs->currbuf = buf;
- cs->mapaddr = buf->ops->map(cs->pipe, buf, 1);
+ cs->mapaddr = buf->ops->map(cs->pipe, buf, 0);
cs->len = buf->len;
cs->buf = cs->mapaddr + buf->offset;
cs->pipebufs++;
@@ -592,7 +610,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
buf->len = 0;
cs->currbuf = buf;
- cs->mapaddr = kmap_atomic(page, KM_USER0);
+ cs->mapaddr = kmap(page);
cs->buf = cs->mapaddr;
cs->len = PAGE_SIZE;
cs->pipebufs++;
@@ -611,7 +629,7 @@ static int fuse_copy_fill(struct fuse_copy_state *cs)
return err;
BUG_ON(err != 1);
offset = cs->addr % PAGE_SIZE;
- cs->mapaddr = kmap_atomic(cs->pg, KM_USER0);
+ cs->mapaddr = kmap(cs->pg);
cs->buf = cs->mapaddr + offset;
cs->len = min(PAGE_SIZE - offset, cs->seglen);
cs->seglen -= cs->len;
@@ -1231,6 +1249,199 @@ err:
return err;
}
+static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
+ struct fuse_copy_state *cs)
+{
+ struct fuse_notify_store_out outarg;
+ struct inode *inode;
+ struct address_space *mapping;
+ u64 nodeid;
+ int err;
+ pgoff_t index;
+ unsigned int offset;
+ unsigned int num;
+ loff_t file_size;
+ loff_t end;
+
+ err = -EINVAL;
+ if (size < sizeof(outarg))
+ goto out_finish;
+
+ err = fuse_copy_one(cs, &outarg, sizeof(outarg));
+ if (err)
+ goto out_finish;
+
+ err = -EINVAL;
+ if (size - sizeof(outarg) != outarg.size)
+ goto out_finish;
+
+ nodeid = outarg.nodeid;
+
+ down_read(&fc->killsb);
+
+ err = -ENOENT;
+ if (!fc->sb)
+ goto out_up_killsb;
+
+ inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+ if (!inode)
+ goto out_up_killsb;
+
+ mapping = inode->i_mapping;
+ index = outarg.offset >> PAGE_CACHE_SHIFT;
+ offset = outarg.offset & ~PAGE_CACHE_MASK;
+ file_size = i_size_read(inode);
+ end = outarg.offset + outarg.size;
+ if (end > file_size) {
+ file_size = end;
+ fuse_write_update_size(inode, file_size);
+ }
+
+ num = outarg.size;
+ while (num) {
+ struct page *page;
+ unsigned int this_num;
+
+ err = -ENOMEM;
+ page = find_or_create_page(mapping, index,
+ mapping_gfp_mask(mapping));
+ if (!page)
+ goto out_iput;
+
+ this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
+ err = fuse_copy_page(cs, &page, offset, this_num, 0);
+ if (!err && offset == 0 && (num != 0 || file_size == end))
+ SetPageUptodate(page);
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (err)
+ goto out_iput;
+
+ num -= this_num;
+ offset = 0;
+ index++;
+ }
+
+ err = 0;
+
+out_iput:
+ iput(inode);
+out_up_killsb:
+ up_read(&fc->killsb);
+out_finish:
+ fuse_copy_finish(cs);
+ return err;
+}
+
+static void fuse_retrieve_end(struct fuse_conn *fc, struct fuse_req *req)
+{
+ int i;
+
+ for (i = 0; i < req->num_pages; i++) {
+ struct page *page = req->pages[i];
+ page_cache_release(page);
+ }
+}
+
+static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode,
+ struct fuse_notify_retrieve_out *outarg)
+{
+ int err;
+ struct address_space *mapping = inode->i_mapping;
+ struct fuse_req *req;
+ pgoff_t index;
+ loff_t file_size;
+ unsigned int num;
+ unsigned int offset;
+ size_t total_len;
+
+ req = fuse_get_req(fc);
+ if (IS_ERR(req))
+ return PTR_ERR(req);
+
+ offset = outarg->offset & ~PAGE_CACHE_MASK;
+
+ req->in.h.opcode = FUSE_NOTIFY_REPLY;
+ req->in.h.nodeid = outarg->nodeid;
+ req->in.numargs = 2;
+ req->in.argpages = 1;
+ req->page_offset = offset;
+ req->end = fuse_retrieve_end;
+
+ index = outarg->offset >> PAGE_CACHE_SHIFT;
+ file_size = i_size_read(inode);
+ num = outarg->size;
+ if (outarg->offset > file_size)
+ num = 0;
+ else if (outarg->offset + num > file_size)
+ num = file_size - outarg->offset;
+
+ while (num) {
+ struct page *page;
+ unsigned int this_num;
+
+ page = find_get_page(mapping, index);
+ if (!page)
+ break;
+
+ this_num = min_t(unsigned, num, PAGE_CACHE_SIZE - offset);
+ req->pages[req->num_pages] = page;
+ req->num_pages++;
+
+ num -= this_num;
+ total_len += this_num;
+ }
+ req->misc.retrieve_in.offset = outarg->offset;
+ req->misc.retrieve_in.size = total_len;
+ req->in.args[0].size = sizeof(req->misc.retrieve_in);
+ req->in.args[0].value = &req->misc.retrieve_in;
+ req->in.args[1].size = total_len;
+
+ err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique);
+ if (err)
+ fuse_retrieve_end(fc, req);
+
+ return err;
+}
+
+static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size,
+ struct fuse_copy_state *cs)
+{
+ struct fuse_notify_retrieve_out outarg;
+ struct inode *inode;
+ int err;
+
+ err = -EINVAL;
+ if (size != sizeof(outarg))
+ goto copy_finish;
+
+ err = fuse_copy_one(cs, &outarg, sizeof(outarg));
+ if (err)
+ goto copy_finish;
+
+ fuse_copy_finish(cs);
+
+ down_read(&fc->killsb);
+ err = -ENOENT;
+ if (fc->sb) {
+ u64 nodeid = outarg.nodeid;
+
+ inode = ilookup5(fc->sb, nodeid, fuse_inode_eq, &nodeid);
+ if (inode) {
+ err = fuse_retrieve(fc, inode, &outarg);
+ iput(inode);
+ }
+ }
+ up_read(&fc->killsb);
+
+ return err;
+
+copy_finish:
+ fuse_copy_finish(cs);
+ return err;
+}
+
static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
unsigned int size, struct fuse_copy_state *cs)
{
@@ -1244,6 +1455,12 @@ static int fuse_notify(struct fuse_conn *fc, enum fuse_notify_code code,
case FUSE_NOTIFY_INVAL_ENTRY:
return fuse_notify_inval_entry(fc, size, cs);
+ case FUSE_NOTIFY_STORE:
+ return fuse_notify_store(fc, size, cs);
+
+ case FUSE_NOTIFY_RETRIEVE:
+ return fuse_notify_retrieve(fc, size, cs);
+
default:
fuse_copy_finish(cs);
return -EINVAL;
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 3cdc5f78a406..3978a42d4f04 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1270,21 +1270,18 @@ static int fuse_do_setattr(struct dentry *entry, struct iattr *attr,
if (!fuse_allow_task(fc, current))
return -EACCES;
- if (fc->flags & FUSE_DEFAULT_PERMISSIONS) {
- err = inode_change_ok(inode, attr);
- if (err)
- return err;
- }
+ if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS))
+ attr->ia_valid |= ATTR_FORCE;
+
+ err = inode_change_ok(inode, attr);
+ if (err)
+ return err;
if ((attr->ia_valid & ATTR_OPEN) && fc->atomic_o_trunc)
return 0;
- if (attr->ia_valid & ATTR_SIZE) {
- err = inode_newsize_ok(inode, attr->ia_size);
- if (err)
- return err;
+ if (attr->ia_valid & ATTR_SIZE)
is_truncate = true;
- }
req = fuse_get_req(fc);
if (IS_ERR(req))
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index ada0adeb3bb5..147c1f71bdb9 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -706,7 +706,7 @@ static int fuse_write_begin(struct file *file, struct address_space *mapping,
return 0;
}
-static void fuse_write_update_size(struct inode *inode, loff_t pos)
+void fuse_write_update_size(struct inode *inode, loff_t pos)
{
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 8f309f04064e..57d4a3a0f102 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -272,6 +272,7 @@ struct fuse_req {
struct fuse_write_in in;
struct fuse_write_out out;
} write;
+ struct fuse_notify_retrieve_in retrieve_in;
struct fuse_lk_in lk_in;
} misc;
@@ -748,4 +749,6 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
unsigned fuse_file_poll(struct file *file, poll_table *wait);
int fuse_dev_release(struct inode *inode, struct file *file);
+void fuse_write_update_size(struct inode *inode, loff_t pos);
+
#endif /* _FS_FUSE_I_H */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index ec14d19ce501..da9e6e11374c 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -122,8 +122,10 @@ void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req,
fuse_request_send_noreply(fc, req);
}
-static void fuse_clear_inode(struct inode *inode)
+static void fuse_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (inode->i_sb->s_flags & MS_ACTIVE) {
struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_inode *fi = get_fuse_inode(inode);
@@ -736,7 +738,7 @@ static const struct export_operations fuse_export_operations = {
static const struct super_operations fuse_super_operations = {
.alloc_inode = fuse_alloc_inode,
.destroy_inode = fuse_destroy_inode,
- .clear_inode = fuse_clear_inode,
+ .evict_inode = fuse_evict_inode,
.drop_inode = generic_delete_inode,
.remount_fs = fuse_remount_fs,
.put_super = fuse_put_super,
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
index 9f8b52500d63..194fe16d8418 100644
--- a/fs/gfs2/aops.c
+++ b/fs/gfs2/aops.c
@@ -136,10 +136,7 @@ static int gfs2_writeback_writepage(struct page *page,
if (ret <= 0)
return ret;
- ret = mpage_writepage(page, gfs2_get_block_noalloc, wbc);
- if (ret == -EAGAIN)
- ret = block_write_full_page(page, gfs2_get_block_noalloc, wbc);
- return ret;
+ return nobh_writepage(page, gfs2_get_block_noalloc, wbc);
}
/**
@@ -637,9 +634,7 @@ static int gfs2_write_begin(struct file *file, struct address_space *mapping,
}
}
- error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
- if (error)
- goto out_unlock;
+ alloc_required = gfs2_write_alloc_required(ip, pos, len);
if (alloc_required || gfs2_is_jdata(ip))
gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
@@ -702,12 +697,12 @@ out:
page_cache_release(page);
/*
- * XXX(hch): the call below should probably be replaced with
+ * XXX(truncate): the call below should probably be replaced with
* a call to the gfs2-specific truncate blocks helper to actually
* release disk blocks..
*/
if (pos + len > ip->i_inode.i_size)
- simple_setsize(&ip->i_inode, ip->i_inode.i_size);
+ truncate_setsize(&ip->i_inode, ip->i_inode.i_size);
out_endtrans:
gfs2_trans_end(sdp);
out_trans_fail:
@@ -1047,9 +1042,9 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
if (rv != 1)
goto out; /* dio not valid, fall back to buffered i/o */
- rv = blockdev_direct_IO_no_locking(rw, iocb, inode, inode->i_sb->s_bdev,
- iov, offset, nr_segs,
- gfs2_get_block_direct, NULL);
+ rv = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ offset, nr_segs, gfs2_get_block_direct,
+ NULL, NULL, 0);
out:
gfs2_glock_dq_m(1, &gh);
gfs2_holder_uninit(&gh);
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 4a48c0f4b402..744c29e2dcf4 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1041,6 +1041,7 @@ static int trunc_start(struct gfs2_inode *ip, u64 size)
if (gfs2_is_stuffed(ip)) {
u64 dsize = size + sizeof(struct gfs2_inode);
+ ip->i_disksize = size;
ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
@@ -1243,13 +1244,12 @@ int gfs2_file_dealloc(struct gfs2_inode *ip)
* @ip: the file being written to
* @offset: the offset to write to
* @len: the number of bytes being written
- * @alloc_required: set to 1 if an alloc is required, 0 otherwise
*
- * Returns: errno
+ * Returns: 1 if an alloc is required, 0 otherwise
*/
int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
- unsigned int len, int *alloc_required)
+ unsigned int len)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head bh;
@@ -1257,26 +1257,23 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
u64 lblock, lblock_stop, size;
u64 end_of_file;
- *alloc_required = 0;
-
if (!len)
return 0;
if (gfs2_is_stuffed(ip)) {
if (offset + len >
sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode))
- *alloc_required = 1;
+ return 1;
return 0;
}
- *alloc_required = 1;
shift = sdp->sd_sb.sb_bsize_shift;
BUG_ON(gfs2_is_dir(ip));
end_of_file = (ip->i_disksize + sdp->sd_sb.sb_bsize - 1) >> shift;
lblock = offset >> shift;
lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift;
if (lblock_stop > end_of_file)
- return 0;
+ return 1;
size = (lblock_stop - lblock) << shift;
do {
@@ -1284,12 +1281,11 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
bh.b_size = size;
gfs2_block_map(&ip->i_inode, lblock, &bh, 0);
if (!buffer_mapped(&bh))
- return 0;
+ return 1;
size -= bh.b_size;
lblock += (bh.b_size >> ip->i_inode.i_blkbits);
} while(size > 0);
- *alloc_required = 0;
return 0;
}
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h
index c983177e05ac..a20a5213135a 100644
--- a/fs/gfs2/bmap.h
+++ b/fs/gfs2/bmap.h
@@ -52,6 +52,6 @@ int gfs2_truncatei(struct gfs2_inode *ip, u64 size);
int gfs2_truncatei_resume(struct gfs2_inode *ip);
int gfs2_file_dealloc(struct gfs2_inode *ip);
int gfs2_write_alloc_required(struct gfs2_inode *ip, u64 offset,
- unsigned int len, int *alloc_required);
+ unsigned int len);
#endif /* __BMAP_DOT_H__ */
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index ed9a94f0ef15..4edd662c8232 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -351,7 +351,6 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
unsigned long last_index;
u64 pos = page->index << PAGE_CACHE_SHIFT;
unsigned int data_blocks, ind_blocks, rblocks;
- int alloc_required = 0;
struct gfs2_holder gh;
struct gfs2_alloc *al;
int ret;
@@ -364,8 +363,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
set_bit(GLF_DIRTY, &ip->i_gl->gl_flags);
set_bit(GIF_SW_PAGED, &ip->i_flags);
- ret = gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE, &alloc_required);
- if (ret || !alloc_required)
+ if (!gfs2_write_alloc_required(ip, pos, PAGE_CACHE_SIZE))
goto out_unlock;
ret = -ENOMEM;
al = gfs2_alloc_get(ip);
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index ddcdbf493536..dbab3fdc2582 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -706,8 +706,18 @@ static void glock_work_func(struct work_struct *work)
{
unsigned long delay = 0;
struct gfs2_glock *gl = container_of(work, struct gfs2_glock, gl_work.work);
+ struct gfs2_holder *gh;
int drop_ref = 0;
+ if (unlikely(test_bit(GLF_FROZEN, &gl->gl_flags))) {
+ spin_lock(&gl->gl_spin);
+ gh = find_first_waiter(gl);
+ if (gh && (gh->gh_flags & LM_FLAG_NOEXP) &&
+ test_and_clear_bit(GLF_FROZEN, &gl->gl_flags))
+ set_bit(GLF_REPLY_PENDING, &gl->gl_flags);
+ spin_unlock(&gl->gl_spin);
+ }
+
if (test_and_clear_bit(GLF_REPLY_PENDING, &gl->gl_flags)) {
finish_xmote(gl, gl->gl_reply);
drop_ref = 1;
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index b5d7363b22da..8fcbce48a128 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -460,6 +460,7 @@ enum {
SDF_NOBARRIERS = 3,
SDF_NORECOVERY = 4,
SDF_DEMOTE = 5,
+ SDF_NOJOURNALID = 6,
};
#define GFS2_FSNAME_LEN 256
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index b5612cbb62a5..08140f185a37 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -84,7 +84,7 @@ static int iget_skip_test(struct inode *inode, void *opaque)
struct gfs2_skip_data *data = opaque;
if (ip->i_no_addr == data->no_addr) {
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)){
+ if (inode->i_state & (I_FREEING|I_WILL_FREE)){
data->skipped = 1;
return 0;
}
@@ -169,7 +169,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
{
struct inode *inode;
struct gfs2_inode *ip;
- struct gfs2_glock *io_gl;
+ struct gfs2_glock *io_gl = NULL;
int error;
inode = gfs2_iget(sb, no_addr);
@@ -198,6 +198,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb,
ip->i_iopen_gh.gh_gl->gl_object = ip;
gfs2_glock_put(io_gl);
+ io_gl = NULL;
if ((type == DT_UNKNOWN) && (no_formal_ino == 0))
goto gfs2_nfsbypass;
@@ -228,7 +229,8 @@ gfs2_nfsbypass:
fail_glock:
gfs2_glock_dq(&ip->i_iopen_gh);
fail_iopen:
- gfs2_glock_put(io_gl);
+ if (io_gl)
+ gfs2_glock_put(io_gl);
fail_put:
if (inode->i_state & I_NEW)
ip->i_gl->gl_object = NULL;
@@ -256,7 +258,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
{
struct gfs2_sbd *sdp;
struct gfs2_inode *ip;
- struct gfs2_glock *io_gl;
+ struct gfs2_glock *io_gl = NULL;
int error;
struct gfs2_holder gh;
struct inode *inode;
@@ -293,6 +295,7 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
ip->i_iopen_gh.gh_gl->gl_object = ip;
gfs2_glock_put(io_gl);
+ io_gl = NULL;
inode->i_mode = DT2IF(DT_UNKNOWN);
@@ -319,7 +322,8 @@ void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr)
fail_glock:
gfs2_glock_dq(&ip->i_iopen_gh);
fail_iopen:
- gfs2_glock_put(io_gl);
+ if (io_gl)
+ gfs2_glock_put(io_gl);
fail_put:
ip->i_gl->gl_object = NULL;
gfs2_glock_put(ip->i_gl);
@@ -987,18 +991,29 @@ fail:
static int __gfs2_setattr_simple(struct gfs2_inode *ip, struct iattr *attr)
{
+ struct inode *inode = &ip->i_inode;
struct buffer_head *dibh;
int error;
error = gfs2_meta_inode_buffer(ip, &dibh);
- if (!error) {
- error = inode_setattr(&ip->i_inode, attr);
- gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
- gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
}
- return error;
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
+ gfs2_assert_warn(GFS2_SB(inode), !error);
+ gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+ gfs2_dinode_out(ip, dibh->b_data);
+ brelse(dibh);
+ return 0;
}
/**
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 3593b3a7290e..45a4a36195d8 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -76,7 +76,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb)
sb->s_fs_info = sdp;
sdp->sd_vfs = sb;
-
+ set_bit(SDF_NOJOURNALID, &sdp->sd_flags);
gfs2_tune_init(&sdp->sd_tune);
init_waitqueue_head(&sdp->sd_glock_wait);
@@ -1050,7 +1050,8 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
ret = match_int(&tmp[0], &option);
if (ret || option < 0)
goto hostdata_error;
- ls->ls_jid = option;
+ if (test_and_clear_bit(SDF_NOJOURNALID, &sdp->sd_flags))
+ ls->ls_jid = option;
break;
case Opt_id:
/* Obsolete, but left for backward compat purposes */
@@ -1102,6 +1103,24 @@ void gfs2_lm_unmount(struct gfs2_sbd *sdp)
lm->lm_unmount(sdp);
}
+static int gfs2_journalid_wait(void *word)
+{
+ if (signal_pending(current))
+ return -EINTR;
+ schedule();
+ return 0;
+}
+
+static int wait_on_journal(struct gfs2_sbd *sdp)
+{
+ if (sdp->sd_args.ar_spectator)
+ return 0;
+ if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
+ return 0;
+
+ return wait_on_bit(&sdp->sd_flags, SDF_NOJOURNALID, gfs2_journalid_wait, TASK_INTERRUPTIBLE);
+}
+
void gfs2_online_uevent(struct gfs2_sbd *sdp)
{
struct super_block *sb = sdp->sd_vfs;
@@ -1194,6 +1213,10 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
if (error)
goto fail_locking;
+ error = wait_on_journal(sdp);
+ if (error)
+ goto fail_sb;
+
error = init_inodes(sdp, DO);
if (error)
goto fail_sb;
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 98cdd05f3316..1009be2c9737 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -1072,7 +1072,7 @@ int gfs2_permission(struct inode *inode, int mask)
}
/*
- * XXX: should be changed to have proper ordering by opencoding simple_setsize
+ * XXX(truncate): the truncate_setsize calls should be moved to the end.
*/
static int setattr_size(struct inode *inode, struct iattr *attr)
{
@@ -1084,10 +1084,8 @@ static int setattr_size(struct inode *inode, struct iattr *attr)
error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks);
if (error)
return error;
- error = simple_setsize(inode, attr->ia_size);
+ truncate_setsize(inode, attr->ia_size);
gfs2_trans_end(sdp);
- if (error)
- return error;
}
error = gfs2_truncatei(ip, attr->ia_size);
@@ -1136,8 +1134,16 @@ static int setattr_chown(struct inode *inode, struct iattr *attr)
if (error)
goto out_end_trans;
- error = inode_setattr(inode, attr);
- gfs2_assert_warn(sdp, !error);
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ int error;
+
+ error = vmtruncate(inode, attr->ia_size);
+ gfs2_assert_warn(sdp, !error);
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c
index 49667d68769e..1880c4dd2208 100644
--- a/fs/gfs2/quota.c
+++ b/fs/gfs2/quota.c
@@ -694,10 +694,8 @@ get_a_page:
if (!buffer_mapped(bh))
goto unlock_out;
/* If it's a newly allocated disk block for quota, zero it */
- if (buffer_new(bh)) {
- memset(bh->b_data, 0, bh->b_size);
- set_buffer_uptodate(bh);
- }
+ if (buffer_new(bh))
+ zero_user(page, pos - blocksize, bh->b_size);
}
if (PageUptodate(page))
@@ -723,7 +721,7 @@ get_a_page:
/* If quota straddles page boundary, we need to update the rest of the
* quota at the beginning of the next page */
- if (offset != 0) { /* first page, offset is closer to PAGE_CACHE_SIZE */
+ if ((offset + sizeof(struct gfs2_quota)) > PAGE_CACHE_SIZE) {
ptr = ptr + nbytes;
nbytes = sizeof(struct gfs2_quota) - nbytes;
offset = 0;
@@ -789,15 +787,9 @@ static int do_sync(unsigned int num_qd, struct gfs2_quota_data **qda)
goto out;
for (x = 0; x < num_qd; x++) {
- int alloc_required;
-
offset = qd2offset(qda[x]);
- error = gfs2_write_alloc_required(ip, offset,
- sizeof(struct gfs2_quota),
- &alloc_required);
- if (error)
- goto out_gunlock;
- if (alloc_required)
+ if (gfs2_write_alloc_required(ip, offset,
+ sizeof(struct gfs2_quota)))
nalloc++;
}
@@ -1457,10 +1449,10 @@ static int gfs2_quota_get_xstate(struct super_block *sb,
switch (sdp->sd_args.ar_quota) {
case GFS2_QUOTA_ON:
- fqs->qs_flags |= (XFS_QUOTA_UDQ_ENFD | XFS_QUOTA_GDQ_ENFD);
+ fqs->qs_flags |= (FS_QUOTA_UDQ_ENFD | FS_QUOTA_GDQ_ENFD);
/*FALLTHRU*/
case GFS2_QUOTA_ACCOUNT:
- fqs->qs_flags |= (XFS_QUOTA_UDQ_ACCT | XFS_QUOTA_GDQ_ACCT);
+ fqs->qs_flags |= (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT);
break;
case GFS2_QUOTA_OFF:
break;
@@ -1506,7 +1498,7 @@ static int gfs2_get_dqblk(struct super_block *sb, int type, qid_t id,
qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lvb;
fdq->d_version = FS_DQUOT_VERSION;
- fdq->d_flags = (type == QUOTA_USER) ? XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+ fdq->d_flags = (type == QUOTA_USER) ? FS_USER_QUOTA : FS_GROUP_QUOTA;
fdq->d_id = id;
fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit);
fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn);
@@ -1541,12 +1533,12 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
switch(type) {
case USRQUOTA:
type = QUOTA_USER;
- if (fdq->d_flags != XFS_USER_QUOTA)
+ if (fdq->d_flags != FS_USER_QUOTA)
return -EINVAL;
break;
case GRPQUOTA:
type = QUOTA_GROUP;
- if (fdq->d_flags != XFS_GROUP_QUOTA)
+ if (fdq->d_flags != FS_GROUP_QUOTA)
return -EINVAL;
break;
default:
@@ -1586,10 +1578,7 @@ static int gfs2_set_dqblk(struct super_block *sb, int type, qid_t id,
goto out_i;
offset = qd2offset(qd);
- error = gfs2_write_alloc_required(ip, offset, sizeof(struct gfs2_quota),
- &alloc_required);
- if (error)
- goto out_i;
+ alloc_required = gfs2_write_alloc_required(ip, offset, sizeof(struct gfs2_quota));
if (alloc_required) {
al = gfs2_alloc_get(ip);
if (al == NULL)
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 4d1aad38f1b1..ed100753a01d 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -342,8 +342,6 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
{
struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
- int ar;
- int error;
if (ip->i_disksize < (8 << 20) || ip->i_disksize > (1 << 30) ||
(ip->i_disksize & (sdp->sd_sb.sb_bsize - 1))) {
@@ -352,13 +350,12 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
}
jd->jd_blocks = ip->i_disksize >> sdp->sd_sb.sb_bsize_shift;
- error = gfs2_write_alloc_required(ip, 0, ip->i_disksize, &ar);
- if (!error && ar) {
+ if (gfs2_write_alloc_required(ip, 0, ip->i_disksize)) {
gfs2_consist_inode(ip);
- error = -EIO;
+ return -EIO;
}
- return error;
+ return 0;
}
/**
@@ -1203,25 +1200,6 @@ static void gfs2_drop_inode(struct inode *inode)
generic_drop_inode(inode);
}
-/**
- * gfs2_clear_inode - Deallocate an inode when VFS is done with it
- * @inode: The VFS inode
- *
- */
-
-static void gfs2_clear_inode(struct inode *inode)
-{
- struct gfs2_inode *ip = GFS2_I(inode);
-
- ip->i_gl->gl_object = NULL;
- gfs2_glock_put(ip->i_gl);
- ip->i_gl = NULL;
- if (ip->i_iopen_gh.gh_gl) {
- ip->i_iopen_gh.gh_gl->gl_object = NULL;
- gfs2_glock_dq_uninit(&ip->i_iopen_gh);
- }
-}
-
static int is_ancestor(const struct dentry *d1, const struct dentry *d2)
{
do {
@@ -1347,13 +1325,16 @@ static int gfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
* is safe, just less efficient.
*/
-static void gfs2_delete_inode(struct inode *inode)
+static void gfs2_evict_inode(struct inode *inode)
{
struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
struct gfs2_inode *ip = GFS2_I(inode);
struct gfs2_holder gh;
int error;
+ if (inode->i_nlink)
+ goto out;
+
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
if (unlikely(error)) {
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
@@ -1407,10 +1388,18 @@ out_unlock:
gfs2_holder_uninit(&ip->i_iopen_gh);
gfs2_glock_dq_uninit(&gh);
if (error && error != GLR_TRYFAILED && error != -EROFS)
- fs_warn(sdp, "gfs2_delete_inode: %d\n", error);
+ fs_warn(sdp, "gfs2_evict_inode: %d\n", error);
out:
truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ end_writeback(inode);
+
+ ip->i_gl->gl_object = NULL;
+ gfs2_glock_put(ip->i_gl);
+ ip->i_gl = NULL;
+ if (ip->i_iopen_gh.gh_gl) {
+ ip->i_iopen_gh.gh_gl->gl_object = NULL;
+ gfs2_glock_dq_uninit(&ip->i_iopen_gh);
+ }
}
static struct inode *gfs2_alloc_inode(struct super_block *sb)
@@ -1434,14 +1423,13 @@ const struct super_operations gfs2_super_ops = {
.alloc_inode = gfs2_alloc_inode,
.destroy_inode = gfs2_destroy_inode,
.write_inode = gfs2_write_inode,
- .delete_inode = gfs2_delete_inode,
+ .evict_inode = gfs2_evict_inode,
.put_super = gfs2_put_super,
.sync_fs = gfs2_sync_fs,
.freeze_fs = gfs2_freeze,
.unfreeze_fs = gfs2_unfreeze,
.statfs = gfs2_statfs,
.remount_fs = gfs2_remount_fs,
- .clear_inode = gfs2_clear_inode,
.drop_inode = gfs2_drop_inode,
.show_options = gfs2_show_options,
};
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 37f5393e68e6..d019d0d55e00 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -325,6 +325,30 @@ static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
return sprintf(buf, "%d\n", ls->ls_first);
}
+static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
+{
+ unsigned first;
+ int rv;
+
+ rv = sscanf(buf, "%u", &first);
+ if (rv != 1 || first > 1)
+ return -EINVAL;
+ spin_lock(&sdp->sd_jindex_spin);
+ rv = -EBUSY;
+ if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
+ goto out;
+ rv = -EINVAL;
+ if (sdp->sd_args.ar_spectator)
+ goto out;
+ if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
+ goto out;
+ sdp->sd_lockstruct.ls_first = first;
+ rv = 0;
+out:
+ spin_unlock(&sdp->sd_jindex_spin);
+ return rv ? rv : len;
+}
+
static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
@@ -377,14 +401,41 @@ static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid);
}
+static ssize_t jid_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;
+
+ spin_lock(&sdp->sd_jindex_spin);
+ rv = -EINVAL;
+ if (sdp->sd_args.ar_spectator)
+ goto out;
+ if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
+ goto out;
+ rv = -EBUSY;
+ if (test_and_clear_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
+ goto out;
+ sdp->sd_lockstruct.ls_jid = jid;
+ smp_mb__after_clear_bit();
+ wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
+ rv = 0;
+out:
+ spin_unlock(&sdp->sd_jindex_spin);
+ return rv ? rv : len;
+}
+
#define GDLM_ATTR(_name,_mode,_show,_store) \
static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
GDLM_ATTR(proto_name, 0444, proto_name_show, NULL);
GDLM_ATTR(block, 0644, block_show, block_store);
GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store);
-GDLM_ATTR(jid, 0444, jid_show, NULL);
-GDLM_ATTR(first, 0444, lkfirst_show, NULL);
+GDLM_ATTR(jid, 0644, jid_show, jid_store);
+GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store);
GDLM_ATTR(first_done, 0444, first_done_show, NULL);
GDLM_ATTR(recover, 0600, NULL, recover_store);
GDLM_ATTR(recover_done, 0444, recover_done_show, NULL);
@@ -564,7 +615,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
- if (!sdp->sd_args.ar_spectator)
+ if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid);
if (gfs2_uuid_valid(uuid))
add_uevent_var(env, "UUID=%pUB", uuid);
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c
index 82f93da00d1b..776af6eb4bcb 100644
--- a/fs/gfs2/xattr.c
+++ b/fs/gfs2/xattr.c
@@ -1296,6 +1296,7 @@ fail:
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
{
+ struct inode *inode = &ip->i_inode;
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct gfs2_ea_location el;
struct buffer_head *dibh;
@@ -1321,14 +1322,25 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
return error;
error = gfs2_meta_inode_buffer(ip, &dibh);
- if (!error) {
- error = inode_setattr(&ip->i_inode, attr);
- gfs2_assert_warn(GFS2_SB(&ip->i_inode), !error);
- gfs2_trans_add_bh(ip->i_gl, dibh, 1);
- gfs2_dinode_out(ip, dibh->b_data);
- brelse(dibh);
+ if (error)
+ goto out_trans_end;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ int error;
+
+ error = vmtruncate(inode, attr->ia_size);
+ gfs2_assert_warn(GFS2_SB(inode), !error);
}
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
+ gfs2_trans_add_bh(ip->i_gl, dibh, 1);
+ gfs2_dinode_out(ip, dibh->b_data);
+ brelse(dibh);
+
+out_trans_end:
gfs2_trans_end(sdp);
return error;
}
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index fe35e3b626c4..4f55651aaa51 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -193,7 +193,7 @@ extern int hfs_inode_setattr(struct dentry *, struct iattr *);
extern void hfs_inode_read_fork(struct inode *inode, struct hfs_extent *ext,
__be32 log_size, __be32 phys_size, u32 clump_size);
extern struct inode *hfs_iget(struct super_block *, struct hfs_cat_key *, hfs_cat_rec *);
-extern void hfs_clear_inode(struct inode *);
+extern void hfs_evict_inode(struct inode *);
extern void hfs_delete_inode(struct inode *);
/* attr.c */
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 14f5cb1b9fdc..397b7adc7ce6 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -39,10 +39,19 @@ static int hfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
hfs_get_block,
&HFS_I(mapping->host)->phys_size);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
@@ -112,9 +121,24 @@ static ssize_t hfs_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
+ ssize_t ret;
- return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, hfs_get_block, NULL);
+
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+
+ return ret;
}
static int hfs_writepages(struct address_space *mapping,
@@ -507,8 +531,10 @@ out:
return NULL;
}
-void hfs_clear_inode(struct inode *inode)
+void hfs_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (HFS_IS_RSRC(inode) && HFS_I(inode)->rsrc_inode) {
HFS_I(HFS_I(inode)->rsrc_inode)->rsrc_inode = NULL;
iput(HFS_I(inode)->rsrc_inode);
@@ -588,13 +614,43 @@ int hfs_inode_setattr(struct dentry *dentry, struct iattr * attr)
attr->ia_mode = inode->i_mode & ~S_IWUGO;
attr->ia_mode &= S_ISDIR(inode->i_mode) ? ~hsb->s_dir_umask: ~hsb->s_file_umask;
}
- error = inode_setattr(inode, attr);
- if (error)
- return error;
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
return 0;
}
+static int hfs_file_fsync(struct file *filp, int datasync)
+{
+ struct inode *inode = filp->f_mapping->host;
+ struct super_block * sb;
+ int ret, err;
+
+ /* sync the inode to buffers */
+ ret = write_inode_now(inode, 0);
+
+ /* sync the superblock to buffers */
+ sb = inode->i_sb;
+ if (sb->s_dirt) {
+ lock_super(sb);
+ sb->s_dirt = 0;
+ if (!(sb->s_flags & MS_RDONLY))
+ hfs_mdb_commit(sb);
+ unlock_super(sb);
+ }
+ /* .. finally sync the buffers to disk */
+ err = sync_blockdev(sb->s_bdev);
+ if (!ret)
+ ret = err;
+ return ret;
+}
static const struct file_operations hfs_file_operations = {
.llseek = generic_file_llseek,
@@ -604,7 +660,7 @@ static const struct file_operations hfs_file_operations = {
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.splice_read = generic_file_splice_read,
- .fsync = file_fsync,
+ .fsync = hfs_file_fsync,
.open = hfs_file_open,
.release = hfs_file_release,
};
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index 0a81eb7111f3..34235d4bf08b 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -181,7 +181,7 @@ static const struct super_operations hfs_super_operations = {
.alloc_inode = hfs_alloc_inode,
.destroy_inode = hfs_destroy_inode,
.write_inode = hfs_write_inode,
- .clear_inode = hfs_clear_inode,
+ .evict_inode = hfs_evict_inode,
.put_super = hfs_put_super,
.write_super = hfs_write_super,
.sync_fs = hfs_sync_fs,
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 6505c30ad965..dc856be3c2b0 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -351,6 +351,7 @@ int hfsplus_show_options(struct seq_file *, struct vfsmount *);
/* super.c */
struct inode *hfsplus_iget(struct super_block *, unsigned long);
+int hfsplus_sync_fs(struct super_block *sb, int wait);
/* tables.c */
extern u16 hfsplus_case_fold_table[];
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 9bbb82924a22..c5a979d62c65 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -31,10 +31,19 @@ static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
hfsplus_get_block,
&HFSPLUS_I(mapping->host).phys_size);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
@@ -105,9 +114,24 @@ static ssize_t hfsplus_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
+ ssize_t ret;
- return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, hfsplus_get_block, NULL);
+
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+
+ return ret;
}
static int hfsplus_writepages(struct address_space *mapping,
@@ -266,9 +290,56 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
return 0;
}
+static int hfsplus_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
+static int hfsplus_file_fsync(struct file *filp, int datasync)
+{
+ struct inode *inode = filp->f_mapping->host;
+ struct super_block * sb;
+ int ret, err;
+
+ /* sync the inode to buffers */
+ ret = write_inode_now(inode, 0);
+
+ /* sync the superblock to buffers */
+ sb = inode->i_sb;
+ if (sb->s_dirt) {
+ if (!(sb->s_flags & MS_RDONLY))
+ hfsplus_sync_fs(sb, 1);
+ else
+ sb->s_dirt = 0;
+ }
+
+ /* .. finally sync the buffers to disk */
+ err = sync_blockdev(sb->s_bdev);
+ if (!ret)
+ ret = err;
+ return ret;
+}
+
static const struct inode_operations hfsplus_file_inode_operations = {
.lookup = hfsplus_file_lookup,
.truncate = hfsplus_file_truncate,
+ .setattr = hfsplus_setattr,
.setxattr = hfsplus_setxattr,
.getxattr = hfsplus_getxattr,
.listxattr = hfsplus_listxattr,
@@ -282,7 +353,7 @@ static const struct file_operations hfsplus_file_operations = {
.aio_write = generic_file_aio_write,
.mmap = generic_file_mmap,
.splice_read = generic_file_splice_read,
- .fsync = file_fsync,
+ .fsync = hfsplus_file_fsync,
.open = hfsplus_file_open,
.release = hfsplus_file_release,
.unlocked_ioctl = hfsplus_ioctl,
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 74b473a8ef92..3b55c050c742 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -145,16 +145,18 @@ static int hfsplus_write_inode(struct inode *inode,
return ret;
}
-static void hfsplus_clear_inode(struct inode *inode)
+static void hfsplus_evict_inode(struct inode *inode)
{
- dprint(DBG_INODE, "hfsplus_clear_inode: %lu\n", inode->i_ino);
+ dprint(DBG_INODE, "hfsplus_evict_inode: %lu\n", inode->i_ino);
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (HFSPLUS_IS_RSRC(inode)) {
HFSPLUS_I(HFSPLUS_I(inode).rsrc_inode).rsrc_inode = NULL;
iput(HFSPLUS_I(inode).rsrc_inode);
}
}
-static int hfsplus_sync_fs(struct super_block *sb, int wait)
+int hfsplus_sync_fs(struct super_block *sb, int wait)
{
struct hfsplus_vh *vhdr = HFSPLUS_SB(sb).s_vhdr;
@@ -293,7 +295,7 @@ static const struct super_operations hfsplus_sops = {
.alloc_inode = hfsplus_alloc_inode,
.destroy_inode = hfsplus_destroy_inode,
.write_inode = hfsplus_write_inode,
- .clear_inode = hfsplus_clear_inode,
+ .evict_inode = hfsplus_evict_inode,
.put_super = hfsplus_put_super,
.write_super = hfsplus_write_super,
.sync_fs = hfsplus_sync_fs,
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 2f34f8f2134b..6bbd75c5589b 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -53,18 +53,28 @@ struct hostfs_iattr {
struct timespec ia_ctime;
};
-extern int stat_file(const char *path, unsigned long long *inode_out,
- int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
- unsigned long long *size_out, struct timespec *atime_out,
- struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out, int fd);
+struct hostfs_stat {
+ unsigned long long ino;
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned long long size;
+ struct timespec atime, mtime, ctime;
+ unsigned int blksize;
+ unsigned long long blocks;
+ unsigned int maj;
+ unsigned int min;
+};
+
+extern int stat_file(const char *path, struct hostfs_stat *p, int fd);
extern int access_file(char *path, int r, int w, int x);
extern int open_file(char *path, int r, int w, int append);
-extern int file_type(const char *path, int *maj, int *min);
extern void *open_dir(char *path, int *err_out);
extern char *read_dir(void *stream, unsigned long long *pos,
unsigned long long *ino_out, int *len_out);
extern void close_file(void *stream);
+extern int replace_file(int oldfd, int fd);
extern void close_dir(void *stream);
extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
extern int write_file(int fd, unsigned long long *offset, const char *buf,
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 87ac1891a185..dd1e55535a4e 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -14,12 +14,12 @@
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/mount.h>
+#include <linux/namei.h>
#include "hostfs.h"
#include "init.h"
#include "kern.h"
struct hostfs_inode_info {
- char *host_filename;
int fd;
fmode_t mode;
struct inode vfs_inode;
@@ -49,7 +49,7 @@ static int append = 0;
static const struct inode_operations hostfs_iops;
static const struct inode_operations hostfs_dir_iops;
-static const struct address_space_operations hostfs_link_aops;
+static const struct inode_operations hostfs_link_iops;
#ifndef MODULE
static int __init hostfs_args(char *options, int *add)
@@ -90,71 +90,58 @@ __uml_setup("hostfs=", hostfs_args,
);
#endif
-static char *dentry_name(struct dentry *dentry, int extra)
+static char *__dentry_name(struct dentry *dentry, char *name)
{
- struct dentry *parent;
- char *root, *name;
- int len;
-
- len = 0;
- parent = dentry;
- while (parent->d_parent != parent) {
- len += parent->d_name.len + 1;
- parent = parent->d_parent;
- }
+ char *p = __dentry_path(dentry, name, PATH_MAX);
+ char *root;
+ size_t len;
- root = HOSTFS_I(parent->d_inode)->host_filename;
- len += strlen(root);
- name = kmalloc(len + extra + 1, GFP_KERNEL);
- if (name == NULL)
- return NULL;
+ spin_unlock(&dcache_lock);
- name[len] = '\0';
- parent = dentry;
- while (parent->d_parent != parent) {
- len -= parent->d_name.len + 1;
- name[len] = '/';
- strncpy(&name[len + 1], parent->d_name.name,
- parent->d_name.len);
- parent = parent->d_parent;
+ root = dentry->d_sb->s_fs_info;
+ len = strlen(root);
+ if (IS_ERR(p)) {
+ __putname(name);
+ return NULL;
+ }
+ strncpy(name, root, PATH_MAX);
+ if (len > p - name) {
+ __putname(name);
+ return NULL;
+ }
+ if (p > name + len) {
+ char *s = name + len;
+ while ((*s++ = *p++) != '\0')
+ ;
}
- strncpy(name, root, strlen(root));
return name;
}
-static char *inode_name(struct inode *ino, int extra)
+static char *dentry_name(struct dentry *dentry)
{
- struct dentry *dentry;
+ char *name = __getname();
+ if (!name)
+ return NULL;
- dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
- return dentry_name(dentry, extra);
+ spin_lock(&dcache_lock);
+ return __dentry_name(dentry, name); /* will unlock */
}
-static int read_name(struct inode *ino, char *name)
+static char *inode_name(struct inode *ino)
{
- /*
- * The non-int inode fields are copied into ints by stat_file and
- * then copied into the inode because passing the actual pointers
- * in and having them treated as int * breaks on big-endian machines
- */
- int err;
- int i_mode, i_nlink, i_blksize;
- unsigned long long i_size;
- unsigned long long i_ino;
- unsigned long long i_blocks;
-
- err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
- &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
- &ino->i_ctime, &i_blksize, &i_blocks, -1);
- if (err)
- return err;
+ struct dentry *dentry;
+ char *name = __getname();
+ if (!name)
+ return NULL;
- ino->i_ino = i_ino;
- ino->i_mode = i_mode;
- ino->i_nlink = i_nlink;
- ino->i_size = i_size;
- ino->i_blocks = i_blocks;
- return 0;
+ spin_lock(&dcache_lock);
+ if (list_empty(&ino->i_dentry)) {
+ spin_unlock(&dcache_lock);
+ __putname(name);
+ return NULL;
+ }
+ dentry = list_first_entry(&ino->i_dentry, struct dentry, d_alias);
+ return __dentry_name(dentry, name); /* will unlock */
}
static char *follow_link(char *link)
@@ -205,53 +192,11 @@ static char *follow_link(char *link)
return ERR_PTR(n);
}
-static int hostfs_read_inode(struct inode *ino)
-{
- char *name;
- int err = 0;
-
- /*
- * Unfortunately, we are called from iget() when we don't have a dentry
- * allocated yet.
- */
- if (list_empty(&ino->i_dentry))
- goto out;
-
- err = -ENOMEM;
- name = inode_name(ino, 0);
- if (name == NULL)
- goto out;
-
- if (file_type(name, NULL, NULL) == OS_TYPE_SYMLINK) {
- name = follow_link(name);
- if (IS_ERR(name)) {
- err = PTR_ERR(name);
- goto out;
- }
- }
-
- err = read_name(ino, name);
- kfree(name);
- out:
- return err;
-}
-
static struct inode *hostfs_iget(struct super_block *sb)
{
- struct inode *inode;
- long ret;
-
- inode = iget_locked(sb, 0);
+ struct inode *inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
- if (inode->i_state & I_NEW) {
- ret = hostfs_read_inode(inode);
- if (ret < 0) {
- iget_failed(inode);
- return ERR_PTR(ret);
- }
- unlock_new_inode(inode);
- }
return inode;
}
@@ -269,7 +214,7 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
long long f_files;
long long f_ffree;
- err = do_statfs(HOSTFS_I(dentry->d_sb->s_root->d_inode)->host_filename,
+ err = do_statfs(dentry->d_sb->s_fs_info,
&sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
&f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
&sf->f_namelen, sf->f_spare);
@@ -288,47 +233,32 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
{
struct hostfs_inode_info *hi;
- hi = kmalloc(sizeof(*hi), GFP_KERNEL);
+ hi = kzalloc(sizeof(*hi), GFP_KERNEL);
if (hi == NULL)
return NULL;
-
- *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
- .fd = -1,
- .mode = 0 });
+ hi->fd = -1;
inode_init_once(&hi->vfs_inode);
return &hi->vfs_inode;
}
-static void hostfs_delete_inode(struct inode *inode)
+static void hostfs_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (HOSTFS_I(inode)->fd != -1) {
close_file(&HOSTFS_I(inode)->fd);
HOSTFS_I(inode)->fd = -1;
}
- clear_inode(inode);
}
static void hostfs_destroy_inode(struct inode *inode)
{
- kfree(HOSTFS_I(inode)->host_filename);
-
- /*
- * XXX: This should not happen, probably. The check is here for
- * additional safety.
- */
- if (HOSTFS_I(inode)->fd != -1) {
- close_file(&HOSTFS_I(inode)->fd);
- printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
- }
-
kfree(HOSTFS_I(inode));
}
static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
- struct inode *root = vfs->mnt_sb->s_root->d_inode;
- const char *root_path = HOSTFS_I(root)->host_filename;
+ const char *root_path = vfs->mnt_sb->s_fs_info;
size_t offset = strlen(root_ino) + 1;
if (strlen(root_path) > offset)
@@ -339,9 +269,8 @@ static int hostfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
static const struct super_operations hostfs_sbops = {
.alloc_inode = hostfs_alloc_inode,
- .drop_inode = generic_delete_inode,
- .delete_inode = hostfs_delete_inode,
.destroy_inode = hostfs_destroy_inode,
+ .evict_inode = hostfs_evict_inode,
.statfs = hostfs_statfs,
.show_options = hostfs_show_options,
};
@@ -353,11 +282,11 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
unsigned long long next, ino;
int error, len;
- name = dentry_name(file->f_path.dentry, 0);
+ name = dentry_name(file->f_path.dentry);
if (name == NULL)
return -ENOMEM;
dir = open_dir(name, &error);
- kfree(name);
+ __putname(name);
if (dir == NULL)
return -error;
next = file->f_pos;
@@ -373,40 +302,59 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
int hostfs_file_open(struct inode *ino, struct file *file)
{
+ static DEFINE_MUTEX(open_mutex);
char *name;
fmode_t mode = 0;
+ int err;
int r = 0, w = 0, fd;
mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
if ((mode & HOSTFS_I(ino)->mode) == mode)
return 0;
- /*
- * The file may already have been opened, but with the wrong access,
- * so this resets things and reopens the file with the new access.
- */
- if (HOSTFS_I(ino)->fd != -1) {
- close_file(&HOSTFS_I(ino)->fd);
- HOSTFS_I(ino)->fd = -1;
- }
+ mode |= HOSTFS_I(ino)->mode;
- HOSTFS_I(ino)->mode |= mode;
- if (HOSTFS_I(ino)->mode & FMODE_READ)
+retry:
+ if (mode & FMODE_READ)
r = 1;
- if (HOSTFS_I(ino)->mode & FMODE_WRITE)
+ if (mode & FMODE_WRITE)
w = 1;
if (w)
r = 1;
- name = dentry_name(file->f_path.dentry, 0);
+ name = dentry_name(file->f_path.dentry);
if (name == NULL)
return -ENOMEM;
fd = open_file(name, r, w, append);
- kfree(name);
+ __putname(name);
if (fd < 0)
return fd;
- FILE_HOSTFS_I(file)->fd = fd;
+
+ mutex_lock(&open_mutex);
+ /* somebody else had handled it first? */
+ if ((mode & HOSTFS_I(ino)->mode) == mode) {
+ mutex_unlock(&open_mutex);
+ return 0;
+ }
+ if ((mode | HOSTFS_I(ino)->mode) != mode) {
+ mode |= HOSTFS_I(ino)->mode;
+ mutex_unlock(&open_mutex);
+ close_file(&fd);
+ goto retry;
+ }
+ if (HOSTFS_I(ino)->fd == -1) {
+ HOSTFS_I(ino)->fd = fd;
+ } else {
+ err = replace_file(fd, HOSTFS_I(ino)->fd);
+ close_file(&fd);
+ if (err < 0) {
+ mutex_unlock(&open_mutex);
+ return err;
+ }
+ }
+ HOSTFS_I(ino)->mode = mode;
+ mutex_unlock(&open_mutex);
return 0;
}
@@ -544,54 +492,50 @@ static const struct address_space_operations hostfs_aops = {
.write_end = hostfs_write_end,
};
-static int init_inode(struct inode *inode, struct dentry *dentry)
+static int read_name(struct inode *ino, char *name)
{
- char *name;
- int type, err = -ENOMEM;
- int maj, min;
- dev_t rdev = 0;
+ dev_t rdev;
+ struct hostfs_stat st;
+ int err = stat_file(name, &st, -1);
+ if (err)
+ return err;
- if (dentry) {
- name = dentry_name(dentry, 0);
- if (name == NULL)
- goto out;
- type = file_type(name, &maj, &min);
- /* Reencode maj and min with the kernel encoding.*/
- rdev = MKDEV(maj, min);
- kfree(name);
- }
- else type = OS_TYPE_DIR;
+ /* Reencode maj and min with the kernel encoding.*/
+ rdev = MKDEV(st.maj, st.min);
- err = 0;
- if (type == OS_TYPE_SYMLINK)
- inode->i_op = &page_symlink_inode_operations;
- else if (type == OS_TYPE_DIR)
- inode->i_op = &hostfs_dir_iops;
- else inode->i_op = &hostfs_iops;
-
- if (type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
- else inode->i_fop = &hostfs_file_fops;
-
- if (type == OS_TYPE_SYMLINK)
- inode->i_mapping->a_ops = &hostfs_link_aops;
- else inode->i_mapping->a_ops = &hostfs_aops;
-
- switch (type) {
- case OS_TYPE_CHARDEV:
- init_special_inode(inode, S_IFCHR, rdev);
+ switch (st.mode & S_IFMT) {
+ case S_IFLNK:
+ ino->i_op = &hostfs_link_iops;
break;
- case OS_TYPE_BLOCKDEV:
- init_special_inode(inode, S_IFBLK, rdev);
+ case S_IFDIR:
+ ino->i_op = &hostfs_dir_iops;
+ ino->i_fop = &hostfs_dir_fops;
break;
- case OS_TYPE_FIFO:
- init_special_inode(inode, S_IFIFO, 0);
+ case S_IFCHR:
+ case S_IFBLK:
+ case S_IFIFO:
+ case S_IFSOCK:
+ init_special_inode(ino, st.mode & S_IFMT, rdev);
+ ino->i_op = &hostfs_iops;
break;
- case OS_TYPE_SOCK:
- init_special_inode(inode, S_IFSOCK, 0);
- break;
- }
- out:
- return err;
+
+ default:
+ ino->i_op = &hostfs_iops;
+ ino->i_fop = &hostfs_file_fops;
+ ino->i_mapping->a_ops = &hostfs_aops;
+ }
+
+ ino->i_ino = st.ino;
+ ino->i_mode = st.mode;
+ ino->i_nlink = st.nlink;
+ ino->i_uid = st.uid;
+ ino->i_gid = st.gid;
+ ino->i_atime = st.atime;
+ ino->i_mtime = st.mtime;
+ ino->i_ctime = st.ctime;
+ ino->i_size = st.size;
+ ino->i_blocks = st.blocks;
+ return 0;
}
int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
@@ -607,12 +551,8 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
goto out;
}
- error = init_inode(inode, dentry);
- if (error)
- goto out_put;
-
error = -ENOMEM;
- name = dentry_name(dentry, 0);
+ name = dentry_name(dentry);
if (name == NULL)
goto out_put;
@@ -622,9 +562,10 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
if (fd < 0)
error = fd;
- else error = read_name(inode, name);
+ else
+ error = read_name(inode, name);
- kfree(name);
+ __putname(name);
if (error)
goto out_put;
@@ -652,17 +593,14 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
goto out;
}
- err = init_inode(inode, dentry);
- if (err)
- goto out_put;
-
err = -ENOMEM;
- name = dentry_name(dentry, 0);
+ name = dentry_name(dentry);
if (name == NULL)
goto out_put;
err = read_name(inode, name);
- kfree(name);
+
+ __putname(name);
if (err == -ENOENT) {
iput(inode);
inode = NULL;
@@ -680,36 +618,21 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
return ERR_PTR(err);
}
-static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
-{
- char *file;
- int len;
-
- file = inode_name(ino, dentry->d_name.len + 1);
- if (file == NULL)
- return NULL;
- strcat(file, "/");
- len = strlen(file);
- strncat(file, dentry->d_name.name, dentry->d_name.len);
- file[len + dentry->d_name.len] = '\0';
- return file;
-}
-
int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
{
char *from_name, *to_name;
int err;
- if ((from_name = inode_dentry_name(ino, from)) == NULL)
+ if ((from_name = dentry_name(from)) == NULL)
return -ENOMEM;
- to_name = dentry_name(to, 0);
+ to_name = dentry_name(to);
if (to_name == NULL) {
- kfree(from_name);
+ __putname(from_name);
return -ENOMEM;
}
err = link_file(to_name, from_name);
- kfree(from_name);
- kfree(to_name);
+ __putname(from_name);
+ __putname(to_name);
return err;
}
@@ -718,13 +641,14 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if ((file = inode_dentry_name(ino, dentry)) == NULL)
- return -ENOMEM;
if (append)
return -EPERM;
+ if ((file = dentry_name(dentry)) == NULL)
+ return -ENOMEM;
+
err = unlink_file(file);
- kfree(file);
+ __putname(file);
return err;
}
@@ -733,10 +657,10 @@ int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
char *file;
int err;
- if ((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = dentry_name(dentry)) == NULL)
return -ENOMEM;
err = make_symlink(file, to);
- kfree(file);
+ __putname(file);
return err;
}
@@ -745,10 +669,10 @@ int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
char *file;
int err;
- if ((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = dentry_name(dentry)) == NULL)
return -ENOMEM;
err = do_mkdir(file, mode);
- kfree(file);
+ __putname(file);
return err;
}
@@ -757,10 +681,10 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
char *file;
int err;
- if ((file = inode_dentry_name(ino, dentry)) == NULL)
+ if ((file = dentry_name(dentry)) == NULL)
return -ENOMEM;
err = do_rmdir(file);
- kfree(file);
+ __putname(file);
return err;
}
@@ -776,22 +700,20 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
goto out;
}
- err = init_inode(inode, dentry);
- if (err)
- goto out_put;
-
err = -ENOMEM;
- name = dentry_name(dentry, 0);
+ name = dentry_name(dentry);
if (name == NULL)
goto out_put;
init_special_inode(inode, mode, dev);
err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
- if (err)
+ if (!err)
goto out_free;
err = read_name(inode, name);
- kfree(name);
+ __putname(name);
+ if (err)
+ goto out_put;
if (err)
goto out_put;
@@ -799,7 +721,7 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
return 0;
out_free:
- kfree(name);
+ __putname(name);
out_put:
iput(inode);
out:
@@ -812,15 +734,15 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
char *from_name, *to_name;
int err;
- if ((from_name = inode_dentry_name(from_ino, from)) == NULL)
+ if ((from_name = dentry_name(from)) == NULL)
return -ENOMEM;
- if ((to_name = inode_dentry_name(to_ino, to)) == NULL) {
- kfree(from_name);
+ if ((to_name = dentry_name(to)) == NULL) {
+ __putname(from_name);
return -ENOMEM;
}
err = rename_file(from_name, to_name);
- kfree(from_name);
- kfree(to_name);
+ __putname(from_name);
+ __putname(to_name);
return err;
}
@@ -832,7 +754,7 @@ int hostfs_permission(struct inode *ino, int desired)
if (desired & MAY_READ) r = 1;
if (desired & MAY_WRITE) w = 1;
if (desired & MAY_EXEC) x = 1;
- name = inode_name(ino, 0);
+ name = inode_name(ino);
if (name == NULL)
return -ENOMEM;
@@ -841,7 +763,7 @@ int hostfs_permission(struct inode *ino, int desired)
err = 0;
else
err = access_file(name, r, w, x);
- kfree(name);
+ __putname(name);
if (!err)
err = generic_permission(ino, desired, NULL);
return err;
@@ -849,13 +771,14 @@ int hostfs_permission(struct inode *ino, int desired)
int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
{
+ struct inode *inode = dentry->d_inode;
struct hostfs_iattr attrs;
char *name;
int err;
- int fd = HOSTFS_I(dentry->d_inode)->fd;
+ int fd = HOSTFS_I(inode)->fd;
- err = inode_change_ok(dentry->d_inode, attr);
+ err = inode_change_ok(inode, attr);
if (err)
return err;
@@ -897,15 +820,26 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
if (attr->ia_valid & ATTR_MTIME_SET) {
attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
}
- name = dentry_name(dentry, 0);
+ name = dentry_name(dentry);
if (name == NULL)
return -ENOMEM;
err = set_attr(name, &attrs, fd);
- kfree(name);
+ __putname(name);
if (err)
return err;
- return inode_setattr(dentry->d_inode, attr);
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ int error;
+
+ error = vmtruncate(inode, attr->ia_size);
+ if (err)
+ return err;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
static const struct inode_operations hostfs_iops = {
@@ -935,32 +869,41 @@ static const struct inode_operations hostfs_dir_iops = {
.setattr = hostfs_setattr,
};
-int hostfs_link_readpage(struct file *file, struct page *page)
-{
- char *buffer, *name;
- int err;
-
- buffer = kmap(page);
- name = inode_name(page->mapping->host, 0);
- if (name == NULL)
- return -ENOMEM;
- err = hostfs_do_readlink(name, buffer, PAGE_CACHE_SIZE);
- kfree(name);
- if (err == PAGE_CACHE_SIZE)
- err = -E2BIG;
- else if (err > 0) {
- flush_dcache_page(page);
- SetPageUptodate(page);
- if (PageError(page)) ClearPageError(page);
- err = 0;
+static void *hostfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+{
+ char *link = __getname();
+ if (link) {
+ char *path = dentry_name(dentry);
+ int err = -ENOMEM;
+ if (path) {
+ int err = hostfs_do_readlink(path, link, PATH_MAX);
+ if (err == PATH_MAX)
+ err = -E2BIG;
+ __putname(path);
+ }
+ if (err < 0) {
+ __putname(link);
+ link = ERR_PTR(err);
+ }
+ } else {
+ link = ERR_PTR(-ENOMEM);
}
- kunmap(page);
- unlock_page(page);
- return err;
+
+ nd_set_link(nd, link);
+ return NULL;
}
-static const struct address_space_operations hostfs_link_aops = {
- .readpage = hostfs_link_readpage,
+static void hostfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie)
+{
+ char *s = nd_get_link(nd);
+ if (!IS_ERR(s))
+ __putname(s);
+}
+
+static const struct inode_operations hostfs_link_iops = {
+ .readlink = generic_readlink,
+ .follow_link = hostfs_follow_link,
+ .put_link = hostfs_put_link,
};
static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
@@ -980,49 +923,41 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
req_root = "";
err = -ENOMEM;
- host_root_path = kmalloc(strlen(root_ino) + 1
- + strlen(req_root) + 1, GFP_KERNEL);
+ sb->s_fs_info = host_root_path =
+ kmalloc(strlen(root_ino) + strlen(req_root) + 2, GFP_KERNEL);
if (host_root_path == NULL)
goto out;
sprintf(host_root_path, "%s/%s", root_ino, req_root);
- root_inode = hostfs_iget(sb);
- if (IS_ERR(root_inode)) {
- err = PTR_ERR(root_inode);
- goto out_free;
- }
+ root_inode = new_inode(sb);
+ if (!root_inode)
+ goto out;
- err = init_inode(root_inode, NULL);
+ err = read_name(root_inode, host_root_path);
if (err)
goto out_put;
- HOSTFS_I(root_inode)->host_filename = host_root_path;
- /*
- * Avoid that in the error path, iput(root_inode) frees again
- * host_root_path through hostfs_destroy_inode!
- */
- host_root_path = NULL;
+ if (S_ISLNK(root_inode->i_mode)) {
+ char *name = follow_link(host_root_path);
+ if (IS_ERR(name))
+ err = PTR_ERR(name);
+ else
+ err = read_name(root_inode, name);
+ kfree(name);
+ if (err)
+ goto out_put;
+ }
err = -ENOMEM;
sb->s_root = d_alloc_root(root_inode);
if (sb->s_root == NULL)
goto out_put;
- err = hostfs_read_inode(root_inode);
- if (err) {
- /* No iput in this case because the dput does that for us */
- dput(sb->s_root);
- sb->s_root = NULL;
- goto out;
- }
-
return 0;
out_put:
iput(root_inode);
-out_free:
- kfree(host_root_path);
out:
return err;
}
@@ -1034,11 +969,17 @@ static int hostfs_read_sb(struct file_system_type *type,
return get_sb_nodev(type, flags, data, hostfs_fill_sb_common, mnt);
}
+static void hostfs_kill_sb(struct super_block *s)
+{
+ kill_anon_super(s);
+ kfree(s->s_fs_info);
+}
+
static struct file_system_type hostfs_type = {
.owner = THIS_MODULE,
.name = "hostfs",
.get_sb = hostfs_read_sb,
- .kill_sb = kill_anon_super,
+ .kill_sb = hostfs_kill_sb,
.fs_flags = 0,
};
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index b79424f93282..6777aa06ce2c 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -19,11 +19,27 @@
#include "user.h"
#include <utime.h>
-int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
- int *nlink_out, int *uid_out, int *gid_out,
- unsigned long long *size_out, struct timespec *atime_out,
- struct timespec *mtime_out, struct timespec *ctime_out,
- int *blksize_out, unsigned long long *blocks_out, int fd)
+static void stat64_to_hostfs(const struct stat64 *buf, struct hostfs_stat *p)
+{
+ p->ino = buf->st_ino;
+ p->mode = buf->st_mode;
+ p->nlink = buf->st_nlink;
+ p->uid = buf->st_uid;
+ p->gid = buf->st_gid;
+ p->size = buf->st_size;
+ p->atime.tv_sec = buf->st_atime;
+ p->atime.tv_nsec = 0;
+ p->ctime.tv_sec = buf->st_ctime;
+ p->ctime.tv_nsec = 0;
+ p->mtime.tv_sec = buf->st_mtime;
+ p->mtime.tv_nsec = 0;
+ p->blksize = buf->st_blksize;
+ p->blocks = buf->st_blocks;
+ p->maj = os_major(buf->st_rdev);
+ p->min = os_minor(buf->st_rdev);
+}
+
+int stat_file(const char *path, struct hostfs_stat *p, int fd)
{
struct stat64 buf;
@@ -33,68 +49,10 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
} else if (lstat64(path, &buf) < 0) {
return -errno;
}
-
- if (inode_out != NULL)
- *inode_out = buf.st_ino;
- if (mode_out != NULL)
- *mode_out = buf.st_mode;
- if (nlink_out != NULL)
- *nlink_out = buf.st_nlink;
- if (uid_out != NULL)
- *uid_out = buf.st_uid;
- if (gid_out != NULL)
- *gid_out = buf.st_gid;
- if (size_out != NULL)
- *size_out = buf.st_size;
- if (atime_out != NULL) {
- atime_out->tv_sec = buf.st_atime;
- atime_out->tv_nsec = 0;
- }
- if (mtime_out != NULL) {
- mtime_out->tv_sec = buf.st_mtime;
- mtime_out->tv_nsec = 0;
- }
- if (ctime_out != NULL) {
- ctime_out->tv_sec = buf.st_ctime;
- ctime_out->tv_nsec = 0;
- }
- if (blksize_out != NULL)
- *blksize_out = buf.st_blksize;
- if (blocks_out != NULL)
- *blocks_out = buf.st_blocks;
+ stat64_to_hostfs(&buf, p);
return 0;
}
-int file_type(const char *path, int *maj, int *min)
-{
- struct stat64 buf;
-
- if (lstat64(path, &buf) < 0)
- return -errno;
- /*
- * We cannot pass rdev as is because glibc and the kernel disagree
- * about its definition.
- */
- if (maj != NULL)
- *maj = major(buf.st_rdev);
- if (min != NULL)
- *min = minor(buf.st_rdev);
-
- if (S_ISDIR(buf.st_mode))
- return OS_TYPE_DIR;
- else if (S_ISLNK(buf.st_mode))
- return OS_TYPE_SYMLINK;
- else if (S_ISCHR(buf.st_mode))
- return OS_TYPE_CHARDEV;
- else if (S_ISBLK(buf.st_mode))
- return OS_TYPE_BLOCKDEV;
- else if (S_ISFIFO(buf.st_mode))
- return OS_TYPE_FIFO;
- else if (S_ISSOCK(buf.st_mode))
- return OS_TYPE_SOCK;
- else return OS_TYPE_FILE;
-}
-
int access_file(char *path, int r, int w, int x)
{
int mode = 0;
@@ -202,6 +160,11 @@ int fsync_file(int fd, int datasync)
return 0;
}
+int replace_file(int oldfd, int fd)
+{
+ return dup2(oldfd, fd);
+}
+
void close_file(void *stream)
{
close(*((int *) stream));
@@ -235,8 +198,8 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
{
+ struct hostfs_stat st;
struct timeval times[2];
- struct timespec atime_ts, mtime_ts;
int err, ma;
if (attrs->ia_valid & HOSTFS_ATTR_MODE) {
@@ -279,15 +242,14 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
*/
ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
if (attrs->ia_valid & ma) {
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
- &atime_ts, &mtime_ts, NULL, NULL, NULL, fd);
+ err = stat_file(file, &st, fd);
if (err != 0)
return err;
- times[0].tv_sec = atime_ts.tv_sec;
- times[0].tv_usec = atime_ts.tv_nsec / 1000;
- times[1].tv_sec = mtime_ts.tv_sec;
- times[1].tv_usec = mtime_ts.tv_nsec / 1000;
+ times[0].tv_sec = st.atime.tv_sec;
+ times[0].tv_usec = st.atime.tv_nsec / 1000;
+ times[1].tv_sec = st.mtime.tv_sec;
+ times[1].tv_usec = st.mtime.tv_nsec / 1000;
if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) {
times[0].tv_sec = attrs->ia_atime.tv_sec;
@@ -308,9 +270,9 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
/* Note: ctime is not handled */
if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) {
- err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
- &attrs->ia_atime, &attrs->ia_mtime, NULL,
- NULL, NULL, fd);
+ err = stat_file(file, &st, fd);
+ attrs->ia_atime = st.atime;
+ attrs->ia_mtime = st.mtime;
if (err != 0)
return err;
}
@@ -361,7 +323,7 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
{
int err;
- err = mknod(file, mode, makedev(major, minor));
+ err = mknod(file, mode, os_makedev(major, minor));
if (err)
return -errno;
return 0;
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index a9ae9bfa752f..c0340887c7ea 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -97,10 +97,19 @@ static int hpfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
hpfs_get_block,
&hpfs_i(mapping->host)->mmu_private);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 75f9d4324851..b59eac0232a0 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -281,7 +281,7 @@ void hpfs_write_inode(struct inode *);
void hpfs_write_inode_nolock(struct inode *);
int hpfs_setattr(struct dentry *, struct iattr *);
void hpfs_write_if_changed(struct inode *);
-void hpfs_delete_inode(struct inode *);
+void hpfs_evict_inode(struct inode *);
/* map.c */
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
index 1042a9bc97f3..56f0da1cfd10 100644
--- a/fs/hpfs/inode.c
+++ b/fs/hpfs/inode.c
@@ -277,9 +277,15 @@ int hpfs_setattr(struct dentry *dentry, struct iattr *attr)
if (error)
goto out_unlock;
- error = inode_setattr(inode, attr);
- if (error)
- goto out_unlock;
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
hpfs_write_inode(inode);
@@ -296,11 +302,13 @@ void hpfs_write_if_changed(struct inode *inode)
hpfs_write_inode(inode);
}
-void hpfs_delete_inode(struct inode *inode)
+void hpfs_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- lock_kernel();
- hpfs_remove_fnode(inode->i_sb, inode->i_ino);
- unlock_kernel();
- clear_inode(inode);
+ end_writeback(inode);
+ if (!inode->i_nlink) {
+ lock_kernel();
+ hpfs_remove_fnode(inode->i_sb, inode->i_ino);
+ unlock_kernel();
+ }
}
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
index aa53842c599c..2607010be2fe 100644
--- a/fs/hpfs/super.c
+++ b/fs/hpfs/super.c
@@ -450,7 +450,7 @@ static const struct super_operations hpfs_sops =
{
.alloc_inode = hpfs_alloc_inode,
.destroy_inode = hpfs_destroy_inode,
- .delete_inode = hpfs_delete_inode,
+ .evict_inode = hpfs_evict_inode,
.put_super = hpfs_put_super,
.statfs = hpfs_statfs,
.remount_fs = hpfs_remount_fs,
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index 826c3f9d29ac..7b027720d820 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -15,6 +15,7 @@
#include <linux/slab.h>
#include <linux/statfs.h>
#include <linux/types.h>
+#include <linux/pid_namespace.h>
#include <asm/uaccess.h>
#include "os.h"
@@ -623,12 +624,11 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb)
return &hi->vfs_inode;
}
-void hppfs_delete_inode(struct inode *ino)
+void hppfs_evict_inode(struct inode *ino)
{
+ end_writeback(ino);
dput(HPPFS_I(ino)->proc_dentry);
mntput(ino->i_sb->s_fs_info);
-
- clear_inode(ino);
}
static void hppfs_destroy_inode(struct inode *inode)
@@ -639,7 +639,7 @@ static void hppfs_destroy_inode(struct inode *inode)
static const struct super_operations hppfs_sbops = {
.alloc_inode = hppfs_alloc_inode,
.destroy_inode = hppfs_destroy_inode,
- .delete_inode = hppfs_delete_inode,
+ .evict_inode = hppfs_evict_inode,
.statfs = hppfs_statfs,
};
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index a4e9a7ec3691..6e5bd42f3860 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -371,27 +371,10 @@ static void truncate_hugepages(struct inode *inode, loff_t lstart)
hugetlb_unreserve_pages(inode, start, freed);
}
-static void hugetlbfs_delete_inode(struct inode *inode)
+static void hugetlbfs_evict_inode(struct inode *inode)
{
truncate_hugepages(inode, 0);
- clear_inode(inode);
-}
-
-static void hugetlbfs_forget_inode(struct inode *inode) __releases(inode_lock)
-{
- if (generic_detach_inode(inode)) {
- truncate_hugepages(inode, 0);
- clear_inode(inode);
- destroy_inode(inode);
- }
-}
-
-static void hugetlbfs_drop_inode(struct inode *inode)
-{
- if (!inode->i_nlink)
- generic_delete_inode(inode);
- else
- hugetlbfs_forget_inode(inode);
+ end_writeback(inode);
}
static inline void
@@ -448,19 +431,20 @@ static int hugetlbfs_setattr(struct dentry *dentry, struct iattr *attr)
error = inode_change_ok(inode, attr);
if (error)
- goto out;
+ return error;
if (ia_valid & ATTR_SIZE) {
error = -EINVAL;
- if (!(attr->ia_size & ~huge_page_mask(h)))
- error = hugetlb_vmtruncate(inode, attr->ia_size);
+ if (attr->ia_size & ~huge_page_mask(h))
+ return -EINVAL;
+ error = hugetlb_vmtruncate(inode, attr->ia_size);
if (error)
- goto out;
- attr->ia_valid &= ~ATTR_SIZE;
+ return error;
}
- error = inode_setattr(inode, attr);
-out:
- return error;
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
@@ -712,9 +696,8 @@ static const struct inode_operations hugetlbfs_inode_operations = {
static const struct super_operations hugetlbfs_ops = {
.alloc_inode = hugetlbfs_alloc_inode,
.destroy_inode = hugetlbfs_destroy_inode,
+ .evict_inode = hugetlbfs_evict_inode,
.statfs = hugetlbfs_statfs,
- .delete_inode = hugetlbfs_delete_inode,
- .drop_inode = hugetlbfs_drop_inode,
.put_super = hugetlbfs_put_super,
.show_options = generic_show_options,
};
diff --git a/fs/inode.c b/fs/inode.c
index 2bee20ae3d65..d213089741bb 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -294,32 +294,34 @@ void __iget(struct inode *inode)
inodes_stat.nr_unused--;
}
-/**
- * clear_inode - clear an inode
- * @inode: inode to clear
- *
- * This is called by the filesystem to tell us
- * that the inode is no longer useful. We just
- * terminate it with extreme prejudice.
- */
-void clear_inode(struct inode *inode)
+void end_writeback(struct inode *inode)
{
might_sleep();
- invalidate_inode_buffers(inode);
-
BUG_ON(inode->i_data.nrpages);
+ BUG_ON(!list_empty(&inode->i_data.private_list));
BUG_ON(!(inode->i_state & I_FREEING));
BUG_ON(inode->i_state & I_CLEAR);
inode_sync_wait(inode);
- if (inode->i_sb->s_op->clear_inode)
- inode->i_sb->s_op->clear_inode(inode);
+ inode->i_state = I_FREEING | I_CLEAR;
+}
+EXPORT_SYMBOL(end_writeback);
+
+static void evict(struct inode *inode)
+{
+ const struct super_operations *op = inode->i_sb->s_op;
+
+ if (op->evict_inode) {
+ op->evict_inode(inode);
+ } else {
+ if (inode->i_data.nrpages)
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
+ }
if (S_ISBLK(inode->i_mode) && inode->i_bdev)
bd_forget(inode);
if (S_ISCHR(inode->i_mode) && inode->i_cdev)
cd_forget(inode);
- inode->i_state = I_CLEAR;
}
-EXPORT_SYMBOL(clear_inode);
/*
* dispose_list - dispose of the contents of a local list
@@ -338,9 +340,7 @@ static void dispose_list(struct list_head *head)
inode = list_first_entry(head, struct inode, i_list);
list_del(&inode->i_list);
- if (inode->i_data.nrpages)
- truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ evict(inode);
spin_lock(&inode_lock);
hlist_del_init(&inode->i_hash);
@@ -553,7 +553,7 @@ repeat:
continue;
if (!test(inode, data))
continue;
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+ if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
__wait_on_freeing_inode(inode);
goto repeat;
}
@@ -578,7 +578,7 @@ repeat:
continue;
if (inode->i_sb != sb)
continue;
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
+ if (inode->i_state & (I_FREEING|I_WILL_FREE)) {
__wait_on_freeing_inode(inode);
goto repeat;
}
@@ -840,7 +840,7 @@ EXPORT_SYMBOL(iunique);
struct inode *igrab(struct inode *inode)
{
spin_lock(&inode_lock);
- if (!(inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)))
+ if (!(inode->i_state & (I_FREEING|I_WILL_FREE)))
__iget(inode);
else
/*
@@ -1089,7 +1089,7 @@ int insert_inode_locked(struct inode *inode)
continue;
if (old->i_sb != sb)
continue;
- if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+ if (old->i_state & (I_FREEING|I_WILL_FREE))
continue;
break;
}
@@ -1128,7 +1128,7 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval,
continue;
if (!test(old, data))
continue;
- if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE))
+ if (old->i_state & (I_FREEING|I_WILL_FREE))
continue;
break;
}
@@ -1194,8 +1194,6 @@ EXPORT_SYMBOL(remove_inode_hash);
*/
void generic_delete_inode(struct inode *inode)
{
- const struct super_operations *op = inode->i_sb->s_op;
-
list_del_init(&inode->i_list);
list_del_init(&inode->i_sb_list);
WARN_ON(inode->i_state & I_NEW);
@@ -1203,22 +1201,13 @@ void generic_delete_inode(struct inode *inode)
inodes_stat.nr_inodes--;
spin_unlock(&inode_lock);
- if (op->delete_inode) {
- void (*delete)(struct inode *) = op->delete_inode;
- /* Filesystems implementing their own
- * s_op->delete_inode are required to call
- * truncate_inode_pages and clear_inode()
- * internally */
- delete(inode);
- } else {
- truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
- }
+ evict(inode);
+
spin_lock(&inode_lock);
hlist_del_init(&inode->i_hash);
spin_unlock(&inode_lock);
wake_up_inode(inode);
- BUG_ON(inode->i_state != I_CLEAR);
+ BUG_ON(inode->i_state != (I_FREEING | I_CLEAR));
destroy_inode(inode);
}
EXPORT_SYMBOL(generic_delete_inode);
@@ -1232,7 +1221,7 @@ EXPORT_SYMBOL(generic_delete_inode);
*
* Returns 1 if inode should be completely destroyed.
*/
-int generic_detach_inode(struct inode *inode)
+static int generic_detach_inode(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
@@ -1262,15 +1251,12 @@ int generic_detach_inode(struct inode *inode)
spin_unlock(&inode_lock);
return 1;
}
-EXPORT_SYMBOL_GPL(generic_detach_inode);
static void generic_forget_inode(struct inode *inode)
{
if (!generic_detach_inode(inode))
return;
- if (inode->i_data.nrpages)
- truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ evict(inode);
wake_up_inode(inode);
destroy_inode(inode);
}
@@ -1322,7 +1308,7 @@ static inline void iput_final(struct inode *inode)
void iput(struct inode *inode)
{
if (inode) {
- BUG_ON(inode->i_state == I_CLEAR);
+ BUG_ON(inode->i_state & I_CLEAR);
if (atomic_dec_and_lock(&inode->i_count, &inode_lock))
iput_final(inode);
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 93d1e47647bd..f19ce94693d8 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -1281,13 +1281,9 @@ int journal_check_used_features (journal_t *journal, unsigned long compat,
int journal_check_available_features (journal_t *journal, unsigned long compat,
unsigned long ro, unsigned long incompat)
{
- journal_superblock_t *sb;
-
if (!compat && !ro && !incompat)
return 1;
- sb = journal->j_superblock;
-
/* We can support any known requested features iff the
* superblock is in version 2. Otherwise we fail to support any
* extended sb features. */
@@ -1481,7 +1477,6 @@ int journal_flush(journal_t *journal)
int journal_wipe(journal_t *journal, int write)
{
- journal_superblock_t *sb;
int err = 0;
J_ASSERT (!(journal->j_flags & JFS_LOADED));
@@ -1490,8 +1485,6 @@ int journal_wipe(journal_t *journal, int write)
if (err)
return err;
- sb = journal->j_superblock;
-
if (!journal->j_tail)
goto no_recovery;
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c
index 54c9bc9e1b17..81051dafebf5 100644
--- a/fs/jbd/recovery.c
+++ b/fs/jbd/recovery.c
@@ -283,12 +283,9 @@ int journal_recover(journal_t *journal)
int journal_skip_recovery(journal_t *journal)
{
int err;
- journal_superblock_t * sb;
-
struct recovery_info info;
memset (&info, 0, sizeof(info));
- sb = journal->j_superblock;
err = do_one_pass(journal, &info, PASS_SCAN);
@@ -297,7 +294,8 @@ int journal_skip_recovery(journal_t *journal)
++journal->j_transaction_sequence;
} else {
#ifdef CONFIG_JBD_DEBUG
- int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence);
+ int dropped = info.end_transaction -
+ be32_to_cpu(journal->j_superblock->s_sequence);
#endif
jbd_debug(1,
"JBD: ignoring %d transaction%s from the journal.\n",
@@ -321,11 +319,6 @@ static int do_one_pass(journal_t *journal,
unsigned int sequence;
int blocktype;
- /* Precompute the maximum metadata descriptors in a descriptor block */
- int MAX_BLOCKS_PER_DESC;
- MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
- / sizeof(journal_block_tag_t));
-
/*
* First thing is to establish what we expect to find in the log
* (in terms of transaction IDs), and where (in terms of log
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 166062a68230..5fd3b5cecda5 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -232,9 +232,7 @@ static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
return 0;
fail:
- make_bad_inode(inode);
- unlock_new_inode(inode);
- iput(inode);
+ iget_failed(inode);
jffs2_free_raw_inode(ri);
return ret;
}
@@ -454,9 +452,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
return 0;
fail:
- make_bad_inode(inode);
- unlock_new_inode(inode);
- iput(inode);
+ iget_failed(inode);
return ret;
}
@@ -601,9 +597,7 @@ static int jffs2_mkdir (struct inode *dir_i, struct dentry *dentry, int mode)
return 0;
fail:
- make_bad_inode(inode);
- unlock_new_inode(inode);
- iput(inode);
+ iget_failed(inode);
return ret;
}
@@ -778,9 +772,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, de
return 0;
fail:
- make_bad_inode(inode);
- unlock_new_inode(inode);
- iput(inode);
+ iget_failed(inode);
return ret;
}
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 459d39d1ea0b..ac0638f04969 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -169,13 +169,13 @@ int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
mutex_unlock(&f->sem);
jffs2_complete_reservation(c);
- /* We have to do the simple_setsize() without f->sem held, since
+ /* We have to do the truncate_setsize() without f->sem held, since
some pages may be locked and waiting for it in readpage().
We are protected from a simultaneous write() extending i_size
back past iattr->ia_size, because do_truncate() holds the
generic inode semaphore. */
if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) {
- simple_setsize(inode, iattr->ia_size);
+ truncate_setsize(inode, iattr->ia_size);
inode->i_blocks = (inode->i_size + 511) >> 9;
}
@@ -225,7 +225,7 @@ int jffs2_statfs(struct dentry *dentry, struct kstatfs *buf)
}
-void jffs2_clear_inode (struct inode *inode)
+void jffs2_evict_inode (struct inode *inode)
{
/* We can forget about this inode for now - drop all
* the nodelists associated with it, etc.
@@ -233,7 +233,9 @@ void jffs2_clear_inode (struct inode *inode)
struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
+ D1(printk(KERN_DEBUG "jffs2_evict_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
jffs2_do_clear_inode(c, f);
}
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 4791aacf3084..00bae7cc2e48 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -171,7 +171,7 @@ extern const struct inode_operations jffs2_symlink_inode_operations;
int jffs2_setattr (struct dentry *, struct iattr *);
int jffs2_do_setattr (struct inode *, struct iattr *);
struct inode *jffs2_iget(struct super_block *, unsigned long);
-void jffs2_clear_inode (struct inode *);
+void jffs2_evict_inode (struct inode *);
void jffs2_dirty_inode(struct inode *inode);
struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
struct jffs2_raw_inode *ri);
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 511e2d609d12..662bba099501 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -135,7 +135,7 @@ static const struct super_operations jffs2_super_operations =
.write_super = jffs2_write_super,
.statfs = jffs2_statfs,
.remount_fs = jffs2_remount_fs,
- .clear_inode = jffs2_clear_inode,
+ .evict_inode = jffs2_evict_inode,
.dirty_inode = jffs2_dirty_inode,
.sync_fs = jffs2_sync_fs,
};
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index a2d58c96f1b4..fcceeab34436 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -588,7 +588,7 @@ static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *re
void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
{
- /* It's called from jffs2_clear_inode() on inode removing.
+ /* It's called from jffs2_evict_inode() on inode removing.
When an inode with XATTR is removed, those XATTRs must be removed. */
struct jffs2_xattr_ref *ref, *_ref;
diff --git a/fs/jfs/file.c b/fs/jfs/file.c
index 127263cc8657..c5ce6c1d1ff4 100644
--- a/fs/jfs/file.c
+++ b/fs/jfs/file.c
@@ -17,6 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h"
@@ -107,11 +108,18 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
return rc;
}
- rc = inode_setattr(inode, iattr);
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(inode)) {
+ rc = vmtruncate(inode, iattr->ia_size);
+ if (rc)
+ return rc;
+ }
- if (!rc && (iattr->ia_valid & ATTR_MODE))
- rc = jfs_acl_chmod(inode);
+ setattr_copy(inode, iattr);
+ mark_inode_dirty(inode);
+ if (iattr->ia_valid & ATTR_MODE)
+ rc = jfs_acl_chmod(inode);
return rc;
}
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index ed9ba6fe04f5..9978803ceedc 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -145,31 +145,32 @@ int jfs_write_inode(struct inode *inode, struct writeback_control *wbc)
return 0;
}
-void jfs_delete_inode(struct inode *inode)
+void jfs_evict_inode(struct inode *inode)
{
- jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
+ jfs_info("In jfs_evict_inode, inode = 0x%p", inode);
- if (!is_bad_inode(inode))
+ if (!inode->i_nlink && !is_bad_inode(inode)) {
dquot_initialize(inode);
- if (!is_bad_inode(inode) &&
- (JFS_IP(inode)->fileset == FILESYSTEM_I)) {
- truncate_inode_pages(&inode->i_data, 0);
+ if (JFS_IP(inode)->fileset == FILESYSTEM_I) {
+ truncate_inode_pages(&inode->i_data, 0);
- if (test_cflag(COMMIT_Freewmap, inode))
- jfs_free_zero_link(inode);
+ if (test_cflag(COMMIT_Freewmap, inode))
+ jfs_free_zero_link(inode);
- diFree(inode);
+ diFree(inode);
- /*
- * Free the inode from the quota allocation.
- */
- dquot_initialize(inode);
- dquot_free_inode(inode);
- dquot_drop(inode);
+ /*
+ * Free the inode from the quota allocation.
+ */
+ dquot_initialize(inode);
+ dquot_free_inode(inode);
+ }
+ } else {
+ truncate_inode_pages(&inode->i_data, 0);
}
-
- clear_inode(inode);
+ end_writeback(inode);
+ dquot_drop(inode);
}
void jfs_dirty_inode(struct inode *inode)
@@ -303,8 +304,17 @@ static int jfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ int ret;
+
+ ret = nobh_write_begin(mapping, pos, len, flags, pagep, fsdata,
jfs_get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
@@ -317,9 +327,24 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
+ ssize_t ret;
- return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, jfs_get_block, NULL);
+
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+
+ return ret;
}
const struct address_space_operations jfs_aops = {
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index 11042b1f44b5..155e91eff07d 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -27,7 +27,7 @@ extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long);
extern struct inode *jfs_iget(struct super_block *, unsigned long);
extern int jfs_commit_inode(struct inode *, int);
extern int jfs_write_inode(struct inode *, struct writeback_control *);
-extern void jfs_delete_inode(struct inode *);
+extern void jfs_evict_inode(struct inode *);
extern void jfs_dirty_inode(struct inode *);
extern void jfs_truncate(struct inode *);
extern void jfs_truncate_nolock(struct inode *, loff_t);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index b38f96bef829..ec8c3e4baca3 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -132,11 +132,6 @@ static void jfs_destroy_inode(struct inode *inode)
kmem_cache_free(jfs_inode_cachep, ji);
}
-static void jfs_clear_inode(struct inode *inode)
-{
- dquot_drop(inode);
-}
-
static int jfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct jfs_sb_info *sbi = JFS_SBI(dentry->d_sb);
@@ -765,8 +760,7 @@ static const struct super_operations jfs_super_operations = {
.destroy_inode = jfs_destroy_inode,
.dirty_inode = jfs_dirty_inode,
.write_inode = jfs_write_inode,
- .delete_inode = jfs_delete_inode,
- .clear_inode = jfs_clear_inode,
+ .evict_inode = jfs_evict_inode,
.put_super = jfs_put_super,
.sync_fs = jfs_sync_fs,
.freeze_fs = jfs_freeze,
diff --git a/fs/libfs.c b/fs/libfs.c
index dcaf972cbf1b..0a9da95317f7 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -327,77 +327,35 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry,
}
/**
- * simple_setsize - handle core mm and vfs requirements for file size change
- * @inode: inode
- * @newsize: new file size
- *
- * Returns 0 on success, -error on failure.
- *
- * simple_setsize must be called with inode_mutex held.
- *
- * simple_setsize will check that the requested new size is OK (see
- * inode_newsize_ok), and then will perform the necessary i_size update
- * and pagecache truncation (if necessary). It will be typically be called
- * from the filesystem's setattr function when ATTR_SIZE is passed in.
- *
- * The inode itself must have correct permissions and attributes to allow
- * i_size to be changed, this function then just checks that the new size
- * requested is valid.
- *
- * In the case of simple in-memory filesystems with inodes stored solely
- * in the inode cache, and file data in the pagecache, nothing more needs
- * to be done to satisfy a truncate request. Filesystems with on-disk
- * blocks for example will need to free them in the case of truncate, in
- * that case it may be easier not to use simple_setsize (but each of its
- * components will likely be required at some point to update pagecache
- * and inode etc).
- */
-int simple_setsize(struct inode *inode, loff_t newsize)
-{
- loff_t oldsize;
- int error;
-
- error = inode_newsize_ok(inode, newsize);
- if (error)
- return error;
-
- oldsize = inode->i_size;
- i_size_write(inode, newsize);
- truncate_pagecache(inode, oldsize, newsize);
-
- return error;
-}
-EXPORT_SYMBOL(simple_setsize);
-
-/**
- * simple_setattr - setattr for simple in-memory filesystem
+ * simple_setattr - setattr for simple filesystem
* @dentry: dentry
* @iattr: iattr structure
*
* Returns 0 on success, -error on failure.
*
- * simple_setattr implements setattr for an in-memory filesystem which
- * does not store its own file data or metadata (eg. uses the page cache
- * and inode cache as its data store).
+ * simple_setattr is a simple ->setattr implementation without a proper
+ * implementation of size changes.
+ *
+ * It can either be used for in-memory filesystems or special files
+ * on simple regular filesystems. Anything that needs to change on-disk
+ * or wire state on size changes needs its own setattr method.
*/
int simple_setattr(struct dentry *dentry, struct iattr *iattr)
{
struct inode *inode = dentry->d_inode;
int error;
+ WARN_ON_ONCE(inode->i_op->truncate);
+
error = inode_change_ok(inode, iattr);
if (error)
return error;
- if (iattr->ia_valid & ATTR_SIZE) {
- error = simple_setsize(inode, iattr->ia_size);
- if (error)
- return error;
- }
-
- generic_setattr(inode, iattr);
-
- return error;
+ if (iattr->ia_valid & ATTR_SIZE)
+ truncate_setsize(inode, iattr->ia_size);
+ setattr_copy(inode, iattr);
+ mark_inode_dirty(inode);
+ return 0;
}
EXPORT_SYMBOL(simple_setattr);
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c
index 72d1893ddd36..9777eb5b5522 100644
--- a/fs/logfs/dir.c
+++ b/fs/logfs/dir.c
@@ -434,8 +434,11 @@ static int __logfs_create(struct inode *dir, struct dentry *dentry,
int ret;
ta = kzalloc(sizeof(*ta), GFP_KERNEL);
- if (!ta)
+ if (!ta) {
+ inode->i_nlink--;
+ iput(inode);
return -ENOMEM;
+ }
ta->state = CREATE_1;
ta->ino = inode->i_ino;
@@ -821,7 +824,7 @@ const struct inode_operations logfs_dir_iops = {
};
const struct file_operations logfs_dir_fops = {
.fsync = logfs_fsync,
- .ioctl = logfs_ioctl,
+ .unlocked_ioctl = logfs_ioctl,
.readdir = logfs_readdir,
.read = generic_read_dir,
};
diff --git a/fs/logfs/file.c b/fs/logfs/file.c
index abe1cafbd4c2..e86376b87af1 100644
--- a/fs/logfs/file.c
+++ b/fs/logfs/file.c
@@ -181,9 +181,9 @@ static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this)
}
-int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
+long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
+ struct inode *inode = file->f_path.dentry->d_inode;
struct logfs_inode *li = logfs_inode(inode);
unsigned int oldflags, flags;
int err;
@@ -232,15 +232,19 @@ static int logfs_setattr(struct dentry *dentry, struct iattr *attr)
struct inode *inode = dentry->d_inode;
int err = 0;
- if (attr->ia_valid & ATTR_SIZE)
+ err = inode_change_ok(inode, attr);
+ if (err)
+ return err;
+
+ if (attr->ia_valid & ATTR_SIZE) {
err = logfs_truncate(inode, attr->ia_size);
- attr->ia_valid &= ~ATTR_SIZE;
+ if (err)
+ return err;
+ }
- if (!err)
- err = inode_change_ok(inode, attr);
- if (!err)
- err = inode_setattr(inode, attr);
- return err;
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
const struct inode_operations logfs_reg_iops = {
@@ -251,7 +255,7 @@ const struct file_operations logfs_reg_fops = {
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.fsync = logfs_fsync,
- .ioctl = logfs_ioctl,
+ .unlocked_ioctl = logfs_ioctl,
.llseek = generic_file_llseek,
.mmap = generic_file_readonly_mmap,
.open = generic_file_open,
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c
index f602e230e162..78be674d95c8 100644
--- a/fs/logfs/inode.c
+++ b/fs/logfs/inode.c
@@ -235,33 +235,21 @@ static struct inode *logfs_alloc_inode(struct super_block *sb)
* purpose is to create a new inode that will not trigger the warning if such
* an inode is still in use. An ugly hack, no doubt. Suggections for
* improvement are welcome.
+ *
+ * AV: that's what ->put_super() is for...
*/
struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino)
{
struct inode *inode;
- inode = logfs_alloc_inode(sb);
+ inode = new_inode(sb);
if (!inode)
return ERR_PTR(-ENOMEM);
inode->i_mode = S_IFREG;
inode->i_ino = ino;
- inode->i_sb = sb;
-
- /* This is a blatant copy of alloc_inode code. We'd need alloc_inode
- * to be nonstatic, alas. */
- {
- struct address_space * const mapping = &inode->i_data;
-
- mapping->a_ops = &logfs_reg_aops;
- mapping->host = inode;
- mapping->flags = 0;
- mapping_set_gfp_mask(mapping, GFP_NOFS);
- mapping->assoc_mapping = NULL;
- mapping->backing_dev_info = &default_backing_dev_info;
- inode->i_mapping = mapping;
- inode->i_nlink = 1;
- }
+ inode->i_data.a_ops = &logfs_reg_aops;
+ mapping_set_gfp_mask(&inode->i_data, GFP_NOFS);
return inode;
}
@@ -277,7 +265,7 @@ struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino)
err = logfs_read_inode(inode);
if (err) {
- destroy_meta_inode(inode);
+ iput(inode);
return ERR_PTR(err);
}
logfs_inode_setops(inode);
@@ -298,16 +286,6 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc)
return ret;
}
-void destroy_meta_inode(struct inode *inode)
-{
- if (inode) {
- if (inode->i_data.nrpages)
- truncate_inode_pages(&inode->i_data, 0);
- logfs_clear_inode(inode);
- kmem_cache_free(logfs_inode_cache, logfs_inode(inode));
- }
-}
-
/* called with inode_lock held */
static void logfs_drop_inode(struct inode *inode)
{
@@ -384,12 +362,21 @@ static int logfs_sync_fs(struct super_block *sb, int wait)
return 0;
}
+static void logfs_put_super(struct super_block *sb)
+{
+ struct logfs_super *super = logfs_super(sb);
+ /* kill the meta-inodes */
+ iput(super->s_master_inode);
+ iput(super->s_segfile_inode);
+ iput(super->s_mapping_inode);
+}
+
const struct super_operations logfs_super_operations = {
.alloc_inode = logfs_alloc_inode,
- .clear_inode = logfs_clear_inode,
- .delete_inode = logfs_delete_inode,
.destroy_inode = logfs_destroy_inode,
+ .evict_inode = logfs_evict_inode,
.drop_inode = logfs_drop_inode,
+ .put_super = logfs_put_super,
.write_inode = logfs_write_inode,
.statfs = logfs_statfs,
.sync_fs = logfs_sync_fs,
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c
index 4b0e0616b357..f46ee8b0e135 100644
--- a/fs/logfs/journal.c
+++ b/fs/logfs/journal.c
@@ -889,8 +889,6 @@ void logfs_cleanup_journal(struct super_block *sb)
struct logfs_super *super = logfs_super(sb);
btree_grim_visitor32(&super->s_reserved_segments, 0, NULL);
- destroy_meta_inode(super->s_master_inode);
- super->s_master_inode = NULL;
kfree(super->s_compressed_je);
kfree(super->s_je);
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h
index c838c4d72111..691208b53005 100644
--- a/fs/logfs/logfs.h
+++ b/fs/logfs/logfs.h
@@ -504,8 +504,8 @@ extern const struct inode_operations logfs_reg_iops;
extern const struct file_operations logfs_reg_fops;
extern const struct address_space_operations logfs_reg_aops;
int logfs_readpage(struct file *file, struct page *page);
-int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg);
+long logfs_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
int logfs_fsync(struct file *file, int datasync);
/* gc.c */
@@ -525,13 +525,11 @@ struct inode *logfs_new_meta_inode(struct super_block *sb, u64 ino);
struct inode *logfs_read_meta_inode(struct super_block *sb, u64 ino);
int logfs_init_inode_cache(void);
void logfs_destroy_inode_cache(void);
-void destroy_meta_inode(struct inode *inode);
void logfs_set_blocks(struct inode *inode, u64 no);
/* these logically belong into inode.c but actually reside in readwrite.c */
int logfs_read_inode(struct inode *inode);
int __logfs_write_inode(struct inode *inode, long flags);
-void logfs_delete_inode(struct inode *inode);
-void logfs_clear_inode(struct inode *inode);
+void logfs_evict_inode(struct inode *inode);
/* journal.c */
void logfs_write_anchor(struct super_block *sb);
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c
index 0718d112a1a5..6127baf0e188 100644
--- a/fs/logfs/readwrite.c
+++ b/fs/logfs/readwrite.c
@@ -1972,31 +1972,6 @@ static struct page *inode_to_page(struct inode *inode)
return page;
}
-/* Cheaper version of write_inode. All changes are concealed in
- * aliases, which are moved back. No write to the medium happens.
- */
-void logfs_clear_inode(struct inode *inode)
-{
- struct super_block *sb = inode->i_sb;
- struct logfs_inode *li = logfs_inode(inode);
- struct logfs_block *block = li->li_block;
- struct page *page;
-
- /* Only deleted files may be dirty at this point */
- BUG_ON(inode->i_state & I_DIRTY && inode->i_nlink);
- if (!block)
- return;
- if ((logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN)) {
- block->ops->free_block(inode->i_sb, block);
- return;
- }
-
- BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);
- page = inode_to_page(inode);
- BUG_ON(!page); /* FIXME: Use emergency page */
- logfs_put_write_page(page);
-}
-
static int do_write_inode(struct inode *inode)
{
struct super_block *sb = inode->i_sb;
@@ -2164,18 +2139,40 @@ static int do_delete_inode(struct inode *inode)
* ZOMBIE inodes have already been deleted before and should remain dead,
* if it weren't for valid checking. No need to kill them again here.
*/
-void logfs_delete_inode(struct inode *inode)
+void logfs_evict_inode(struct inode *inode)
{
+ struct super_block *sb = inode->i_sb;
struct logfs_inode *li = logfs_inode(inode);
+ struct logfs_block *block = li->li_block;
+ struct page *page;
- if (!(li->li_flags & LOGFS_IF_ZOMBIE)) {
- li->li_flags |= LOGFS_IF_ZOMBIE;
- if (i_size_read(inode) > 0)
- logfs_truncate(inode, 0);
- do_delete_inode(inode);
+ if (!inode->i_nlink) {
+ if (!(li->li_flags & LOGFS_IF_ZOMBIE)) {
+ li->li_flags |= LOGFS_IF_ZOMBIE;
+ if (i_size_read(inode) > 0)
+ logfs_truncate(inode, 0);
+ do_delete_inode(inode);
+ }
}
truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ end_writeback(inode);
+
+ /* Cheaper version of write_inode. All changes are concealed in
+ * aliases, which are moved back. No write to the medium happens.
+ */
+ /* Only deleted files may be dirty at this point */
+ BUG_ON(inode->i_state & I_DIRTY && inode->i_nlink);
+ if (!block)
+ return;
+ if ((logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN)) {
+ block->ops->free_block(inode->i_sb, block);
+ return;
+ }
+
+ BUG_ON(inode->i_ino < LOGFS_RESERVED_INOS);
+ page = inode_to_page(inode);
+ BUG_ON(!page); /* FIXME: Use emergency page */
+ logfs_put_write_page(page);
}
void btree_write_block(struct logfs_block *block)
@@ -2272,7 +2269,6 @@ void logfs_cleanup_rw(struct super_block *sb)
{
struct logfs_super *super = logfs_super(sb);
- destroy_meta_inode(super->s_segfile_inode);
logfs_mempool_destroy(super->s_block_pool);
logfs_mempool_destroy(super->s_shadow_pool);
}
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c
index a9657afb70ad..9d5187353255 100644
--- a/fs/logfs/segment.c
+++ b/fs/logfs/segment.c
@@ -929,5 +929,4 @@ void logfs_cleanup_areas(struct super_block *sb)
for_each_area(i)
free_area(super->s_area[i]);
free_area(super->s_journal_area);
- destroy_meta_inode(super->s_mapping_inode);
}
diff --git a/fs/logfs/super.c b/fs/logfs/super.c
index d651e10a1e9c..5336155c5d81 100644
--- a/fs/logfs/super.c
+++ b/fs/logfs/super.c
@@ -342,24 +342,27 @@ static int logfs_get_sb_final(struct super_block *sb, struct vfsmount *mnt)
goto fail;
}
+ /* at that point we know that ->put_super() will be called */
super->s_erase_page = alloc_pages(GFP_KERNEL, 0);
if (!super->s_erase_page)
- goto fail;
+ return -ENOMEM;
memset(page_address(super->s_erase_page), 0xFF, PAGE_SIZE);
/* FIXME: check for read-only mounts */
err = logfs_make_writeable(sb);
- if (err)
- goto fail1;
+ if (err) {
+ __free_page(super->s_erase_page);
+ return err;
+ }
log_super("LogFS: Finished mounting\n");
simple_set_mnt(mnt, sb);
return 0;
-fail1:
- __free_page(super->s_erase_page);
fail:
- iput(logfs_super(sb)->s_master_inode);
+ iput(super->s_master_inode);
+ iput(super->s_segfile_inode);
+ iput(super->s_mapping_inode);
return -EIO;
}
@@ -580,10 +583,14 @@ int logfs_get_sb_device(struct file_system_type *type, int flags,
sb->s_flags |= MS_ACTIVE;
err = logfs_get_sb_final(sb, mnt);
if (err)
- goto err1;
- return 0;
+ deactivate_locked_super(sb);
+ return err;
err1:
+ /* no ->s_root, no ->put_super() */
+ iput(super->s_master_inode);
+ iput(super->s_segfile_inode);
+ iput(super->s_mapping_inode);
deactivate_locked_super(sb);
return err;
err0:
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index 482779fe4e7c..3f32bcb0d9bd 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -200,13 +200,13 @@ void minix_free_inode(struct inode * inode)
ino = inode->i_ino;
if (ino < 1 || ino > sbi->s_ninodes) {
printk("minix_free_inode: inode 0 or nonexistent inode\n");
- goto out;
+ return;
}
bit = ino & ((1<<k) - 1);
ino >>= k;
if (ino >= sbi->s_imap_blocks) {
printk("minix_free_inode: nonexistent imap in superblock\n");
- goto out;
+ return;
}
minix_clear_inode(inode); /* clear on-disk copy */
@@ -217,8 +217,6 @@ void minix_free_inode(struct inode * inode)
printk("minix_free_inode: bit %lu already cleared\n", bit);
spin_unlock(&bitmap_lock);
mark_buffer_dirty(bh);
- out:
- clear_inode(inode); /* clear in-memory copy */
}
struct inode *minix_new_inode(const struct inode *dir, int mode, int *error)
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index 1dbf921ca44b..085a9262c692 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -271,8 +271,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
got_it:
pos = page_offset(page) + p - (char *)page_address(page);
- err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
if (err)
goto out_unlock;
memcpy (namx, name, namelen);
@@ -297,8 +296,7 @@ out_unlock:
int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = page->mapping->host;
char *kaddr = page_address(page);
loff_t pos = page_offset(page) + (char*)de - kaddr;
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
@@ -306,8 +304,7 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int err;
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, len);
if (err == 0) {
if (sbi->s_version == MINIX_V3)
((minix3_dirent *) de)->inode = 0;
@@ -325,16 +322,14 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
int minix_make_empty(struct inode *inode, struct inode *dir)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct page *page = grab_cache_page(inode->i_mapping, 0);
struct minix_sb_info *sbi = minix_sb(inode->i_sb);
char *kaddr;
int err;
if (!page)
return -ENOMEM;
- err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, 0, 2 * sbi->s_dirsize);
if (err) {
unlock_page(page);
goto fail;
@@ -425,8 +420,7 @@ not_empty:
void minix_set_link(struct minix_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct address_space *mapping = page->mapping;
- struct inode *dir = mapping->host;
+ struct inode *dir = page->mapping->host;
struct minix_sb_info *sbi = minix_sb(dir->i_sb);
loff_t pos = page_offset(page) +
(char *)de-(char*)page_address(page);
@@ -434,8 +428,7 @@ void minix_set_link(struct minix_dir_entry *de, struct page *page,
lock_page(page);
- err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = minix_prepare_chunk(page, pos, sbi->s_dirsize);
if (err == 0) {
if (sbi->s_version == MINIX_V3)
((minix3_dirent *) de)->inode = inode->i_ino;
diff --git a/fs/minix/file.c b/fs/minix/file.c
index d5320ff23faf..4493ce695ab8 100644
--- a/fs/minix/file.c
+++ b/fs/minix/file.c
@@ -23,7 +23,29 @@ const struct file_operations minix_file_operations = {
.splice_read = generic_file_splice_read,
};
+static int minix_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
const struct inode_operations minix_file_inode_operations = {
.truncate = minix_truncate,
+ .setattr = minix_setattr,
.getattr = minix_getattr,
};
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 756f8c93780c..e39d6bf2e8fb 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -24,12 +24,17 @@ static int minix_write_inode(struct inode *inode,
static int minix_statfs(struct dentry *dentry, struct kstatfs *buf);
static int minix_remount (struct super_block * sb, int * flags, char * data);
-static void minix_delete_inode(struct inode *inode)
+static void minix_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- inode->i_size = 0;
- minix_truncate(inode);
- minix_free_inode(inode);
+ if (!inode->i_nlink) {
+ inode->i_size = 0;
+ minix_truncate(inode);
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
+ if (!inode->i_nlink)
+ minix_free_inode(inode);
}
static void minix_put_super(struct super_block *sb)
@@ -96,7 +101,7 @@ static const struct super_operations minix_sops = {
.alloc_inode = minix_alloc_inode,
.destroy_inode = minix_destroy_inode,
.write_inode = minix_write_inode,
- .delete_inode = minix_delete_inode,
+ .evict_inode = minix_evict_inode,
.put_super = minix_put_super,
.statfs = minix_statfs,
.remount_fs = minix_remount,
@@ -357,20 +362,26 @@ static int minix_readpage(struct file *file, struct page *page)
return block_read_full_page(page,minix_get_block);
}
-int __minix_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- minix_get_block);
+ return __block_write_begin(page, pos, len, minix_get_block);
}
static int minix_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ minix_get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t minix_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index 111f34ee9e3b..407b1c84911e 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -53,9 +53,7 @@ extern int minix_new_block(struct inode * inode);
extern void minix_free_block(struct inode *inode, unsigned long block);
extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int __minix_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
+extern int minix_prepare_chunk(struct page *page, loff_t pos, unsigned len);
extern void V1_minix_truncate(struct inode *);
extern void V2_minix_truncate(struct inode *);
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index fa3385154023..c0434313f920 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -43,7 +43,7 @@
#define NCP_DEFAULT_TIME_OUT 10
#define NCP_DEFAULT_RETRY_COUNT 20
-static void ncp_delete_inode(struct inode *);
+static void ncp_evict_inode(struct inode *);
static void ncp_put_super(struct super_block *);
static int ncp_statfs(struct dentry *, struct kstatfs *);
static int ncp_show_options(struct seq_file *, struct vfsmount *);
@@ -100,7 +100,7 @@ static const struct super_operations ncp_sops =
.alloc_inode = ncp_alloc_inode,
.destroy_inode = ncp_destroy_inode,
.drop_inode = generic_delete_inode,
- .delete_inode = ncp_delete_inode,
+ .evict_inode = ncp_evict_inode,
.put_super = ncp_put_super,
.statfs = ncp_statfs,
.remount_fs = ncp_remount,
@@ -282,19 +282,19 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
}
static void
-ncp_delete_inode(struct inode *inode)
+ncp_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
if (S_ISDIR(inode->i_mode)) {
- DDPRINTK("ncp_delete_inode: put directory %ld\n", inode->i_ino);
+ DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
}
if (ncp_make_closed(inode) != 0) {
/* We can't do anything but complain. */
- printk(KERN_ERR "ncp_delete_inode: could not close\n");
+ printk(KERN_ERR "ncp_evict_inode: could not close\n");
}
- clear_inode(inode);
}
static void ncp_stop_tasks(struct ncp_server *server) {
@@ -924,9 +924,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
tmpattr.ia_valid = ATTR_MODE;
tmpattr.ia_mode = attr->ia_mode;
- result = inode_setattr(inode, &tmpattr);
- if (result)
- goto out;
+ setattr_copy(inode, &tmpattr);
+ mark_inode_dirty(inode);
}
}
#endif
@@ -954,15 +953,12 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
result = ncp_make_closed(inode);
if (result)
goto out;
- {
- struct iattr tmpattr;
-
- tmpattr.ia_valid = ATTR_SIZE;
- tmpattr.ia_size = attr->ia_size;
-
- result = inode_setattr(inode, &tmpattr);
+
+ if (attr->ia_size != i_size_read(inode)) {
+ result = vmtruncate(inode, attr->ia_size);
if (result)
goto out;
+ mark_inode_dirty(inode);
}
}
if ((attr->ia_valid & ATTR_CTIME) != 0) {
@@ -1002,8 +998,12 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
NCP_FINFO(inode)->nwattr = info.attributes;
#endif
}
- if (!result)
- result = inode_setattr(inode, attr);
+ if (result)
+ goto out;
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
out:
unlock_kernel();
return result;
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index a08770a7e857..7445dd0ae3f3 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -62,16 +62,6 @@ out:
return res->status;
}
-static int (*nfs_validate_delegation_stateid(struct nfs_client *clp))(struct nfs_delegation *, const nfs4_stateid *)
-{
-#if defined(CONFIG_NFS_V4_1)
- if (clp->cl_minorversion > 0)
- return nfs41_validate_delegation_stateid;
-#endif
- return nfs4_validate_delegation_stateid;
-}
-
-
__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
{
struct nfs_client *clp;
@@ -92,8 +82,7 @@ __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy)
inode = nfs_delegation_find_inode(clp, &args->fh);
if (inode != NULL) {
/* Set up a helper thread to actually return the delegation */
- switch (nfs_async_inode_return_delegation(inode, &args->stateid,
- nfs_validate_delegation_stateid(clp))) {
+ switch (nfs_async_inode_return_delegation(inode, &args->stateid)) {
case 0:
res = 0;
break;
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index d25b5257b7a1..4e7df2adb212 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -150,6 +150,7 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
clp->cl_boot_time = CURRENT_TIME;
clp->cl_state = 1 << NFS4CLNT_LEASE_EXPIRED;
clp->cl_minorversion = cl_init->minorversion;
+ clp->cl_mvops = nfs_v4_minor_ops[cl_init->minorversion];
#endif
cred = rpc_lookup_machine_cred();
if (!IS_ERR(cred))
@@ -178,7 +179,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
clp->cl_session = NULL;
}
- clp->cl_call_sync = _nfs4_call_sync;
+ clp->cl_mvops = nfs_v4_minor_ops[0];
#endif /* CONFIG_NFS_V4_1 */
}
@@ -188,7 +189,7 @@ static void nfs4_clear_client_minor_version(struct nfs_client *clp)
static void nfs4_destroy_callback(struct nfs_client *clp)
{
if (__test_and_clear_bit(NFS_CS_CALLBACK, &clp->cl_res_state))
- nfs_callback_down(clp->cl_minorversion);
+ nfs_callback_down(clp->cl_mvops->minor_version);
}
static void nfs4_shutdown_client(struct nfs_client *clp)
@@ -1126,7 +1127,7 @@ static int nfs4_init_callback(struct nfs_client *clp)
return error;
}
- error = nfs_callback_up(clp->cl_minorversion,
+ error = nfs_callback_up(clp->cl_mvops->minor_version,
clp->cl_rpcclient->cl_xprt);
if (error < 0) {
dprintk("%s: failed to start callback. Error = %d\n",
@@ -1143,10 +1144,8 @@ static int nfs4_init_callback(struct nfs_client *clp)
*/
static int nfs4_init_client_minor_version(struct nfs_client *clp)
{
- clp->cl_call_sync = _nfs4_call_sync;
-
#if defined(CONFIG_NFS_V4_1)
- if (clp->cl_minorversion) {
+ if (clp->cl_mvops->minor_version) {
struct nfs4_session *session = NULL;
/*
* Create the session and mark it expired.
@@ -1158,7 +1157,13 @@ static int nfs4_init_client_minor_version(struct nfs_client *clp)
return -ENOMEM;
clp->cl_session = session;
- clp->cl_call_sync = _nfs4_call_sync_session;
+ /*
+ * The create session reply races with the server back
+ * channel probe. Mark the client NFS_CS_SESSION_INITING
+ * so that the client back channel can find the
+ * nfs_client struct
+ */
+ clp->cl_cons_state = NFS_CS_SESSION_INITING;
}
#endif /* CONFIG_NFS_V4_1 */
@@ -1454,7 +1459,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
data->authflavor,
parent_server->client->cl_xprt->prot,
parent_server->client->cl_timeout,
- parent_client->cl_minorversion);
+ parent_client->cl_mvops->minor_version);
if (error < 0)
goto error;
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 301634543974..f34f4ac52b81 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -471,9 +471,7 @@ void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
/*
* Asynchronous delegation recall!
*/
-int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
- int (*validate_stateid)(struct nfs_delegation *delegation,
- const nfs4_stateid *stateid))
+int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid)
{
struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
struct nfs_delegation *delegation;
@@ -481,7 +479,7 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
rcu_read_lock();
delegation = rcu_dereference(NFS_I(inode)->delegation);
- if (!validate_stateid(delegation, stateid)) {
+ if (!clp->cl_mvops->validate_stateid(delegation, stateid)) {
rcu_read_unlock();
return -ENOENT;
}
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 69e7b8140122..2026304bda19 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -34,9 +34,7 @@ enum {
int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
int nfs_inode_return_delegation(struct inode *inode);
-int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid,
- int (*validate_stateid)(struct nfs_delegation *delegation,
- const nfs4_stateid *stateid));
+int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
void nfs_inode_return_delegation_noreclaim(struct inode *inode);
struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 099b3518feea..f7037076d303 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -98,7 +98,7 @@ u64 nfs_compat_user_ino64(u64 fileid)
return ino;
}
-void nfs_clear_inode(struct inode *inode)
+static void nfs_clear_inode(struct inode *inode)
{
/*
* The following should never happen...
@@ -110,6 +110,13 @@ void nfs_clear_inode(struct inode *inode)
nfs_fscache_release_inode_cookie(inode);
}
+void nfs_evict_inode(struct inode *inode)
+{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
+ nfs_clear_inode(inode);
+}
+
/**
* nfs_sync_mapping - helper to flush all mmapped dirty data to disk
*/
@@ -530,6 +537,68 @@ out:
return err;
}
+static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
+{
+ atomic_set(&l_ctx->count, 1);
+ l_ctx->lockowner = current->files;
+ l_ctx->pid = current->tgid;
+ INIT_LIST_HEAD(&l_ctx->list);
+}
+
+static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx)
+{
+ struct nfs_lock_context *pos;
+
+ list_for_each_entry(pos, &ctx->lock_context.list, list) {
+ if (pos->lockowner != current->files)
+ continue;
+ if (pos->pid != current->tgid)
+ continue;
+ atomic_inc(&pos->count);
+ return pos;
+ }
+ return NULL;
+}
+
+struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx)
+{
+ struct nfs_lock_context *res, *new = NULL;
+ struct inode *inode = ctx->path.dentry->d_inode;
+
+ spin_lock(&inode->i_lock);
+ res = __nfs_find_lock_context(ctx);
+ if (res == NULL) {
+ spin_unlock(&inode->i_lock);
+ new = kmalloc(sizeof(*new), GFP_KERNEL);
+ if (new == NULL)
+ return NULL;
+ nfs_init_lock_context(new);
+ spin_lock(&inode->i_lock);
+ res = __nfs_find_lock_context(ctx);
+ if (res == NULL) {
+ list_add_tail(&new->list, &ctx->lock_context.list);
+ new->open_context = ctx;
+ res = new;
+ new = NULL;
+ }
+ }
+ spin_unlock(&inode->i_lock);
+ kfree(new);
+ return res;
+}
+
+void nfs_put_lock_context(struct nfs_lock_context *l_ctx)
+{
+ struct nfs_open_context *ctx = l_ctx->open_context;
+ struct inode *inode = ctx->path.dentry->d_inode;
+
+ if (!atomic_dec_and_lock(&l_ctx->count, &inode->i_lock))
+ return;
+ list_del(&l_ctx->list);
+ spin_unlock(&inode->i_lock);
+ kfree(l_ctx);
+}
+
/**
* nfs_close_context - Common close_context() routine NFSv2/v3
* @ctx: pointer to context
@@ -566,11 +635,11 @@ static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct
path_get(&ctx->path);
ctx->cred = get_rpccred(cred);
ctx->state = NULL;
- ctx->lockowner = current->files;
ctx->flags = 0;
ctx->error = 0;
ctx->dir_cookie = 0;
- atomic_set(&ctx->count, 1);
+ nfs_init_lock_context(&ctx->lock_context);
+ ctx->lock_context.open_context = ctx;
}
return ctx;
}
@@ -578,7 +647,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct path *path, struct
struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
{
if (ctx != NULL)
- atomic_inc(&ctx->count);
+ atomic_inc(&ctx->lock_context.count);
return ctx;
}
@@ -586,7 +655,7 @@ static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
{
struct inode *inode = ctx->path.dentry->d_inode;
- if (!atomic_dec_and_lock(&ctx->count, &inode->i_lock))
+ if (!atomic_dec_and_lock(&ctx->lock_context.count, &inode->i_lock))
return;
list_del(&ctx->list);
spin_unlock(&inode->i_lock);
@@ -1338,8 +1407,10 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
* to open() calls that passed nfs_atomic_lookup, but failed to call
* nfs_open().
*/
-void nfs4_clear_inode(struct inode *inode)
+void nfs4_evict_inode(struct inode *inode)
{
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
/* If we are holding a delegation, return it! */
nfs_inode_return_delegation_noreclaim(inode);
/* First call standard NFS clear_inode() code */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index d8bd619e386c..a9c7c7c5db3a 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -212,9 +212,9 @@ extern struct workqueue_struct *nfsiod_workqueue;
extern struct inode *nfs_alloc_inode(struct super_block *sb);
extern void nfs_destroy_inode(struct inode *);
extern int nfs_write_inode(struct inode *, struct writeback_control *);
-extern void nfs_clear_inode(struct inode *);
+extern void nfs_evict_inode(struct inode *);
#ifdef CONFIG_NFS_V4
-extern void nfs4_clear_inode(struct inode *);
+extern void nfs4_evict_inode(struct inode *);
#endif
void nfs_zap_acl_cache(struct inode *inode);
extern int nfs_wait_bit_killable(void *word);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index c538c6106e16..311e15cc8af0 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -45,10 +45,29 @@ enum nfs4_client_state {
NFS4CLNT_RECLAIM_NOGRACE,
NFS4CLNT_DELEGRETURN,
NFS4CLNT_SESSION_RESET,
- NFS4CLNT_SESSION_DRAINING,
NFS4CLNT_RECALL_SLOT,
};
+enum nfs4_session_state {
+ NFS4_SESSION_INITING,
+ NFS4_SESSION_DRAINING,
+};
+
+struct nfs4_minor_version_ops {
+ u32 minor_version;
+
+ int (*call_sync)(struct nfs_server *server,
+ struct rpc_message *msg,
+ struct nfs4_sequence_args *args,
+ struct nfs4_sequence_res *res,
+ int cache_reply);
+ int (*validate_stateid)(struct nfs_delegation *,
+ const nfs4_stateid *);
+ const struct nfs4_state_recovery_ops *reboot_recovery_ops;
+ const struct nfs4_state_recovery_ops *nograce_recovery_ops;
+ const struct nfs4_state_maintenance_ops *state_renewal_ops;
+};
+
/*
* struct rpc_sequence ensures that RPC calls are sent in the exact
* order that they appear on the list.
@@ -89,7 +108,6 @@ struct nfs_unique_id {
*/
struct nfs4_state_owner {
struct nfs_unique_id so_owner_id;
- struct nfs_client *so_client;
struct nfs_server *so_server;
struct rb_node so_client_node;
@@ -99,7 +117,6 @@ struct nfs4_state_owner {
atomic_t so_count;
unsigned long so_flags;
struct list_head so_states;
- struct list_head so_delegations;
struct nfs_seqid_counter so_seqid;
struct rpc_sequence so_sequence;
};
@@ -125,10 +142,20 @@ enum {
* LOCK: one nfs4_state (LOCK) to hold the lock stateid nfs4_state(OPEN)
*/
+struct nfs4_lock_owner {
+ unsigned int lo_type;
+#define NFS4_ANY_LOCK_TYPE (0U)
+#define NFS4_FLOCK_LOCK_TYPE (1U << 0)
+#define NFS4_POSIX_LOCK_TYPE (1U << 1)
+ union {
+ fl_owner_t posix_owner;
+ pid_t flock_owner;
+ } lo_u;
+};
+
struct nfs4_lock_state {
struct list_head ls_locks; /* Other lock stateids */
struct nfs4_state * ls_state; /* Pointer to open state */
- fl_owner_t ls_owner; /* POSIX lock owner */
#define NFS_LOCK_INITIALIZED 1
int ls_flags;
struct nfs_seqid_counter ls_seqid;
@@ -136,6 +163,7 @@ struct nfs4_lock_state {
struct nfs_unique_id ls_id;
nfs4_stateid ls_stateid;
atomic_t ls_count;
+ struct nfs4_lock_owner ls_owner;
};
/* bits for nfs4_state->flags */
@@ -219,11 +247,15 @@ extern int nfs4_open_revalidate(struct inode *, struct dentry *, int, struct nam
extern int nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle);
extern int nfs4_proc_fs_locations(struct inode *dir, const struct qstr *name,
struct nfs4_fs_locations *fs_locations, struct page *page);
+extern void nfs4_release_lockowner(const struct nfs4_lock_state *);
-extern struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[];
-extern struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[];
#if defined(CONFIG_NFS_V4_1)
-extern int nfs4_setup_sequence(struct nfs_client *clp,
+static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
+{
+ return server->nfs_client->cl_session;
+}
+
+extern int nfs4_setup_sequence(const struct nfs_server *server,
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
int cache_reply, struct rpc_task *task);
extern void nfs4_destroy_session(struct nfs4_session *session);
@@ -234,7 +266,12 @@ extern int nfs4_init_session(struct nfs_server *server);
extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
struct nfs_fsinfo *fsinfo);
#else /* CONFIG_NFS_v4_1 */
-static inline int nfs4_setup_sequence(struct nfs_client *clp,
+static inline struct nfs4_session *nfs4_get_session(const struct nfs_server *server)
+{
+ return NULL;
+}
+
+static inline int nfs4_setup_sequence(const struct nfs_server *server,
struct nfs4_sequence_args *args, struct nfs4_sequence_res *res,
int cache_reply, struct rpc_task *task)
{
@@ -247,7 +284,7 @@ static inline int nfs4_init_session(struct nfs_server *server)
}
#endif /* CONFIG_NFS_V4_1 */
-extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[];
+extern const struct nfs4_minor_version_ops *nfs_v4_minor_ops[];
extern const u32 nfs4_fattr_bitmap[2];
extern const u32 nfs4_statfs_bitmap[2];
@@ -284,7 +321,7 @@ extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags)
extern void nfs41_handle_recall_slot(struct nfs_client *clp);
extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp);
extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl);
-extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t);
+extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t, pid_t);
extern struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_mask);
extern int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task);
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 70015dd60a98..d6413b48b057 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -356,7 +356,7 @@ static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
{
struct rpc_task *task;
- if (!test_bit(NFS4CLNT_SESSION_DRAINING, &ses->clp->cl_state)) {
+ if (!test_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
task = rpc_wake_up_next(&ses->fc_slot_table.slot_tbl_waitq);
if (task)
rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
@@ -370,12 +370,11 @@ static void nfs41_check_drain_session_complete(struct nfs4_session *ses)
complete(&ses->complete);
}
-static void nfs41_sequence_free_slot(const struct nfs_client *clp,
- struct nfs4_sequence_res *res)
+static void nfs41_sequence_free_slot(struct nfs4_sequence_res *res)
{
struct nfs4_slot_table *tbl;
- tbl = &clp->cl_session->fc_slot_table;
+ tbl = &res->sr_session->fc_slot_table;
if (res->sr_slotid == NFS4_MAX_SLOT_TABLE) {
/* just wake up the next guy waiting since
* we may have not consumed a slot after all */
@@ -385,14 +384,12 @@ static void nfs41_sequence_free_slot(const struct nfs_client *clp,
spin_lock(&tbl->slot_tbl_lock);
nfs4_free_slot(tbl, res->sr_slotid);
- nfs41_check_drain_session_complete(clp->cl_session);
+ nfs41_check_drain_session_complete(res->sr_session);
spin_unlock(&tbl->slot_tbl_lock);
res->sr_slotid = NFS4_MAX_SLOT_TABLE;
}
-static void nfs41_sequence_done(struct nfs_client *clp,
- struct nfs4_sequence_res *res,
- int rpc_status)
+static void nfs41_sequence_done(struct nfs4_sequence_res *res)
{
unsigned long timestamp;
struct nfs4_slot_table *tbl;
@@ -413,7 +410,8 @@ static void nfs41_sequence_done(struct nfs_client *clp,
/* Check the SEQUENCE operation status */
if (res->sr_status == 0) {
- tbl = &clp->cl_session->fc_slot_table;
+ struct nfs_client *clp = res->sr_session->clp;
+ tbl = &res->sr_session->fc_slot_table;
slot = tbl->slots + res->sr_slotid;
/* Update the slot's sequence and clientid lease timer */
++slot->seq_nr;
@@ -429,7 +427,14 @@ static void nfs41_sequence_done(struct nfs_client *clp,
out:
/* The session may be reset by one of the error handlers. */
dprintk("%s: Error %d free the slot \n", __func__, res->sr_status);
- nfs41_sequence_free_slot(clp, res);
+ nfs41_sequence_free_slot(res);
+}
+
+static void nfs4_sequence_done(const struct nfs_server *server,
+ struct nfs4_sequence_res *res, int rpc_status)
+{
+ if (res->sr_session != NULL)
+ nfs41_sequence_done(res);
}
/*
@@ -480,12 +485,11 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
if (res->sr_slotid != NFS4_MAX_SLOT_TABLE)
return 0;
- memset(res, 0, sizeof(*res));
res->sr_slotid = NFS4_MAX_SLOT_TABLE;
tbl = &session->fc_slot_table;
spin_lock(&tbl->slot_tbl_lock);
- if (test_bit(NFS4CLNT_SESSION_DRAINING, &session->clp->cl_state) &&
+ if (test_bit(NFS4_SESSION_DRAINING, &session->session_state) &&
!rpc_task_has_priority(task, RPC_PRIORITY_PRIVILEGED)) {
/*
* The state manager will wait until the slot table is empty.
@@ -525,6 +529,7 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
res->sr_session = session;
res->sr_slotid = slotid;
res->sr_renewal_time = jiffies;
+ res->sr_status_flags = 0;
/*
* sr_status is only set in decode_sequence, and so will remain
* set to 1 if an rpc level failure occurs.
@@ -533,33 +538,33 @@ static int nfs41_setup_sequence(struct nfs4_session *session,
return 0;
}
-int nfs4_setup_sequence(struct nfs_client *clp,
+int nfs4_setup_sequence(const struct nfs_server *server,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
int cache_reply,
struct rpc_task *task)
{
+ struct nfs4_session *session = nfs4_get_session(server);
int ret = 0;
+ if (session == NULL) {
+ args->sa_session = NULL;
+ res->sr_session = NULL;
+ goto out;
+ }
+
dprintk("--> %s clp %p session %p sr_slotid %d\n",
- __func__, clp, clp->cl_session, res->sr_slotid);
+ __func__, session->clp, session, res->sr_slotid);
- if (!nfs4_has_session(clp))
- goto out;
- ret = nfs41_setup_sequence(clp->cl_session, args, res, cache_reply,
+ ret = nfs41_setup_sequence(session, args, res, cache_reply,
task);
- if (ret && ret != -EAGAIN) {
- /* terminate rpc task */
- task->tk_status = ret;
- task->tk_action = NULL;
- }
out:
dprintk("<-- %s status=%d\n", __func__, ret);
return ret;
}
struct nfs41_call_sync_data {
- struct nfs_client *clp;
+ const struct nfs_server *seq_server;
struct nfs4_sequence_args *seq_args;
struct nfs4_sequence_res *seq_res;
int cache_reply;
@@ -569,9 +574,9 @@ static void nfs41_call_sync_prepare(struct rpc_task *task, void *calldata)
{
struct nfs41_call_sync_data *data = calldata;
- dprintk("--> %s data->clp->cl_session %p\n", __func__,
- data->clp->cl_session);
- if (nfs4_setup_sequence(data->clp, data->seq_args,
+ dprintk("--> %s data->seq_server %p\n", __func__, data->seq_server);
+
+ if (nfs4_setup_sequence(data->seq_server, data->seq_args,
data->seq_res, data->cache_reply, task))
return;
rpc_call_start(task);
@@ -587,7 +592,7 @@ static void nfs41_call_sync_done(struct rpc_task *task, void *calldata)
{
struct nfs41_call_sync_data *data = calldata;
- nfs41_sequence_done(data->clp, data->seq_res, task->tk_status);
+ nfs41_sequence_done(data->seq_res);
}
struct rpc_call_ops nfs41_call_sync_ops = {
@@ -600,8 +605,7 @@ struct rpc_call_ops nfs41_call_priv_sync_ops = {
.rpc_call_done = nfs41_call_sync_done,
};
-static int nfs4_call_sync_sequence(struct nfs_client *clp,
- struct rpc_clnt *clnt,
+static int nfs4_call_sync_sequence(struct nfs_server *server,
struct rpc_message *msg,
struct nfs4_sequence_args *args,
struct nfs4_sequence_res *res,
@@ -611,13 +615,13 @@ static int nfs4_call_sync_sequence(struct nfs_client *clp,
int ret;
struct rpc_task *task;
struct nfs41_call_sync_data data = {
- .clp = clp,
+ .seq_server = server,
.seq_args = args,
.seq_res = res,
.cache_reply = cache_reply,
};
struct rpc_task_setup task_setup = {
- .rpc_client = clnt,
+ .rpc_client = server->client,
.rpc_message = msg,
.callback_ops = &nfs41_call_sync_ops,
.callback_data = &data
@@ -642,10 +646,14 @@ int _nfs4_call_sync_session(struct nfs_server *server,
struct nfs4_sequence_res *res,
int cache_reply)
{
- return nfs4_call_sync_sequence(server->nfs_client, server->client,
- msg, args, res, cache_reply, 0);
+ return nfs4_call_sync_sequence(server, msg, args, res, cache_reply, 0);
}
+#else
+static void nfs4_sequence_done(const struct nfs_server *server,
+ struct nfs4_sequence_res *res, int rpc_status)
+{
+}
#endif /* CONFIG_NFS_V4_1 */
int _nfs4_call_sync(struct nfs_server *server,
@@ -659,18 +667,9 @@ int _nfs4_call_sync(struct nfs_server *server,
}
#define nfs4_call_sync(server, msg, args, res, cache_reply) \
- (server)->nfs_client->cl_call_sync((server), (msg), &(args)->seq_args, \
+ (server)->nfs_client->cl_mvops->call_sync((server), (msg), &(args)->seq_args, \
&(res)->seq_res, (cache_reply))
-static void nfs4_sequence_done(const struct nfs_server *server,
- struct nfs4_sequence_res *res, int rpc_status)
-{
-#ifdef CONFIG_NFS_V4_1
- if (nfs4_has_session(server->nfs_client))
- nfs41_sequence_done(server->nfs_client, res, rpc_status);
-#endif /* CONFIG_NFS_V4_1 */
-}
-
static void update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo)
{
struct nfs_inode *nfsi = NFS_I(dir);
@@ -745,19 +744,14 @@ static struct nfs4_opendata *nfs4_opendata_alloc(struct path *path,
p->o_arg.server = server;
p->o_arg.bitmask = server->attr_bitmask;
p->o_arg.claim = NFS4_OPEN_CLAIM_NULL;
- if (flags & O_EXCL) {
- if (nfs4_has_persistent_session(server->nfs_client)) {
- /* GUARDED */
- p->o_arg.u.attrs = &p->attrs;
- memcpy(&p->attrs, attrs, sizeof(p->attrs));
- } else { /* EXCLUSIVE4_1 */
- u32 *s = (u32 *) p->o_arg.u.verifier.data;
- s[0] = jiffies;
- s[1] = current->pid;
- }
- } else if (flags & O_CREAT) {
+ if (flags & O_CREAT) {
+ u32 *s;
+
p->o_arg.u.attrs = &p->attrs;
memcpy(&p->attrs, attrs, sizeof(p->attrs));
+ s = (u32 *) p->o_arg.u.verifier.data;
+ s[0] = jiffies;
+ s[1] = current->pid;
}
p->c_arg.fh = &p->o_res.fh;
p->c_arg.stateid = &p->o_res.stateid;
@@ -1356,13 +1350,13 @@ static void nfs4_open_prepare(struct rpc_task *task, void *calldata)
}
/* Update sequence id. */
data->o_arg.id = sp->so_owner_id.id;
- data->o_arg.clientid = sp->so_client->cl_clientid;
+ data->o_arg.clientid = sp->so_server->nfs_client->cl_clientid;
if (data->o_arg.claim == NFS4_OPEN_CLAIM_PREVIOUS) {
task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_NOATTR];
nfs_copy_fh(&data->o_res.fh, data->o_arg.fh);
}
data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->o_arg.server->nfs_client,
+ if (nfs4_setup_sequence(data->o_arg.server,
&data->o_arg.seq_args,
&data->o_res.seq_res, 1, task))
return;
@@ -1773,7 +1767,7 @@ static int _nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
if (nfs4_copy_delegation_stateid(&arg.stateid, inode)) {
/* Use that stateid */
} else if (state != NULL) {
- nfs4_copy_stateid(&arg.stateid, state, current->files);
+ nfs4_copy_stateid(&arg.stateid, state, current->files, current->tgid);
} else
memcpy(&arg.stateid, &zero_stateid, sizeof(arg.stateid));
@@ -1903,7 +1897,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
nfs_fattr_init(calldata->res.fattr);
calldata->timestamp = jiffies;
- if (nfs4_setup_sequence((NFS_SERVER(calldata->inode))->nfs_client,
+ if (nfs4_setup_sequence(NFS_SERVER(calldata->inode),
&calldata->arg.seq_args, &calldata->res.seq_res,
1, task))
return;
@@ -3464,9 +3458,11 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen
}
static int
-_nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs_client *clp, struct nfs4_state *state)
+nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
{
- if (!clp || task->tk_status >= 0)
+ struct nfs_client *clp = server->nfs_client;
+
+ if (task->tk_status >= 0)
return 0;
switch(task->tk_status) {
case -NFS4ERR_ADMIN_REVOKED:
@@ -3498,8 +3494,7 @@ _nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server,
return -EAGAIN;
#endif /* CONFIG_NFS_V4_1 */
case -NFS4ERR_DELAY:
- if (server)
- nfs_inc_server_stats(server, NFSIOS_DELAY);
+ nfs_inc_server_stats(server, NFSIOS_DELAY);
case -NFS4ERR_GRACE:
case -EKEYEXPIRED:
rpc_delay(task, NFS4_POLL_RETRY_MAX);
@@ -3520,12 +3515,6 @@ do_state_recovery:
return -EAGAIN;
}
-static int
-nfs4_async_handle_error(struct rpc_task *task, const struct nfs_server *server, struct nfs4_state *state)
-{
- return _nfs4_async_handle_error(task, server, server->nfs_client, state);
-}
-
int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
unsigned short port, struct rpc_cred *cred,
struct nfs4_setclientid_res *res)
@@ -3672,7 +3661,7 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data)
d_data = (struct nfs4_delegreturndata *)data;
- if (nfs4_setup_sequence(d_data->res.server->nfs_client,
+ if (nfs4_setup_sequence(d_data->res.server,
&d_data->args.seq_args,
&d_data->res.seq_res, 1, task))
return;
@@ -3927,7 +3916,7 @@ static void nfs4_locku_prepare(struct rpc_task *task, void *data)
return;
}
calldata->timestamp = jiffies;
- if (nfs4_setup_sequence(calldata->server->nfs_client,
+ if (nfs4_setup_sequence(calldata->server,
&calldata->arg.seq_args,
&calldata->res.seq_res, 1, task))
return;
@@ -4082,7 +4071,8 @@ static void nfs4_lock_prepare(struct rpc_task *task, void *calldata)
} else
data->arg.new_lock_owner = 0;
data->timestamp = jiffies;
- if (nfs4_setup_sequence(data->server->nfs_client, &data->arg.seq_args,
+ if (nfs4_setup_sequence(data->server,
+ &data->arg.seq_args,
&data->res.seq_res, 1, task))
return;
rpc_call_start(task);
@@ -4424,6 +4414,34 @@ out:
return err;
}
+static void nfs4_release_lockowner_release(void *calldata)
+{
+ kfree(calldata);
+}
+
+const struct rpc_call_ops nfs4_release_lockowner_ops = {
+ .rpc_release = nfs4_release_lockowner_release,
+};
+
+void nfs4_release_lockowner(const struct nfs4_lock_state *lsp)
+{
+ struct nfs_server *server = lsp->ls_state->owner->so_server;
+ struct nfs_release_lockowner_args *args;
+ struct rpc_message msg = {
+ .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_RELEASE_LOCKOWNER],
+ };
+
+ if (server->nfs_client->cl_mvops->minor_version != 0)
+ return;
+ args = kmalloc(sizeof(*args), GFP_NOFS);
+ if (!args)
+ return;
+ args->lock_owner.clientid = server->nfs_client->cl_clientid;
+ args->lock_owner.id = lsp->ls_id.id;
+ msg.rpc_argp = args;
+ rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, args);
+}
+
#define XATTR_NAME_NFSV4_ACL "system.nfs4_acl"
int nfs4_setxattr(struct dentry *dentry, const char *key, const void *buf,
@@ -4611,7 +4629,7 @@ static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
(struct nfs4_get_lease_time_data *)calldata;
dprintk("--> %s\n", __func__);
- nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status);
+ nfs41_sequence_done(&data->res->lr_seq_res);
switch (task->tk_status) {
case -NFS4ERR_DELAY:
case -NFS4ERR_GRACE:
@@ -4805,13 +4823,6 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
if (!session)
return NULL;
- /*
- * The create session reply races with the server back
- * channel probe. Mark the client NFS_CS_SESSION_INITING
- * so that the client back channel can find the
- * nfs_client struct
- */
- clp->cl_cons_state = NFS_CS_SESSION_INITING;
init_completion(&session->complete);
tbl = &session->fc_slot_table;
@@ -4824,6 +4835,8 @@ struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp)
spin_lock_init(&tbl->slot_tbl_lock);
rpc_init_wait_queue(&tbl->slot_tbl_waitq, "BackChannel Slot table");
+ session->session_state = 1<<NFS4_SESSION_INITING;
+
session->clp = clp;
return session;
}
@@ -5040,6 +5053,10 @@ int nfs4_init_session(struct nfs_server *server)
if (!nfs4_has_session(clp))
return 0;
+ session = clp->cl_session;
+ if (!test_and_clear_bit(NFS4_SESSION_INITING, &session->session_state))
+ return 0;
+
rsize = server->rsize;
if (rsize == 0)
rsize = NFS_MAX_FILE_IO_SIZE;
@@ -5047,7 +5064,6 @@ int nfs4_init_session(struct nfs_server *server)
if (wsize == 0)
wsize = NFS_MAX_FILE_IO_SIZE;
- session = clp->cl_session;
session->fc_attrs.max_rqst_sz = wsize + nfs41_maxwrite_overhead;
session->fc_attrs.max_resp_sz = rsize + nfs41_maxread_overhead;
@@ -5060,69 +5076,69 @@ int nfs4_init_session(struct nfs_server *server)
/*
* Renew the cl_session lease.
*/
-static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
-{
+struct nfs4_sequence_data {
+ struct nfs_client *clp;
struct nfs4_sequence_args args;
struct nfs4_sequence_res res;
-
- struct rpc_message msg = {
- .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
- .rpc_argp = &args,
- .rpc_resp = &res,
- .rpc_cred = cred,
- };
-
- args.sa_cache_this = 0;
-
- return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args,
- &res, args.sa_cache_this, 1);
-}
+};
static void nfs41_sequence_release(void *data)
{
- struct nfs_client *clp = (struct nfs_client *)data;
+ struct nfs4_sequence_data *calldata = data;
+ struct nfs_client *clp = calldata->clp;
if (atomic_read(&clp->cl_count) > 1)
nfs4_schedule_state_renewal(clp);
nfs_put_client(clp);
+ kfree(calldata);
+}
+
+static int nfs41_sequence_handle_errors(struct rpc_task *task, struct nfs_client *clp)
+{
+ switch(task->tk_status) {
+ case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
+ rpc_delay(task, NFS4_POLL_RETRY_MAX);
+ return -EAGAIN;
+ default:
+ nfs4_schedule_state_recovery(clp);
+ }
+ return 0;
}
static void nfs41_sequence_call_done(struct rpc_task *task, void *data)
{
- struct nfs_client *clp = (struct nfs_client *)data;
+ struct nfs4_sequence_data *calldata = data;
+ struct nfs_client *clp = calldata->clp;
- nfs41_sequence_done(clp, task->tk_msg.rpc_resp, task->tk_status);
+ nfs41_sequence_done(task->tk_msg.rpc_resp);
if (task->tk_status < 0) {
dprintk("%s ERROR %d\n", __func__, task->tk_status);
if (atomic_read(&clp->cl_count) == 1)
goto out;
- if (_nfs4_async_handle_error(task, NULL, clp, NULL)
- == -EAGAIN) {
- nfs_restart_rpc(task, clp);
+ if (nfs41_sequence_handle_errors(task, clp) == -EAGAIN) {
+ rpc_restart_call_prepare(task);
return;
}
}
dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred);
out:
- kfree(task->tk_msg.rpc_argp);
- kfree(task->tk_msg.rpc_resp);
-
dprintk("<-- %s\n", __func__);
}
static void nfs41_sequence_prepare(struct rpc_task *task, void *data)
{
- struct nfs_client *clp;
+ struct nfs4_sequence_data *calldata = data;
+ struct nfs_client *clp = calldata->clp;
struct nfs4_sequence_args *args;
struct nfs4_sequence_res *res;
- clp = (struct nfs_client *)data;
args = task->tk_msg.rpc_argp;
res = task->tk_msg.rpc_resp;
- if (nfs4_setup_sequence(clp, args, res, 0, task))
+ if (nfs41_setup_sequence(clp->cl_session, args, res, 0, task))
return;
rpc_call_start(task);
}
@@ -5133,32 +5149,67 @@ static const struct rpc_call_ops nfs41_sequence_ops = {
.rpc_release = nfs41_sequence_release,
};
-static int nfs41_proc_async_sequence(struct nfs_client *clp,
- struct rpc_cred *cred)
+static struct rpc_task *_nfs41_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
{
- struct nfs4_sequence_args *args;
- struct nfs4_sequence_res *res;
+ struct nfs4_sequence_data *calldata;
struct rpc_message msg = {
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE],
.rpc_cred = cred,
};
+ struct rpc_task_setup task_setup_data = {
+ .rpc_client = clp->cl_rpcclient,
+ .rpc_message = &msg,
+ .callback_ops = &nfs41_sequence_ops,
+ .flags = RPC_TASK_ASYNC | RPC_TASK_SOFT,
+ };
if (!atomic_inc_not_zero(&clp->cl_count))
- return -EIO;
- args = kzalloc(sizeof(*args), GFP_NOFS);
- res = kzalloc(sizeof(*res), GFP_NOFS);
- if (!args || !res) {
- kfree(args);
- kfree(res);
+ return ERR_PTR(-EIO);
+ calldata = kmalloc(sizeof(*calldata), GFP_NOFS);
+ if (calldata == NULL) {
nfs_put_client(clp);
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
- res->sr_slotid = NFS4_MAX_SLOT_TABLE;
- msg.rpc_argp = args;
- msg.rpc_resp = res;
+ calldata->res.sr_slotid = NFS4_MAX_SLOT_TABLE;
+ msg.rpc_argp = &calldata->args;
+ msg.rpc_resp = &calldata->res;
+ calldata->clp = clp;
+ task_setup_data.callback_data = calldata;
- return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT,
- &nfs41_sequence_ops, (void *)clp);
+ return rpc_run_task(&task_setup_data);
+}
+
+static int nfs41_proc_async_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ struct rpc_task *task;
+ int ret = 0;
+
+ task = _nfs41_proc_sequence(clp, cred);
+ if (IS_ERR(task))
+ ret = PTR_ERR(task);
+ else
+ rpc_put_task(task);
+ dprintk("<-- %s status=%d\n", __func__, ret);
+ return ret;
+}
+
+static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred)
+{
+ struct rpc_task *task;
+ int ret;
+
+ task = _nfs41_proc_sequence(clp, cred);
+ if (IS_ERR(task)) {
+ ret = PTR_ERR(task);
+ goto out;
+ }
+ ret = rpc_wait_for_completion_task(task);
+ if (!ret)
+ ret = task->tk_status;
+ rpc_put_task(task);
+out:
+ dprintk("<-- %s status=%d\n", __func__, ret);
+ return ret;
}
struct nfs4_reclaim_complete_data {
@@ -5172,13 +5223,31 @@ static void nfs4_reclaim_complete_prepare(struct rpc_task *task, void *data)
struct nfs4_reclaim_complete_data *calldata = data;
rpc_task_set_priority(task, RPC_PRIORITY_PRIVILEGED);
- if (nfs4_setup_sequence(calldata->clp, &calldata->arg.seq_args,
+ if (nfs41_setup_sequence(calldata->clp->cl_session,
+ &calldata->arg.seq_args,
&calldata->res.seq_res, 0, task))
return;
rpc_call_start(task);
}
+static int nfs41_reclaim_complete_handle_errors(struct rpc_task *task, struct nfs_client *clp)
+{
+ switch(task->tk_status) {
+ case 0:
+ case -NFS4ERR_COMPLETE_ALREADY:
+ case -NFS4ERR_WRONG_CRED: /* What to do here? */
+ break;
+ case -NFS4ERR_DELAY:
+ case -EKEYEXPIRED:
+ rpc_delay(task, NFS4_POLL_RETRY_MAX);
+ return -EAGAIN;
+ default:
+ nfs4_schedule_state_recovery(clp);
+ }
+ return 0;
+}
+
static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
{
struct nfs4_reclaim_complete_data *calldata = data;
@@ -5186,32 +5255,12 @@ static void nfs4_reclaim_complete_done(struct rpc_task *task, void *data)
struct nfs4_sequence_res *res = &calldata->res.seq_res;
dprintk("--> %s\n", __func__);
- nfs41_sequence_done(clp, res, task->tk_status);
- switch (task->tk_status) {
- case 0:
- case -NFS4ERR_COMPLETE_ALREADY:
- break;
- case -NFS4ERR_BADSESSION:
- case -NFS4ERR_DEADSESSION:
- /*
- * Handle the session error, but do not retry the operation, as
- * we have no way of telling whether the clientid had to be
- * reset before we got our reply. If reset, a new wave of
- * reclaim operations will follow, containing their own reclaim
- * complete. We don't want our retry to get on the way of
- * recovery by incorrectly indicating to the server that we're
- * done reclaiming state since the process had to be restarted.
- */
- _nfs4_async_handle_error(task, NULL, clp, NULL);
- break;
- default:
- if (_nfs4_async_handle_error(
- task, NULL, clp, NULL) == -EAGAIN) {
- rpc_restart_call_prepare(task);
- return;
- }
- }
+ nfs41_sequence_done(res);
+ if (nfs41_reclaim_complete_handle_errors(task, clp) == -EAGAIN) {
+ rpc_restart_call_prepare(task);
+ return;
+ }
dprintk("<-- %s\n", __func__);
}
@@ -5325,28 +5374,30 @@ struct nfs4_state_maintenance_ops nfs41_state_renewal_ops = {
};
#endif
-/*
- * Per minor version reboot and network partition recovery ops
- */
-
-struct nfs4_state_recovery_ops *nfs4_reboot_recovery_ops[] = {
- &nfs40_reboot_recovery_ops,
-#if defined(CONFIG_NFS_V4_1)
- &nfs41_reboot_recovery_ops,
-#endif
+static const struct nfs4_minor_version_ops nfs_v4_0_minor_ops = {
+ .minor_version = 0,
+ .call_sync = _nfs4_call_sync,
+ .validate_stateid = nfs4_validate_delegation_stateid,
+ .reboot_recovery_ops = &nfs40_reboot_recovery_ops,
+ .nograce_recovery_ops = &nfs40_nograce_recovery_ops,
+ .state_renewal_ops = &nfs40_state_renewal_ops,
};
-struct nfs4_state_recovery_ops *nfs4_nograce_recovery_ops[] = {
- &nfs40_nograce_recovery_ops,
#if defined(CONFIG_NFS_V4_1)
- &nfs41_nograce_recovery_ops,
-#endif
+static const struct nfs4_minor_version_ops nfs_v4_1_minor_ops = {
+ .minor_version = 1,
+ .call_sync = _nfs4_call_sync_session,
+ .validate_stateid = nfs41_validate_delegation_stateid,
+ .reboot_recovery_ops = &nfs41_reboot_recovery_ops,
+ .nograce_recovery_ops = &nfs41_nograce_recovery_ops,
+ .state_renewal_ops = &nfs41_state_renewal_ops,
};
+#endif
-struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[] = {
- &nfs40_state_renewal_ops,
+const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
+ [0] = &nfs_v4_0_minor_ops,
#if defined(CONFIG_NFS_V4_1)
- &nfs41_state_renewal_ops,
+ [1] = &nfs_v4_1_minor_ops,
#endif
};
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index d87f10327b72..72b6c580af13 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -54,14 +54,14 @@
void
nfs4_renew_state(struct work_struct *work)
{
- struct nfs4_state_maintenance_ops *ops;
+ const struct nfs4_state_maintenance_ops *ops;
struct nfs_client *clp =
container_of(work, struct nfs_client, cl_renewd.work);
struct rpc_cred *cred;
long lease;
unsigned long last, now;
- ops = nfs4_state_renewal_ops[clp->cl_minorversion];
+ ops = clp->cl_mvops->state_renewal_ops;
dprintk("%s: start\n", __func__);
/* Are there any active superblocks? */
if (list_empty(&clp->cl_superblocks))
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 34acf5926fdc..3e2f19b04c06 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -145,7 +145,9 @@ static void nfs4_end_drain_session(struct nfs_client *clp)
struct nfs4_session *ses = clp->cl_session;
int max_slots;
- if (test_and_clear_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state)) {
+ if (ses == NULL)
+ return;
+ if (test_and_clear_bit(NFS4_SESSION_DRAINING, &ses->session_state)) {
spin_lock(&ses->fc_slot_table.slot_tbl_lock);
max_slots = ses->fc_slot_table.max_slots;
while (max_slots--) {
@@ -167,7 +169,7 @@ static int nfs4_begin_drain_session(struct nfs_client *clp)
struct nfs4_slot_table *tbl = &ses->fc_slot_table;
spin_lock(&tbl->slot_tbl_lock);
- set_bit(NFS4CLNT_SESSION_DRAINING, &clp->cl_state);
+ set_bit(NFS4_SESSION_DRAINING, &ses->session_state);
if (tbl->highest_used_slotid != -1) {
INIT_COMPLETION(ses->complete);
spin_unlock(&tbl->slot_tbl_lock);
@@ -371,7 +373,6 @@ nfs4_alloc_state_owner(void)
return NULL;
spin_lock_init(&sp->so_lock);
INIT_LIST_HEAD(&sp->so_states);
- INIT_LIST_HEAD(&sp->so_delegations);
rpc_init_wait_queue(&sp->so_sequence.wait, "Seqid_waitqueue");
sp->so_seqid.sequence = &sp->so_sequence;
spin_lock_init(&sp->so_sequence.lock);
@@ -384,7 +385,7 @@ static void
nfs4_drop_state_owner(struct nfs4_state_owner *sp)
{
if (!RB_EMPTY_NODE(&sp->so_client_node)) {
- struct nfs_client *clp = sp->so_client;
+ struct nfs_client *clp = sp->so_server->nfs_client;
spin_lock(&clp->cl_lock);
rb_erase(&sp->so_client_node, &clp->cl_state_owners);
@@ -406,7 +407,6 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
new = nfs4_alloc_state_owner();
if (new == NULL)
return NULL;
- new->so_client = clp;
new->so_server = server;
new->so_cred = cred;
spin_lock(&clp->cl_lock);
@@ -423,7 +423,7 @@ struct nfs4_state_owner *nfs4_get_state_owner(struct nfs_server *server, struct
void nfs4_put_state_owner(struct nfs4_state_owner *sp)
{
- struct nfs_client *clp = sp->so_client;
+ struct nfs_client *clp = sp->so_server->nfs_client;
struct rpc_cred *cred = sp->so_cred;
if (!atomic_dec_and_lock(&sp->so_count, &clp->cl_lock))
@@ -602,12 +602,21 @@ void nfs4_close_sync(struct path *path, struct nfs4_state *state, fmode_t fmode)
* that is compatible with current->files
*/
static struct nfs4_lock_state *
-__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
+__nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
{
struct nfs4_lock_state *pos;
list_for_each_entry(pos, &state->lock_states, ls_locks) {
- if (pos->ls_owner != fl_owner)
+ if (type != NFS4_ANY_LOCK_TYPE && pos->ls_owner.lo_type != type)
continue;
+ switch (pos->ls_owner.lo_type) {
+ case NFS4_POSIX_LOCK_TYPE:
+ if (pos->ls_owner.lo_u.posix_owner != fl_owner)
+ continue;
+ break;
+ case NFS4_FLOCK_LOCK_TYPE:
+ if (pos->ls_owner.lo_u.flock_owner != fl_pid)
+ continue;
+ }
atomic_inc(&pos->ls_count);
return pos;
}
@@ -619,10 +628,10 @@ __nfs4_find_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
* exists, return an uninitialized one.
*
*/
-static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner)
+static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid, unsigned int type)
{
struct nfs4_lock_state *lsp;
- struct nfs_client *clp = state->owner->so_client;
+ struct nfs_client *clp = state->owner->so_server->nfs_client;
lsp = kzalloc(sizeof(*lsp), GFP_NOFS);
if (lsp == NULL)
@@ -633,7 +642,18 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
lsp->ls_seqid.sequence = &lsp->ls_sequence;
atomic_set(&lsp->ls_count, 1);
lsp->ls_state = state;
- lsp->ls_owner = fl_owner;
+ lsp->ls_owner.lo_type = type;
+ switch (lsp->ls_owner.lo_type) {
+ case NFS4_FLOCK_LOCK_TYPE:
+ lsp->ls_owner.lo_u.flock_owner = fl_pid;
+ break;
+ case NFS4_POSIX_LOCK_TYPE:
+ lsp->ls_owner.lo_u.posix_owner = fl_owner;
+ break;
+ default:
+ kfree(lsp);
+ return NULL;
+ }
spin_lock(&clp->cl_lock);
nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64);
spin_unlock(&clp->cl_lock);
@@ -643,7 +663,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f
static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
{
- struct nfs_client *clp = lsp->ls_state->owner->so_client;
+ struct nfs_client *clp = lsp->ls_state->owner->so_server->nfs_client;
spin_lock(&clp->cl_lock);
nfs_free_unique_id(&clp->cl_lockowner_id, &lsp->ls_id);
@@ -657,13 +677,13 @@ static void nfs4_free_lock_state(struct nfs4_lock_state *lsp)
* exists, return an uninitialized one.
*
*/
-static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner)
+static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_owner_t owner, pid_t pid, unsigned int type)
{
struct nfs4_lock_state *lsp, *new = NULL;
for(;;) {
spin_lock(&state->state_lock);
- lsp = __nfs4_find_lock_state(state, owner);
+ lsp = __nfs4_find_lock_state(state, owner, pid, type);
if (lsp != NULL)
break;
if (new != NULL) {
@@ -674,7 +694,7 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_
break;
}
spin_unlock(&state->state_lock);
- new = nfs4_alloc_lock_state(state, owner);
+ new = nfs4_alloc_lock_state(state, owner, pid, type);
if (new == NULL)
return NULL;
}
@@ -701,6 +721,8 @@ void nfs4_put_lock_state(struct nfs4_lock_state *lsp)
if (list_empty(&state->lock_states))
clear_bit(LK_STATE_IN_USE, &state->flags);
spin_unlock(&state->state_lock);
+ if (lsp->ls_flags & NFS_LOCK_INITIALIZED)
+ nfs4_release_lockowner(lsp);
nfs4_free_lock_state(lsp);
}
@@ -728,7 +750,12 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
if (fl->fl_ops != NULL)
return 0;
- lsp = nfs4_get_lock_state(state, fl->fl_owner);
+ if (fl->fl_flags & FL_POSIX)
+ lsp = nfs4_get_lock_state(state, fl->fl_owner, 0, NFS4_POSIX_LOCK_TYPE);
+ else if (fl->fl_flags & FL_FLOCK)
+ lsp = nfs4_get_lock_state(state, 0, fl->fl_pid, NFS4_FLOCK_LOCK_TYPE);
+ else
+ return -EINVAL;
if (lsp == NULL)
return -ENOMEM;
fl->fl_u.nfs4_fl.owner = lsp;
@@ -740,7 +767,7 @@ int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl)
* Byte-range lock aware utility to initialize the stateid of read/write
* requests.
*/
-void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner)
+void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t fl_owner, pid_t fl_pid)
{
struct nfs4_lock_state *lsp;
int seq;
@@ -753,7 +780,7 @@ void nfs4_copy_stateid(nfs4_stateid *dst, struct nfs4_state *state, fl_owner_t f
return;
spin_lock(&state->state_lock);
- lsp = __nfs4_find_lock_state(state, fl_owner);
+ lsp = __nfs4_find_lock_state(state, fl_owner, fl_pid, NFS4_ANY_LOCK_TYPE);
if (lsp != NULL && (lsp->ls_flags & NFS_LOCK_INITIALIZED) != 0)
memcpy(dst, &lsp->ls_stateid, sizeof(*dst));
spin_unlock(&state->state_lock);
@@ -1041,11 +1068,11 @@ restart:
case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_RECLAIM_BAD:
case -NFS4ERR_RECLAIM_CONFLICT:
- nfs4_state_mark_reclaim_nograce(sp->so_client, state);
+ nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
break;
case -NFS4ERR_EXPIRED:
case -NFS4ERR_NO_GRACE:
- nfs4_state_mark_reclaim_nograce(sp->so_client, state);
+ nfs4_state_mark_reclaim_nograce(sp->so_server->nfs_client, state);
case -NFS4ERR_STALE_CLIENTID:
case -NFS4ERR_BADSESSION:
case -NFS4ERR_BADSLOT:
@@ -1120,8 +1147,7 @@ static void nfs4_state_end_reclaim_reboot(struct nfs_client *clp)
if (!test_and_clear_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
return;
- nfs4_reclaim_complete(clp,
- nfs4_reboot_recovery_ops[clp->cl_minorversion]);
+ nfs4_reclaim_complete(clp, clp->cl_mvops->reboot_recovery_ops);
for (pos = rb_first(&clp->cl_state_owners); pos != NULL; pos = rb_next(pos)) {
sp = rb_entry(pos, struct nfs4_state_owner, so_client_node);
@@ -1211,8 +1237,8 @@ restart:
static int nfs4_check_lease(struct nfs_client *clp)
{
struct rpc_cred *cred;
- struct nfs4_state_maintenance_ops *ops =
- nfs4_state_renewal_ops[clp->cl_minorversion];
+ const struct nfs4_state_maintenance_ops *ops =
+ clp->cl_mvops->state_renewal_ops;
int status = -NFS4ERR_EXPIRED;
/* Is the client already known to have an expired lease? */
@@ -1235,8 +1261,8 @@ out:
static int nfs4_reclaim_lease(struct nfs_client *clp)
{
struct rpc_cred *cred;
- struct nfs4_state_recovery_ops *ops =
- nfs4_reboot_recovery_ops[clp->cl_minorversion];
+ const struct nfs4_state_recovery_ops *ops =
+ clp->cl_mvops->reboot_recovery_ops;
int status = -ENOENT;
cred = ops->get_clid_cred(clp);
@@ -1444,7 +1470,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
/* First recover reboot state... */
if (test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state)) {
status = nfs4_do_reclaim(clp,
- nfs4_reboot_recovery_ops[clp->cl_minorversion]);
+ clp->cl_mvops->reboot_recovery_ops);
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state))
continue;
@@ -1458,7 +1484,7 @@ static void nfs4_state_manager(struct nfs_client *clp)
/* Now recover expired state... */
if (test_and_clear_bit(NFS4CLNT_RECLAIM_NOGRACE, &clp->cl_state)) {
status = nfs4_do_reclaim(clp,
- nfs4_nograce_recovery_ops[clp->cl_minorversion]);
+ clp->cl_mvops->nograce_recovery_ops);
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) ||
test_bit(NFS4CLNT_SESSION_RESET, &clp->cl_state) ||
test_bit(NFS4CLNT_RECLAIM_REBOOT, &clp->cl_state))
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 65c8dae4b267..257c1811feb4 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -202,14 +202,17 @@ static int nfs4_stat_to_errno(int);
#define encode_link_maxsz (op_encode_hdr_maxsz + \
nfs4_name_maxsz)
#define decode_link_maxsz (op_decode_hdr_maxsz + decode_change_info_maxsz)
+#define encode_lockowner_maxsz (7)
#define encode_lock_maxsz (op_encode_hdr_maxsz + \
7 + \
- 1 + encode_stateid_maxsz + 8)
+ 1 + encode_stateid_maxsz + 1 + \
+ encode_lockowner_maxsz)
#define decode_lock_denied_maxsz \
(8 + decode_lockowner_maxsz)
#define decode_lock_maxsz (op_decode_hdr_maxsz + \
decode_lock_denied_maxsz)
-#define encode_lockt_maxsz (op_encode_hdr_maxsz + 12)
+#define encode_lockt_maxsz (op_encode_hdr_maxsz + 5 + \
+ encode_lockowner_maxsz)
#define decode_lockt_maxsz (op_decode_hdr_maxsz + \
decode_lock_denied_maxsz)
#define encode_locku_maxsz (op_encode_hdr_maxsz + 3 + \
@@ -217,6 +220,11 @@ static int nfs4_stat_to_errno(int);
4)
#define decode_locku_maxsz (op_decode_hdr_maxsz + \
decode_stateid_maxsz)
+#define encode_release_lockowner_maxsz \
+ (op_encode_hdr_maxsz + \
+ encode_lockowner_maxsz)
+#define decode_release_lockowner_maxsz \
+ (op_decode_hdr_maxsz)
#define encode_access_maxsz (op_encode_hdr_maxsz + 1)
#define decode_access_maxsz (op_decode_hdr_maxsz + 2)
#define encode_symlink_maxsz (op_encode_hdr_maxsz + \
@@ -471,6 +479,12 @@ static int nfs4_stat_to_errno(int);
decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_locku_maxsz)
+#define NFS4_enc_release_lockowner_sz \
+ (compound_encode_hdr_maxsz + \
+ encode_lockowner_maxsz)
+#define NFS4_dec_release_lockowner_sz \
+ (compound_decode_hdr_maxsz + \
+ decode_lockowner_maxsz)
#define NFS4_enc_access_sz (compound_encode_hdr_maxsz + \
encode_sequence_maxsz + \
encode_putfh_maxsz + \
@@ -1042,6 +1056,17 @@ static inline uint64_t nfs4_lock_length(struct file_lock *fl)
return fl->fl_end - fl->fl_start + 1;
}
+static void encode_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner)
+{
+ __be32 *p;
+
+ p = reserve_space(xdr, 28);
+ p = xdr_encode_hyper(p, lowner->clientid);
+ *p++ = cpu_to_be32(16);
+ p = xdr_encode_opaque_fixed(p, "lock id:", 8);
+ xdr_encode_hyper(p, lowner->id);
+}
+
/*
* opcode,type,reclaim,offset,length,new_lock_owner = 32
* open_seqid,open_stateid,lock_seqid,lock_owner.clientid, lock_owner.id = 40
@@ -1058,14 +1083,11 @@ static void encode_lock(struct xdr_stream *xdr, const struct nfs_lock_args *args
p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
*p = cpu_to_be32(args->new_lock_owner);
if (args->new_lock_owner){
- p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+32);
+ p = reserve_space(xdr, 4+NFS4_STATEID_SIZE+4);
*p++ = cpu_to_be32(args->open_seqid->sequence->counter);
p = xdr_encode_opaque_fixed(p, args->open_stateid->data, NFS4_STATEID_SIZE);
*p++ = cpu_to_be32(args->lock_seqid->sequence->counter);
- p = xdr_encode_hyper(p, args->lock_owner.clientid);
- *p++ = cpu_to_be32(16);
- p = xdr_encode_opaque_fixed(p, "lock id:", 8);
- xdr_encode_hyper(p, args->lock_owner.id);
+ encode_lockowner(xdr, &args->lock_owner);
}
else {
p = reserve_space(xdr, NFS4_STATEID_SIZE+4);
@@ -1080,15 +1102,12 @@ static void encode_lockt(struct xdr_stream *xdr, const struct nfs_lockt_args *ar
{
__be32 *p;
- p = reserve_space(xdr, 52);
+ p = reserve_space(xdr, 24);
*p++ = cpu_to_be32(OP_LOCKT);
*p++ = cpu_to_be32(nfs4_lock_type(args->fl, 0));
p = xdr_encode_hyper(p, args->fl->fl_start);
p = xdr_encode_hyper(p, nfs4_lock_length(args->fl));
- p = xdr_encode_hyper(p, args->lock_owner.clientid);
- *p++ = cpu_to_be32(16);
- p = xdr_encode_opaque_fixed(p, "lock id:", 8);
- xdr_encode_hyper(p, args->lock_owner.id);
+ encode_lockowner(xdr, &args->lock_owner);
hdr->nops++;
hdr->replen += decode_lockt_maxsz;
}
@@ -1108,6 +1127,17 @@ static void encode_locku(struct xdr_stream *xdr, const struct nfs_locku_args *ar
hdr->replen += decode_locku_maxsz;
}
+static void encode_release_lockowner(struct xdr_stream *xdr, const struct nfs_lowner *lowner, struct compound_hdr *hdr)
+{
+ __be32 *p;
+
+ p = reserve_space(xdr, 4);
+ *p = cpu_to_be32(OP_RELEASE_LOCKOWNER);
+ encode_lockowner(xdr, lowner);
+ hdr->nops++;
+ hdr->replen += decode_release_lockowner_maxsz;
+}
+
static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struct compound_hdr *hdr)
{
int len = name->len;
@@ -1172,7 +1202,7 @@ static inline void encode_createmode(struct xdr_stream *xdr, const struct nfs_op
break;
default:
clp = arg->server->nfs_client;
- if (clp->cl_minorversion > 0) {
+ if (clp->cl_mvops->minor_version > 0) {
if (nfs4_has_persistent_session(clp)) {
*p = cpu_to_be32(NFS4_CREATE_GUARDED);
encode_attrs(xdr, arg->u.attrs, arg->server);
@@ -1324,14 +1354,14 @@ static void encode_putrootfh(struct xdr_stream *xdr, struct compound_hdr *hdr)
hdr->replen += decode_putrootfh_maxsz;
}
-static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx)
+static void encode_stateid(struct xdr_stream *xdr, const struct nfs_open_context *ctx, const struct nfs_lock_context *l_ctx)
{
nfs4_stateid stateid;
__be32 *p;
p = reserve_space(xdr, NFS4_STATEID_SIZE);
if (ctx->state != NULL) {
- nfs4_copy_stateid(&stateid, ctx->state, ctx->lockowner);
+ nfs4_copy_stateid(&stateid, ctx->state, l_ctx->lockowner, l_ctx->pid);
xdr_encode_opaque_fixed(p, stateid.data, NFS4_STATEID_SIZE);
} else
xdr_encode_opaque_fixed(p, zero_stateid.data, NFS4_STATEID_SIZE);
@@ -1344,7 +1374,7 @@ static void encode_read(struct xdr_stream *xdr, const struct nfs_readargs *args,
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_READ);
- encode_stateid(xdr, args->context);
+ encode_stateid(xdr, args->context, args->lock_context);
p = reserve_space(xdr, 12);
p = xdr_encode_hyper(p, args->offset);
@@ -1523,7 +1553,7 @@ static void encode_write(struct xdr_stream *xdr, const struct nfs_writeargs *arg
p = reserve_space(xdr, 4);
*p = cpu_to_be32(OP_WRITE);
- encode_stateid(xdr, args->context);
+ encode_stateid(xdr, args->context, args->lock_context);
p = reserve_space(xdr, 16);
p = xdr_encode_hyper(p, args->offset);
@@ -1704,7 +1734,7 @@ static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args)
{
#if defined(CONFIG_NFS_V4_1)
if (args->sa_session)
- return args->sa_session->clp->cl_minorversion;
+ return args->sa_session->clp->cl_mvops->minor_version;
#endif /* CONFIG_NFS_V4_1 */
return 0;
}
@@ -2048,6 +2078,20 @@ static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_
return 0;
}
+static int nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, __be32 *p, struct nfs_release_lockowner_args *args)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr = {
+ .minorversion = 0,
+ };
+
+ xdr_init_encode(&xdr, &req->rq_snd_buf, p);
+ encode_compound_hdr(&xdr, req, &hdr);
+ encode_release_lockowner(&xdr, &args->lock_owner, &hdr);
+ encode_nops(&hdr);
+ return 0;
+}
+
/*
* Encode a READLINK request
*/
@@ -2395,7 +2439,7 @@ static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p,
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .minorversion = args->client->cl_minorversion,
+ .minorversion = args->client->cl_mvops->minor_version,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -2413,7 +2457,7 @@ static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p,
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .minorversion = args->client->cl_minorversion,
+ .minorversion = args->client->cl_mvops->minor_version,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -2431,7 +2475,7 @@ static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p,
{
struct xdr_stream xdr;
struct compound_hdr hdr = {
- .minorversion = session->clp->cl_minorversion,
+ .minorversion = session->clp->cl_mvops->minor_version,
};
xdr_init_encode(&xdr, &req->rq_snd_buf, p);
@@ -3973,6 +4017,11 @@ static int decode_locku(struct xdr_stream *xdr, struct nfs_locku_res *res)
return status;
}
+static int decode_release_lockowner(struct xdr_stream *xdr)
+{
+ return decode_op_hdr(xdr, OP_RELEASE_LOCKOWNER);
+}
+
static int decode_lookup(struct xdr_stream *xdr)
{
return decode_op_hdr(xdr, OP_LOOKUP);
@@ -5259,6 +5308,19 @@ out:
return status;
}
+static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, __be32 *p, void *dummy)
+{
+ struct xdr_stream xdr;
+ struct compound_hdr hdr;
+ int status;
+
+ xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
+ status = decode_compound_hdr(&xdr, &hdr);
+ if (!status)
+ status = decode_release_lockowner(&xdr);
+ return status;
+}
+
/*
* Decode READLINK response
*/
@@ -5866,6 +5928,7 @@ struct rpc_procinfo nfs4_procedures[] = {
PROC(GETACL, enc_getacl, dec_getacl),
PROC(SETACL, enc_setacl, dec_setacl),
PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations),
+ PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner),
#if defined(CONFIG_NFS_V4_1)
PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id),
PROC(CREATE_SESSION, enc_create_session, dec_create_session),
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index a3654e57b589..919490232e17 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -79,6 +79,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct inode *inode,
req->wb_pgbase = offset;
req->wb_bytes = count;
req->wb_context = get_nfs_open_context(ctx);
+ req->wb_lock_context = nfs_get_lock_context(ctx);
kref_init(&req->wb_kref);
return req;
}
@@ -141,11 +142,16 @@ void nfs_clear_request(struct nfs_page *req)
{
struct page *page = req->wb_page;
struct nfs_open_context *ctx = req->wb_context;
+ struct nfs_lock_context *l_ctx = req->wb_lock_context;
if (page != NULL) {
page_cache_release(page);
req->wb_page = NULL;
}
+ if (l_ctx != NULL) {
+ nfs_put_lock_context(l_ctx);
+ req->wb_lock_context = NULL;
+ }
if (ctx != NULL) {
put_nfs_open_context(ctx);
req->wb_context = NULL;
@@ -235,7 +241,7 @@ static int nfs_can_coalesce_requests(struct nfs_page *prev,
{
if (req->wb_context->cred != prev->wb_context->cred)
return 0;
- if (req->wb_context->lockowner != prev->wb_context->lockowner)
+ if (req->wb_lock_context->lockowner != prev->wb_lock_context->lockowner)
return 0;
if (req->wb_context->state != prev->wb_context->state)
return 0;
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 6e2b06e6ca79..87adc2744246 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -190,6 +190,7 @@ static int nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
data->args.pages = data->pagevec;
data->args.count = count;
data->args.context = get_nfs_open_context(req->wb_context);
+ data->args.lock_context = req->wb_lock_context;
data->res.fattr = &data->fattr;
data->res.count = count;
@@ -410,7 +411,7 @@ void nfs_read_prepare(struct rpc_task *task, void *calldata)
{
struct nfs_read_data *data = calldata;
- if (nfs4_setup_sequence(NFS_SERVER(data->inode)->nfs_client,
+ if (nfs4_setup_sequence(NFS_SERVER(data->inode),
&data->args.seq_args, &data->res.seq_res,
0, task))
return;
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index f9df16de4a56..ef2b7e468a7e 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -270,7 +270,7 @@ static const struct super_operations nfs_sops = {
.write_inode = nfs_write_inode,
.put_super = nfs_put_super,
.statfs = nfs_statfs,
- .clear_inode = nfs_clear_inode,
+ .evict_inode = nfs_evict_inode,
.umount_begin = nfs_umount_begin,
.show_options = nfs_show_options,
.show_stats = nfs_show_stats,
@@ -340,7 +340,7 @@ static const struct super_operations nfs4_sops = {
.write_inode = nfs_write_inode,
.put_super = nfs_put_super,
.statfs = nfs_statfs,
- .clear_inode = nfs4_clear_inode,
+ .evict_inode = nfs4_evict_inode,
.umount_begin = nfs_umount_begin,
.show_options = nfs_show_options,
.show_stats = nfs_show_stats,
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index a2242af6a17d..2f84adaad427 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -110,7 +110,7 @@ void nfs_unlink_prepare(struct rpc_task *task, void *calldata)
struct nfs_unlinkdata *data = calldata;
struct nfs_server *server = NFS_SERVER(data->dir);
- if (nfs4_setup_sequence(server->nfs_client, &data->args.seq_args,
+ if (nfs4_setup_sequence(server, &data->args.seq_args,
&data->res.seq_res, 1, task))
return;
rpc_call_start(task);
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 91679e2631ee..5eccea127cac 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -689,7 +689,9 @@ int nfs_flush_incompatible(struct file *file, struct page *page)
req = nfs_page_find_request(page);
if (req == NULL)
return 0;
- do_flush = req->wb_page != page || req->wb_context != ctx;
+ do_flush = req->wb_page != page || req->wb_context != ctx ||
+ req->wb_lock_context->lockowner != current->files ||
+ req->wb_lock_context->pid != current->tgid;
nfs_release_request(req);
if (!do_flush)
return 0;
@@ -813,6 +815,7 @@ static int nfs_write_rpcsetup(struct nfs_page *req,
data->args.pages = data->pagevec;
data->args.count = count;
data->args.context = get_nfs_open_context(req->wb_context);
+ data->args.lock_context = req->wb_lock_context;
data->args.stable = NFS_UNSTABLE;
if (how & FLUSH_STABLE) {
data->args.stable = NFS_DATA_SYNC;
@@ -1036,9 +1039,9 @@ out:
void nfs_write_prepare(struct rpc_task *task, void *calldata)
{
struct nfs_write_data *data = calldata;
- struct nfs_client *clp = (NFS_SERVER(data->inode))->nfs_client;
- if (nfs4_setup_sequence(clp, &data->args.seq_args,
+ if (nfs4_setup_sequence(NFS_SERVER(data->inode),
+ &data->args.seq_args,
&data->res.seq_res, 1, task))
return;
rpc_call_start(task);
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 3d68f45a37b9..9ae93317abe4 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -271,7 +271,7 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
fh_init(&resp->fh, NFS3_FHSIZE);
nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
&argp->attrs, S_IFDIR, 0, &resp->fh);
-
+ fh_unlock(&resp->dirfh);
RETURN_STATUS(nfserr);
}
@@ -327,7 +327,7 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
type = nfs3_ftypes[argp->ftype];
nfserr = nfsd_create(rqstp, &resp->dirfh, argp->name, argp->len,
&argp->attrs, type, rdev, &resp->fh);
-
+ fh_unlock(&resp->dirfh);
RETURN_STATUS(nfserr);
}
@@ -348,6 +348,7 @@ nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
/* Unlink. -S_IFDIR means file must not be a directory */
fh_copy(&resp->fh, &argp->fh);
nfserr = nfsd_unlink(rqstp, &resp->fh, -S_IFDIR, argp->name, argp->len);
+ fh_unlock(&resp->fh);
RETURN_STATUS(nfserr);
}
@@ -367,6 +368,7 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
fh_copy(&resp->fh, &argp->fh);
nfserr = nfsd_unlink(rqstp, &resp->fh, S_IFDIR, argp->name, argp->len);
+ fh_unlock(&resp->fh);
RETURN_STATUS(nfserr);
}
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index eb78e7e22077..1e6497ed3e12 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -143,8 +143,6 @@ struct nfs4_cb_compound_hdr {
u32 minorversion;
/* res */
int status;
- u32 taglen;
- char *tag;
};
static struct {
@@ -205,6 +203,16 @@ nfs_cb_stat_to_errno(int stat)
*/
static void
+encode_stateid(struct xdr_stream *xdr, stateid_t *sid)
+{
+ __be32 *p;
+
+ RESERVE_SPACE(sizeof(stateid_t));
+ WRITE32(sid->si_generation);
+ WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t));
+}
+
+static void
encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr)
{
__be32 * p;
@@ -229,10 +237,10 @@ encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp,
__be32 *p;
int len = dp->dl_fh.fh_size;
- RESERVE_SPACE(12+sizeof(dp->dl_stateid) + len);
+ RESERVE_SPACE(4);
WRITE32(OP_CB_RECALL);
- WRITE32(dp->dl_stateid.si_generation);
- WRITEMEM(&dp->dl_stateid.si_opaque, sizeof(stateid_opaque_t));
+ encode_stateid(xdr, &dp->dl_stateid);
+ RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2));
WRITE32(0); /* truncate optimization not implemented */
WRITE32(len);
WRITEMEM(&dp->dl_fh.fh_base, len);
@@ -293,13 +301,14 @@ nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p,
static int
decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){
__be32 *p;
+ u32 taglen;
READ_BUF(8);
READ32(hdr->status);
- READ32(hdr->taglen);
- READ_BUF(hdr->taglen + 4);
- hdr->tag = (char *)p;
- p += XDR_QUADLEN(hdr->taglen);
+ /* We've got no use for the tag; ignore it: */
+ READ32(taglen);
+ READ_BUF(taglen + 4);
+ p += XDR_QUADLEN(taglen);
READ32(hdr->nops);
return 0;
}
@@ -667,23 +676,23 @@ static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
}
switch (task->tk_status) {
- case -EIO:
+ case 0:
+ return;
+ case -EBADHANDLE:
+ case -NFS4ERR_BAD_STATEID:
+ /* Race: client probably got cb_recall
+ * before open reply granting delegation */
+ break;
+ default:
/* Network partition? */
atomic_set(&clp->cl_cb_set, 0);
warn_no_callback_path(clp, task->tk_status);
if (current_rpc_client != task->tk_client) {
/* queue a callback on the new connection: */
+ atomic_inc(&dp->dl_count);
nfsd4_cb_recall(dp);
return;
}
- case -EBADHANDLE:
- case -NFS4ERR_BAD_STATEID:
- /* Race: client probably got cb_recall
- * before open reply granting delegation */
- break;
- default:
- /* success, or error we can't handle */
- return;
}
if (dp->dl_retries--) {
rpc_delay(task, 2*HZ);
@@ -752,18 +761,16 @@ static void _nfsd4_cb_recall(struct nfs4_delegation *dp)
.rpc_proc = &nfs4_cb_procedures[NFSPROC4_CLNT_CB_RECALL],
.rpc_cred = callback_cred
};
- int status;
- if (clnt == NULL)
+ if (clnt == NULL) {
+ nfs4_put_delegation(dp);
return; /* Client is shutting down; give up. */
+ }
args->args_op = dp;
msg.rpc_argp = args;
dp->dl_retries = 1;
- status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
- &nfsd4_cb_recall_ops, dp);
- if (status)
- nfs4_put_delegation(dp);
+ rpc_call_async(clnt, &msg, RPC_TASK_SOFT, &nfsd4_cb_recall_ops, dp);
}
void nfsd4_do_callback_rpc(struct work_struct *w)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 4a2734758778..dc69a05efd3b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -457,7 +457,7 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan)
spin_unlock(&nfsd_drc_lock);
if (fchan->maxreqs == 0)
- return nfserr_serverfault;
+ return nfserr_jukebox;
fchan->maxresp_cached = size + NFSD_MIN_HDR_SEQ_SZ;
return 0;
@@ -542,7 +542,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp,
BUILD_BUG_ON(NFSD_MAX_SLOTS_PER_SESSION * sizeof(struct nfsd4_slot)
+ sizeof(struct nfsd4_session) > PAGE_SIZE);
- status = nfserr_serverfault;
+ status = nfserr_jukebox;
/* allocate struct nfsd4_session and slot table pointers in one piece */
slotsize = tmp.se_fchannel.maxreqs * sizeof(struct nfsd4_slot *);
new = kzalloc(sizeof(*new) + slotsize, GFP_KERNEL);
@@ -591,10 +591,8 @@ find_in_sessionid_hashtbl(struct nfs4_sessionid *sessionid)
dump_sessionid(__func__, sessionid);
idx = hash_sessionid(sessionid);
- dprintk("%s: idx is %d\n", __func__, idx);
/* Search in the appropriate list */
list_for_each_entry(elem, &sessionid_hashtbl[idx], se_hash) {
- dump_sessionid("list traversal", &elem->se_sessionid);
if (!memcmp(elem->se_sessionid.data, sessionid->data,
NFS4_MAX_SESSIONID_LEN)) {
return elem;
@@ -714,7 +712,6 @@ release_session_client(struct nfsd4_session *session)
} else
renew_client_locked(clp);
spin_unlock(&client_lock);
- nfsd4_put_session(session);
}
/* must be called under the client_lock */
@@ -1220,7 +1217,7 @@ out_new:
/* Normal case */
new = create_client(exid->clname, dname, rqstp, &verf);
if (new == NULL) {
- status = nfserr_serverfault;
+ status = nfserr_jukebox;
goto out;
}
@@ -2255,6 +2252,13 @@ find_delegation_file(struct nfs4_file *fp, stateid_t *stid)
return NULL;
}
+int share_access_to_flags(u32 share_access)
+{
+ share_access &= ~NFS4_SHARE_WANT_MASK;
+
+ return share_access == NFS4_SHARE_ACCESS_READ ? RD_STATE : WR_STATE;
+}
+
static __be32
nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
struct nfs4_delegation **dp)
@@ -2265,8 +2269,7 @@ nfs4_check_deleg(struct nfs4_file *fp, struct nfsd4_open *open,
*dp = find_delegation_file(fp, &open->op_delegate_stateid);
if (*dp == NULL)
goto out;
- flags = open->op_share_access == NFS4_SHARE_ACCESS_READ ?
- RD_STATE : WR_STATE;
+ flags = share_access_to_flags(open->op_share_access);
status = nfs4_check_delegmode(*dp, flags);
if (status)
*dp = NULL;
@@ -2358,6 +2361,7 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta
struct file *filp = stp->st_vfs_file;
struct inode *inode = filp->f_path.dentry->d_inode;
unsigned int share_access, new_writer;
+ u32 op_share_access;
__be32 status;
set_access(&share_access, stp->st_access_bmap);
@@ -2380,8 +2384,9 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta
return status;
}
/* remember the open */
- filp->f_mode |= open->op_share_access;
- __set_bit(open->op_share_access, &stp->st_access_bmap);
+ op_share_access = open->op_share_access & ~NFS4_SHARE_WANT_MASK;
+ filp->f_mode |= op_share_access;
+ __set_bit(op_share_access, &stp->st_access_bmap);
__set_bit(open->op_share_deny, &stp->st_deny_bmap);
return nfs_ok;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index ac17a7080239..835924f5ca54 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3325,6 +3325,7 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
}
/* Renew the clientid on success and on replay */
release_session_client(cs->session);
+ nfsd4_put_session(cs->session);
}
return 1;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 3c111120b619..2f86224181a1 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -604,7 +604,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac
return error;
}
-#endif /* defined(CONFIG_NFS_V4) */
+#endif /* defined(CONFIG_NFSD_V4) */
#ifdef CONFIG_NFSD_V3
/*
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index effdbdbe6c11..3dbdc1d356bf 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -26,6 +26,8 @@
#include "nilfs.h"
#include "bmap.h"
#include "sb.h"
+#include "btree.h"
+#include "direct.h"
#include "btnode.h"
#include "mdt.h"
#include "dat.h"
@@ -533,7 +535,7 @@ void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
void nilfs_bmap_init_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
{
- memcpy(gcbmap, bmap, sizeof(union nilfs_bmap_union));
+ memcpy(gcbmap, bmap, sizeof(*bmap));
init_rwsem(&gcbmap->b_sem);
lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
gcbmap->b_inode = &NILFS_BMAP_I(gcbmap)->vfs_inode;
@@ -541,7 +543,7 @@ void nilfs_bmap_init_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
void nilfs_bmap_commit_gcdat(struct nilfs_bmap *gcbmap, struct nilfs_bmap *bmap)
{
- memcpy(bmap, gcbmap, sizeof(union nilfs_bmap_union));
+ memcpy(bmap, gcbmap, sizeof(*bmap));
init_rwsem(&bmap->b_sem);
lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
diff --git a/fs/nilfs2/bmap.h b/fs/nilfs2/bmap.h
index 9980d7dbab91..a20569b19929 100644
--- a/fs/nilfs2/bmap.h
+++ b/fs/nilfs2/bmap.h
@@ -32,11 +32,6 @@
#define NILFS_BMAP_INVALID_PTR 0
-#define nilfs_bmap_dkey_to_key(dkey) le64_to_cpu(dkey)
-#define nilfs_bmap_key_to_dkey(key) cpu_to_le64(key)
-#define nilfs_bmap_dptr_to_ptr(dptr) le64_to_cpu(dptr)
-#define nilfs_bmap_ptr_to_dptr(ptr) cpu_to_le64(ptr)
-
#define nilfs_bmap_keydiff_abs(diff) ((diff) < 0 ? -(diff) : (diff))
@@ -71,7 +66,7 @@ struct nilfs_bmap_operations {
int (*bop_delete)(struct nilfs_bmap *, __u64);
void (*bop_clear)(struct nilfs_bmap *);
- int (*bop_propagate)(const struct nilfs_bmap *, struct buffer_head *);
+ int (*bop_propagate)(struct nilfs_bmap *, struct buffer_head *);
void (*bop_lookup_dirty_buffers)(struct nilfs_bmap *,
struct list_head *);
@@ -110,6 +105,7 @@ static inline int nilfs_bmap_is_new_ptr(unsigned long ptr)
* @b_last_allocated_ptr: last allocated ptr for data block
* @b_ptr_type: pointer type
* @b_state: state
+ * @b_nchildren_per_block: maximum number of child nodes for non-root nodes
*/
struct nilfs_bmap {
union {
@@ -123,6 +119,7 @@ struct nilfs_bmap {
__u64 b_last_allocated_ptr;
int b_ptr_type;
int b_state;
+ __u16 b_nchildren_per_block;
};
/* pointer type */
@@ -224,6 +221,13 @@ static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap,
nilfs_dat_abort_end(dat, &req->bpr_req);
}
+static inline void nilfs_bmap_set_target_v(struct nilfs_bmap *bmap, __u64 key,
+ __u64 ptr)
+{
+ bmap->b_last_allocated_key = key;
+ bmap->b_last_allocated_ptr = ptr;
+}
+
__u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
const struct buffer_head *);
diff --git a/fs/nilfs2/bmap_union.h b/fs/nilfs2/bmap_union.h
deleted file mode 100644
index d41509bff47b..000000000000
--- a/fs/nilfs2/bmap_union.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * bmap_union.h - NILFS block mapping.
- *
- * Copyright (C) 2006-2008 Nippon Telegraph and Telephone Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Written by Koji Sato <koji@osrg.net>.
- */
-
-#ifndef _NILFS_BMAP_UNION_H
-#define _NILFS_BMAP_UNION_H
-
-#include "bmap.h"
-#include "direct.h"
-#include "btree.h"
-
-/**
- * nilfs_bmap_union -
- * @bi_bmap: bmap structure
- * @bi_btree: direct map structure
- * @bi_direct: B-tree structure
- */
-union nilfs_bmap_union {
- struct nilfs_bmap bi_bmap;
- struct nilfs_direct bi_direct;
- struct nilfs_btree bi_btree;
-};
-
-#endif /* _NILFS_BMAP_UNION_H */
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c
index b27a342c5af6..2733105bcc40 100644
--- a/fs/nilfs2/btree.c
+++ b/fs/nilfs2/btree.c
@@ -66,30 +66,34 @@ static void nilfs_btree_free_path(struct nilfs_btree_path *path)
/*
* B-tree node operations
*/
-static int nilfs_btree_get_block(const struct nilfs_btree *btree, __u64 ptr,
+static int nilfs_btree_get_block(const struct nilfs_bmap *btree, __u64 ptr,
struct buffer_head **bhp)
{
- struct address_space *btnc =
- &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+ struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
+ struct buffer_head *bh;
int err;
err = nilfs_btnode_submit_block(btnc, ptr, 0, bhp);
if (err)
return err == -EEXIST ? 0 : err;
- wait_on_buffer(*bhp);
- if (!buffer_uptodate(*bhp)) {
- brelse(*bhp);
+ bh = *bhp;
+ wait_on_buffer(bh);
+ if (!buffer_uptodate(bh)) {
+ brelse(bh);
return -EIO;
}
+ if (nilfs_btree_broken_node_block(bh)) {
+ clear_buffer_uptodate(bh);
+ return -EINVAL;
+ }
return 0;
}
-static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
+static int nilfs_btree_get_new_block(const struct nilfs_bmap *btree,
__u64 ptr, struct buffer_head **bhp)
{
- struct address_space *btnc =
- &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+ struct address_space *btnc = &NILFS_BMAP_I(btree)->i_btnode_cache;
struct buffer_head *bh;
bh = nilfs_btnode_create_block(btnc, ptr);
@@ -101,71 +105,55 @@ static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
return 0;
}
-static inline int
-nilfs_btree_node_get_flags(const struct nilfs_btree_node *node)
+static int nilfs_btree_node_get_flags(const struct nilfs_btree_node *node)
{
return node->bn_flags;
}
-static inline void
+static void
nilfs_btree_node_set_flags(struct nilfs_btree_node *node, int flags)
{
node->bn_flags = flags;
}
-static inline int nilfs_btree_node_root(const struct nilfs_btree_node *node)
+static int nilfs_btree_node_root(const struct nilfs_btree_node *node)
{
return nilfs_btree_node_get_flags(node) & NILFS_BTREE_NODE_ROOT;
}
-static inline int
-nilfs_btree_node_get_level(const struct nilfs_btree_node *node)
+static int nilfs_btree_node_get_level(const struct nilfs_btree_node *node)
{
return node->bn_level;
}
-static inline void
+static void
nilfs_btree_node_set_level(struct nilfs_btree_node *node, int level)
{
node->bn_level = level;
}
-static inline int
-nilfs_btree_node_get_nchildren(const struct nilfs_btree_node *node)
+static int nilfs_btree_node_get_nchildren(const struct nilfs_btree_node *node)
{
return le16_to_cpu(node->bn_nchildren);
}
-static inline void
+static void
nilfs_btree_node_set_nchildren(struct nilfs_btree_node *node, int nchildren)
{
node->bn_nchildren = cpu_to_le16(nchildren);
}
-static inline int nilfs_btree_node_size(const struct nilfs_btree *btree)
+static int nilfs_btree_node_size(const struct nilfs_bmap *btree)
{
- return 1 << btree->bt_bmap.b_inode->i_blkbits;
+ return 1 << btree->b_inode->i_blkbits;
}
-static inline int
-nilfs_btree_node_nchildren_min(const struct nilfs_btree_node *node,
- const struct nilfs_btree *btree)
+static int nilfs_btree_nchildren_per_block(const struct nilfs_bmap *btree)
{
- return nilfs_btree_node_root(node) ?
- NILFS_BTREE_ROOT_NCHILDREN_MIN :
- NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree));
+ return btree->b_nchildren_per_block;
}
-static inline int
-nilfs_btree_node_nchildren_max(const struct nilfs_btree_node *node,
- const struct nilfs_btree *btree)
-{
- return nilfs_btree_node_root(node) ?
- NILFS_BTREE_ROOT_NCHILDREN_MAX :
- NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(btree));
-}
-
-static inline __le64 *
+static __le64 *
nilfs_btree_node_dkeys(const struct nilfs_btree_node *node)
{
return (__le64 *)((char *)(node + 1) +
@@ -173,45 +161,40 @@ nilfs_btree_node_dkeys(const struct nilfs_btree_node *node)
0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE));
}
-static inline __le64 *
-nilfs_btree_node_dptrs(const struct nilfs_btree_node *node,
- const struct nilfs_btree *btree)
+static __le64 *
+nilfs_btree_node_dptrs(const struct nilfs_btree_node *node, int ncmax)
{
- return (__le64 *)(nilfs_btree_node_dkeys(node) +
- nilfs_btree_node_nchildren_max(node, btree));
+ return (__le64 *)(nilfs_btree_node_dkeys(node) + ncmax);
}
-static inline __u64
+static __u64
nilfs_btree_node_get_key(const struct nilfs_btree_node *node, int index)
{
- return nilfs_bmap_dkey_to_key(*(nilfs_btree_node_dkeys(node) + index));
+ return le64_to_cpu(*(nilfs_btree_node_dkeys(node) + index));
}
-static inline void
+static void
nilfs_btree_node_set_key(struct nilfs_btree_node *node, int index, __u64 key)
{
- *(nilfs_btree_node_dkeys(node) + index) = nilfs_bmap_key_to_dkey(key);
+ *(nilfs_btree_node_dkeys(node) + index) = cpu_to_le64(key);
}
-static inline __u64
-nilfs_btree_node_get_ptr(const struct nilfs_btree *btree,
- const struct nilfs_btree_node *node, int index)
+static __u64
+nilfs_btree_node_get_ptr(const struct nilfs_btree_node *node, int index,
+ int ncmax)
{
- return nilfs_bmap_dptr_to_ptr(*(nilfs_btree_node_dptrs(node, btree) +
- index));
+ return le64_to_cpu(*(nilfs_btree_node_dptrs(node, ncmax) + index));
}
-static inline void
-nilfs_btree_node_set_ptr(struct nilfs_btree *btree,
- struct nilfs_btree_node *node, int index, __u64 ptr)
+static void
+nilfs_btree_node_set_ptr(struct nilfs_btree_node *node, int index, __u64 ptr,
+ int ncmax)
{
- *(nilfs_btree_node_dptrs(node, btree) + index) =
- nilfs_bmap_ptr_to_dptr(ptr);
+ *(nilfs_btree_node_dptrs(node, ncmax) + index) = cpu_to_le64(ptr);
}
-static void nilfs_btree_node_init(struct nilfs_btree *btree,
- struct nilfs_btree_node *node,
- int flags, int level, int nchildren,
+static void nilfs_btree_node_init(struct nilfs_btree_node *node, int flags,
+ int level, int nchildren, int ncmax,
const __u64 *keys, const __u64 *ptrs)
{
__le64 *dkeys;
@@ -223,29 +206,28 @@ static void nilfs_btree_node_init(struct nilfs_btree *btree,
nilfs_btree_node_set_nchildren(node, nchildren);
dkeys = nilfs_btree_node_dkeys(node);
- dptrs = nilfs_btree_node_dptrs(node, btree);
+ dptrs = nilfs_btree_node_dptrs(node, ncmax);
for (i = 0; i < nchildren; i++) {
- dkeys[i] = nilfs_bmap_key_to_dkey(keys[i]);
- dptrs[i] = nilfs_bmap_ptr_to_dptr(ptrs[i]);
+ dkeys[i] = cpu_to_le64(keys[i]);
+ dptrs[i] = cpu_to_le64(ptrs[i]);
}
}
/* Assume the buffer heads corresponding to left and right are locked. */
-static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
- struct nilfs_btree_node *left,
+static void nilfs_btree_node_move_left(struct nilfs_btree_node *left,
struct nilfs_btree_node *right,
- int n)
+ int n, int lncmax, int rncmax)
{
__le64 *ldkeys, *rdkeys;
__le64 *ldptrs, *rdptrs;
int lnchildren, rnchildren;
ldkeys = nilfs_btree_node_dkeys(left);
- ldptrs = nilfs_btree_node_dptrs(left, btree);
+ ldptrs = nilfs_btree_node_dptrs(left, lncmax);
lnchildren = nilfs_btree_node_get_nchildren(left);
rdkeys = nilfs_btree_node_dkeys(right);
- rdptrs = nilfs_btree_node_dptrs(right, btree);
+ rdptrs = nilfs_btree_node_dptrs(right, rncmax);
rnchildren = nilfs_btree_node_get_nchildren(right);
memcpy(ldkeys + lnchildren, rdkeys, n * sizeof(*rdkeys));
@@ -260,21 +242,20 @@ static void nilfs_btree_node_move_left(struct nilfs_btree *btree,
}
/* Assume that the buffer heads corresponding to left and right are locked. */
-static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
- struct nilfs_btree_node *left,
+static void nilfs_btree_node_move_right(struct nilfs_btree_node *left,
struct nilfs_btree_node *right,
- int n)
+ int n, int lncmax, int rncmax)
{
__le64 *ldkeys, *rdkeys;
__le64 *ldptrs, *rdptrs;
int lnchildren, rnchildren;
ldkeys = nilfs_btree_node_dkeys(left);
- ldptrs = nilfs_btree_node_dptrs(left, btree);
+ ldptrs = nilfs_btree_node_dptrs(left, lncmax);
lnchildren = nilfs_btree_node_get_nchildren(left);
rdkeys = nilfs_btree_node_dkeys(right);
- rdptrs = nilfs_btree_node_dptrs(right, btree);
+ rdptrs = nilfs_btree_node_dptrs(right, rncmax);
rnchildren = nilfs_btree_node_get_nchildren(right);
memmove(rdkeys + n, rdkeys, rnchildren * sizeof(*rdkeys));
@@ -289,16 +270,15 @@ static void nilfs_btree_node_move_right(struct nilfs_btree *btree,
}
/* Assume that the buffer head corresponding to node is locked. */
-static void nilfs_btree_node_insert(struct nilfs_btree *btree,
- struct nilfs_btree_node *node,
- __u64 key, __u64 ptr, int index)
+static void nilfs_btree_node_insert(struct nilfs_btree_node *node, int index,
+ __u64 key, __u64 ptr, int ncmax)
{
__le64 *dkeys;
__le64 *dptrs;
int nchildren;
dkeys = nilfs_btree_node_dkeys(node);
- dptrs = nilfs_btree_node_dptrs(node, btree);
+ dptrs = nilfs_btree_node_dptrs(node, ncmax);
nchildren = nilfs_btree_node_get_nchildren(node);
if (index < nchildren) {
memmove(dkeys + index + 1, dkeys + index,
@@ -306,16 +286,15 @@ static void nilfs_btree_node_insert(struct nilfs_btree *btree,
memmove(dptrs + index + 1, dptrs + index,
(nchildren - index) * sizeof(*dptrs));
}
- dkeys[index] = nilfs_bmap_key_to_dkey(key);
- dptrs[index] = nilfs_bmap_ptr_to_dptr(ptr);
+ dkeys[index] = cpu_to_le64(key);
+ dptrs[index] = cpu_to_le64(ptr);
nchildren++;
nilfs_btree_node_set_nchildren(node, nchildren);
}
/* Assume that the buffer head corresponding to node is locked. */
-static void nilfs_btree_node_delete(struct nilfs_btree *btree,
- struct nilfs_btree_node *node,
- __u64 *keyp, __u64 *ptrp, int index)
+static void nilfs_btree_node_delete(struct nilfs_btree_node *node, int index,
+ __u64 *keyp, __u64 *ptrp, int ncmax)
{
__u64 key;
__u64 ptr;
@@ -324,9 +303,9 @@ static void nilfs_btree_node_delete(struct nilfs_btree *btree,
int nchildren;
dkeys = nilfs_btree_node_dkeys(node);
- dptrs = nilfs_btree_node_dptrs(node, btree);
- key = nilfs_bmap_dkey_to_key(dkeys[index]);
- ptr = nilfs_bmap_dptr_to_ptr(dptrs[index]);
+ dptrs = nilfs_btree_node_dptrs(node, ncmax);
+ key = le64_to_cpu(dkeys[index]);
+ ptr = le64_to_cpu(dptrs[index]);
nchildren = nilfs_btree_node_get_nchildren(node);
if (keyp != NULL)
*keyp = key;
@@ -382,40 +361,84 @@ static int nilfs_btree_node_lookup(const struct nilfs_btree_node *node,
return s == 0;
}
-static inline struct nilfs_btree_node *
-nilfs_btree_get_root(const struct nilfs_btree *btree)
+/**
+ * nilfs_btree_node_broken - verify consistency of btree node
+ * @node: btree node block to be examined
+ * @size: node size (in bytes)
+ * @blocknr: block number
+ *
+ * Return Value: If node is broken, 1 is returned. Otherwise, 0 is returned.
+ */
+static int nilfs_btree_node_broken(const struct nilfs_btree_node *node,
+ size_t size, sector_t blocknr)
{
- return (struct nilfs_btree_node *)btree->bt_bmap.b_u.u_data;
+ int level, flags, nchildren;
+ int ret = 0;
+
+ level = nilfs_btree_node_get_level(node);
+ flags = nilfs_btree_node_get_flags(node);
+ nchildren = nilfs_btree_node_get_nchildren(node);
+
+ if (unlikely(level < NILFS_BTREE_LEVEL_NODE_MIN ||
+ level >= NILFS_BTREE_LEVEL_MAX ||
+ (flags & NILFS_BTREE_NODE_ROOT) ||
+ nchildren < 0 ||
+ nchildren > NILFS_BTREE_NODE_NCHILDREN_MAX(size))) {
+ printk(KERN_CRIT "NILFS: bad btree node (blocknr=%llu): "
+ "level = %d, flags = 0x%x, nchildren = %d\n",
+ (unsigned long long)blocknr, level, flags, nchildren);
+ ret = 1;
+ }
+ return ret;
+}
+
+int nilfs_btree_broken_node_block(struct buffer_head *bh)
+{
+ return nilfs_btree_node_broken((struct nilfs_btree_node *)bh->b_data,
+ bh->b_size, bh->b_blocknr);
}
-static inline struct nilfs_btree_node *
+static struct nilfs_btree_node *
+nilfs_btree_get_root(const struct nilfs_bmap *btree)
+{
+ return (struct nilfs_btree_node *)btree->b_u.u_data;
+}
+
+static struct nilfs_btree_node *
nilfs_btree_get_nonroot_node(const struct nilfs_btree_path *path, int level)
{
return (struct nilfs_btree_node *)path[level].bp_bh->b_data;
}
-static inline struct nilfs_btree_node *
+static struct nilfs_btree_node *
nilfs_btree_get_sib_node(const struct nilfs_btree_path *path, int level)
{
return (struct nilfs_btree_node *)path[level].bp_sib_bh->b_data;
}
-static inline int nilfs_btree_height(const struct nilfs_btree *btree)
+static int nilfs_btree_height(const struct nilfs_bmap *btree)
{
return nilfs_btree_node_get_level(nilfs_btree_get_root(btree)) + 1;
}
-static inline struct nilfs_btree_node *
-nilfs_btree_get_node(const struct nilfs_btree *btree,
+static struct nilfs_btree_node *
+nilfs_btree_get_node(const struct nilfs_bmap *btree,
const struct nilfs_btree_path *path,
- int level)
+ int level, int *ncmaxp)
{
- return (level == nilfs_btree_height(btree) - 1) ?
- nilfs_btree_get_root(btree) :
- nilfs_btree_get_nonroot_node(path, level);
+ struct nilfs_btree_node *node;
+
+ if (level == nilfs_btree_height(btree) - 1) {
+ node = nilfs_btree_get_root(btree);
+ *ncmaxp = NILFS_BTREE_ROOT_NCHILDREN_MAX;
+ } else {
+ node = nilfs_btree_get_nonroot_node(path, level);
+ *ncmaxp = nilfs_btree_nchildren_per_block(btree);
+ }
+ return node;
}
-static inline int
+static int
nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
{
if (unlikely(nilfs_btree_node_get_level(node) != level)) {
@@ -427,13 +450,13 @@ nilfs_btree_bad_node(struct nilfs_btree_node *node, int level)
return 0;
}
-static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
+static int nilfs_btree_do_lookup(const struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
__u64 key, __u64 *ptrp, int minlevel)
{
struct nilfs_btree_node *node;
__u64 ptr;
- int level, index, found, ret;
+ int level, index, found, ncmax, ret;
node = nilfs_btree_get_root(btree);
level = nilfs_btree_node_get_level(node);
@@ -441,10 +464,13 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
return -ENOENT;
found = nilfs_btree_node_lookup(node, key, &index);
- ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ ptr = nilfs_btree_node_get_ptr(node, index,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
path[level].bp_bh = NULL;
path[level].bp_index = index;
+ ncmax = nilfs_btree_nchildren_per_block(btree);
+
for (level--; level >= minlevel; level--) {
ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
if (ret < 0)
@@ -456,9 +482,9 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
found = nilfs_btree_node_lookup(node, key, &index);
else
index = 0;
- if (index < nilfs_btree_node_nchildren_max(node, btree))
- ptr = nilfs_btree_node_get_ptr(btree, node, index);
- else {
+ if (index < ncmax) {
+ ptr = nilfs_btree_node_get_ptr(node, index, ncmax);
+ } else {
WARN_ON(found || level != NILFS_BTREE_LEVEL_NODE_MIN);
/* insert */
ptr = NILFS_BMAP_INVALID_PTR;
@@ -474,22 +500,24 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
return 0;
}
-static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
+static int nilfs_btree_do_lookup_last(const struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
__u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node;
__u64 ptr;
- int index, level, ret;
+ int index, level, ncmax, ret;
node = nilfs_btree_get_root(btree);
index = nilfs_btree_node_get_nchildren(node) - 1;
if (index < 0)
return -ENOENT;
level = nilfs_btree_node_get_level(node);
- ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ ptr = nilfs_btree_node_get_ptr(node, index,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
path[level].bp_bh = NULL;
path[level].bp_index = index;
+ ncmax = nilfs_btree_nchildren_per_block(btree);
for (level--; level > 0; level--) {
ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
@@ -499,7 +527,7 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
if (nilfs_btree_bad_node(node, level))
return -EINVAL;
index = nilfs_btree_node_get_nchildren(node) - 1;
- ptr = nilfs_btree_node_get_ptr(btree, node, index);
+ ptr = nilfs_btree_node_get_ptr(node, index, ncmax);
path[level].bp_index = index;
}
@@ -511,40 +539,33 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
return 0;
}
-static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
+static int nilfs_btree_lookup(const struct nilfs_bmap *btree,
__u64 key, int level, __u64 *ptrp)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
- __u64 ptr;
int ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
- ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
-
- if (ptrp != NULL)
- *ptrp = ptr;
+ ret = nilfs_btree_do_lookup(btree, path, key, ptrp, level);
nilfs_btree_free_path(path);
return ret;
}
-static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
+static int nilfs_btree_lookup_contig(const struct nilfs_bmap *btree,
__u64 key, __u64 *ptrp, unsigned maxblocks)
{
- struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
struct nilfs_btree_path *path;
struct nilfs_btree_node *node;
struct inode *dat = NULL;
__u64 ptr, ptr2;
sector_t blocknr;
int level = NILFS_BTREE_LEVEL_NODE_MIN;
- int ret, cnt, index, maxlevel;
+ int ret, cnt, index, maxlevel, ncmax;
path = nilfs_btree_alloc_path();
if (path == NULL)
@@ -554,8 +575,8 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
if (ret < 0)
goto out;
- if (NILFS_BMAP_USE_VBN(bmap)) {
- dat = nilfs_bmap_get_dat(bmap);
+ if (NILFS_BMAP_USE_VBN(btree)) {
+ dat = nilfs_bmap_get_dat(btree);
ret = nilfs_dat_translate(dat, ptr, &blocknr);
if (ret < 0)
goto out;
@@ -566,14 +587,14 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
goto end;
maxlevel = nilfs_btree_height(btree) - 1;
- node = nilfs_btree_get_node(btree, path, level);
+ node = nilfs_btree_get_node(btree, path, level, &ncmax);
index = path[level].bp_index + 1;
for (;;) {
while (index < nilfs_btree_node_get_nchildren(node)) {
if (nilfs_btree_node_get_key(node, index) !=
key + cnt)
goto end;
- ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+ ptr2 = nilfs_btree_node_get_ptr(node, index, ncmax);
if (dat) {
ret = nilfs_dat_translate(dat, ptr2, &blocknr);
if (ret < 0)
@@ -589,12 +610,12 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
break;
/* look-up right sibling node */
- node = nilfs_btree_get_node(btree, path, level + 1);
+ node = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
index = path[level + 1].bp_index + 1;
if (index >= nilfs_btree_node_get_nchildren(node) ||
nilfs_btree_node_get_key(node, index) != key + cnt)
break;
- ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+ ptr2 = nilfs_btree_node_get_ptr(node, index, ncmax);
path[level + 1].bp_index = index;
brelse(path[level].bp_bh);
@@ -603,6 +624,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
if (ret < 0)
goto out;
node = nilfs_btree_get_nonroot_node(path, level);
+ ncmax = nilfs_btree_nchildren_per_block(btree);
index = 0;
path[level].bp_index = index;
}
@@ -614,7 +636,7 @@ static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
return ret;
}
-static void nilfs_btree_promote_key(struct nilfs_btree *btree,
+static void nilfs_btree_promote_key(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 key)
{
@@ -636,16 +658,18 @@ static void nilfs_btree_promote_key(struct nilfs_btree *btree,
}
}
-static void nilfs_btree_do_insert(struct nilfs_btree *btree,
+static void nilfs_btree_do_insert(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node;
+ int ncblk;
if (level < nilfs_btree_height(btree) - 1) {
node = nilfs_btree_get_nonroot_node(path, level);
- nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
- path[level].bp_index);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
+ nilfs_btree_node_insert(node, path[level].bp_index,
+ *keyp, *ptrp, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -655,22 +679,24 @@ static void nilfs_btree_do_insert(struct nilfs_btree *btree,
0));
} else {
node = nilfs_btree_get_root(btree);
- nilfs_btree_node_insert(btree, node, *keyp, *ptrp,
- path[level].bp_index);
+ nilfs_btree_node_insert(node, path[level].bp_index,
+ *keyp, *ptrp,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
}
}
-static void nilfs_btree_carry_left(struct nilfs_btree *btree,
+static void nilfs_btree_carry_left(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *left;
- int nchildren, lnchildren, n, move;
+ int nchildren, lnchildren, n, move, ncblk;
node = nilfs_btree_get_nonroot_node(path, level);
left = nilfs_btree_get_sib_node(path, level);
nchildren = nilfs_btree_node_get_nchildren(node);
lnchildren = nilfs_btree_node_get_nchildren(left);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
move = 0;
n = (nchildren + lnchildren + 1) / 2 - lnchildren;
@@ -680,7 +706,7 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
move = 1;
}
- nilfs_btree_node_move_left(btree, left, node, n);
+ nilfs_btree_node_move_left(left, node, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -705,17 +731,18 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
}
-static void nilfs_btree_carry_right(struct nilfs_btree *btree,
+static void nilfs_btree_carry_right(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *right;
- int nchildren, rnchildren, n, move;
+ int nchildren, rnchildren, n, move, ncblk;
node = nilfs_btree_get_nonroot_node(path, level);
right = nilfs_btree_get_sib_node(path, level);
nchildren = nilfs_btree_node_get_nchildren(node);
rnchildren = nilfs_btree_node_get_nchildren(right);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
move = 0;
n = (nchildren + rnchildren + 1) / 2 - rnchildren;
@@ -725,7 +752,7 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
move = 1;
}
- nilfs_btree_node_move_right(btree, node, right, n);
+ nilfs_btree_node_move_right(node, right, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -751,18 +778,19 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
nilfs_btree_do_insert(btree, path, level, keyp, ptrp);
}
-static void nilfs_btree_split(struct nilfs_btree *btree,
+static void nilfs_btree_split(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *right;
__u64 newkey;
__u64 newptr;
- int nchildren, n, move;
+ int nchildren, n, move, ncblk;
node = nilfs_btree_get_nonroot_node(path, level);
right = nilfs_btree_get_sib_node(path, level);
nchildren = nilfs_btree_node_get_nchildren(node);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
move = 0;
n = (nchildren + 1) / 2;
@@ -771,7 +799,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
move = 1;
}
- nilfs_btree_node_move_right(btree, node, right, n);
+ nilfs_btree_node_move_right(node, right, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -783,8 +811,8 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
if (move) {
path[level].bp_index -= nilfs_btree_node_get_nchildren(node);
- nilfs_btree_node_insert(btree, right, *keyp, *ptrp,
- path[level].bp_index);
+ nilfs_btree_node_insert(right, path[level].bp_index,
+ *keyp, *ptrp, ncblk);
*keyp = nilfs_btree_node_get_key(right, 0);
*ptrp = path[level].bp_newreq.bpr_ptr;
@@ -805,19 +833,21 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
path[level + 1].bp_index++;
}
-static void nilfs_btree_grow(struct nilfs_btree *btree,
+static void nilfs_btree_grow(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *root, *child;
- int n;
+ int n, ncblk;
root = nilfs_btree_get_root(btree);
child = nilfs_btree_get_sib_node(path, level);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
n = nilfs_btree_node_get_nchildren(root);
- nilfs_btree_node_move_right(btree, root, child, n);
+ nilfs_btree_node_move_right(root, child, n,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX, ncblk);
nilfs_btree_node_set_level(root, level + 1);
if (!buffer_dirty(path[level].bp_sib_bh))
@@ -832,11 +862,11 @@ static void nilfs_btree_grow(struct nilfs_btree *btree,
*ptrp = path[level].bp_newreq.bpr_ptr;
}
-static __u64 nilfs_btree_find_near(const struct nilfs_btree *btree,
+static __u64 nilfs_btree_find_near(const struct nilfs_bmap *btree,
const struct nilfs_btree_path *path)
{
struct nilfs_btree_node *node;
- int level;
+ int level, ncmax;
if (path == NULL)
return NILFS_BMAP_INVALID_PTR;
@@ -844,29 +874,30 @@ static __u64 nilfs_btree_find_near(const struct nilfs_btree *btree,
/* left sibling */
level = NILFS_BTREE_LEVEL_NODE_MIN;
if (path[level].bp_index > 0) {
- node = nilfs_btree_get_node(btree, path, level);
- return nilfs_btree_node_get_ptr(btree, node,
- path[level].bp_index - 1);
+ node = nilfs_btree_get_node(btree, path, level, &ncmax);
+ return nilfs_btree_node_get_ptr(node,
+ path[level].bp_index - 1,
+ ncmax);
}
/* parent */
level = NILFS_BTREE_LEVEL_NODE_MIN + 1;
if (level <= nilfs_btree_height(btree) - 1) {
- node = nilfs_btree_get_node(btree, path, level);
- return nilfs_btree_node_get_ptr(btree, node,
- path[level].bp_index);
+ node = nilfs_btree_get_node(btree, path, level, &ncmax);
+ return nilfs_btree_node_get_ptr(node, path[level].bp_index,
+ ncmax);
}
return NILFS_BMAP_INVALID_PTR;
}
-static __u64 nilfs_btree_find_target_v(const struct nilfs_btree *btree,
+static __u64 nilfs_btree_find_target_v(const struct nilfs_bmap *btree,
const struct nilfs_btree_path *path,
__u64 key)
{
__u64 ptr;
- ptr = nilfs_bmap_find_target_seq(&btree->bt_bmap, key);
+ ptr = nilfs_bmap_find_target_seq(btree, key);
if (ptr != NILFS_BMAP_INVALID_PTR)
/* sequential access */
return ptr;
@@ -877,17 +908,10 @@ static __u64 nilfs_btree_find_target_v(const struct nilfs_btree *btree,
return ptr;
}
/* block group */
- return nilfs_bmap_find_target_in_group(&btree->bt_bmap);
+ return nilfs_bmap_find_target_in_group(btree);
}
-static void nilfs_btree_set_target_v(struct nilfs_btree *btree, __u64 key,
- __u64 ptr)
-{
- btree->bt_bmap.b_last_allocated_key = key;
- btree->bt_bmap.b_last_allocated_ptr = ptr;
-}
-
-static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
+static int nilfs_btree_prepare_insert(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int *levelp, __u64 key, __u64 ptr,
struct nilfs_bmap_stats *stats)
@@ -895,79 +919,78 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
struct buffer_head *bh;
struct nilfs_btree_node *node, *parent, *sib;
__u64 sibptr;
- int pindex, level, ret;
+ int pindex, level, ncmax, ncblk, ret;
struct inode *dat = NULL;
stats->bs_nblocks = 0;
level = NILFS_BTREE_LEVEL_DATA;
/* allocate a new ptr for data block */
- if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
+ if (NILFS_BMAP_USE_VBN(btree)) {
path[level].bp_newreq.bpr_ptr =
nilfs_btree_find_target_v(btree, path, key);
- dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+ dat = nilfs_bmap_get_dat(btree);
}
- ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
- &path[level].bp_newreq, dat);
+ ret = nilfs_bmap_prepare_alloc_ptr(btree, &path[level].bp_newreq, dat);
if (ret < 0)
goto err_out_data;
+ ncblk = nilfs_btree_nchildren_per_block(btree);
+
for (level = NILFS_BTREE_LEVEL_NODE_MIN;
level < nilfs_btree_height(btree) - 1;
level++) {
node = nilfs_btree_get_nonroot_node(path, level);
- if (nilfs_btree_node_get_nchildren(node) <
- nilfs_btree_node_nchildren_max(node, btree)) {
+ if (nilfs_btree_node_get_nchildren(node) < ncblk) {
path[level].bp_op = nilfs_btree_do_insert;
stats->bs_nblocks++;
goto out;
}
- parent = nilfs_btree_get_node(btree, path, level + 1);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
pindex = path[level + 1].bp_index;
/* left sibling */
if (pindex > 0) {
- sibptr = nilfs_btree_node_get_ptr(btree, parent,
- pindex - 1);
+ sibptr = nilfs_btree_node_get_ptr(parent, pindex - 1,
+ ncmax);
ret = nilfs_btree_get_block(btree, sibptr, &bh);
if (ret < 0)
goto err_out_child_node;
sib = (struct nilfs_btree_node *)bh->b_data;
- if (nilfs_btree_node_get_nchildren(sib) <
- nilfs_btree_node_nchildren_max(sib, btree)) {
+ if (nilfs_btree_node_get_nchildren(sib) < ncblk) {
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_carry_left;
stats->bs_nblocks++;
goto out;
- } else
+ } else {
brelse(bh);
+ }
}
/* right sibling */
- if (pindex <
- nilfs_btree_node_get_nchildren(parent) - 1) {
- sibptr = nilfs_btree_node_get_ptr(btree, parent,
- pindex + 1);
+ if (pindex < nilfs_btree_node_get_nchildren(parent) - 1) {
+ sibptr = nilfs_btree_node_get_ptr(parent, pindex + 1,
+ ncmax);
ret = nilfs_btree_get_block(btree, sibptr, &bh);
if (ret < 0)
goto err_out_child_node;
sib = (struct nilfs_btree_node *)bh->b_data;
- if (nilfs_btree_node_get_nchildren(sib) <
- nilfs_btree_node_nchildren_max(sib, btree)) {
+ if (nilfs_btree_node_get_nchildren(sib) < ncblk) {
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_carry_right;
stats->bs_nblocks++;
goto out;
- } else
+ } else {
brelse(bh);
+ }
}
/* split */
path[level].bp_newreq.bpr_ptr =
path[level - 1].bp_newreq.bpr_ptr + 1;
- ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+ ret = nilfs_bmap_prepare_alloc_ptr(btree,
&path[level].bp_newreq, dat);
if (ret < 0)
goto err_out_child_node;
@@ -979,9 +1002,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
stats->bs_nblocks++;
- nilfs_btree_node_init(btree,
- (struct nilfs_btree_node *)bh->b_data,
- 0, level, 0, NULL, NULL);
+ sib = (struct nilfs_btree_node *)bh->b_data;
+ nilfs_btree_node_init(sib, 0, level, 0, ncblk, NULL, NULL);
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_split;
}
@@ -989,7 +1011,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
/* root */
node = nilfs_btree_get_root(btree);
if (nilfs_btree_node_get_nchildren(node) <
- nilfs_btree_node_nchildren_max(node, btree)) {
+ NILFS_BTREE_ROOT_NCHILDREN_MAX) {
path[level].bp_op = nilfs_btree_do_insert;
stats->bs_nblocks++;
goto out;
@@ -997,8 +1019,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
/* grow */
path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
- ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
- &path[level].bp_newreq, dat);
+ ret = nilfs_bmap_prepare_alloc_ptr(btree, &path[level].bp_newreq, dat);
if (ret < 0)
goto err_out_child_node;
ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr,
@@ -1006,8 +1027,8 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
if (ret < 0)
goto err_out_curr_node;
- nilfs_btree_node_init(btree, (struct nilfs_btree_node *)bh->b_data,
- 0, level, 0, NULL, NULL);
+ nilfs_btree_node_init((struct nilfs_btree_node *)bh->b_data,
+ 0, level, 0, ncblk, NULL, NULL);
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_grow;
@@ -1024,25 +1045,22 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
/* error */
err_out_curr_node:
- nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
- dat);
+ nilfs_bmap_abort_alloc_ptr(btree, &path[level].bp_newreq, dat);
err_out_child_node:
for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
nilfs_btnode_delete(path[level].bp_sib_bh);
- nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap,
- &path[level].bp_newreq, dat);
+ nilfs_bmap_abort_alloc_ptr(btree, &path[level].bp_newreq, dat);
}
- nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq,
- dat);
+ nilfs_bmap_abort_alloc_ptr(btree, &path[level].bp_newreq, dat);
err_out_data:
*levelp = level;
stats->bs_nblocks = 0;
return ret;
}
-static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
+static void nilfs_btree_commit_insert(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int maxlevel, __u64 key, __u64 ptr)
{
@@ -1051,29 +1069,27 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
- if (NILFS_BMAP_USE_VBN(&btree->bt_bmap)) {
- nilfs_btree_set_target_v(btree, key, ptr);
- dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+ if (NILFS_BMAP_USE_VBN(btree)) {
+ nilfs_bmap_set_target_v(btree, key, ptr);
+ dat = nilfs_bmap_get_dat(btree);
}
for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
- nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap,
+ nilfs_bmap_commit_alloc_ptr(btree,
&path[level - 1].bp_newreq, dat);
path[level].bp_op(btree, path, level, &key, &ptr);
}
- if (!nilfs_bmap_dirty(&btree->bt_bmap))
- nilfs_bmap_set_dirty(&btree->bt_bmap);
+ if (!nilfs_bmap_dirty(btree))
+ nilfs_bmap_set_dirty(btree);
}
-static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
+static int nilfs_btree_insert(struct nilfs_bmap *btree, __u64 key, __u64 ptr)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
struct nilfs_bmap_stats stats;
int level, ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -1090,23 +1106,25 @@ static int nilfs_btree_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
if (ret < 0)
goto out;
nilfs_btree_commit_insert(btree, path, level, key, ptr);
- nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+ nilfs_bmap_add_blocks(btree, stats.bs_nblocks);
out:
nilfs_btree_free_path(path);
return ret;
}
-static void nilfs_btree_do_delete(struct nilfs_btree *btree,
+static void nilfs_btree_do_delete(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node;
+ int ncblk;
if (level < nilfs_btree_height(btree) - 1) {
node = nilfs_btree_get_nonroot_node(path, level);
- nilfs_btree_node_delete(btree, node, keyp, ptrp,
- path[level].bp_index);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
+ nilfs_btree_node_delete(node, path[level].bp_index,
+ keyp, ptrp, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
if (path[level].bp_index == 0)
@@ -1114,17 +1132,18 @@ static void nilfs_btree_do_delete(struct nilfs_btree *btree,
nilfs_btree_node_get_key(node, 0));
} else {
node = nilfs_btree_get_root(btree);
- nilfs_btree_node_delete(btree, node, keyp, ptrp,
- path[level].bp_index);
+ nilfs_btree_node_delete(node, path[level].bp_index,
+ keyp, ptrp,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
}
}
-static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
+static void nilfs_btree_borrow_left(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *left;
- int nchildren, lnchildren, n;
+ int nchildren, lnchildren, n, ncblk;
nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
@@ -1132,10 +1151,11 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
left = nilfs_btree_get_sib_node(path, level);
nchildren = nilfs_btree_node_get_nchildren(node);
lnchildren = nilfs_btree_node_get_nchildren(left);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
n = (nchildren + lnchildren) / 2 - nchildren;
- nilfs_btree_node_move_right(btree, left, node, n);
+ nilfs_btree_node_move_right(left, node, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -1150,12 +1170,12 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
path[level].bp_index += n;
}
-static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
+static void nilfs_btree_borrow_right(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *right;
- int nchildren, rnchildren, n;
+ int nchildren, rnchildren, n, ncblk;
nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
@@ -1163,10 +1183,11 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
right = nilfs_btree_get_sib_node(path, level);
nchildren = nilfs_btree_node_get_nchildren(node);
rnchildren = nilfs_btree_node_get_nchildren(right);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
n = (nchildren + rnchildren) / 2 - nchildren;
- nilfs_btree_node_move_left(btree, node, right, n);
+ nilfs_btree_node_move_left(node, right, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -1182,21 +1203,22 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
path[level].bp_sib_bh = NULL;
}
-static void nilfs_btree_concat_left(struct nilfs_btree *btree,
+static void nilfs_btree_concat_left(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *left;
- int n;
+ int n, ncblk;
nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
node = nilfs_btree_get_nonroot_node(path, level);
left = nilfs_btree_get_sib_node(path, level);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
n = nilfs_btree_node_get_nchildren(node);
- nilfs_btree_node_move_left(btree, left, node, n);
+ nilfs_btree_node_move_left(left, node, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_sib_bh))
nilfs_btnode_mark_dirty(path[level].bp_sib_bh);
@@ -1207,21 +1229,22 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
path[level].bp_index += nilfs_btree_node_get_nchildren(left);
}
-static void nilfs_btree_concat_right(struct nilfs_btree *btree,
+static void nilfs_btree_concat_right(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *node, *right;
- int n;
+ int n, ncblk;
nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
node = nilfs_btree_get_nonroot_node(path, level);
right = nilfs_btree_get_sib_node(path, level);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
n = nilfs_btree_node_get_nchildren(right);
- nilfs_btree_node_move_left(btree, node, right, n);
+ nilfs_btree_node_move_left(node, right, n, ncblk, ncblk);
if (!buffer_dirty(path[level].bp_bh))
nilfs_btnode_mark_dirty(path[level].bp_bh);
@@ -1231,29 +1254,32 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
path[level + 1].bp_index++;
}
-static void nilfs_btree_shrink(struct nilfs_btree *btree,
+static void nilfs_btree_shrink(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, __u64 *keyp, __u64 *ptrp)
{
struct nilfs_btree_node *root, *child;
- int n;
+ int n, ncblk;
nilfs_btree_do_delete(btree, path, level, keyp, ptrp);
root = nilfs_btree_get_root(btree);
child = nilfs_btree_get_nonroot_node(path, level);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
- nilfs_btree_node_delete(btree, root, NULL, NULL, 0);
+ nilfs_btree_node_delete(root, 0, NULL, NULL,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
nilfs_btree_node_set_level(root, level);
n = nilfs_btree_node_get_nchildren(child);
- nilfs_btree_node_move_left(btree, root, child, n);
+ nilfs_btree_node_move_left(root, child, n,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX, ncblk);
nilfs_btnode_delete(path[level].bp_bh);
path[level].bp_bh = NULL;
}
-static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
+static int nilfs_btree_prepare_delete(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int *levelp,
struct nilfs_bmap_stats *stats,
@@ -1262,42 +1288,43 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
struct buffer_head *bh;
struct nilfs_btree_node *node, *parent, *sib;
__u64 sibptr;
- int pindex, level, ret;
+ int pindex, level, ncmin, ncmax, ncblk, ret;
ret = 0;
stats->bs_nblocks = 0;
+ ncmin = NILFS_BTREE_NODE_NCHILDREN_MIN(nilfs_btree_node_size(btree));
+ ncblk = nilfs_btree_nchildren_per_block(btree);
+
for (level = NILFS_BTREE_LEVEL_NODE_MIN;
level < nilfs_btree_height(btree) - 1;
level++) {
node = nilfs_btree_get_nonroot_node(path, level);
path[level].bp_oldreq.bpr_ptr =
- nilfs_btree_node_get_ptr(btree, node,
- path[level].bp_index);
- ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
+ nilfs_btree_node_get_ptr(node, path[level].bp_index,
+ ncblk);
+ ret = nilfs_bmap_prepare_end_ptr(btree,
&path[level].bp_oldreq, dat);
if (ret < 0)
goto err_out_child_node;
- if (nilfs_btree_node_get_nchildren(node) >
- nilfs_btree_node_nchildren_min(node, btree)) {
+ if (nilfs_btree_node_get_nchildren(node) > ncmin) {
path[level].bp_op = nilfs_btree_do_delete;
stats->bs_nblocks++;
goto out;
}
- parent = nilfs_btree_get_node(btree, path, level + 1);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
pindex = path[level + 1].bp_index;
if (pindex > 0) {
/* left sibling */
- sibptr = nilfs_btree_node_get_ptr(btree, parent,
- pindex - 1);
+ sibptr = nilfs_btree_node_get_ptr(parent, pindex - 1,
+ ncmax);
ret = nilfs_btree_get_block(btree, sibptr, &bh);
if (ret < 0)
goto err_out_curr_node;
sib = (struct nilfs_btree_node *)bh->b_data;
- if (nilfs_btree_node_get_nchildren(sib) >
- nilfs_btree_node_nchildren_min(sib, btree)) {
+ if (nilfs_btree_node_get_nchildren(sib) > ncmin) {
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_borrow_left;
stats->bs_nblocks++;
@@ -1311,14 +1338,13 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
} else if (pindex <
nilfs_btree_node_get_nchildren(parent) - 1) {
/* right sibling */
- sibptr = nilfs_btree_node_get_ptr(btree, parent,
- pindex + 1);
+ sibptr = nilfs_btree_node_get_ptr(parent, pindex + 1,
+ ncmax);
ret = nilfs_btree_get_block(btree, sibptr, &bh);
if (ret < 0)
goto err_out_curr_node;
sib = (struct nilfs_btree_node *)bh->b_data;
- if (nilfs_btree_node_get_nchildren(sib) >
- nilfs_btree_node_nchildren_min(sib, btree)) {
+ if (nilfs_btree_node_get_nchildren(sib) > ncmin) {
path[level].bp_sib_bh = bh;
path[level].bp_op = nilfs_btree_borrow_right;
stats->bs_nblocks++;
@@ -1349,10 +1375,10 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
node = nilfs_btree_get_root(btree);
path[level].bp_oldreq.bpr_ptr =
- nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
+ nilfs_btree_node_get_ptr(node, path[level].bp_index,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
- ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
- &path[level].bp_oldreq, dat);
+ ret = nilfs_bmap_prepare_end_ptr(btree, &path[level].bp_oldreq, dat);
if (ret < 0)
goto err_out_child_node;
@@ -1367,44 +1393,40 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
/* error */
err_out_curr_node:
- nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq, dat);
+ nilfs_bmap_abort_end_ptr(btree, &path[level].bp_oldreq, dat);
err_out_child_node:
for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
brelse(path[level].bp_sib_bh);
- nilfs_bmap_abort_end_ptr(&btree->bt_bmap,
- &path[level].bp_oldreq, dat);
+ nilfs_bmap_abort_end_ptr(btree, &path[level].bp_oldreq, dat);
}
*levelp = level;
stats->bs_nblocks = 0;
return ret;
}
-static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
+static void nilfs_btree_commit_delete(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int maxlevel, struct inode *dat)
{
int level;
for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
- nilfs_bmap_commit_end_ptr(&btree->bt_bmap,
- &path[level].bp_oldreq, dat);
+ nilfs_bmap_commit_end_ptr(btree, &path[level].bp_oldreq, dat);
path[level].bp_op(btree, path, level, NULL, NULL);
}
- if (!nilfs_bmap_dirty(&btree->bt_bmap))
- nilfs_bmap_set_dirty(&btree->bt_bmap);
+ if (!nilfs_bmap_dirty(btree))
+ nilfs_bmap_set_dirty(btree);
}
-static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
+static int nilfs_btree_delete(struct nilfs_bmap *btree, __u64 key)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
struct nilfs_bmap_stats stats;
struct inode *dat;
int level, ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -1415,27 +1437,24 @@ static int nilfs_btree_delete(struct nilfs_bmap *bmap, __u64 key)
goto out;
- dat = NILFS_BMAP_USE_VBN(&btree->bt_bmap) ?
- nilfs_bmap_get_dat(&btree->bt_bmap) : NULL;
+ dat = NILFS_BMAP_USE_VBN(btree) ? nilfs_bmap_get_dat(btree) : NULL;
ret = nilfs_btree_prepare_delete(btree, path, &level, &stats, dat);
if (ret < 0)
goto out;
nilfs_btree_commit_delete(btree, path, level, dat);
- nilfs_bmap_sub_blocks(bmap, stats.bs_nblocks);
+ nilfs_bmap_sub_blocks(btree, stats.bs_nblocks);
out:
nilfs_btree_free_path(path);
return ret;
}
-static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
+static int nilfs_btree_last_key(const struct nilfs_bmap *btree, __u64 *keyp)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
int ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -1447,16 +1466,14 @@ static int nilfs_btree_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
return ret;
}
-static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
+static int nilfs_btree_check_delete(struct nilfs_bmap *btree, __u64 key)
{
struct buffer_head *bh;
- struct nilfs_btree *btree;
struct nilfs_btree_node *root, *node;
__u64 maxkey, nextmaxkey;
__u64 ptr;
int nchildren, ret;
- btree = (struct nilfs_btree *)bmap;
root = nilfs_btree_get_root(btree);
switch (nilfs_btree_height(btree)) {
case 2:
@@ -1467,7 +1484,8 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
nchildren = nilfs_btree_node_get_nchildren(root);
if (nchildren > 1)
return 0;
- ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
+ ptr = nilfs_btree_node_get_ptr(root, nchildren - 1,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
ret = nilfs_btree_get_block(btree, ptr, &bh);
if (ret < 0)
return ret;
@@ -1487,32 +1505,33 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
return (maxkey == key) && (nextmaxkey < NILFS_BMAP_LARGE_LOW);
}
-static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
+static int nilfs_btree_gather_data(struct nilfs_bmap *btree,
__u64 *keys, __u64 *ptrs, int nitems)
{
struct buffer_head *bh;
- struct nilfs_btree *btree;
struct nilfs_btree_node *node, *root;
__le64 *dkeys;
__le64 *dptrs;
__u64 ptr;
- int nchildren, i, ret;
+ int nchildren, ncmax, i, ret;
- btree = (struct nilfs_btree *)bmap;
root = nilfs_btree_get_root(btree);
switch (nilfs_btree_height(btree)) {
case 2:
bh = NULL;
node = root;
+ ncmax = NILFS_BTREE_ROOT_NCHILDREN_MAX;
break;
case 3:
nchildren = nilfs_btree_node_get_nchildren(root);
WARN_ON(nchildren > 1);
- ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
+ ptr = nilfs_btree_node_get_ptr(root, nchildren - 1,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
ret = nilfs_btree_get_block(btree, ptr, &bh);
if (ret < 0)
return ret;
node = (struct nilfs_btree_node *)bh->b_data;
+ ncmax = nilfs_btree_nchildren_per_block(btree);
break;
default:
node = NULL;
@@ -1523,10 +1542,10 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
if (nchildren < nitems)
nitems = nchildren;
dkeys = nilfs_btree_node_dkeys(node);
- dptrs = nilfs_btree_node_dptrs(node, btree);
+ dptrs = nilfs_btree_node_dptrs(node, ncmax);
for (i = 0; i < nitems; i++) {
- keys[i] = nilfs_bmap_dkey_to_key(dkeys[i]);
- ptrs[i] = nilfs_bmap_dptr_to_ptr(dptrs[i]);
+ keys[i] = le64_to_cpu(dkeys[i]);
+ ptrs[i] = le64_to_cpu(dptrs[i]);
}
if (bh != NULL)
@@ -1536,14 +1555,13 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
}
static int
-nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
+nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *btree, __u64 key,
union nilfs_bmap_ptr_req *dreq,
union nilfs_bmap_ptr_req *nreq,
struct buffer_head **bhp,
struct nilfs_bmap_stats *stats)
{
struct buffer_head *bh;
- struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
struct inode *dat = NULL;
int ret;
@@ -1551,12 +1569,12 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
/* for data */
/* cannot find near ptr */
- if (NILFS_BMAP_USE_VBN(bmap)) {
+ if (NILFS_BMAP_USE_VBN(btree)) {
dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key);
- dat = nilfs_bmap_get_dat(bmap);
+ dat = nilfs_bmap_get_dat(btree);
}
- ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq, dat);
+ ret = nilfs_bmap_prepare_alloc_ptr(btree, dreq, dat);
if (ret < 0)
return ret;
@@ -1564,7 +1582,7 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
stats->bs_nblocks++;
if (nreq != NULL) {
nreq->bpr_ptr = dreq->bpr_ptr + 1;
- ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq, dat);
+ ret = nilfs_bmap_prepare_alloc_ptr(btree, nreq, dat);
if (ret < 0)
goto err_out_dreq;
@@ -1581,16 +1599,16 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
/* error */
err_out_nreq:
- nilfs_bmap_abort_alloc_ptr(bmap, nreq, dat);
+ nilfs_bmap_abort_alloc_ptr(btree, nreq, dat);
err_out_dreq:
- nilfs_bmap_abort_alloc_ptr(bmap, dreq, dat);
+ nilfs_bmap_abort_alloc_ptr(btree, dreq, dat);
stats->bs_nblocks = 0;
return ret;
}
static void
-nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
+nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *btree,
__u64 key, __u64 ptr,
const __u64 *keys, const __u64 *ptrs,
int n,
@@ -1598,57 +1616,59 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
union nilfs_bmap_ptr_req *nreq,
struct buffer_head *bh)
{
- struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
struct nilfs_btree_node *node;
struct inode *dat;
__u64 tmpptr;
+ int ncblk;
/* free resources */
- if (bmap->b_ops->bop_clear != NULL)
- bmap->b_ops->bop_clear(bmap);
+ if (btree->b_ops->bop_clear != NULL)
+ btree->b_ops->bop_clear(btree);
/* ptr must be a pointer to a buffer head. */
set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
/* convert and insert */
- dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
- nilfs_btree_init(bmap);
+ dat = NILFS_BMAP_USE_VBN(btree) ? nilfs_bmap_get_dat(btree) : NULL;
+ nilfs_btree_init(btree);
if (nreq != NULL) {
- nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
- nilfs_bmap_commit_alloc_ptr(bmap, nreq, dat);
+ nilfs_bmap_commit_alloc_ptr(btree, dreq, dat);
+ nilfs_bmap_commit_alloc_ptr(btree, nreq, dat);
/* create child node at level 1 */
node = (struct nilfs_btree_node *)bh->b_data;
- nilfs_btree_node_init(btree, node, 0, 1, n, keys, ptrs);
- nilfs_btree_node_insert(btree, node,
- key, dreq->bpr_ptr, n);
+ ncblk = nilfs_btree_nchildren_per_block(btree);
+ nilfs_btree_node_init(node, 0, 1, n, ncblk, keys, ptrs);
+ nilfs_btree_node_insert(node, n, key, dreq->bpr_ptr, ncblk);
if (!buffer_dirty(bh))
nilfs_btnode_mark_dirty(bh);
- if (!nilfs_bmap_dirty(bmap))
- nilfs_bmap_set_dirty(bmap);
+ if (!nilfs_bmap_dirty(btree))
+ nilfs_bmap_set_dirty(btree);
brelse(bh);
/* create root node at level 2 */
node = nilfs_btree_get_root(btree);
tmpptr = nreq->bpr_ptr;
- nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
- 2, 1, &keys[0], &tmpptr);
+ nilfs_btree_node_init(node, NILFS_BTREE_NODE_ROOT, 2, 1,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX,
+ &keys[0], &tmpptr);
} else {
- nilfs_bmap_commit_alloc_ptr(bmap, dreq, dat);
+ nilfs_bmap_commit_alloc_ptr(btree, dreq, dat);
/* create root node at level 1 */
node = nilfs_btree_get_root(btree);
- nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
- 1, n, keys, ptrs);
- nilfs_btree_node_insert(btree, node,
- key, dreq->bpr_ptr, n);
- if (!nilfs_bmap_dirty(bmap))
- nilfs_bmap_set_dirty(bmap);
+ nilfs_btree_node_init(node, NILFS_BTREE_NODE_ROOT, 1, n,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX,
+ keys, ptrs);
+ nilfs_btree_node_insert(node, n, key, dreq->bpr_ptr,
+ NILFS_BTREE_ROOT_NCHILDREN_MAX);
+ if (!nilfs_bmap_dirty(btree))
+ nilfs_bmap_set_dirty(btree);
}
- if (NILFS_BMAP_USE_VBN(bmap))
- nilfs_btree_set_target_v(btree, key, dreq->bpr_ptr);
+ if (NILFS_BMAP_USE_VBN(btree))
+ nilfs_bmap_set_target_v(btree, key, dreq->bpr_ptr);
}
/**
@@ -1660,7 +1680,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
* @ptrs:
* @n:
*/
-int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
+int nilfs_btree_convert_and_insert(struct nilfs_bmap *btree,
__u64 key, __u64 ptr,
const __u64 *keys, const __u64 *ptrs, int n)
{
@@ -1673,7 +1693,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
di = &dreq;
ni = NULL;
} else if ((n + 1) <= NILFS_BTREE_NODE_NCHILDREN_MAX(
- 1 << bmap->b_inode->i_blkbits)) {
+ 1 << btree->b_inode->i_blkbits)) {
di = &dreq;
ni = &nreq;
} else {
@@ -1682,17 +1702,17 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
BUG();
}
- ret = nilfs_btree_prepare_convert_and_insert(bmap, key, di, ni, &bh,
+ ret = nilfs_btree_prepare_convert_and_insert(btree, key, di, ni, &bh,
&stats);
if (ret < 0)
return ret;
- nilfs_btree_commit_convert_and_insert(bmap, key, ptr, keys, ptrs, n,
+ nilfs_btree_commit_convert_and_insert(btree, key, ptr, keys, ptrs, n,
di, ni, bh);
- nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
+ nilfs_bmap_add_blocks(btree, stats.bs_nblocks);
return 0;
}
-static int nilfs_btree_propagate_p(struct nilfs_btree *btree,
+static int nilfs_btree_propagate_p(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level,
struct buffer_head *bh)
@@ -1704,17 +1724,17 @@ static int nilfs_btree_propagate_p(struct nilfs_btree *btree,
return 0;
}
-static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
+static int nilfs_btree_prepare_update_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, struct inode *dat)
{
struct nilfs_btree_node *parent;
- int ret;
+ int ncmax, ret;
- parent = nilfs_btree_get_node(btree, path, level + 1);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
path[level].bp_oldreq.bpr_ptr =
- nilfs_btree_node_get_ptr(btree, parent,
- path[level + 1].bp_index);
+ nilfs_btree_node_get_ptr(parent, path[level + 1].bp_index,
+ ncmax);
path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
ret = nilfs_dat_prepare_update(dat, &path[level].bp_oldreq.bpr_req,
&path[level].bp_newreq.bpr_req);
@@ -1726,7 +1746,7 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
path[level].bp_ctxt.newkey = path[level].bp_newreq.bpr_ptr;
path[level].bp_ctxt.bh = path[level].bp_bh;
ret = nilfs_btnode_prepare_change_key(
- &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &NILFS_BMAP_I(btree)->i_btnode_cache,
&path[level].bp_ctxt);
if (ret < 0) {
nilfs_dat_abort_update(dat,
@@ -1739,30 +1759,31 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
return 0;
}
-static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
+static void nilfs_btree_commit_update_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, struct inode *dat)
{
struct nilfs_btree_node *parent;
+ int ncmax;
nilfs_dat_commit_update(dat, &path[level].bp_oldreq.bpr_req,
&path[level].bp_newreq.bpr_req,
- btree->bt_bmap.b_ptr_type == NILFS_BMAP_PTR_VS);
+ btree->b_ptr_type == NILFS_BMAP_PTR_VS);
if (buffer_nilfs_node(path[level].bp_bh)) {
nilfs_btnode_commit_change_key(
- &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &NILFS_BMAP_I(btree)->i_btnode_cache,
&path[level].bp_ctxt);
path[level].bp_bh = path[level].bp_ctxt.bh;
}
set_buffer_nilfs_volatile(path[level].bp_bh);
- parent = nilfs_btree_get_node(btree, path, level + 1);
- nilfs_btree_node_set_ptr(btree, parent, path[level + 1].bp_index,
- path[level].bp_newreq.bpr_ptr);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
+ nilfs_btree_node_set_ptr(parent, path[level + 1].bp_index,
+ path[level].bp_newreq.bpr_ptr, ncmax);
}
-static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
+static void nilfs_btree_abort_update_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, struct inode *dat)
{
@@ -1770,11 +1791,11 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
&path[level].bp_newreq.bpr_req);
if (buffer_nilfs_node(path[level].bp_bh))
nilfs_btnode_abort_change_key(
- &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &NILFS_BMAP_I(btree)->i_btnode_cache,
&path[level].bp_ctxt);
}
-static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
+static int nilfs_btree_prepare_propagate_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int minlevel, int *maxlevelp,
struct inode *dat)
@@ -1809,7 +1830,7 @@ static int nilfs_btree_prepare_propagate_v(struct nilfs_btree *btree,
return ret;
}
-static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree,
+static void nilfs_btree_commit_propagate_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int minlevel, int maxlevel,
struct buffer_head *bh,
@@ -1824,14 +1845,15 @@ static void nilfs_btree_commit_propagate_v(struct nilfs_btree *btree,
nilfs_btree_commit_update_v(btree, path, level, dat);
}
-static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
+static int nilfs_btree_propagate_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level, struct buffer_head *bh)
{
int maxlevel = 0, ret;
struct nilfs_btree_node *parent;
- struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+ struct inode *dat = nilfs_bmap_get_dat(btree);
__u64 ptr;
+ int ncmax;
get_bh(bh);
path[level].bp_bh = bh;
@@ -1841,9 +1863,10 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
goto out;
if (buffer_nilfs_volatile(path[level].bp_bh)) {
- parent = nilfs_btree_get_node(btree, path, level + 1);
- ptr = nilfs_btree_node_get_ptr(btree, parent,
- path[level + 1].bp_index);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
+ ptr = nilfs_btree_node_get_ptr(parent,
+ path[level + 1].bp_index,
+ ncmax);
ret = nilfs_dat_mark_dirty(dat, ptr);
if (ret < 0)
goto out;
@@ -1857,10 +1880,9 @@ static int nilfs_btree_propagate_v(struct nilfs_btree *btree,
return ret;
}
-static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
+static int nilfs_btree_propagate(struct nilfs_bmap *btree,
struct buffer_head *bh)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
struct nilfs_btree_node *node;
__u64 key;
@@ -1868,7 +1890,6 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
WARN_ON(!buffer_dirty(bh));
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -1878,7 +1899,7 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
key = nilfs_btree_node_get_key(node, 0);
level = nilfs_btree_node_get_level(node);
} else {
- key = nilfs_bmap_data_get_key(bmap, bh);
+ key = nilfs_bmap_data_get_key(btree, bh);
level = NILFS_BTREE_LEVEL_DATA;
}
@@ -1890,7 +1911,7 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
goto out;
}
- ret = NILFS_BMAP_USE_VBN(bmap) ?
+ ret = NILFS_BMAP_USE_VBN(btree) ?
nilfs_btree_propagate_v(btree, path, level, bh) :
nilfs_btree_propagate_p(btree, path, level, bh);
@@ -1900,13 +1921,13 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
return ret;
}
-static int nilfs_btree_propagate_gc(const struct nilfs_bmap *bmap,
+static int nilfs_btree_propagate_gc(struct nilfs_bmap *btree,
struct buffer_head *bh)
{
- return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), bh->b_blocknr);
+ return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(btree), bh->b_blocknr);
}
-static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
+static void nilfs_btree_add_dirty_buffer(struct nilfs_bmap *btree,
struct list_head *lists,
struct buffer_head *bh)
{
@@ -1920,6 +1941,18 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
node = (struct nilfs_btree_node *)bh->b_data;
key = nilfs_btree_node_get_key(node, 0);
level = nilfs_btree_node_get_level(node);
+ if (level < NILFS_BTREE_LEVEL_NODE_MIN ||
+ level >= NILFS_BTREE_LEVEL_MAX) {
+ dump_stack();
+ printk(KERN_WARNING
+ "%s: invalid btree level: %d (key=%llu, ino=%lu, "
+ "blocknr=%llu)\n",
+ __func__, level, (unsigned long long)key,
+ NILFS_BMAP_I(btree)->vfs_inode.i_ino,
+ (unsigned long long)bh->b_blocknr);
+ return;
+ }
+
list_for_each(head, &lists[level]) {
cbh = list_entry(head, struct buffer_head, b_assoc_buffers);
cnode = (struct nilfs_btree_node *)cbh->b_data;
@@ -1930,11 +1963,10 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
list_add_tail(&bh->b_assoc_buffers, head);
}
-static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *bmap,
+static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *btree,
struct list_head *listp)
{
- struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
- struct address_space *btcache = &NILFS_BMAP_I(bmap)->i_btnode_cache;
+ struct address_space *btcache = &NILFS_BMAP_I(btree)->i_btnode_cache;
struct list_head lists[NILFS_BTREE_LEVEL_MAX];
struct pagevec pvec;
struct buffer_head *bh, *head;
@@ -1968,7 +2000,7 @@ static void nilfs_btree_lookup_dirty_buffers(struct nilfs_bmap *bmap,
list_splice_tail(&lists[level], listp);
}
-static int nilfs_btree_assign_p(struct nilfs_btree *btree,
+static int nilfs_btree_assign_p(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level,
struct buffer_head **bh,
@@ -1978,38 +2010,38 @@ static int nilfs_btree_assign_p(struct nilfs_btree *btree,
struct nilfs_btree_node *parent;
__u64 key;
__u64 ptr;
- int ret;
+ int ncmax, ret;
- parent = nilfs_btree_get_node(btree, path, level + 1);
- ptr = nilfs_btree_node_get_ptr(btree, parent,
- path[level + 1].bp_index);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
+ ptr = nilfs_btree_node_get_ptr(parent, path[level + 1].bp_index,
+ ncmax);
if (buffer_nilfs_node(*bh)) {
path[level].bp_ctxt.oldkey = ptr;
path[level].bp_ctxt.newkey = blocknr;
path[level].bp_ctxt.bh = *bh;
ret = nilfs_btnode_prepare_change_key(
- &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &NILFS_BMAP_I(btree)->i_btnode_cache,
&path[level].bp_ctxt);
if (ret < 0)
return ret;
nilfs_btnode_commit_change_key(
- &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
+ &NILFS_BMAP_I(btree)->i_btnode_cache,
&path[level].bp_ctxt);
*bh = path[level].bp_ctxt.bh;
}
- nilfs_btree_node_set_ptr(btree, parent,
- path[level + 1].bp_index, blocknr);
+ nilfs_btree_node_set_ptr(parent, path[level + 1].bp_index, blocknr,
+ ncmax);
key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
/* on-disk format */
- binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
binfo->bi_dat.bi_level = level;
return 0;
}
-static int nilfs_btree_assign_v(struct nilfs_btree *btree,
+static int nilfs_btree_assign_v(struct nilfs_bmap *btree,
struct nilfs_btree_path *path,
int level,
struct buffer_head **bh,
@@ -2017,15 +2049,15 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
union nilfs_binfo *binfo)
{
struct nilfs_btree_node *parent;
- struct inode *dat = nilfs_bmap_get_dat(&btree->bt_bmap);
+ struct inode *dat = nilfs_bmap_get_dat(btree);
__u64 key;
__u64 ptr;
union nilfs_bmap_ptr_req req;
- int ret;
+ int ncmax, ret;
- parent = nilfs_btree_get_node(btree, path, level + 1);
- ptr = nilfs_btree_node_get_ptr(btree, parent,
- path[level + 1].bp_index);
+ parent = nilfs_btree_get_node(btree, path, level + 1, &ncmax);
+ ptr = nilfs_btree_node_get_ptr(parent, path[level + 1].bp_index,
+ ncmax);
req.bpr_ptr = ptr;
ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
if (ret < 0)
@@ -2034,24 +2066,22 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
key = nilfs_btree_node_get_key(parent, path[level + 1].bp_index);
/* on-disk format */
- binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
- binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_v.bi_vblocknr = cpu_to_le64(ptr);
+ binfo->bi_v.bi_blkoff = cpu_to_le64(key);
return 0;
}
-static int nilfs_btree_assign(struct nilfs_bmap *bmap,
+static int nilfs_btree_assign(struct nilfs_bmap *btree,
struct buffer_head **bh,
sector_t blocknr,
union nilfs_binfo *binfo)
{
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
struct nilfs_btree_node *node;
__u64 key;
int level, ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -2061,7 +2091,7 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
key = nilfs_btree_node_get_key(node, 0);
level = nilfs_btree_node_get_level(node);
} else {
- key = nilfs_bmap_data_get_key(bmap, *bh);
+ key = nilfs_bmap_data_get_key(btree, *bh);
level = NILFS_BTREE_LEVEL_DATA;
}
@@ -2071,7 +2101,7 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
goto out;
}
- ret = NILFS_BMAP_USE_VBN(bmap) ?
+ ret = NILFS_BMAP_USE_VBN(btree) ?
nilfs_btree_assign_v(btree, path, level, bh, blocknr, binfo) :
nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
@@ -2081,7 +2111,7 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
return ret;
}
-static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
+static int nilfs_btree_assign_gc(struct nilfs_bmap *btree,
struct buffer_head **bh,
sector_t blocknr,
union nilfs_binfo *binfo)
@@ -2090,7 +2120,7 @@ static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
__u64 key;
int ret;
- ret = nilfs_dat_move(nilfs_bmap_get_dat(bmap), (*bh)->b_blocknr,
+ ret = nilfs_dat_move(nilfs_bmap_get_dat(btree), (*bh)->b_blocknr,
blocknr);
if (ret < 0)
return ret;
@@ -2099,24 +2129,22 @@ static int nilfs_btree_assign_gc(struct nilfs_bmap *bmap,
node = (struct nilfs_btree_node *)(*bh)->b_data;
key = nilfs_btree_node_get_key(node, 0);
} else
- key = nilfs_bmap_data_get_key(bmap, *bh);
+ key = nilfs_bmap_data_get_key(btree, *bh);
/* on-disk format */
binfo->bi_v.bi_vblocknr = cpu_to_le64((*bh)->b_blocknr);
- binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_v.bi_blkoff = cpu_to_le64(key);
return 0;
}
-static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
+static int nilfs_btree_mark(struct nilfs_bmap *btree, __u64 key, int level)
{
struct buffer_head *bh;
- struct nilfs_btree *btree;
struct nilfs_btree_path *path;
__u64 ptr;
int ret;
- btree = (struct nilfs_btree *)bmap;
path = nilfs_btree_alloc_path();
if (path == NULL)
return -ENOMEM;
@@ -2135,8 +2163,8 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
if (!buffer_dirty(bh))
nilfs_btnode_mark_dirty(bh);
brelse(bh);
- if (!nilfs_bmap_dirty(&btree->bt_bmap))
- nilfs_bmap_set_dirty(&btree->bt_bmap);
+ if (!nilfs_bmap_dirty(btree))
+ nilfs_bmap_set_dirty(btree);
out:
nilfs_btree_free_path(path);
@@ -2186,10 +2214,14 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
int nilfs_btree_init(struct nilfs_bmap *bmap)
{
bmap->b_ops = &nilfs_btree_ops;
+ bmap->b_nchildren_per_block =
+ NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(bmap));
return 0;
}
void nilfs_btree_init_gc(struct nilfs_bmap *bmap)
{
bmap->b_ops = &nilfs_btree_ops_gc;
+ bmap->b_nchildren_per_block =
+ NILFS_BTREE_NODE_NCHILDREN_MAX(nilfs_btree_node_size(bmap));
}
diff --git a/fs/nilfs2/btree.h b/fs/nilfs2/btree.h
index 43c8c5b541fd..22c02e35b6ef 100644
--- a/fs/nilfs2/btree.h
+++ b/fs/nilfs2/btree.h
@@ -31,14 +31,6 @@
#include "bmap.h"
/**
- * struct nilfs_btree - B-tree structure
- * @bt_bmap: bmap base structure
- */
-struct nilfs_btree {
- struct nilfs_bmap bt_bmap;
-};
-
-/**
* struct nilfs_btree_path - A path on which B-tree operations are executed
* @bp_bh: buffer head of node block
* @bp_sib_bh: buffer head of sibling node block
@@ -54,7 +46,7 @@ struct nilfs_btree_path {
union nilfs_bmap_ptr_req bp_oldreq;
union nilfs_bmap_ptr_req bp_newreq;
struct nilfs_btnode_chkey_ctxt bp_ctxt;
- void (*bp_op)(struct nilfs_btree *, struct nilfs_btree_path *,
+ void (*bp_op)(struct nilfs_bmap *, struct nilfs_btree_path *,
int, __u64 *, __u64 *);
};
@@ -80,4 +72,6 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
const __u64 *, const __u64 *, int);
void nilfs_btree_init_gc(struct nilfs_bmap *);
+int nilfs_btree_broken_node_block(struct buffer_head *bh);
+
#endif /* _NILFS_BTREE_H */
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c
index 85c89dfc71f0..d14e3b94d81f 100644
--- a/fs/nilfs2/dir.c
+++ b/fs/nilfs2/dir.c
@@ -80,23 +80,10 @@ static unsigned nilfs_last_byte(struct inode *inode, unsigned long page_nr)
return last_byte;
}
-static int nilfs_prepare_chunk_uninterruptible(struct page *page,
- struct address_space *mapping,
- unsigned from, unsigned to)
+static int nilfs_prepare_chunk(struct page *page, unsigned from, unsigned to)
{
loff_t pos = page_offset(page) + from;
- return block_write_begin(NULL, mapping, pos, to - from,
- AOP_FLAG_UNINTERRUPTIBLE, &page,
- NULL, nilfs_get_block);
-}
-
-static int nilfs_prepare_chunk(struct page *page,
- struct address_space *mapping,
- unsigned from, unsigned to)
-{
- loff_t pos = page_offset(page) + from;
- return block_write_begin(NULL, mapping, pos, to - from, 0, &page,
- NULL, nilfs_get_block);
+ return __block_write_begin(page, pos, to - from, nilfs_get_block);
}
static void nilfs_commit_chunk(struct page *page,
@@ -449,7 +436,7 @@ void nilfs_set_link(struct inode *dir, struct nilfs_dir_entry *de,
int err;
lock_page(page);
- err = nilfs_prepare_chunk_uninterruptible(page, mapping, from, to);
+ err = nilfs_prepare_chunk(page, from, to);
BUG_ON(err);
de->inode = cpu_to_le64(inode->i_ino);
nilfs_set_de_type(de, inode);
@@ -530,7 +517,7 @@ int nilfs_add_link(struct dentry *dentry, struct inode *inode)
got_it:
from = (char *)de - (char *)page_address(page);
to = from + rec_len;
- err = nilfs_prepare_chunk(page, page->mapping, from, to);
+ err = nilfs_prepare_chunk(page, from, to);
if (err)
goto out_unlock;
if (de->inode) {
@@ -587,7 +574,7 @@ int nilfs_delete_entry(struct nilfs_dir_entry *dir, struct page *page)
if (pde)
from = (char *)pde - (char *)page_address(page);
lock_page(page);
- err = nilfs_prepare_chunk(page, mapping, from, to);
+ err = nilfs_prepare_chunk(page, from, to);
BUG_ON(err);
if (pde)
pde->rec_len = cpu_to_le16(to - from);
@@ -615,7 +602,7 @@ int nilfs_make_empty(struct inode *inode, struct inode *parent)
if (!page)
return -ENOMEM;
- err = nilfs_prepare_chunk(page, mapping, 0, chunk_size);
+ err = nilfs_prepare_chunk(page, 0, chunk_size);
if (unlikely(err)) {
unlock_page(page);
goto fail;
diff --git a/fs/nilfs2/direct.c b/fs/nilfs2/direct.c
index 236753df5cdf..324d80c57518 100644
--- a/fs/nilfs2/direct.c
+++ b/fs/nilfs2/direct.c
@@ -27,47 +27,43 @@
#include "alloc.h"
#include "dat.h"
-static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
+static inline __le64 *nilfs_direct_dptrs(const struct nilfs_bmap *direct)
{
return (__le64 *)
- ((struct nilfs_direct_node *)direct->d_bmap.b_u.u_data + 1);
+ ((struct nilfs_direct_node *)direct->b_u.u_data + 1);
}
static inline __u64
-nilfs_direct_get_ptr(const struct nilfs_direct *direct, __u64 key)
+nilfs_direct_get_ptr(const struct nilfs_bmap *direct, __u64 key)
{
- return nilfs_bmap_dptr_to_ptr(*(nilfs_direct_dptrs(direct) + key));
+ return le64_to_cpu(*(nilfs_direct_dptrs(direct) + key));
}
-static inline void nilfs_direct_set_ptr(struct nilfs_direct *direct,
+static inline void nilfs_direct_set_ptr(struct nilfs_bmap *direct,
__u64 key, __u64 ptr)
{
- *(nilfs_direct_dptrs(direct) + key) = nilfs_bmap_ptr_to_dptr(ptr);
+ *(nilfs_direct_dptrs(direct) + key) = cpu_to_le64(ptr);
}
-static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
+static int nilfs_direct_lookup(const struct nilfs_bmap *direct,
__u64 key, int level, __u64 *ptrp)
{
- struct nilfs_direct *direct;
__u64 ptr;
- direct = (struct nilfs_direct *)bmap; /* XXX: use macro for level 1 */
if (key > NILFS_DIRECT_KEY_MAX || level != 1)
return -ENOENT;
ptr = nilfs_direct_get_ptr(direct, key);
if (ptr == NILFS_BMAP_INVALID_PTR)
return -ENOENT;
- if (ptrp != NULL)
- *ptrp = ptr;
+ *ptrp = ptr;
return 0;
}
-static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
+static int nilfs_direct_lookup_contig(const struct nilfs_bmap *direct,
__u64 key, __u64 *ptrp,
unsigned maxblocks)
{
- struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
struct inode *dat = NULL;
__u64 ptr, ptr2;
sector_t blocknr;
@@ -79,8 +75,8 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
if (ptr == NILFS_BMAP_INVALID_PTR)
return -ENOENT;
- if (NILFS_BMAP_USE_VBN(bmap)) {
- dat = nilfs_bmap_get_dat(bmap);
+ if (NILFS_BMAP_USE_VBN(direct)) {
+ dat = nilfs_bmap_get_dat(direct);
ret = nilfs_dat_translate(dat, ptr, &blocknr);
if (ret < 0)
return ret;
@@ -106,29 +102,21 @@ static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
}
static __u64
-nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
+nilfs_direct_find_target_v(const struct nilfs_bmap *direct, __u64 key)
{
__u64 ptr;
- ptr = nilfs_bmap_find_target_seq(&direct->d_bmap, key);
+ ptr = nilfs_bmap_find_target_seq(direct, key);
if (ptr != NILFS_BMAP_INVALID_PTR)
/* sequential access */
return ptr;
else
/* block group */
- return nilfs_bmap_find_target_in_group(&direct->d_bmap);
-}
-
-static void nilfs_direct_set_target_v(struct nilfs_direct *direct,
- __u64 key, __u64 ptr)
-{
- direct->d_bmap.b_last_allocated_key = key;
- direct->d_bmap.b_last_allocated_ptr = ptr;
+ return nilfs_bmap_find_target_in_group(direct);
}
static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
{
- struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
union nilfs_bmap_ptr_req req;
struct inode *dat = NULL;
struct buffer_head *bh;
@@ -136,11 +124,11 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
if (key > NILFS_DIRECT_KEY_MAX)
return -ENOENT;
- if (nilfs_direct_get_ptr(direct, key) != NILFS_BMAP_INVALID_PTR)
+ if (nilfs_direct_get_ptr(bmap, key) != NILFS_BMAP_INVALID_PTR)
return -EEXIST;
if (NILFS_BMAP_USE_VBN(bmap)) {
- req.bpr_ptr = nilfs_direct_find_target_v(direct, key);
+ req.bpr_ptr = nilfs_direct_find_target_v(bmap, key);
dat = nilfs_bmap_get_dat(bmap);
}
ret = nilfs_bmap_prepare_alloc_ptr(bmap, &req, dat);
@@ -150,13 +138,13 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
set_buffer_nilfs_volatile(bh);
nilfs_bmap_commit_alloc_ptr(bmap, &req, dat);
- nilfs_direct_set_ptr(direct, key, req.bpr_ptr);
+ nilfs_direct_set_ptr(bmap, key, req.bpr_ptr);
if (!nilfs_bmap_dirty(bmap))
nilfs_bmap_set_dirty(bmap);
if (NILFS_BMAP_USE_VBN(bmap))
- nilfs_direct_set_target_v(direct, key, req.bpr_ptr);
+ nilfs_bmap_set_target_v(bmap, key, req.bpr_ptr);
nilfs_bmap_add_blocks(bmap, 1);
}
@@ -165,33 +153,30 @@ static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
static int nilfs_direct_delete(struct nilfs_bmap *bmap, __u64 key)
{
- struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
union nilfs_bmap_ptr_req req;
struct inode *dat;
int ret;
if (key > NILFS_DIRECT_KEY_MAX ||
- nilfs_direct_get_ptr(direct, key) == NILFS_BMAP_INVALID_PTR)
+ nilfs_direct_get_ptr(bmap, key) == NILFS_BMAP_INVALID_PTR)
return -ENOENT;
dat = NILFS_BMAP_USE_VBN(bmap) ? nilfs_bmap_get_dat(bmap) : NULL;
- req.bpr_ptr = nilfs_direct_get_ptr(direct, key);
+ req.bpr_ptr = nilfs_direct_get_ptr(bmap, key);
ret = nilfs_bmap_prepare_end_ptr(bmap, &req, dat);
if (!ret) {
nilfs_bmap_commit_end_ptr(bmap, &req, dat);
- nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
+ nilfs_direct_set_ptr(bmap, key, NILFS_BMAP_INVALID_PTR);
nilfs_bmap_sub_blocks(bmap, 1);
}
return ret;
}
-static int nilfs_direct_last_key(const struct nilfs_bmap *bmap, __u64 *keyp)
+static int nilfs_direct_last_key(const struct nilfs_bmap *direct, __u64 *keyp)
{
- struct nilfs_direct *direct;
__u64 key, lastkey;
- direct = (struct nilfs_direct *)bmap;
lastkey = NILFS_DIRECT_KEY_MAX + 1;
for (key = NILFS_DIRECT_KEY_MIN; key <= NILFS_DIRECT_KEY_MAX; key++)
if (nilfs_direct_get_ptr(direct, key) !=
@@ -211,15 +196,13 @@ static int nilfs_direct_check_insert(const struct nilfs_bmap *bmap, __u64 key)
return key > NILFS_DIRECT_KEY_MAX;
}
-static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
+static int nilfs_direct_gather_data(struct nilfs_bmap *direct,
__u64 *keys, __u64 *ptrs, int nitems)
{
- struct nilfs_direct *direct;
__u64 key;
__u64 ptr;
int n;
- direct = (struct nilfs_direct *)bmap;
if (nitems > NILFS_DIRECT_NBLOCKS)
nitems = NILFS_DIRECT_NBLOCKS;
n = 0;
@@ -237,7 +220,6 @@ static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
__u64 key, __u64 *keys, __u64 *ptrs, int n)
{
- struct nilfs_direct *direct;
__le64 *dptrs;
int ret, i, j;
@@ -253,12 +235,11 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
bmap->b_ops->bop_clear(bmap);
/* convert */
- direct = (struct nilfs_direct *)bmap;
- dptrs = nilfs_direct_dptrs(direct);
+ dptrs = nilfs_direct_dptrs(bmap);
for (i = 0, j = 0; i < NILFS_DIRECT_NBLOCKS; i++) {
if ((j < n) && (i == keys[j])) {
dptrs[i] = (i != key) ?
- nilfs_bmap_ptr_to_dptr(ptrs[j]) :
+ cpu_to_le64(ptrs[j]) :
NILFS_BMAP_INVALID_PTR;
j++;
} else
@@ -269,10 +250,9 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
return 0;
}
-static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
+static int nilfs_direct_propagate(struct nilfs_bmap *bmap,
struct buffer_head *bh)
{
- struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
struct nilfs_palloc_req oldreq, newreq;
struct inode *dat;
__u64 key;
@@ -284,7 +264,7 @@ static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
dat = nilfs_bmap_get_dat(bmap);
key = nilfs_bmap_data_get_key(bmap, bh);
- ptr = nilfs_direct_get_ptr(direct, key);
+ ptr = nilfs_direct_get_ptr(bmap, key);
if (!buffer_nilfs_volatile(bh)) {
oldreq.pr_entry_nr = ptr;
newreq.pr_entry_nr = ptr;
@@ -294,20 +274,20 @@ static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
nilfs_dat_commit_update(dat, &oldreq, &newreq,
bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
set_buffer_nilfs_volatile(bh);
- nilfs_direct_set_ptr(direct, key, newreq.pr_entry_nr);
+ nilfs_direct_set_ptr(bmap, key, newreq.pr_entry_nr);
} else
ret = nilfs_dat_mark_dirty(dat, ptr);
return ret;
}
-static int nilfs_direct_assign_v(struct nilfs_direct *direct,
+static int nilfs_direct_assign_v(struct nilfs_bmap *direct,
__u64 key, __u64 ptr,
struct buffer_head **bh,
sector_t blocknr,
union nilfs_binfo *binfo)
{
- struct inode *dat = nilfs_bmap_get_dat(&direct->d_bmap);
+ struct inode *dat = nilfs_bmap_get_dat(direct);
union nilfs_bmap_ptr_req req;
int ret;
@@ -315,13 +295,13 @@ static int nilfs_direct_assign_v(struct nilfs_direct *direct,
ret = nilfs_dat_prepare_start(dat, &req.bpr_req);
if (!ret) {
nilfs_dat_commit_start(dat, &req.bpr_req, blocknr);
- binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
- binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_v.bi_vblocknr = cpu_to_le64(ptr);
+ binfo->bi_v.bi_blkoff = cpu_to_le64(key);
}
return ret;
}
-static int nilfs_direct_assign_p(struct nilfs_direct *direct,
+static int nilfs_direct_assign_p(struct nilfs_bmap *direct,
__u64 key, __u64 ptr,
struct buffer_head **bh,
sector_t blocknr,
@@ -329,7 +309,7 @@ static int nilfs_direct_assign_p(struct nilfs_direct *direct,
{
nilfs_direct_set_ptr(direct, key, blocknr);
- binfo->bi_dat.bi_blkoff = nilfs_bmap_key_to_dkey(key);
+ binfo->bi_dat.bi_blkoff = cpu_to_le64(key);
binfo->bi_dat.bi_level = 0;
return 0;
@@ -340,18 +320,16 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap,
sector_t blocknr,
union nilfs_binfo *binfo)
{
- struct nilfs_direct *direct;
__u64 key;
__u64 ptr;
- direct = (struct nilfs_direct *)bmap;
key = nilfs_bmap_data_get_key(bmap, *bh);
if (unlikely(key > NILFS_DIRECT_KEY_MAX)) {
printk(KERN_CRIT "%s: invalid key: %llu\n", __func__,
(unsigned long long)key);
return -EINVAL;
}
- ptr = nilfs_direct_get_ptr(direct, key);
+ ptr = nilfs_direct_get_ptr(bmap, key);
if (unlikely(ptr == NILFS_BMAP_INVALID_PTR)) {
printk(KERN_CRIT "%s: invalid pointer: %llu\n", __func__,
(unsigned long long)ptr);
@@ -359,8 +337,8 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap,
}
return NILFS_BMAP_USE_VBN(bmap) ?
- nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) :
- nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo);
+ nilfs_direct_assign_v(bmap, key, ptr, bh, blocknr, binfo) :
+ nilfs_direct_assign_p(bmap, key, ptr, bh, blocknr, binfo);
}
static const struct nilfs_bmap_operations nilfs_direct_ops = {
diff --git a/fs/nilfs2/direct.h b/fs/nilfs2/direct.h
index a5ffd66e25d0..dc643de20a25 100644
--- a/fs/nilfs2/direct.h
+++ b/fs/nilfs2/direct.h
@@ -28,8 +28,6 @@
#include "bmap.h"
-struct nilfs_direct;
-
/**
* struct nilfs_direct_node - direct node
* @dn_flags: flags
@@ -40,15 +38,6 @@ struct nilfs_direct_node {
__u8 pad[7];
};
-/**
- * struct nilfs_direct - direct mapping
- * @d_bmap: bmap structure
- */
-struct nilfs_direct {
- struct nilfs_bmap d_bmap;
-};
-
-
#define NILFS_DIRECT_NBLOCKS (NILFS_BMAP_SIZE / sizeof(__le64) - 1)
#define NILFS_DIRECT_KEY_MIN 0
#define NILFS_DIRECT_KEY_MAX (NILFS_DIRECT_NBLOCKS - 1)
diff --git a/fs/nilfs2/gcdat.c b/fs/nilfs2/gcdat.c
index dd5f7e0a95f6..84a45d1d5464 100644
--- a/fs/nilfs2/gcdat.c
+++ b/fs/nilfs2/gcdat.c
@@ -78,7 +78,7 @@ void nilfs_clear_gcdat_inode(struct the_nilfs *nilfs)
struct inode *gcdat = nilfs->ns_gc_dat;
struct nilfs_inode_info *gii = NILFS_I(gcdat);
- gcdat->i_state = I_CLEAR;
+ gcdat->i_state = I_FREEING | I_CLEAR;
gii->i_flags = 0;
nilfs_palloc_clear_cache(gcdat);
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c
index 145f03cd7d3e..b6343825f91a 100644
--- a/fs/nilfs2/gcinode.c
+++ b/fs/nilfs2/gcinode.c
@@ -48,6 +48,8 @@
#include <linux/slab.h>
#include <linux/swap.h>
#include "nilfs.h"
+#include "btree.h"
+#include "btnode.h"
#include "page.h"
#include "mdt.h"
#include "dat.h"
@@ -164,10 +166,15 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh)
if (buffer_dirty(bh))
return -EEXIST;
- if (buffer_nilfs_node(bh))
+ if (buffer_nilfs_node(bh)) {
+ if (nilfs_btree_broken_node_block(bh)) {
+ clear_buffer_uptodate(bh);
+ return -EIO;
+ }
nilfs_btnode_mark_dirty(bh);
- else
+ } else {
nilfs_mdt_mark_buffer_dirty(bh);
+ }
return 0;
}
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 39e038ac8fcb..eccb2f2e2315 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -27,6 +27,7 @@
#include <linux/writeback.h>
#include <linux/uio.h>
#include "nilfs.h"
+#include "btnode.h"
#include "segment.h"
#include "page.h"
#include "mdt.h"
@@ -197,11 +198,15 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping,
if (unlikely(err))
return err;
- *pagep = NULL;
- err = block_write_begin(file, mapping, pos, len, flags, pagep,
- fsdata, nilfs_get_block);
- if (unlikely(err))
+ err = block_write_begin(mapping, pos, len, flags, pagep,
+ nilfs_get_block);
+ if (unlikely(err)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+
nilfs_transaction_abort(inode->i_sb);
+ }
return err;
}
@@ -237,6 +242,19 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
/* Needs synchronization with the cleaner */
size = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs, nilfs_get_block, NULL);
+
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && size < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+
return size;
}
@@ -337,7 +355,6 @@ void nilfs_free_inode(struct inode *inode)
struct super_block *sb = inode->i_sb;
struct nilfs_sb_info *sbi = NILFS_SB(sb);
- clear_inode(inode);
/* XXX: check error code? Is there any thing I can do? */
(void) nilfs_ifile_delete_inode(sbi->s_ifile, inode->i_ino);
atomic_dec(&sbi->s_inodes_count);
@@ -597,16 +614,34 @@ void nilfs_truncate(struct inode *inode)
But truncate has no return value. */
}
-void nilfs_delete_inode(struct inode *inode)
+static void nilfs_clear_inode(struct inode *inode)
+{
+ struct nilfs_inode_info *ii = NILFS_I(inode);
+
+ /*
+ * Free resources allocated in nilfs_read_inode(), here.
+ */
+ BUG_ON(!list_empty(&ii->i_dirty));
+ brelse(ii->i_bh);
+ ii->i_bh = NULL;
+
+ if (test_bit(NILFS_I_BMAP, &ii->i_state))
+ nilfs_bmap_clear(ii->i_bmap);
+
+ nilfs_btnode_cache_clear(&ii->i_btnode_cache);
+}
+
+void nilfs_evict_inode(struct inode *inode)
{
struct nilfs_transaction_info ti;
struct super_block *sb = inode->i_sb;
struct nilfs_inode_info *ii = NILFS_I(inode);
- if (unlikely(is_bad_inode(inode))) {
+ if (inode->i_nlink || unlikely(is_bad_inode(inode))) {
if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ end_writeback(inode);
+ nilfs_clear_inode(inode);
return;
}
nilfs_transaction_begin(sb, &ti, 0); /* never fails */
@@ -616,6 +651,8 @@ void nilfs_delete_inode(struct inode *inode)
nilfs_truncate_bmap(ii, 0);
nilfs_mark_inode_dirty(inode);
+ end_writeback(inode);
+ nilfs_clear_inode(inode);
nilfs_free_inode(inode);
/* nilfs_free_inode() marks inode buffer dirty */
if (IS_SYNC(inode))
@@ -639,14 +676,27 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr)
err = nilfs_transaction_begin(sb, &ti, 0);
if (unlikely(err))
return err;
- err = inode_setattr(inode, iattr);
- if (!err && (iattr->ia_valid & ATTR_MODE))
+
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(inode)) {
+ err = vmtruncate(inode, iattr->ia_size);
+ if (unlikely(err))
+ goto out_err;
+ }
+
+ setattr_copy(inode, iattr);
+ mark_inode_dirty(inode);
+
+ if (iattr->ia_valid & ATTR_MODE) {
err = nilfs_acl_chmod(inode);
- if (likely(!err))
- err = nilfs_transaction_commit(sb);
- else
- nilfs_transaction_abort(sb);
+ if (unlikely(err))
+ goto out_err;
+ }
+
+ return nilfs_transaction_commit(sb);
+out_err:
+ nilfs_transaction_abort(sb);
return err;
}
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 024be8c35bb6..d01aff4957d9 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -28,6 +28,7 @@
#include <linux/swap.h>
#include <linux/slab.h>
#include "nilfs.h"
+#include "btnode.h"
#include "segment.h"
#include "page.h"
#include "mdt.h"
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 47d6d7928122..7ecbb394f27d 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -32,7 +32,6 @@
#include "the_nilfs.h"
#include "sb.h"
#include "bmap.h"
-#include "bmap_union.h"
/*
* nilfs inode data in memory
@@ -41,7 +40,7 @@ struct nilfs_inode_info {
__u32 i_flags;
unsigned long i_state; /* Dynamic state flags */
struct nilfs_bmap *i_bmap;
- union nilfs_bmap_union i_bmap_union;
+ struct nilfs_bmap i_bmap_data;
__u64 i_xattr; /* sector_t ??? */
__u32 i_dir_start_lookup;
__u64 i_cno; /* check point number for GC inode */
@@ -71,9 +70,7 @@ static inline struct nilfs_inode_info *NILFS_I(const struct inode *inode)
static inline struct nilfs_inode_info *
NILFS_BMAP_I(const struct nilfs_bmap *bmap)
{
- return container_of((union nilfs_bmap_union *)bmap,
- struct nilfs_inode_info,
- i_bmap_union);
+ return container_of(bmap, struct nilfs_inode_info, i_bmap_data);
}
static inline struct inode *NILFS_BTNC_I(struct address_space *btnc)
@@ -107,6 +104,14 @@ enum {
};
/*
+ * commit flags for nilfs_commit_super and nilfs_sync_super
+ */
+enum {
+ NILFS_SB_COMMIT = 0, /* Commit a super block alternately */
+ NILFS_SB_COMMIT_ALL /* Commit both super blocks */
+};
+
+/*
* Macros to check inode numbers
*/
#define NILFS_MDT_INO_BITS \
@@ -245,7 +250,7 @@ extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int);
extern struct inode *nilfs_iget(struct super_block *, unsigned long);
extern void nilfs_update_inode(struct inode *, struct buffer_head *);
extern void nilfs_truncate(struct inode *);
-extern void nilfs_delete_inode(struct inode *);
+extern void nilfs_evict_inode(struct inode *);
extern int nilfs_setattr(struct dentry *, struct iattr *);
extern int nilfs_load_inode_block(struct nilfs_sb_info *, struct inode *,
struct buffer_head **);
@@ -270,7 +275,12 @@ extern struct nilfs_super_block *
nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
extern int nilfs_store_magic_and_option(struct super_block *,
struct nilfs_super_block *, char *);
+extern void nilfs_set_log_cursor(struct nilfs_super_block *,
+ struct the_nilfs *);
+extern struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *,
+ int flip);
extern int nilfs_commit_super(struct nilfs_sb_info *, int);
+extern int nilfs_cleanup_super(struct nilfs_sb_info *);
extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64);
extern void nilfs_detach_checkpoint(struct nilfs_sb_info *);
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index bae2a516b4ee..d0c35ef39f6a 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -91,27 +91,9 @@ static int nilfs_warn_segment_error(int err)
return -EINVAL;
}
-static void store_segsum_info(struct nilfs_segsum_info *ssi,
- struct nilfs_segment_summary *sum,
- unsigned int blocksize)
-{
- ssi->flags = le16_to_cpu(sum->ss_flags);
- ssi->seg_seq = le64_to_cpu(sum->ss_seq);
- ssi->ctime = le64_to_cpu(sum->ss_create);
- ssi->next = le64_to_cpu(sum->ss_next);
- ssi->nblocks = le32_to_cpu(sum->ss_nblocks);
- ssi->nfinfo = le32_to_cpu(sum->ss_nfinfo);
- ssi->sumbytes = le32_to_cpu(sum->ss_sumbytes);
-
- ssi->nsumblk = DIV_ROUND_UP(ssi->sumbytes, blocksize);
- ssi->nfileblk = ssi->nblocks - ssi->nsumblk - !!NILFS_SEG_HAS_SR(ssi);
-
- /* need to verify ->ss_bytes field if read ->ss_cno */
-}
-
/**
- * calc_crc_cont - check CRC of blocks continuously
- * @sbi: nilfs_sb_info
+ * nilfs_compute_checksum - compute checksum of blocks continuously
+ * @nilfs: nilfs object
* @bhs: buffer head of start block
* @sum: place to store result
* @offset: offset bytes in the first block
@@ -119,23 +101,25 @@ static void store_segsum_info(struct nilfs_segsum_info *ssi,
* @start: DBN of start block
* @nblock: number of blocks to be checked
*/
-static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs,
- u32 *sum, unsigned long offset, u64 check_bytes,
- sector_t start, unsigned long nblock)
+static int nilfs_compute_checksum(struct the_nilfs *nilfs,
+ struct buffer_head *bhs, u32 *sum,
+ unsigned long offset, u64 check_bytes,
+ sector_t start, unsigned long nblock)
{
- unsigned long blocksize = sbi->s_super->s_blocksize;
+ unsigned int blocksize = nilfs->ns_blocksize;
unsigned long size;
u32 crc;
BUG_ON(offset >= blocksize);
check_bytes -= offset;
size = min_t(u64, check_bytes, blocksize - offset);
- crc = crc32_le(sbi->s_nilfs->ns_crc_seed,
+ crc = crc32_le(nilfs->ns_crc_seed,
(unsigned char *)bhs->b_data + offset, size);
if (--nblock > 0) {
do {
- struct buffer_head *bh
- = sb_bread(sbi->s_super, ++start);
+ struct buffer_head *bh;
+
+ bh = __bread(nilfs->ns_bdev, ++start, blocksize);
if (!bh)
return -EIO;
check_bytes -= size;
@@ -150,12 +134,12 @@ static int calc_crc_cont(struct nilfs_sb_info *sbi, struct buffer_head *bhs,
/**
* nilfs_read_super_root_block - read super root block
- * @sb: super_block
+ * @nilfs: nilfs object
* @sr_block: disk block number of the super root block
* @pbh: address of a buffer_head pointer to return super root buffer
* @check: CRC check flag
*/
-int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
+int nilfs_read_super_root_block(struct the_nilfs *nilfs, sector_t sr_block,
struct buffer_head **pbh, int check)
{
struct buffer_head *bh_sr;
@@ -164,7 +148,7 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
int ret;
*pbh = NULL;
- bh_sr = sb_bread(sb, sr_block);
+ bh_sr = __bread(nilfs->ns_bdev, sr_block, nilfs->ns_blocksize);
if (unlikely(!bh_sr)) {
ret = NILFS_SEG_FAIL_IO;
goto failed;
@@ -174,12 +158,13 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
if (check) {
unsigned bytes = le16_to_cpu(sr->sr_bytes);
- if (bytes == 0 || bytes > sb->s_blocksize) {
+ if (bytes == 0 || bytes > nilfs->ns_blocksize) {
ret = NILFS_SEG_FAIL_CHECKSUM_SUPER_ROOT;
goto failed_bh;
}
- if (calc_crc_cont(NILFS_SB(sb), bh_sr, &crc,
- sizeof(sr->sr_sum), bytes, sr_block, 1)) {
+ if (nilfs_compute_checksum(
+ nilfs, bh_sr, &crc, sizeof(sr->sr_sum), bytes,
+ sr_block, 1)) {
ret = NILFS_SEG_FAIL_IO;
goto failed_bh;
}
@@ -199,64 +184,76 @@ int nilfs_read_super_root_block(struct super_block *sb, sector_t sr_block,
}
/**
- * load_segment_summary - read segment summary of the specified partial segment
- * @sbi: nilfs_sb_info
- * @pseg_start: start disk block number of partial segment
- * @seg_seq: sequence number requested
- * @ssi: pointer to nilfs_segsum_info struct to store information
+ * nilfs_read_log_header - read summary header of the specified log
+ * @nilfs: nilfs object
+ * @start_blocknr: start block number of the log
+ * @sum: pointer to return segment summary structure
*/
-static int
-load_segment_summary(struct nilfs_sb_info *sbi, sector_t pseg_start,
- u64 seg_seq, struct nilfs_segsum_info *ssi)
+static struct buffer_head *
+nilfs_read_log_header(struct the_nilfs *nilfs, sector_t start_blocknr,
+ struct nilfs_segment_summary **sum)
{
struct buffer_head *bh_sum;
- struct nilfs_segment_summary *sum;
+
+ bh_sum = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize);
+ if (bh_sum)
+ *sum = (struct nilfs_segment_summary *)bh_sum->b_data;
+ return bh_sum;
+}
+
+/**
+ * nilfs_validate_log - verify consistency of log
+ * @nilfs: nilfs object
+ * @seg_seq: sequence number of segment
+ * @bh_sum: buffer head of summary block
+ * @sum: segment summary struct
+ */
+static int nilfs_validate_log(struct the_nilfs *nilfs, u64 seg_seq,
+ struct buffer_head *bh_sum,
+ struct nilfs_segment_summary *sum)
+{
unsigned long nblock;
u32 crc;
- int ret = NILFS_SEG_FAIL_IO;
+ int ret;
- bh_sum = sb_bread(sbi->s_super, pseg_start);
- if (!bh_sum)
+ ret = NILFS_SEG_FAIL_MAGIC;
+ if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC)
goto out;
- sum = (struct nilfs_segment_summary *)bh_sum->b_data;
-
- /* Check consistency of segment summary */
- if (le32_to_cpu(sum->ss_magic) != NILFS_SEGSUM_MAGIC) {
- ret = NILFS_SEG_FAIL_MAGIC;
- goto failed;
- }
- store_segsum_info(ssi, sum, sbi->s_super->s_blocksize);
- if (seg_seq != ssi->seg_seq) {
- ret = NILFS_SEG_FAIL_SEQ;
- goto failed;
- }
+ ret = NILFS_SEG_FAIL_SEQ;
+ if (le64_to_cpu(sum->ss_seq) != seg_seq)
+ goto out;
- nblock = ssi->nblocks;
- if (unlikely(nblock == 0 ||
- nblock > sbi->s_nilfs->ns_blocks_per_segment)) {
+ nblock = le32_to_cpu(sum->ss_nblocks);
+ ret = NILFS_SEG_FAIL_CONSISTENCY;
+ if (unlikely(nblock == 0 || nblock > nilfs->ns_blocks_per_segment))
/* This limits the number of blocks read in the CRC check */
- ret = NILFS_SEG_FAIL_CONSISTENCY;
- goto failed;
- }
- if (calc_crc_cont(sbi, bh_sum, &crc, sizeof(sum->ss_datasum),
- ((u64)nblock << sbi->s_super->s_blocksize_bits),
- pseg_start, nblock)) {
- ret = NILFS_SEG_FAIL_IO;
- goto failed;
- }
- if (crc == le32_to_cpu(sum->ss_datasum))
- ret = 0;
- else
- ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
- failed:
- brelse(bh_sum);
- out:
+ goto out;
+
+ ret = NILFS_SEG_FAIL_IO;
+ if (nilfs_compute_checksum(nilfs, bh_sum, &crc, sizeof(sum->ss_datasum),
+ ((u64)nblock << nilfs->ns_blocksize_bits),
+ bh_sum->b_blocknr, nblock))
+ goto out;
+
+ ret = NILFS_SEG_FAIL_CHECKSUM_FULL;
+ if (crc != le32_to_cpu(sum->ss_datasum))
+ goto out;
+ ret = 0;
+out:
return ret;
}
-static void *segsum_get(struct super_block *sb, struct buffer_head **pbh,
- unsigned int *offset, unsigned int bytes)
+/**
+ * nilfs_read_summary_info - read an item on summary blocks of a log
+ * @nilfs: nilfs object
+ * @pbh: the current buffer head on summary blocks [in, out]
+ * @offset: the current byte offset on summary blocks [in, out]
+ * @bytes: byte size of the item to be read
+ */
+static void *nilfs_read_summary_info(struct the_nilfs *nilfs,
+ struct buffer_head **pbh,
+ unsigned int *offset, unsigned int bytes)
{
void *ptr;
sector_t blocknr;
@@ -265,7 +262,8 @@ static void *segsum_get(struct super_block *sb, struct buffer_head **pbh,
if (bytes > (*pbh)->b_size - *offset) {
blocknr = (*pbh)->b_blocknr;
brelse(*pbh);
- *pbh = sb_bread(sb, blocknr + 1);
+ *pbh = __bread(nilfs->ns_bdev, blocknr + 1,
+ nilfs->ns_blocksize);
if (unlikely(!*pbh))
return NULL;
*offset = 0;
@@ -275,9 +273,18 @@ static void *segsum_get(struct super_block *sb, struct buffer_head **pbh,
return ptr;
}
-static void segsum_skip(struct super_block *sb, struct buffer_head **pbh,
- unsigned int *offset, unsigned int bytes,
- unsigned long count)
+/**
+ * nilfs_skip_summary_info - skip items on summary blocks of a log
+ * @nilfs: nilfs object
+ * @pbh: the current buffer head on summary blocks [in, out]
+ * @offset: the current byte offset on summary blocks [in, out]
+ * @bytes: byte size of the item to be skipped
+ * @count: number of items to be skipped
+ */
+static void nilfs_skip_summary_info(struct the_nilfs *nilfs,
+ struct buffer_head **pbh,
+ unsigned int *offset, unsigned int bytes,
+ unsigned long count)
{
unsigned int rest_item_in_current_block
= ((*pbh)->b_size - *offset) / bytes;
@@ -294,36 +301,46 @@ static void segsum_skip(struct super_block *sb, struct buffer_head **pbh,
*offset = bytes * (count - (bcnt - 1) * nitem_per_block);
brelse(*pbh);
- *pbh = sb_bread(sb, blocknr + bcnt);
+ *pbh = __bread(nilfs->ns_bdev, blocknr + bcnt,
+ nilfs->ns_blocksize);
}
}
-static int
-collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr,
- struct nilfs_segsum_info *ssi,
- struct list_head *head)
+/**
+ * nilfs_scan_dsync_log - get block information of a log written for data sync
+ * @nilfs: nilfs object
+ * @start_blocknr: start block number of the log
+ * @sum: log summary information
+ * @head: list head to add nilfs_recovery_block struct
+ */
+static int nilfs_scan_dsync_log(struct the_nilfs *nilfs, sector_t start_blocknr,
+ struct nilfs_segment_summary *sum,
+ struct list_head *head)
{
struct buffer_head *bh;
unsigned int offset;
- unsigned long nfinfo = ssi->nfinfo;
- sector_t blocknr = sum_blocknr + ssi->nsumblk;
+ u32 nfinfo, sumbytes;
+ sector_t blocknr;
ino_t ino;
int err = -EIO;
+ nfinfo = le32_to_cpu(sum->ss_nfinfo);
if (!nfinfo)
return 0;
- bh = sb_bread(sbi->s_super, sum_blocknr);
+ sumbytes = le32_to_cpu(sum->ss_sumbytes);
+ blocknr = start_blocknr + DIV_ROUND_UP(sumbytes, nilfs->ns_blocksize);
+ bh = __bread(nilfs->ns_bdev, start_blocknr, nilfs->ns_blocksize);
if (unlikely(!bh))
goto out;
- offset = le16_to_cpu(
- ((struct nilfs_segment_summary *)bh->b_data)->ss_bytes);
+ offset = le16_to_cpu(sum->ss_bytes);
for (;;) {
unsigned long nblocks, ndatablk, nnodeblk;
struct nilfs_finfo *finfo;
- finfo = segsum_get(sbi->s_super, &bh, &offset, sizeof(*finfo));
+ finfo = nilfs_read_summary_info(nilfs, &bh, &offset,
+ sizeof(*finfo));
if (unlikely(!finfo))
goto out;
@@ -336,8 +353,8 @@ collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr,
struct nilfs_recovery_block *rb;
struct nilfs_binfo_v *binfo;
- binfo = segsum_get(sbi->s_super, &bh, &offset,
- sizeof(*binfo));
+ binfo = nilfs_read_summary_info(nilfs, &bh, &offset,
+ sizeof(*binfo));
if (unlikely(!binfo))
goto out;
@@ -355,9 +372,9 @@ collect_blocks_from_segsum(struct nilfs_sb_info *sbi, sector_t sum_blocknr,
}
if (--nfinfo == 0)
break;
- blocknr += nnodeblk; /* always 0 for the data sync segments */
- segsum_skip(sbi->s_super, &bh, &offset, sizeof(__le64),
- nnodeblk);
+ blocknr += nnodeblk; /* always 0 for data sync logs */
+ nilfs_skip_summary_info(nilfs, &bh, &offset, sizeof(__le64),
+ nnodeblk);
if (unlikely(!bh))
goto out;
}
@@ -467,14 +484,14 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
return err;
}
-static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi,
+static int nilfs_recovery_copy_block(struct the_nilfs *nilfs,
struct nilfs_recovery_block *rb,
struct page *page)
{
struct buffer_head *bh_org;
void *kaddr;
- bh_org = sb_bread(sbi->s_super, rb->blocknr);
+ bh_org = __bread(nilfs->ns_bdev, rb->blocknr, nilfs->ns_blocksize);
if (unlikely(!bh_org))
return -EIO;
@@ -485,13 +502,14 @@ static int nilfs_recovery_copy_block(struct nilfs_sb_info *sbi,
return 0;
}
-static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
- struct list_head *head,
- unsigned long *nr_salvaged_blocks)
+static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
+ struct list_head *head,
+ unsigned long *nr_salvaged_blocks)
{
struct inode *inode;
struct nilfs_recovery_block *rb, *n;
- unsigned blocksize = sbi->s_super->s_blocksize;
+ unsigned blocksize = nilfs->ns_blocksize;
struct page *page;
loff_t pos;
int err = 0, err2 = 0;
@@ -505,13 +523,16 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
}
pos = rb->blkoff << inode->i_blkbits;
- page = NULL;
- err = block_write_begin(NULL, inode->i_mapping, pos, blocksize,
- 0, &page, NULL, nilfs_get_block);
- if (unlikely(err))
+ err = block_write_begin(inode->i_mapping, pos, blocksize,
+ 0, &page, nilfs_get_block);
+ if (unlikely(err)) {
+ loff_t isize = inode->i_size;
+ if (pos + blocksize > isize)
+ vmtruncate(inode, isize);
goto failed_inode;
+ }
- err = nilfs_recovery_copy_block(sbi, rb, page);
+ err = nilfs_recovery_copy_block(nilfs, rb, page);
if (unlikely(err))
goto failed_page;
@@ -551,18 +572,20 @@ static int recover_dsync_blocks(struct nilfs_sb_info *sbi,
/**
* nilfs_do_roll_forward - salvage logical segments newer than the latest
* checkpoint
+ * @nilfs: nilfs object
* @sbi: nilfs_sb_info
- * @nilfs: the_nilfs
* @ri: pointer to a nilfs_recovery_info
*/
static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
struct nilfs_sb_info *sbi,
struct nilfs_recovery_info *ri)
{
- struct nilfs_segsum_info ssi;
+ struct buffer_head *bh_sum = NULL;
+ struct nilfs_segment_summary *sum;
sector_t pseg_start;
sector_t seg_start, seg_end; /* Starting/ending DBN of full segment */
unsigned long nsalvaged_blocks = 0;
+ unsigned int flags;
u64 seg_seq;
__u64 segnum, nextnum = 0;
int empty_seg = 0;
@@ -581,8 +604,14 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
nilfs_get_segment_range(nilfs, segnum, &seg_start, &seg_end);
while (segnum != ri->ri_segnum || pseg_start <= ri->ri_pseg_start) {
+ brelse(bh_sum);
+ bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum);
+ if (!bh_sum) {
+ err = -EIO;
+ goto failed;
+ }
- ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi);
+ ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum);
if (ret) {
if (ret == NILFS_SEG_FAIL_IO) {
err = -EIO;
@@ -590,33 +619,38 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
}
goto strayed;
}
- if (unlikely(NILFS_SEG_HAS_SR(&ssi)))
+
+ flags = le16_to_cpu(sum->ss_flags);
+ if (flags & NILFS_SS_SR)
goto confused;
/* Found a valid partial segment; do recovery actions */
- nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next);
+ nextnum = nilfs_get_segnum_of_block(nilfs,
+ le64_to_cpu(sum->ss_next));
empty_seg = 0;
- nilfs->ns_ctime = ssi.ctime;
- if (!(ssi.flags & NILFS_SS_GC))
- nilfs->ns_nongc_ctime = ssi.ctime;
+ nilfs->ns_ctime = le64_to_cpu(sum->ss_create);
+ if (!(flags & NILFS_SS_GC))
+ nilfs->ns_nongc_ctime = nilfs->ns_ctime;
switch (state) {
case RF_INIT_ST:
- if (!NILFS_SEG_LOGBGN(&ssi) || !NILFS_SEG_DSYNC(&ssi))
+ if (!(flags & NILFS_SS_LOGBGN) ||
+ !(flags & NILFS_SS_SYNDT))
goto try_next_pseg;
state = RF_DSYNC_ST;
/* Fall through */
case RF_DSYNC_ST:
- if (!NILFS_SEG_DSYNC(&ssi))
+ if (!(flags & NILFS_SS_SYNDT))
goto confused;
- err = collect_blocks_from_segsum(
- sbi, pseg_start, &ssi, &dsync_blocks);
+ err = nilfs_scan_dsync_log(nilfs, pseg_start, sum,
+ &dsync_blocks);
if (unlikely(err))
goto failed;
- if (NILFS_SEG_LOGEND(&ssi)) {
- err = recover_dsync_blocks(
- sbi, &dsync_blocks, &nsalvaged_blocks);
+ if (flags & NILFS_SS_LOGEND) {
+ err = nilfs_recover_dsync_blocks(
+ nilfs, sbi, &dsync_blocks,
+ &nsalvaged_blocks);
if (unlikely(err))
goto failed;
state = RF_INIT_ST;
@@ -627,7 +661,7 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
try_next_pseg:
if (pseg_start == ri->ri_lsegs_end)
break;
- pseg_start += ssi.nblocks;
+ pseg_start += le32_to_cpu(sum->ss_nblocks);
if (pseg_start < seg_end)
continue;
goto feed_segment;
@@ -652,8 +686,9 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
ri->ri_need_recovery = NILFS_RECOVERY_ROLLFORWARD_DONE;
}
out:
+ brelse(bh_sum);
dispose_recovery_list(&dsync_blocks);
- nilfs_detach_writer(sbi->s_nilfs, sbi);
+ nilfs_detach_writer(nilfs, sbi);
return err;
confused:
@@ -667,7 +702,6 @@ static int nilfs_do_roll_forward(struct the_nilfs *nilfs,
}
static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
- struct nilfs_sb_info *sbi,
struct nilfs_recovery_info *ri)
{
struct buffer_head *bh;
@@ -677,7 +711,7 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
nilfs_get_segnum_of_block(nilfs, ri->ri_super_root))
return;
- bh = sb_getblk(sbi->s_super, ri->ri_lsegs_start);
+ bh = __getblk(nilfs->ns_bdev, ri->ri_lsegs_start, nilfs->ns_blocksize);
BUG_ON(!bh);
memset(bh->b_data, 0, bh->b_size);
set_buffer_dirty(bh);
@@ -690,9 +724,8 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
}
/**
- * nilfs_recover_logical_segments - salvage logical segments written after
- * the latest super root
- * @nilfs: the_nilfs
+ * nilfs_salvage_orphan_logs - salvage logs written after the latest checkpoint
+ * @nilfs: nilfs object
* @sbi: nilfs_sb_info
* @ri: pointer to a nilfs_recovery_info struct to store search results.
*
@@ -709,9 +742,9 @@ static void nilfs_finish_roll_forward(struct the_nilfs *nilfs,
*
* %-ENOMEM - Insufficient memory available.
*/
-int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
- struct nilfs_sb_info *sbi,
- struct nilfs_recovery_info *ri)
+int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
+ struct nilfs_recovery_info *ri)
{
int err;
@@ -751,7 +784,7 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
goto failed;
}
- nilfs_finish_roll_forward(nilfs, sbi, ri);
+ nilfs_finish_roll_forward(nilfs, ri);
}
failed:
@@ -762,7 +795,6 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
/**
* nilfs_search_super_root - search the latest valid super root
* @nilfs: the_nilfs
- * @sbi: nilfs_sb_info
* @ri: pointer to a nilfs_recovery_info struct to store search results.
*
* nilfs_search_super_root() looks for the latest super-root from a partial
@@ -775,14 +807,19 @@ int nilfs_recover_logical_segments(struct the_nilfs *nilfs,
* %-EINVAL - No valid segment found
*
* %-EIO - I/O error
+ *
+ * %-ENOMEM - Insufficient memory available.
*/
-int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
+int nilfs_search_super_root(struct the_nilfs *nilfs,
struct nilfs_recovery_info *ri)
{
- struct nilfs_segsum_info ssi;
+ struct buffer_head *bh_sum = NULL;
+ struct nilfs_segment_summary *sum;
sector_t pseg_start, pseg_end, sr_pseg_start = 0;
sector_t seg_start, seg_end; /* range of full segment (block number) */
sector_t b, end;
+ unsigned long nblocks;
+ unsigned int flags;
u64 seg_seq;
__u64 segnum, nextnum = 0;
__u64 cno;
@@ -801,17 +838,24 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
/* Read ahead segment */
b = seg_start;
while (b <= seg_end)
- sb_breadahead(sbi->s_super, b++);
+ __breadahead(nilfs->ns_bdev, b++, nilfs->ns_blocksize);
for (;;) {
- /* Load segment summary */
- ret = load_segment_summary(sbi, pseg_start, seg_seq, &ssi);
+ brelse(bh_sum);
+ ret = NILFS_SEG_FAIL_IO;
+ bh_sum = nilfs_read_log_header(nilfs, pseg_start, &sum);
+ if (!bh_sum)
+ goto failed;
+
+ ret = nilfs_validate_log(nilfs, seg_seq, bh_sum, sum);
if (ret) {
if (ret == NILFS_SEG_FAIL_IO)
goto failed;
goto strayed;
}
- pseg_end = pseg_start + ssi.nblocks - 1;
+
+ nblocks = le32_to_cpu(sum->ss_nblocks);
+ pseg_end = pseg_start + nblocks - 1;
if (unlikely(pseg_end > seg_end)) {
ret = NILFS_SEG_FAIL_CONSISTENCY;
goto strayed;
@@ -821,11 +865,13 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
ri->ri_pseg_start = pseg_start;
ri->ri_seq = seg_seq;
ri->ri_segnum = segnum;
- nextnum = nilfs_get_segnum_of_block(nilfs, ssi.next);
+ nextnum = nilfs_get_segnum_of_block(nilfs,
+ le64_to_cpu(sum->ss_next));
ri->ri_nextnum = nextnum;
empty_seg = 0;
- if (!NILFS_SEG_HAS_SR(&ssi) && !scan_newer) {
+ flags = le16_to_cpu(sum->ss_flags);
+ if (!(flags & NILFS_SS_SR) && !scan_newer) {
/* This will never happen because a superblock
(last_segment) always points to a pseg
having a super root. */
@@ -836,14 +882,15 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
if (pseg_start == seg_start) {
nilfs_get_segment_range(nilfs, nextnum, &b, &end);
while (b <= end)
- sb_breadahead(sbi->s_super, b++);
+ __breadahead(nilfs->ns_bdev, b++,
+ nilfs->ns_blocksize);
}
- if (!NILFS_SEG_HAS_SR(&ssi)) {
- if (!ri->ri_lsegs_start && NILFS_SEG_LOGBGN(&ssi)) {
+ if (!(flags & NILFS_SS_SR)) {
+ if (!ri->ri_lsegs_start && (flags & NILFS_SS_LOGBGN)) {
ri->ri_lsegs_start = pseg_start;
ri->ri_lsegs_start_seq = seg_seq;
}
- if (NILFS_SEG_LOGEND(&ssi))
+ if (flags & NILFS_SS_LOGEND)
ri->ri_lsegs_end = pseg_start;
goto try_next_pseg;
}
@@ -854,12 +901,12 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
ri->ri_lsegs_start = ri->ri_lsegs_end = 0;
nilfs_dispose_segment_list(&segments);
- nilfs->ns_pseg_offset = (sr_pseg_start = pseg_start)
- + ssi.nblocks - seg_start;
+ sr_pseg_start = pseg_start;
+ nilfs->ns_pseg_offset = pseg_start + nblocks - seg_start;
nilfs->ns_seg_seq = seg_seq;
nilfs->ns_segnum = segnum;
nilfs->ns_cno = cno; /* nilfs->ns_cno = ri->ri_cno + 1 */
- nilfs->ns_ctime = ssi.ctime;
+ nilfs->ns_ctime = le64_to_cpu(sum->ss_create);
nilfs->ns_nextnum = nextnum;
if (scan_newer)
@@ -870,15 +917,9 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
scan_newer = 1;
}
- /* reset region for roll-forward */
- pseg_start += ssi.nblocks;
- if (pseg_start < seg_end)
- continue;
- goto feed_segment;
-
try_next_pseg:
/* Standing on a course, or met an inconsistent state */
- pseg_start += ssi.nblocks;
+ pseg_start += nblocks;
if (pseg_start < seg_end)
continue;
goto feed_segment;
@@ -909,6 +950,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
super_root_found:
/* Updating pointers relating to the latest checkpoint */
+ brelse(bh_sum);
list_splice_tail(&segments, &ri->ri_used_segments);
nilfs->ns_last_pseg = sr_pseg_start;
nilfs->ns_last_seq = nilfs->ns_seg_seq;
@@ -916,6 +958,7 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
return 0;
failed:
+ brelse(bh_sum);
nilfs_dispose_segment_list(&segments);
return (ret < 0) ? ret : nilfs_warn_segment_error(ret);
}
diff --git a/fs/nilfs2/segbuf.h b/fs/nilfs2/segbuf.h
index 85fbb66455e2..b04f08cc2397 100644
--- a/fs/nilfs2/segbuf.h
+++ b/fs/nilfs2/segbuf.h
@@ -54,17 +54,6 @@ struct nilfs_segsum_info {
sector_t next;
};
-/* macro for the flags */
-#define NILFS_SEG_HAS_SR(sum) ((sum)->flags & NILFS_SS_SR)
-#define NILFS_SEG_LOGBGN(sum) ((sum)->flags & NILFS_SS_LOGBGN)
-#define NILFS_SEG_LOGEND(sum) ((sum)->flags & NILFS_SS_LOGEND)
-#define NILFS_SEG_DSYNC(sum) ((sum)->flags & NILFS_SS_SYNDT)
-#define NILFS_SEG_SIMPLEX(sum) \
- (((sum)->flags & (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) == \
- (NILFS_SS_LOGBGN | NILFS_SS_LOGEND))
-
-#define NILFS_SEG_EMPTY(sum) ((sum)->nblocks == (sum)->nsumblk)
-
/**
* struct nilfs_segment_buffer - Segment buffer
* @sb_super: back pointer to a superblock struct
@@ -141,6 +130,19 @@ int nilfs_segbuf_extend_payload(struct nilfs_segment_buffer *,
struct buffer_head **);
void nilfs_segbuf_fill_in_segsum(struct nilfs_segment_buffer *);
+static inline int nilfs_segbuf_simplex(struct nilfs_segment_buffer *segbuf)
+{
+ unsigned int flags = segbuf->sb_sum.flags;
+
+ return (flags & (NILFS_SS_LOGBGN | NILFS_SS_LOGEND)) ==
+ (NILFS_SS_LOGBGN | NILFS_SS_LOGEND);
+}
+
+static inline int nilfs_segbuf_empty(struct nilfs_segment_buffer *segbuf)
+{
+ return segbuf->sb_sum.nblocks == segbuf->sb_sum.nsumblk;
+}
+
static inline void
nilfs_segbuf_add_segsum_buffer(struct nilfs_segment_buffer *segbuf,
struct buffer_head *bh)
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index c9201649cc49..9fd051a33c4f 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -1914,12 +1914,12 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
}
}
- if (!NILFS_SEG_SIMPLEX(&segbuf->sb_sum)) {
- if (NILFS_SEG_LOGBGN(&segbuf->sb_sum)) {
+ if (!nilfs_segbuf_simplex(segbuf)) {
+ if (segbuf->sb_sum.flags & NILFS_SS_LOGBGN) {
set_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
sci->sc_lseg_stime = jiffies;
}
- if (NILFS_SEG_LOGEND(&segbuf->sb_sum))
+ if (segbuf->sb_sum.flags & NILFS_SS_LOGEND)
clear_bit(NILFS_SC_UNCLOSED, &sci->sc_flags);
}
}
@@ -1951,7 +1951,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
if (update_sr) {
nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
- set_nilfs_sb_dirty(nilfs);
clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
@@ -2082,7 +2081,7 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
/* Avoid empty segment */
if (sci->sc_stage.scnt == NILFS_ST_DONE &&
- NILFS_SEG_EMPTY(&sci->sc_curseg->sb_sum)) {
+ nilfs_segbuf_empty(sci->sc_curseg)) {
nilfs_segctor_abort_construction(sci, nilfs, 1);
goto out;
}
@@ -2408,6 +2407,7 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
{
struct nilfs_sb_info *sbi = sci->sc_sbi;
struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block **sbp;
int err = 0;
nilfs_segctor_accept(sci);
@@ -2423,8 +2423,13 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode)
if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
nilfs_discontinued(nilfs)) {
down_write(&nilfs->ns_sem);
- err = nilfs_commit_super(
- sbi, nilfs_altsb_need_update(nilfs));
+ err = -EIO;
+ sbp = nilfs_prepare_super(sbi,
+ nilfs_sb_will_flip(nilfs));
+ if (likely(sbp)) {
+ nilfs_set_log_cursor(sbp[0], nilfs);
+ err = nilfs_commit_super(sbi, NILFS_SB_COMMIT);
+ }
up_write(&nilfs->ns_sem);
}
}
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 01e20dbb217d..17c487bd8152 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -234,13 +234,13 @@ extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
/* recovery.c */
-extern int nilfs_read_super_root_block(struct super_block *, sector_t,
+extern int nilfs_read_super_root_block(struct the_nilfs *, sector_t,
struct buffer_head **, int);
-extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_sb_info *,
+extern int nilfs_search_super_root(struct the_nilfs *,
struct nilfs_recovery_info *);
-extern int nilfs_recover_logical_segments(struct the_nilfs *,
- struct nilfs_sb_info *,
- struct nilfs_recovery_info *);
+extern int nilfs_salvage_orphan_logs(struct the_nilfs *,
+ struct nilfs_sb_info *,
+ struct nilfs_recovery_info *);
extern void nilfs_dispose_segment_list(struct list_head *);
#endif /* _NILFS_SEGMENT_H */
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 414ef68931cf..777b88dd7bbc 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -55,6 +55,8 @@
#include "nilfs.h"
#include "mdt.h"
#include "alloc.h"
+#include "btree.h"
+#include "btnode.h"
#include "page.h"
#include "cpfile.h"
#include "ifile.h"
@@ -74,6 +76,25 @@ struct kmem_cache *nilfs_btree_path_cache;
static int nilfs_remount(struct super_block *sb, int *flags, char *data);
+static void nilfs_set_error(struct nilfs_sb_info *sbi)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block **sbp;
+
+ down_write(&nilfs->ns_sem);
+ if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
+ nilfs->ns_mount_state |= NILFS_ERROR_FS;
+ sbp = nilfs_prepare_super(sbi, 0);
+ if (likely(sbp)) {
+ sbp[0]->s_state |= cpu_to_le16(NILFS_ERROR_FS);
+ if (sbp[1])
+ sbp[1]->s_state |= cpu_to_le16(NILFS_ERROR_FS);
+ nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
+ }
+ }
+ up_write(&nilfs->ns_sem);
+}
+
/**
* nilfs_error() - report failure condition on a filesystem
*
@@ -99,16 +120,7 @@ void nilfs_error(struct super_block *sb, const char *function,
va_end(args);
if (!(sb->s_flags & MS_RDONLY)) {
- struct the_nilfs *nilfs = sbi->s_nilfs;
-
- down_write(&nilfs->ns_sem);
- if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
- nilfs->ns_mount_state |= NILFS_ERROR_FS;
- nilfs->ns_sbp[0]->s_state |=
- cpu_to_le16(NILFS_ERROR_FS);
- nilfs_commit_super(sbi, 1);
- }
- up_write(&nilfs->ns_sem);
+ nilfs_set_error(sbi);
if (nilfs_test_opt(sbi, ERRORS_RO)) {
printk(KERN_CRIT "Remounting filesystem read-only\n");
@@ -159,24 +171,7 @@ void nilfs_destroy_inode(struct inode *inode)
kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
}
-static void nilfs_clear_inode(struct inode *inode)
-{
- struct nilfs_inode_info *ii = NILFS_I(inode);
-
- /*
- * Free resources allocated in nilfs_read_inode(), here.
- */
- BUG_ON(!list_empty(&ii->i_dirty));
- brelse(ii->i_bh);
- ii->i_bh = NULL;
-
- if (test_bit(NILFS_I_BMAP, &ii->i_state))
- nilfs_bmap_clear(ii->i_bmap);
-
- nilfs_btnode_cache_clear(&ii->i_btnode_cache);
-}
-
-static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
+static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
int err;
@@ -202,12 +197,20 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
printk(KERN_ERR
"NILFS: unable to write superblock (err=%d)\n", err);
if (err == -EIO && nilfs->ns_sbh[1]) {
+ /*
+ * sbp[0] points to newer log than sbp[1],
+ * so copy sbp[0] to sbp[1] to take over sbp[0].
+ */
+ memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0],
+ nilfs->ns_sbsize);
nilfs_fall_back_super_block(nilfs);
goto retry;
}
} else {
struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
+ nilfs->ns_sbwcount++;
+
/*
* The latest segment becomes trailable from the position
* written in superblock.
@@ -216,66 +219,122 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
/* update GC protection for recent segments */
if (nilfs->ns_sbh[1]) {
- sbp = NULL;
- if (dupsb) {
+ if (flag == NILFS_SB_COMMIT_ALL) {
set_buffer_dirty(nilfs->ns_sbh[1]);
- if (!sync_dirty_buffer(nilfs->ns_sbh[1]))
- sbp = nilfs->ns_sbp[1];
+ if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0)
+ goto out;
}
+ if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) <
+ le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno))
+ sbp = nilfs->ns_sbp[1];
}
- if (sbp) {
- spin_lock(&nilfs->ns_last_segment_lock);
- nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
- spin_unlock(&nilfs->ns_last_segment_lock);
- }
- }
+ spin_lock(&nilfs->ns_last_segment_lock);
+ nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
+ spin_unlock(&nilfs->ns_last_segment_lock);
+ }
+ out:
return err;
}
-int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb)
+void nilfs_set_log_cursor(struct nilfs_super_block *sbp,
+ struct the_nilfs *nilfs)
+{
+ sector_t nfreeblocks;
+
+ /* nilfs->ns_sem must be locked by the caller. */
+ nilfs_count_free_blocks(nilfs, &nfreeblocks);
+ sbp->s_free_blocks_count = cpu_to_le64(nfreeblocks);
+
+ spin_lock(&nilfs->ns_last_segment_lock);
+ sbp->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
+ sbp->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
+ sbp->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
+ spin_unlock(&nilfs->ns_last_segment_lock);
+}
+
+struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *sbi,
+ int flip)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
struct nilfs_super_block **sbp = nilfs->ns_sbp;
- sector_t nfreeblocks;
- time_t t;
- int err;
- /* nilfs->sem must be locked by the caller. */
+ /* nilfs->ns_sem must be locked by the caller. */
if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
- if (sbp[1] && sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC))
- nilfs_swap_super_block(nilfs);
- else {
+ if (sbp[1] &&
+ sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) {
+ memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
+ } else {
printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
sbi->s_super->s_id);
- return -EIO;
+ return NULL;
}
+ } else if (sbp[1] &&
+ sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
+ memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
}
- err = nilfs_count_free_blocks(nilfs, &nfreeblocks);
- if (unlikely(err)) {
- printk(KERN_ERR "NILFS: failed to count free blocks\n");
- return err;
- }
- spin_lock(&nilfs->ns_last_segment_lock);
- sbp[0]->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
- sbp[0]->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
- sbp[0]->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
- spin_unlock(&nilfs->ns_last_segment_lock);
+ if (flip && sbp[1])
+ nilfs_swap_super_block(nilfs);
+
+ return sbp;
+}
+
+int nilfs_commit_super(struct nilfs_sb_info *sbi, int flag)
+{
+ struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ time_t t;
+
+ /* nilfs->ns_sem must be locked by the caller. */
t = get_seconds();
- nilfs->ns_sbwtime[0] = t;
- sbp[0]->s_free_blocks_count = cpu_to_le64(nfreeblocks);
+ nilfs->ns_sbwtime = t;
sbp[0]->s_wtime = cpu_to_le64(t);
sbp[0]->s_sum = 0;
sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
(unsigned char *)sbp[0],
nilfs->ns_sbsize));
- if (dupsb && sbp[1]) {
- memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
- nilfs->ns_sbwtime[1] = t;
+ if (flag == NILFS_SB_COMMIT_ALL && sbp[1]) {
+ sbp[1]->s_wtime = sbp[0]->s_wtime;
+ sbp[1]->s_sum = 0;
+ sbp[1]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
+ (unsigned char *)sbp[1],
+ nilfs->ns_sbsize));
}
clear_nilfs_sb_dirty(nilfs);
- return nilfs_sync_super(sbi, dupsb);
+ return nilfs_sync_super(sbi, flag);
+}
+
+/**
+ * nilfs_cleanup_super() - write filesystem state for cleanup
+ * @sbi: nilfs_sb_info to be unmounted or degraded to read-only
+ *
+ * This function restores state flags in the on-disk super block.
+ * This will set "clean" flag (i.e. NILFS_VALID_FS) unless the
+ * filesystem was not clean previously.
+ */
+int nilfs_cleanup_super(struct nilfs_sb_info *sbi)
+{
+ struct nilfs_super_block **sbp;
+ int flag = NILFS_SB_COMMIT;
+ int ret = -EIO;
+
+ sbp = nilfs_prepare_super(sbi, 0);
+ if (sbp) {
+ sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state);
+ nilfs_set_log_cursor(sbp[0], sbi->s_nilfs);
+ if (sbp[1] && sbp[0]->s_last_cno == sbp[1]->s_last_cno) {
+ /*
+ * make the "clean" flag also to the opposite
+ * super block if both super blocks point to
+ * the same checkpoint.
+ */
+ sbp[1]->s_state = sbp[0]->s_state;
+ flag = NILFS_SB_COMMIT_ALL;
+ }
+ ret = nilfs_commit_super(sbi, flag);
+ }
+ return ret;
}
static void nilfs_put_super(struct super_block *sb)
@@ -289,8 +348,7 @@ static void nilfs_put_super(struct super_block *sb)
if (!(sb->s_flags & MS_RDONLY)) {
down_write(&nilfs->ns_sem);
- nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
- nilfs_commit_super(sbi, 1);
+ nilfs_cleanup_super(sbi);
up_write(&nilfs->ns_sem);
}
down_write(&nilfs->ns_super_sem);
@@ -311,6 +369,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct the_nilfs *nilfs = sbi->s_nilfs;
+ struct nilfs_super_block **sbp;
int err = 0;
/* This function is called when super block should be written back */
@@ -318,8 +377,13 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
err = nilfs_construct_segment(sb);
down_write(&nilfs->ns_sem);
- if (nilfs_sb_dirty(nilfs))
- nilfs_commit_super(sbi, 1);
+ if (nilfs_sb_dirty(nilfs)) {
+ sbp = nilfs_prepare_super(sbi, nilfs_sb_will_flip(nilfs));
+ if (likely(sbp)) {
+ nilfs_set_log_cursor(sbp[0], nilfs);
+ nilfs_commit_super(sbi, NILFS_SB_COMMIT);
+ }
+ }
up_write(&nilfs->ns_sem);
return err;
@@ -442,20 +506,20 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
struct nilfs_sb_info *sbi = NILFS_SB(sb);
if (!nilfs_test_opt(sbi, BARRIER))
- seq_printf(seq, ",nobarrier");
+ seq_puts(seq, ",nobarrier");
if (nilfs_test_opt(sbi, SNAPSHOT))
seq_printf(seq, ",cp=%llu",
(unsigned long long int)sbi->s_snapshot_cno);
if (nilfs_test_opt(sbi, ERRORS_PANIC))
- seq_printf(seq, ",errors=panic");
+ seq_puts(seq, ",errors=panic");
if (nilfs_test_opt(sbi, ERRORS_CONT))
- seq_printf(seq, ",errors=continue");
+ seq_puts(seq, ",errors=continue");
if (nilfs_test_opt(sbi, STRICT_ORDER))
- seq_printf(seq, ",order=strict");
+ seq_puts(seq, ",order=strict");
if (nilfs_test_opt(sbi, NORECOVERY))
- seq_printf(seq, ",norecovery");
+ seq_puts(seq, ",norecovery");
if (nilfs_test_opt(sbi, DISCARD))
- seq_printf(seq, ",discard");
+ seq_puts(seq, ",discard");
return 0;
}
@@ -467,7 +531,7 @@ static const struct super_operations nilfs_sops = {
/* .write_inode = nilfs_write_inode, */
/* .put_inode = nilfs_put_inode, */
/* .drop_inode = nilfs_drop_inode, */
- .delete_inode = nilfs_delete_inode,
+ .evict_inode = nilfs_evict_inode,
.put_super = nilfs_put_super,
/* .write_super = nilfs_write_super, */
.sync_fs = nilfs_sync_fs,
@@ -475,7 +539,6 @@ static const struct super_operations nilfs_sops = {
/* .unlockfs */
.statfs = nilfs_statfs,
.remount_fs = nilfs_remount,
- .clear_inode = nilfs_clear_inode,
/* .umount_begin */
.show_options = nilfs_show_options
};
@@ -524,23 +587,25 @@ static const struct export_operations nilfs_export_ops = {
enum {
Opt_err_cont, Opt_err_panic, Opt_err_ro,
- Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
- Opt_discard, Opt_err,
+ Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
+ Opt_discard, Opt_nodiscard, Opt_err,
};
static match_table_t tokens = {
{Opt_err_cont, "errors=continue"},
{Opt_err_panic, "errors=panic"},
{Opt_err_ro, "errors=remount-ro"},
+ {Opt_barrier, "barrier"},
{Opt_nobarrier, "nobarrier"},
{Opt_snapshot, "cp=%u"},
{Opt_order, "order=%s"},
{Opt_norecovery, "norecovery"},
{Opt_discard, "discard"},
+ {Opt_nodiscard, "nodiscard"},
{Opt_err, NULL}
};
-static int parse_options(char *options, struct super_block *sb)
+static int parse_options(char *options, struct super_block *sb, int is_remount)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
char *p;
@@ -557,6 +622,9 @@ static int parse_options(char *options, struct super_block *sb)
token = match_token(p, tokens, args);
switch (token) {
+ case Opt_barrier:
+ nilfs_set_opt(sbi, BARRIER);
+ break;
case Opt_nobarrier:
nilfs_clear_opt(sbi, BARRIER);
break;
@@ -582,8 +650,26 @@ static int parse_options(char *options, struct super_block *sb)
case Opt_snapshot:
if (match_int(&args[0], &option) || option <= 0)
return 0;
- if (!(sb->s_flags & MS_RDONLY))
+ if (is_remount) {
+ if (!nilfs_test_opt(sbi, SNAPSHOT)) {
+ printk(KERN_ERR
+ "NILFS: cannot change regular "
+ "mount to snapshot.\n");
+ return 0;
+ } else if (option != sbi->s_snapshot_cno) {
+ printk(KERN_ERR
+ "NILFS: cannot remount to a "
+ "different snapshot.\n");
+ return 0;
+ }
+ break;
+ }
+ if (!(sb->s_flags & MS_RDONLY)) {
+ printk(KERN_ERR "NILFS: cannot mount snapshot "
+ "read/write. A read-only option is "
+ "required.\n");
return 0;
+ }
sbi->s_snapshot_cno = option;
nilfs_set_opt(sbi, SNAPSHOT);
break;
@@ -593,6 +679,9 @@ static int parse_options(char *options, struct super_block *sb)
case Opt_discard:
nilfs_set_opt(sbi, DISCARD);
break;
+ case Opt_nodiscard:
+ nilfs_clear_opt(sbi, DISCARD);
+ break;
default:
printk(KERN_ERR
"NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -613,11 +702,18 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi,
static int nilfs_setup_super(struct nilfs_sb_info *sbi)
{
struct the_nilfs *nilfs = sbi->s_nilfs;
- struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
- int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count);
- int mnt_count = le16_to_cpu(sbp->s_mnt_count);
+ struct nilfs_super_block **sbp;
+ int max_mnt_count;
+ int mnt_count;
+
+ /* nilfs->ns_sem must be locked by the caller. */
+ sbp = nilfs_prepare_super(sbi, 0);
+ if (!sbp)
+ return -EIO;
+
+ max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count);
+ mnt_count = le16_to_cpu(sbp[0]->s_mnt_count);
- /* nilfs->sem must be locked by the caller. */
if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
printk(KERN_WARNING
"NILFS warning: mounting fs with errors\n");
@@ -628,12 +724,15 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
#endif
}
if (!max_mnt_count)
- sbp->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
-
- sbp->s_mnt_count = cpu_to_le16(mnt_count + 1);
- sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS);
- sbp->s_mtime = cpu_to_le64(get_seconds());
- return nilfs_commit_super(sbi, 1);
+ sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
+
+ sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1);
+ sbp[0]->s_state =
+ cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
+ sbp[0]->s_mtime = cpu_to_le64(get_seconds());
+ /* synchronize sbp[1] with sbp[0] */
+ memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
+ return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
}
struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb,
@@ -670,7 +769,7 @@ int nilfs_store_magic_and_option(struct super_block *sb,
sbi->s_interval = le32_to_cpu(sbp->s_c_interval);
sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max);
- return !parse_options(data, sb) ? -EINVAL : 0 ;
+ return !parse_options(data, sb, 0) ? -EINVAL : 0 ;
}
/**
@@ -819,7 +918,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
static int nilfs_remount(struct super_block *sb, int *flags, char *data)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
- struct nilfs_super_block *sbp;
struct the_nilfs *nilfs = sbi->s_nilfs;
unsigned long old_sb_flags;
struct nilfs_mount_options old_opts;
@@ -833,32 +931,17 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
old_opts.snapshot_cno = sbi->s_snapshot_cno;
was_snapshot = nilfs_test_opt(sbi, SNAPSHOT);
- if (!parse_options(data, sb)) {
+ if (!parse_options(data, sb, 1)) {
err = -EINVAL;
goto restore_opts;
}
sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
err = -EINVAL;
- if (was_snapshot) {
- if (!(*flags & MS_RDONLY)) {
- printk(KERN_ERR "NILFS (device %s): cannot remount "
- "snapshot read/write.\n",
- sb->s_id);
- goto restore_opts;
- } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) {
- printk(KERN_ERR "NILFS (device %s): cannot "
- "remount to a different snapshot.\n",
- sb->s_id);
- goto restore_opts;
- }
- } else {
- if (nilfs_test_opt(sbi, SNAPSHOT)) {
- printk(KERN_ERR "NILFS (device %s): cannot change "
- "a regular mount to a snapshot.\n",
- sb->s_id);
- goto restore_opts;
- }
+ if (was_snapshot && !(*flags & MS_RDONLY)) {
+ printk(KERN_ERR "NILFS (device %s): cannot remount snapshot "
+ "read/write.\n", sb->s_id);
+ goto restore_opts;
}
if (!nilfs_valid_fs(nilfs)) {
@@ -880,12 +963,7 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
* the RDONLY flag and then mark the partition as valid again.
*/
down_write(&nilfs->ns_sem);
- sbp = nilfs->ns_sbp[0];
- if (!(sbp->s_state & le16_to_cpu(NILFS_VALID_FS)) &&
- (nilfs->ns_mount_state & NILFS_VALID_FS))
- sbp->s_state = cpu_to_le16(nilfs->ns_mount_state);
- sbp->s_mtime = cpu_to_le64(get_seconds());
- nilfs_commit_super(sbi, 1);
+ nilfs_cleanup_super(sbi);
up_write(&nilfs->ns_sem);
} else {
/*
@@ -1119,7 +1197,7 @@ static void nilfs_inode_init_once(void *obj)
init_rwsem(&ii->xattr_sem);
#endif
nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
- ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union;
+ ii->i_bmap = &ii->i_bmap_data;
inode_init_once(&ii->vfs_inode);
}
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 8c1097327abc..f2efc8c5be7f 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -38,6 +38,8 @@
static LIST_HEAD(nilfs_objects);
static DEFINE_SPINLOCK(nilfs_lock);
+static int nilfs_valid_sb(struct nilfs_super_block *sbp);
+
void nilfs_set_last_segment(struct the_nilfs *nilfs,
sector_t start_blocknr, u64 seq, __u64 cno)
{
@@ -45,6 +47,16 @@ void nilfs_set_last_segment(struct the_nilfs *nilfs,
nilfs->ns_last_pseg = start_blocknr;
nilfs->ns_last_seq = seq;
nilfs->ns_last_cno = cno;
+
+ if (!nilfs_sb_dirty(nilfs)) {
+ if (nilfs->ns_prev_seq == nilfs->ns_last_seq)
+ goto stay_cursor;
+
+ set_nilfs_sb_dirty(nilfs);
+ }
+ nilfs->ns_prev_seq = nilfs->ns_last_seq;
+
+ stay_cursor:
spin_unlock(&nilfs->ns_last_segment_lock);
}
@@ -159,8 +171,7 @@ void put_nilfs(struct the_nilfs *nilfs)
kfree(nilfs);
}
-static int nilfs_load_super_root(struct the_nilfs *nilfs,
- struct nilfs_sb_info *sbi, sector_t sr_block)
+static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block)
{
struct buffer_head *bh_sr;
struct nilfs_super_root *raw_sr;
@@ -169,7 +180,7 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
unsigned inode_size;
int err;
- err = nilfs_read_super_root_block(sbi->s_super, sr_block, &bh_sr, 1);
+ err = nilfs_read_super_root_block(nilfs, sr_block, &bh_sr, 1);
if (unlikely(err))
return err;
@@ -248,6 +259,37 @@ static void nilfs_clear_recovery_info(struct nilfs_recovery_info *ri)
}
/**
+ * nilfs_store_log_cursor - load log cursor from a super block
+ * @nilfs: nilfs object
+ * @sbp: buffer storing super block to be read
+ *
+ * nilfs_store_log_cursor() reads the last position of the log
+ * containing a super root from a given super block, and initializes
+ * relevant information on the nilfs object preparatory for log
+ * scanning and recovery.
+ */
+static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
+ struct nilfs_super_block *sbp)
+{
+ int ret = 0;
+
+ nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
+ nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
+ nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
+
+ nilfs->ns_prev_seq = nilfs->ns_last_seq;
+ nilfs->ns_seg_seq = nilfs->ns_last_seq;
+ nilfs->ns_segnum =
+ nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
+ nilfs->ns_cno = nilfs->ns_last_cno + 1;
+ if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
+ printk(KERN_ERR "NILFS invalid last segment number.\n");
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+/**
* load_nilfs - load and recover the nilfs
* @nilfs: the_nilfs structure to be released
* @sbi: nilfs_sb_info used to recover past segment
@@ -285,13 +327,55 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
nilfs_init_recovery_info(&ri);
- err = nilfs_search_super_root(nilfs, sbi, &ri);
+ err = nilfs_search_super_root(nilfs, &ri);
if (unlikely(err)) {
- printk(KERN_ERR "NILFS: error searching super root.\n");
- goto failed;
+ struct nilfs_super_block **sbp = nilfs->ns_sbp;
+ int blocksize;
+
+ if (err != -EINVAL)
+ goto scan_error;
+
+ if (!nilfs_valid_sb(sbp[1])) {
+ printk(KERN_WARNING
+ "NILFS warning: unable to fall back to spare"
+ "super block\n");
+ goto scan_error;
+ }
+ printk(KERN_INFO
+ "NILFS: try rollback from an earlier position\n");
+
+ /*
+ * restore super block with its spare and reconfigure
+ * relevant states of the nilfs object.
+ */
+ memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
+ nilfs->ns_crc_seed = le32_to_cpu(sbp[0]->s_crc_seed);
+ nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
+
+ /* verify consistency between two super blocks */
+ blocksize = BLOCK_SIZE << le32_to_cpu(sbp[0]->s_log_block_size);
+ if (blocksize != nilfs->ns_blocksize) {
+ printk(KERN_WARNING
+ "NILFS warning: blocksize differs between "
+ "two super blocks (%d != %d)\n",
+ blocksize, nilfs->ns_blocksize);
+ goto scan_error;
+ }
+
+ err = nilfs_store_log_cursor(nilfs, sbp[0]);
+ if (err)
+ goto scan_error;
+
+ /* drop clean flag to allow roll-forward and recovery */
+ nilfs->ns_mount_state &= ~NILFS_VALID_FS;
+ valid_fs = 0;
+
+ err = nilfs_search_super_root(nilfs, &ri);
+ if (err)
+ goto scan_error;
}
- err = nilfs_load_super_root(nilfs, sbi, ri.ri_super_root);
+ err = nilfs_load_super_root(nilfs, ri.ri_super_root);
if (unlikely(err)) {
printk(KERN_ERR "NILFS: error loading super root.\n");
goto failed;
@@ -320,14 +404,13 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
goto failed_unload;
}
- err = nilfs_recover_logical_segments(nilfs, sbi, &ri);
+ err = nilfs_salvage_orphan_logs(nilfs, sbi, &ri);
if (err)
goto failed_unload;
down_write(&nilfs->ns_sem);
- nilfs->ns_mount_state |= NILFS_VALID_FS;
- nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
- err = nilfs_commit_super(sbi, 1);
+ nilfs->ns_mount_state |= NILFS_VALID_FS; /* set "clean" flag */
+ err = nilfs_cleanup_super(sbi);
up_write(&nilfs->ns_sem);
if (err) {
@@ -343,6 +426,10 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
sbi->s_super->s_flags = s_flags;
return 0;
+ scan_error:
+ printk(KERN_ERR "NILFS: error searching super root.\n");
+ goto failed;
+
failed_unload:
nilfs_mdt_destroy(nilfs->ns_cpfile);
nilfs_mdt_destroy(nilfs->ns_sufile);
@@ -515,8 +602,8 @@ static int nilfs_load_super_block(struct the_nilfs *nilfs,
nilfs_swap_super_block(nilfs);
}
- nilfs->ns_sbwtime[0] = le64_to_cpu(sbp[0]->s_wtime);
- nilfs->ns_sbwtime[1] = valid[!swp] ? le64_to_cpu(sbp[1]->s_wtime) : 0;
+ nilfs->ns_sbwcount = 0;
+ nilfs->ns_sbwtime = le64_to_cpu(sbp[0]->s_wtime);
nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
*sbpp = sbp[0];
return 0;
@@ -604,6 +691,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
when reloading fails. */
}
nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
+ nilfs->ns_blocksize = blocksize;
err = nilfs_store_disk_layout(nilfs, sbp);
if (err)
@@ -616,23 +704,9 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
bdi = nilfs->ns_bdev->bd_inode->i_mapping->backing_dev_info;
nilfs->ns_bdi = bdi ? : &default_backing_dev_info;
- /* Finding last segment */
- nilfs->ns_last_pseg = le64_to_cpu(sbp->s_last_pseg);
- nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
- nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);
-
- nilfs->ns_seg_seq = nilfs->ns_last_seq;
- nilfs->ns_segnum =
- nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
- nilfs->ns_cno = nilfs->ns_last_cno + 1;
- if (nilfs->ns_segnum >= nilfs->ns_nsegments) {
- printk(KERN_ERR "NILFS invalid last segment number.\n");
- err = -EINVAL;
+ err = nilfs_store_log_cursor(nilfs, sbp);
+ if (err)
goto failed_sbh;
- }
- /* Dummy values */
- nilfs->ns_free_segments_count =
- nilfs->ns_nsegments - (nilfs->ns_segnum + 1);
/* Initialize gcinode cache */
err = nilfs_init_gccache(nilfs);
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 1ab974533697..f785a7b0ab99 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -57,7 +57,8 @@ enum {
* @ns_current: back pointer to current mount
* @ns_sbh: buffer heads of on-disk super blocks
* @ns_sbp: pointers to super block data
- * @ns_sbwtime: previous write time of super blocks
+ * @ns_sbwtime: previous write time of super block
+ * @ns_sbwcount: write count of super block
* @ns_sbsize: size of valid data in super block
* @ns_supers: list of nilfs super block structs
* @ns_seg_seq: segment sequence counter
@@ -73,7 +74,7 @@ enum {
* @ns_last_seq: sequence value of the latest segment
* @ns_last_cno: checkpoint number of the latest segment
* @ns_prot_seq: least sequence number of segments which must not be reclaimed
- * @ns_free_segments_count: counter of free segments
+ * @ns_prev_seq: base sequence number used to decide if advance log cursor
* @ns_segctor_sem: segment constructor semaphore
* @ns_dat: DAT file inode
* @ns_cpfile: checkpoint file inode
@@ -82,6 +83,7 @@ enum {
* @ns_gc_inodes: dummy inodes to keep live blocks
* @ns_gc_inodes_h: hash list to keep dummy inode holding live blocks
* @ns_blocksize_bits: bit length of block size
+ * @ns_blocksize: block size
* @ns_nsegments: number of segments in filesystem
* @ns_blocks_per_segment: number of blocks per segment
* @ns_r_segments_percentage: reserved segments percentage
@@ -119,7 +121,8 @@ struct the_nilfs {
*/
struct buffer_head *ns_sbh[2];
struct nilfs_super_block *ns_sbp[2];
- time_t ns_sbwtime[2];
+ time_t ns_sbwtime;
+ unsigned ns_sbwcount;
unsigned ns_sbsize;
unsigned ns_mount_state;
@@ -149,7 +152,7 @@ struct the_nilfs {
u64 ns_last_seq;
__u64 ns_last_cno;
u64 ns_prot_seq;
- unsigned long ns_free_segments_count;
+ u64 ns_prev_seq;
struct rw_semaphore ns_segctor_sem;
@@ -168,6 +171,7 @@ struct the_nilfs {
/* Disk layout information (static) */
unsigned int ns_blocksize_bits;
+ unsigned int ns_blocksize;
unsigned long ns_nsegments;
unsigned long ns_blocks_per_segment;
unsigned long ns_r_segments_percentage;
@@ -203,20 +207,17 @@ THE_NILFS_FNS(SB_DIRTY, sb_dirty)
/* Minimum interval of periodical update of superblocks (in seconds) */
#define NILFS_SB_FREQ 10
-#define NILFS_ALTSB_FREQ 60 /* spare superblock */
static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
{
u64 t = get_seconds();
- return t < nilfs->ns_sbwtime[0] ||
- t > nilfs->ns_sbwtime[0] + NILFS_SB_FREQ;
+ return t < nilfs->ns_sbwtime || t > nilfs->ns_sbwtime + NILFS_SB_FREQ;
}
-static inline int nilfs_altsb_need_update(struct the_nilfs *nilfs)
+static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
{
- u64 t = get_seconds();
- struct nilfs_super_block **sbp = nilfs->ns_sbp;
- return sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
+ int flip_bits = nilfs->ns_sbwcount & 0x0FL;
+ return (flip_bits != 0x08 && flip_bits != 0x0F);
}
void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 0399bcbe09c8..152b83ec005d 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -369,11 +369,11 @@ void fsnotify_unmount_inodes(struct list_head *list)
struct inode *need_iput_tmp;
/*
- * We cannot __iget() an inode in state I_CLEAR, I_FREEING,
+ * We cannot __iget() an inode in state I_FREEING,
* I_WILL_FREE, or I_NEW which is fine because by that point
* the inode cannot have any associated watches.
*/
- if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW))
+ if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue;
/*
@@ -397,7 +397,7 @@ void fsnotify_unmount_inodes(struct list_head *list)
/* In case the dropping of a reference would nuke next_i. */
if ((&next_i->i_sb_list != list) &&
atomic_read(&next_i->i_count) &&
- !(next_i->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))) {
+ !(next_i->i_state & (I_FREEING | I_WILL_FREE))) {
__iget(next_i);
need_iput = next_i;
}
diff --git a/fs/notify/inotify/inotify.c b/fs/notify/inotify/inotify.c
index 27b75ebc7460..cf6b0429a257 100644
--- a/fs/notify/inotify/inotify.c
+++ b/fs/notify/inotify/inotify.c
@@ -377,11 +377,11 @@ void inotify_unmount_inodes(struct list_head *list)
struct list_head *watches;
/*
- * We cannot __iget() an inode in state I_CLEAR, I_FREEING,
+ * We cannot __iget() an inode in state I_FREEING,
* I_WILL_FREE, or I_NEW which is fine because by that point
* the inode cannot have any associated watches.
*/
- if (inode->i_state & (I_CLEAR|I_FREEING|I_WILL_FREE|I_NEW))
+ if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue;
/*
@@ -403,8 +403,7 @@ void inotify_unmount_inodes(struct list_head *list)
/* In case the dropping of a reference would nuke next_i. */
if ((&next_i->i_sb_list != list) &&
atomic_read(&next_i->i_count) &&
- !(next_i->i_state & (I_CLEAR | I_FREEING |
- I_WILL_FREE))) {
+ !(next_i->i_state & (I_FREEING|I_WILL_FREE))) {
__iget(next_i);
need_iput = next_i;
}
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 4b57fb1eac2a..93622b175fc7 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -2238,7 +2238,7 @@ void ntfs_clear_extent_inode(ntfs_inode *ni)
}
/**
- * ntfs_clear_big_inode - clean up the ntfs specific part of an inode
+ * ntfs_evict_big_inode - clean up the ntfs specific part of an inode
* @vi: vfs inode pending annihilation
*
* When the VFS is going to remove an inode from memory, ntfs_clear_big_inode()
@@ -2247,10 +2247,13 @@ void ntfs_clear_extent_inode(ntfs_inode *ni)
*
* If the MFT record is dirty, we commit it before doing anything else.
*/
-void ntfs_clear_big_inode(struct inode *vi)
+void ntfs_evict_big_inode(struct inode *vi)
{
ntfs_inode *ni = NTFS_I(vi);
+ truncate_inode_pages(&vi->i_data, 0);
+ end_writeback(vi);
+
#ifdef NTFS_RW
if (NInoDirty(ni)) {
bool was_bad = (is_bad_inode(vi));
@@ -2879,9 +2882,6 @@ void ntfs_truncate_vfs(struct inode *vi) {
*
* Called with ->i_mutex held. For the ATTR_SIZE (i.e. ->truncate) case, also
* called with ->i_alloc_sem held for writing.
- *
- * Basically this is a copy of generic notify_change() and inode_setattr()
- * functionality, except we intercept and abort changes in i_size.
*/
int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
{
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index 9a113544605d..2dabf813456c 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -279,7 +279,7 @@ extern struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name,
extern struct inode *ntfs_alloc_big_inode(struct super_block *sb);
extern void ntfs_destroy_big_inode(struct inode *inode);
-extern void ntfs_clear_big_inode(struct inode *vi);
+extern void ntfs_evict_big_inode(struct inode *vi);
extern void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni);
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 0de1db6cddbf..512806171bfa 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -2700,7 +2700,7 @@ static const struct super_operations ntfs_sops = {
.put_super = ntfs_put_super, /* Syscall: umount. */
.statfs = ntfs_statfs, /* Syscall: statfs */
.remount_fs = ntfs_remount, /* Syscall: mount -o remount. */
- .clear_inode = ntfs_clear_big_inode, /* VFS: Called when an inode is
+ .evict_inode = ntfs_evict_big_inode, /* VFS: Called when an inode is
removed from memory. */
//.umount_begin = NULL, /* Forced umount. */
.show_options = ntfs_show_options, /* Show mount options in
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 3623ca20cc18..fa57345a9af6 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -196,15 +196,14 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
dump_stack();
goto bail;
}
-
- past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
- mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino,
- (unsigned long long)past_eof);
-
- if (create && (iblock >= past_eof))
- set_buffer_new(bh_result);
}
+ past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
+ mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino,
+ (unsigned long long)past_eof);
+ if (create && (iblock >= past_eof))
+ set_buffer_new(bh_result);
+
bail:
if (err < 0)
err = -EIO;
@@ -459,36 +458,6 @@ int walk_page_buffers( handle_t *handle,
return ret;
}
-handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
- struct page *page,
- unsigned from,
- unsigned to)
-{
- struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- handle_t *handle;
- int ret = 0;
-
- handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
- if (IS_ERR(handle)) {
- ret = -ENOMEM;
- mlog_errno(ret);
- goto out;
- }
-
- if (ocfs2_should_order_data(inode)) {
- ret = ocfs2_jbd2_file_inode(handle, inode);
- if (ret < 0)
- mlog_errno(ret);
- }
-out:
- if (ret) {
- if (!IS_ERR(handle))
- ocfs2_commit_trans(osb, handle);
- handle = ERR_PTR(ret);
- }
- return handle;
-}
-
static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
{
sector_t status;
@@ -669,11 +638,10 @@ static ssize_t ocfs2_direct_IO(int rw,
if (i_size_read(inode) <= offset)
return 0;
- ret = blockdev_direct_IO_no_locking(rw, iocb, inode,
- inode->i_sb->s_bdev, iov, offset,
- nr_segs,
- ocfs2_direct_IO_get_blocks,
- ocfs2_dio_end_io);
+ ret = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
+ iov, offset, nr_segs,
+ ocfs2_direct_IO_get_blocks,
+ ocfs2_dio_end_io, NULL, 0);
mlog_exit(ret);
return ret;
@@ -1131,23 +1099,37 @@ out:
*/
static int ocfs2_grab_pages_for_write(struct address_space *mapping,
struct ocfs2_write_ctxt *wc,
- u32 cpos, loff_t user_pos, int new,
+ u32 cpos, loff_t user_pos,
+ unsigned user_len, int new,
struct page *mmap_page)
{
int ret = 0, i;
- unsigned long start, target_index, index;
+ unsigned long start, target_index, end_index, index;
struct inode *inode = mapping->host;
+ loff_t last_byte;
target_index = user_pos >> PAGE_CACHE_SHIFT;
/*
* Figure out how many pages we'll be manipulating here. For
* non allocating write, we just change the one
- * page. Otherwise, we'll need a whole clusters worth.
+ * page. Otherwise, we'll need a whole clusters worth. If we're
+ * writing past i_size, we only need enough pages to cover the
+ * last page of the write.
*/
if (new) {
wc->w_num_pages = ocfs2_pages_per_cluster(inode->i_sb);
start = ocfs2_align_clusters_to_page_index(inode->i_sb, cpos);
+ /*
+ * We need the index *past* the last page we could possibly
+ * touch. This is the page past the end of the write or
+ * i_size, whichever is greater.
+ */
+ last_byte = max(user_pos + user_len, i_size_read(inode));
+ BUG_ON(last_byte < 1);
+ end_index = ((last_byte - 1) >> PAGE_CACHE_SHIFT) + 1;
+ if ((start + wc->w_num_pages) > end_index)
+ wc->w_num_pages = end_index - start;
} else {
wc->w_num_pages = 1;
start = target_index;
@@ -1620,21 +1602,20 @@ out:
* write path can treat it as an non-allocating write, which has no
* special case code for sparse/nonsparse files.
*/
-static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
- unsigned len,
+static int ocfs2_expand_nonsparse_inode(struct inode *inode,
+ struct buffer_head *di_bh,
+ loff_t pos, unsigned len,
struct ocfs2_write_ctxt *wc)
{
int ret;
- struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
loff_t newsize = pos + len;
- if (ocfs2_sparse_alloc(osb))
- return 0;
+ BUG_ON(ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)));
if (newsize <= i_size_read(inode))
return 0;
- ret = ocfs2_extend_no_holes(inode, newsize, pos);
+ ret = ocfs2_extend_no_holes(inode, di_bh, newsize, pos);
if (ret)
mlog_errno(ret);
@@ -1644,6 +1625,18 @@ static int ocfs2_expand_nonsparse_inode(struct inode *inode, loff_t pos,
return ret;
}
+static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh,
+ loff_t pos)
+{
+ int ret = 0;
+
+ BUG_ON(!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)));
+ if (pos > i_size_read(inode))
+ ret = ocfs2_zero_extend(inode, di_bh, pos);
+
+ return ret;
+}
+
int ocfs2_write_begin_nolock(struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata,
@@ -1679,7 +1672,11 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
}
}
- ret = ocfs2_expand_nonsparse_inode(inode, pos, len, wc);
+ if (ocfs2_sparse_alloc(osb))
+ ret = ocfs2_zero_tail(inode, di_bh, pos);
+ else
+ ret = ocfs2_expand_nonsparse_inode(inode, di_bh, pos, len,
+ wc);
if (ret) {
mlog_errno(ret);
goto out;
@@ -1789,7 +1786,7 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
* that we can zero and flush if we error after adding the
* extent.
*/
- ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos,
+ ret = ocfs2_grab_pages_for_write(mapping, wc, wc->w_cpos, pos, len,
cluster_of_pages, mmap_page);
if (ret) {
mlog_errno(ret);
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 6b5a492e1749..153abb5abef0 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -1671,7 +1671,7 @@ struct dlm_ctxt * dlm_register_domain(const char *domain,
struct dlm_ctxt *dlm = NULL;
struct dlm_ctxt *new_ctxt = NULL;
- if (strlen(domain) > O2NM_MAX_NAME_LEN) {
+ if (strlen(domain) >= O2NM_MAX_NAME_LEN) {
ret = -ENAMETOOLONG;
mlog(ML_ERROR, "domain name length too long\n");
goto leave;
@@ -1709,6 +1709,7 @@ retry:
}
if (dlm_protocol_compare(&dlm->fs_locking_proto, fs_proto)) {
+ spin_unlock(&dlm_domain_lock);
mlog(ML_ERROR,
"Requested locking protocol version is not "
"compatible with already registered domain "
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index f8b75ce4be70..9dfaac73b36d 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -463,7 +463,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm)
if (dlm->reco.dead_node == O2NM_INVALID_NODE_NUM) {
int bit;
- bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES+1, 0);
+ bit = find_next_bit (dlm->recovery_map, O2NM_MAX_NODES, 0);
if (bit >= O2NM_MAX_NODES || bit < 0)
dlm_set_reco_dead_node(dlm, O2NM_INVALID_NODE_NUM);
else
diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c
index b83d6107a1f5..a43ebb11ad3b 100644
--- a/fs/ocfs2/dlmfs/dlmfs.c
+++ b/fs/ocfs2/dlmfs/dlmfs.c
@@ -214,10 +214,12 @@ static int dlmfs_file_setattr(struct dentry *dentry, struct iattr *attr)
attr->ia_valid &= ~ATTR_SIZE;
error = inode_change_ok(inode, attr);
- if (!error)
- error = inode_setattr(inode, attr);
+ if (error)
+ return error;
- return error;
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
static unsigned int dlmfs_file_poll(struct file *file, poll_table *wait)
@@ -355,13 +357,12 @@ static void dlmfs_destroy_inode(struct inode *inode)
kmem_cache_free(dlmfs_inode_cache, DLMFS_I(inode));
}
-static void dlmfs_clear_inode(struct inode *inode)
+static void dlmfs_evict_inode(struct inode *inode)
{
int status;
struct dlmfs_inode_private *ip;
- if (!inode)
- return;
+ end_writeback(inode);
mlog(0, "inode %lu\n", inode->i_ino);
@@ -631,7 +632,7 @@ static const struct super_operations dlmfs_ops = {
.statfs = simple_statfs,
.alloc_inode = dlmfs_alloc_inode,
.destroy_inode = dlmfs_destroy_inode,
- .clear_inode = dlmfs_clear_inode,
+ .evict_inode = dlmfs_evict_inode,
.drop_inode = generic_delete_inode,
};
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 6a13ea64c447..f5415bdbbac7 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -724,28 +724,55 @@ leave:
return status;
}
+/*
+ * While a write will already be ordering the data, a truncate will not.
+ * Thus, we need to explicitly order the zeroed pages.
+ */
+static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode)
+{
+ struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ handle_t *handle = NULL;
+ int ret = 0;
+
+ if (!ocfs2_should_order_data(inode))
+ goto out;
+
+ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
+ if (IS_ERR(handle)) {
+ ret = -ENOMEM;
+ mlog_errno(ret);
+ goto out;
+ }
+
+ ret = ocfs2_jbd2_file_inode(handle, inode);
+ if (ret < 0)
+ mlog_errno(ret);
+
+out:
+ if (ret) {
+ if (!IS_ERR(handle))
+ ocfs2_commit_trans(osb, handle);
+ handle = ERR_PTR(ret);
+ }
+ return handle;
+}
+
/* Some parts of this taken from generic_cont_expand, which turned out
* to be too fragile to do exactly what we need without us having to
* worry about recursive locking in ->write_begin() and ->write_end(). */
-static int ocfs2_write_zero_page(struct inode *inode,
- u64 size)
+static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from,
+ u64 abs_to)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
- unsigned long index;
- unsigned int offset;
+ unsigned long index = abs_from >> PAGE_CACHE_SHIFT;
handle_t *handle = NULL;
int ret;
+ unsigned zero_from, zero_to, block_start, block_end;
- offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
- /* ugh. in prepare/commit_write, if from==to==start of block, we
- ** skip the prepare. make sure we never send an offset for the start
- ** of a block
- */
- if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) {
- offset++;
- }
- index = size >> PAGE_CACHE_SHIFT;
+ BUG_ON(abs_from >= abs_to);
+ BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT));
+ BUG_ON(abs_from & (inode->i_blkbits - 1));
page = grab_cache_page(mapping, index);
if (!page) {
@@ -754,31 +781,56 @@ static int ocfs2_write_zero_page(struct inode *inode,
goto out;
}
- ret = ocfs2_prepare_write_nolock(inode, page, offset, offset);
- if (ret < 0) {
- mlog_errno(ret);
- goto out_unlock;
- }
+ /* Get the offsets within the page that we want to zero */
+ zero_from = abs_from & (PAGE_CACHE_SIZE - 1);
+ zero_to = abs_to & (PAGE_CACHE_SIZE - 1);
+ if (!zero_to)
+ zero_to = PAGE_CACHE_SIZE;
- if (ocfs2_should_order_data(inode)) {
- handle = ocfs2_start_walk_page_trans(inode, page, offset,
- offset);
- if (IS_ERR(handle)) {
- ret = PTR_ERR(handle);
- handle = NULL;
+ mlog(0,
+ "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n",
+ (unsigned long long)abs_from, (unsigned long long)abs_to,
+ index, zero_from, zero_to);
+
+ /* We know that zero_from is block aligned */
+ for (block_start = zero_from; block_start < zero_to;
+ block_start = block_end) {
+ block_end = block_start + (1 << inode->i_blkbits);
+
+ /*
+ * block_start is block-aligned. Bump it by one to
+ * force ocfs2_{prepare,commit}_write() to zero the
+ * whole block.
+ */
+ ret = ocfs2_prepare_write_nolock(inode, page,
+ block_start + 1,
+ block_start + 1);
+ if (ret < 0) {
+ mlog_errno(ret);
goto out_unlock;
}
- }
- /* must not update i_size! */
- ret = block_commit_write(page, offset, offset);
- if (ret < 0)
- mlog_errno(ret);
- else
- ret = 0;
+ if (!handle) {
+ handle = ocfs2_zero_start_ordered_transaction(inode);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ handle = NULL;
+ break;
+ }
+ }
+
+ /* must not update i_size! */
+ ret = block_commit_write(page, block_start + 1,
+ block_start + 1);
+ if (ret < 0)
+ mlog_errno(ret);
+ else
+ ret = 0;
+ }
if (handle)
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
+
out_unlock:
unlock_page(page);
page_cache_release(page);
@@ -786,22 +838,114 @@ out:
return ret;
}
-static int ocfs2_zero_extend(struct inode *inode,
- u64 zero_to_size)
+/*
+ * Find the next range to zero. We do this in terms of bytes because
+ * that's what ocfs2_zero_extend() wants, and it is dealing with the
+ * pagecache. We may return multiple extents.
+ *
+ * zero_start and zero_end are ocfs2_zero_extend()s current idea of what
+ * needs to be zeroed. range_start and range_end return the next zeroing
+ * range. A subsequent call should pass the previous range_end as its
+ * zero_start. If range_end is 0, there's nothing to do.
+ *
+ * Unwritten extents are skipped over. Refcounted extents are CoWd.
+ */
+static int ocfs2_zero_extend_get_range(struct inode *inode,
+ struct buffer_head *di_bh,
+ u64 zero_start, u64 zero_end,
+ u64 *range_start, u64 *range_end)
{
- int ret = 0;
- u64 start_off;
- struct super_block *sb = inode->i_sb;
+ int rc = 0, needs_cow = 0;
+ u32 p_cpos, zero_clusters = 0;
+ u32 zero_cpos =
+ zero_start >> OCFS2_SB(inode->i_sb)->s_clustersize_bits;
+ u32 last_cpos = ocfs2_clusters_for_bytes(inode->i_sb, zero_end);
+ unsigned int num_clusters = 0;
+ unsigned int ext_flags = 0;
- start_off = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode));
- while (start_off < zero_to_size) {
- ret = ocfs2_write_zero_page(inode, start_off);
- if (ret < 0) {
- mlog_errno(ret);
+ while (zero_cpos < last_cpos) {
+ rc = ocfs2_get_clusters(inode, zero_cpos, &p_cpos,
+ &num_clusters, &ext_flags);
+ if (rc) {
+ mlog_errno(rc);
goto out;
}
- start_off += sb->s_blocksize;
+ if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
+ zero_clusters = num_clusters;
+ if (ext_flags & OCFS2_EXT_REFCOUNTED)
+ needs_cow = 1;
+ break;
+ }
+
+ zero_cpos += num_clusters;
+ }
+ if (!zero_clusters) {
+ *range_end = 0;
+ goto out;
+ }
+
+ while ((zero_cpos + zero_clusters) < last_cpos) {
+ rc = ocfs2_get_clusters(inode, zero_cpos + zero_clusters,
+ &p_cpos, &num_clusters,
+ &ext_flags);
+ if (rc) {
+ mlog_errno(rc);
+ goto out;
+ }
+
+ if (!p_cpos || (ext_flags & OCFS2_EXT_UNWRITTEN))
+ break;
+ if (ext_flags & OCFS2_EXT_REFCOUNTED)
+ needs_cow = 1;
+ zero_clusters += num_clusters;
+ }
+ if ((zero_cpos + zero_clusters) > last_cpos)
+ zero_clusters = last_cpos - zero_cpos;
+
+ if (needs_cow) {
+ rc = ocfs2_refcount_cow(inode, di_bh, zero_cpos, zero_clusters,
+ UINT_MAX);
+ if (rc) {
+ mlog_errno(rc);
+ goto out;
+ }
+ }
+
+ *range_start = ocfs2_clusters_to_bytes(inode->i_sb, zero_cpos);
+ *range_end = ocfs2_clusters_to_bytes(inode->i_sb,
+ zero_cpos + zero_clusters);
+
+out:
+ return rc;
+}
+
+/*
+ * Zero one range returned from ocfs2_zero_extend_get_range(). The caller
+ * has made sure that the entire range needs zeroing.
+ */
+static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start,
+ u64 range_end)
+{
+ int rc = 0;
+ u64 next_pos;
+ u64 zero_pos = range_start;
+
+ mlog(0, "range_start = %llu, range_end = %llu\n",
+ (unsigned long long)range_start,
+ (unsigned long long)range_end);
+ BUG_ON(range_start >= range_end);
+
+ while (zero_pos < range_end) {
+ next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE;
+ if (next_pos > range_end)
+ next_pos = range_end;
+ rc = ocfs2_write_zero_page(inode, zero_pos, next_pos);
+ if (rc < 0) {
+ mlog_errno(rc);
+ break;
+ }
+ zero_pos = next_pos;
/*
* Very large extends have the potential to lock up
@@ -810,16 +954,63 @@ static int ocfs2_zero_extend(struct inode *inode,
cond_resched();
}
-out:
+ return rc;
+}
+
+int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh,
+ loff_t zero_to_size)
+{
+ int ret = 0;
+ u64 zero_start, range_start = 0, range_end = 0;
+ struct super_block *sb = inode->i_sb;
+
+ zero_start = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode));
+ mlog(0, "zero_start %llu for i_size %llu\n",
+ (unsigned long long)zero_start,
+ (unsigned long long)i_size_read(inode));
+ while (zero_start < zero_to_size) {
+ ret = ocfs2_zero_extend_get_range(inode, di_bh, zero_start,
+ zero_to_size,
+ &range_start,
+ &range_end);
+ if (ret) {
+ mlog_errno(ret);
+ break;
+ }
+ if (!range_end)
+ break;
+ /* Trim the ends */
+ if (range_start < zero_start)
+ range_start = zero_start;
+ if (range_end > zero_to_size)
+ range_end = zero_to_size;
+
+ ret = ocfs2_zero_extend_range(inode, range_start,
+ range_end);
+ if (ret) {
+ mlog_errno(ret);
+ break;
+ }
+ zero_start = range_end;
+ }
+
return ret;
}
-int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to)
+int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh,
+ u64 new_i_size, u64 zero_to)
{
int ret;
u32 clusters_to_add;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
+ /*
+ * Only quota files call this without a bh, and they can't be
+ * refcounted.
+ */
+ BUG_ON(!di_bh && (oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL));
+ BUG_ON(!di_bh && !(oi->ip_flags & OCFS2_INODE_SYSTEM_FILE));
+
clusters_to_add = ocfs2_clusters_for_bytes(inode->i_sb, new_i_size);
if (clusters_to_add < oi->ip_clusters)
clusters_to_add = 0;
@@ -840,7 +1031,7 @@ int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size, u64 zero_to)
* still need to zero the area between the old i_size and the
* new i_size.
*/
- ret = ocfs2_zero_extend(inode, zero_to);
+ ret = ocfs2_zero_extend(inode, di_bh, zero_to);
if (ret < 0)
mlog_errno(ret);
@@ -862,27 +1053,15 @@ static int ocfs2_extend_file(struct inode *inode,
goto out;
if (i_size_read(inode) == new_i_size)
- goto out;
+ goto out;
BUG_ON(new_i_size < i_size_read(inode));
/*
- * Fall through for converting inline data, even if the fs
- * supports sparse files.
- *
- * The check for inline data here is legal - nobody can add
- * the feature since we have i_mutex. We must check it again
- * after acquiring ip_alloc_sem though, as paths like mmap
- * might have raced us to converting the inode to extents.
- */
- if (!(oi->ip_dyn_features & OCFS2_INLINE_DATA_FL)
- && ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
- goto out_update_size;
-
- /*
* The alloc sem blocks people in read/write from reading our
* allocation until we're done changing it. We depend on
* i_mutex to block other extend/truncate calls while we're
- * here.
+ * here. We even have to hold it for sparse files because there
+ * might be some tail zeroing.
*/
down_write(&oi->ip_alloc_sem);
@@ -899,14 +1078,16 @@ static int ocfs2_extend_file(struct inode *inode,
ret = ocfs2_convert_inline_data_to_extents(inode, di_bh);
if (ret) {
up_write(&oi->ip_alloc_sem);
-
mlog_errno(ret);
goto out;
}
}
- if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
- ret = ocfs2_extend_no_holes(inode, new_i_size, new_i_size);
+ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+ ret = ocfs2_zero_extend(inode, di_bh, new_i_size);
+ else
+ ret = ocfs2_extend_no_holes(inode, di_bh, new_i_size,
+ new_i_size);
up_write(&oi->ip_alloc_sem);
@@ -1052,18 +1233,26 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
}
/*
- * This will intentionally not wind up calling simple_setsize(),
+ * This will intentionally not wind up calling truncate_setsize(),
* since all the work for a size change has been done above.
* Otherwise, we could get into problems with truncate as
* ip_alloc_sem is used there to protect against i_size
* changes.
+ *
+ * XXX: this means the conditional below can probably be removed.
*/
- status = inode_setattr(inode, attr);
- if (status < 0) {
- mlog_errno(status);
- goto bail_commit;
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ status = vmtruncate(inode, attr->ia_size);
+ if (status) {
+ mlog_errno(status);
+ goto bail_commit;
+ }
}
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+
status = ocfs2_mark_inode_dirty(handle, inode, bh);
if (status < 0)
mlog_errno(status);
@@ -2119,12 +2308,12 @@ relock:
* blocks outside i_size. Trim these off again.
* Don't need i_size_read because we hold i_mutex.
*
- * XXX(hch): this looks buggy because ocfs2 did not
+ * XXX(truncate): this looks buggy because ocfs2 did not
* actually implement ->truncate. Take a look at
* the new truncate sequence and update this accordingly
*/
if (*ppos + count > inode->i_size)
- simple_setsize(inode, inode->i_size);
+ truncate_setsize(inode, inode->i_size);
ret = written;
goto out_dio;
}
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h
index d66cf4f7c70e..97bf761c9e7c 100644
--- a/fs/ocfs2/file.h
+++ b/fs/ocfs2/file.h
@@ -54,8 +54,10 @@ int ocfs2_add_inode_data(struct ocfs2_super *osb,
int ocfs2_simple_size_update(struct inode *inode,
struct buffer_head *di_bh,
u64 new_i_size);
-int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size,
- u64 zero_to);
+int ocfs2_extend_no_holes(struct inode *inode, struct buffer_head *di_bh,
+ u64 new_i_size, u64 zero_to);
+int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh,
+ loff_t zero_to);
int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index abb0a95cc717..eb7fd07c90f2 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -969,7 +969,7 @@ static void ocfs2_cleanup_delete_inode(struct inode *inode,
truncate_inode_pages(&inode->i_data, 0);
}
-void ocfs2_delete_inode(struct inode *inode)
+static void ocfs2_delete_inode(struct inode *inode)
{
int wipe, status;
sigset_t oldset;
@@ -1075,20 +1075,17 @@ bail_unlock_nfs_sync:
bail_unblock:
ocfs2_unblock_signals(&oldset);
bail:
- clear_inode(inode);
mlog_exit_void();
}
-void ocfs2_clear_inode(struct inode *inode)
+static void ocfs2_clear_inode(struct inode *inode)
{
int status;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
mlog_entry_void();
- if (!inode)
- goto bail;
-
+ end_writeback(inode);
mlog(0, "Clearing inode: %llu, nlink = %u\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_nlink);
@@ -1180,10 +1177,20 @@ void ocfs2_clear_inode(struct inode *inode)
jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal,
&oi->ip_jinode);
-bail:
mlog_exit_void();
}
+void ocfs2_evict_inode(struct inode *inode)
+{
+ if (!inode->i_nlink ||
+ (OCFS2_I(inode)->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)) {
+ ocfs2_delete_inode(inode);
+ } else {
+ truncate_inode_pages(&inode->i_data, 0);
+ }
+ ocfs2_clear_inode(inode);
+}
+
/* Called under inode_lock, with no more references on the
* struct inode, so it's safe here to check the flags field
* and to manipulate i_nlink without any other locks. */
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 9f5f5fcadc45..975eedd7b243 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -123,8 +123,7 @@ static inline struct ocfs2_caching_info *INODE_CACHE(struct inode *inode)
return &OCFS2_I(inode)->ip_metadata_cache;
}
-void ocfs2_clear_inode(struct inode *inode);
-void ocfs2_delete_inode(struct inode *inode);
+void ocfs2_evict_inode(struct inode *inode);
void ocfs2_drop_inode(struct inode *inode);
/* Flags for ocfs2_iget() */
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 47878cf16418..39113b5e79e7 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -1936,7 +1936,7 @@ void ocfs2_orphan_scan_work(struct work_struct *work)
mutex_lock(&os->os_lock);
ocfs2_queue_orphan_scan(osb);
if (atomic_read(&os->os_state) == ORPHAN_SCAN_ACTIVE)
- schedule_delayed_work(&os->os_orphan_scan_work,
+ queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work,
ocfs2_orphan_scan_timeout());
mutex_unlock(&os->os_lock);
}
@@ -1976,8 +1976,8 @@ void ocfs2_orphan_scan_start(struct ocfs2_super *osb)
atomic_set(&os->os_state, ORPHAN_SCAN_INACTIVE);
else {
atomic_set(&os->os_state, ORPHAN_SCAN_ACTIVE);
- schedule_delayed_work(&os->os_orphan_scan_work,
- ocfs2_orphan_scan_timeout());
+ queue_delayed_work(ocfs2_wq, &os->os_orphan_scan_work,
+ ocfs2_orphan_scan_timeout());
}
}
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 3d7419682dc0..ec6adbf8f551 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -118,6 +118,7 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb)
{
unsigned int la_mb;
unsigned int gd_mb;
+ unsigned int la_max_mb;
unsigned int megs_per_slot;
struct super_block *sb = osb->sb;
@@ -182,6 +183,12 @@ unsigned int ocfs2_la_default_mb(struct ocfs2_super *osb)
if (megs_per_slot < la_mb)
la_mb = megs_per_slot;
+ /* We can't store more bits than we can in a block. */
+ la_max_mb = ocfs2_clusters_to_megabytes(osb->sb,
+ ocfs2_local_alloc_size(sb) * 8);
+ if (la_mb > la_max_mb)
+ la_mb = la_max_mb;
+
return la_mb;
}
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index 2bb35fe00511..4607923eb24c 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -775,7 +775,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot)
* locking allocators ranks above a transaction start
*/
WARN_ON(journal_current_handle());
- status = ocfs2_extend_no_holes(gqinode,
+ status = ocfs2_extend_no_holes(gqinode, NULL,
gqinode->i_size + (need_alloc << sb->s_blocksize_bits),
gqinode->i_size);
if (status < 0)
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index 8bd70d4d184d..dc78764ccc4c 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -971,7 +971,7 @@ static struct ocfs2_quota_chunk *ocfs2_local_quota_add_chunk(
u64 p_blkno;
/* We are protected by dqio_sem so no locking needed */
- status = ocfs2_extend_no_holes(lqinode,
+ status = ocfs2_extend_no_holes(lqinode, NULL,
lqinode->i_size + 2 * sb->s_blocksize,
lqinode->i_size);
if (status < 0) {
@@ -1114,7 +1114,7 @@ static struct ocfs2_quota_chunk *ocfs2_extend_local_quota_file(
return ocfs2_local_quota_add_chunk(sb, type, offset);
/* We are protected by dqio_sem so no locking needed */
- status = ocfs2_extend_no_holes(lqinode,
+ status = ocfs2_extend_no_holes(lqinode, NULL,
lqinode->i_size + sb->s_blocksize,
lqinode->i_size);
if (status < 0) {
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 4793f36f6518..32949df10694 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4166,6 +4166,12 @@ static int __ocfs2_reflink(struct dentry *old_dentry,
struct inode *inode = old_dentry->d_inode;
struct buffer_head *new_bh = NULL;
+ if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE) {
+ ret = -EINVAL;
+ mlog_errno(ret);
+ goto out;
+ }
+
ret = filemap_fdatawrite(inode->i_mapping);
if (ret) {
mlog_errno(ret);
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index f4c2a9eb8c4d..a8e6a95a353f 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -741,7 +741,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
le16_to_cpu(bg->bg_free_bits_count));
le32_add_cpu(&cl->cl_recs[alloc_rec].c_total,
le16_to_cpu(bg->bg_bits));
- cl->cl_recs[alloc_rec].c_blkno = cpu_to_le64(bg->bg_blkno);
+ cl->cl_recs[alloc_rec].c_blkno = bg->bg_blkno;
if (le16_to_cpu(cl->cl_next_free_rec) < le16_to_cpu(cl->cl_count))
le16_add_cpu(&cl->cl_next_free_rec, 1);
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 0eaa929a4dbf..ae1a4437a980 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -145,8 +145,7 @@ static const struct super_operations ocfs2_sops = {
.alloc_inode = ocfs2_alloc_inode,
.destroy_inode = ocfs2_destroy_inode,
.drop_inode = ocfs2_drop_inode,
- .clear_inode = ocfs2_clear_inode,
- .delete_inode = ocfs2_delete_inode,
+ .evict_inode = ocfs2_evict_inode,
.sync_fs = ocfs2_sync_fs,
.put_super = ocfs2_put_super,
.remount_fs = ocfs2_remount,
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e97b34842cfe..d03469f61801 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -709,7 +709,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
struct ocfs2_xattr_value_buf *vb,
struct ocfs2_xattr_set_ctxt *ctxt)
{
- int status = 0;
+ int status = 0, credits;
handle_t *handle = ctxt->handle;
enum ocfs2_alloc_restarted why;
u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters);
@@ -719,38 +719,54 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
- status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
- OCFS2_JOURNAL_ACCESS_WRITE);
- if (status < 0) {
- mlog_errno(status);
- goto leave;
- }
+ while (clusters_to_add) {
+ status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (status < 0) {
+ mlog_errno(status);
+ break;
+ }
- prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
- status = ocfs2_add_clusters_in_btree(handle,
- &et,
- &logical_start,
- clusters_to_add,
- 0,
- ctxt->data_ac,
- ctxt->meta_ac,
- &why);
- if (status < 0) {
- mlog_errno(status);
- goto leave;
- }
+ prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
+ status = ocfs2_add_clusters_in_btree(handle,
+ &et,
+ &logical_start,
+ clusters_to_add,
+ 0,
+ ctxt->data_ac,
+ ctxt->meta_ac,
+ &why);
+ if ((status < 0) && (status != -EAGAIN)) {
+ if (status != -ENOSPC)
+ mlog_errno(status);
+ break;
+ }
- ocfs2_journal_dirty(handle, vb->vb_bh);
+ ocfs2_journal_dirty(handle, vb->vb_bh);
- clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - prev_clusters;
+ clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) -
+ prev_clusters;
- /*
- * We should have already allocated enough space before the transaction,
- * so no need to restart.
- */
- BUG_ON(why != RESTART_NONE || clusters_to_add);
-
-leave:
+ if (why != RESTART_NONE && clusters_to_add) {
+ /*
+ * We can only fail in case the alloc file doesn't give
+ * up enough clusters.
+ */
+ BUG_ON(why == RESTART_META);
+
+ mlog(0, "restarting xattr value extension for %u"
+ " clusters,.\n", clusters_to_add);
+ credits = ocfs2_calc_extend_credits(inode->i_sb,
+ &vb->vb_xv->xr_list,
+ clusters_to_add);
+ status = ocfs2_extend_trans(handle, credits);
+ if (status < 0) {
+ status = -ENOMEM;
+ mlog_errno(status);
+ break;
+ }
+ }
+ }
return status;
}
@@ -6788,16 +6804,15 @@ out:
return ret;
}
-static int ocfs2_reflink_xattr_buckets(handle_t *handle,
+static int ocfs2_reflink_xattr_bucket(handle_t *handle,
u64 blkno, u64 new_blkno, u32 clusters,
+ u32 *cpos, int num_buckets,
struct ocfs2_alloc_context *meta_ac,
struct ocfs2_alloc_context *data_ac,
struct ocfs2_reflink_xattr_tree_args *args)
{
int i, j, ret = 0;
struct super_block *sb = args->reflink->old_inode->i_sb;
- u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb));
- u32 num_buckets = clusters * bpc;
int bpb = args->old_bucket->bu_blocks;
struct ocfs2_xattr_value_buf vb = {
.vb_access = ocfs2_journal_access,
@@ -6816,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
break;
}
- /*
- * The real bucket num in this series of blocks is stored
- * in the 1st bucket.
- */
- if (i == 0)
- num_buckets = le16_to_cpu(
- bucket_xh(args->old_bucket)->xh_num_buckets);
-
ret = ocfs2_xattr_bucket_journal_access(handle,
args->new_bucket,
OCFS2_JOURNAL_ACCESS_CREATE);
@@ -6837,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
bucket_block(args->old_bucket, j),
sb->s_blocksize);
+ /*
+ * Record the start cpos so that we can use it to initialize
+ * our xattr tree we also set the xh_num_bucket for the new
+ * bucket.
+ */
+ if (i == 0) {
+ *cpos = le32_to_cpu(bucket_xh(args->new_bucket)->
+ xh_entries[0].xe_name_hash);
+ bucket_xh(args->new_bucket)->xh_num_buckets =
+ cpu_to_le16(num_buckets);
+ }
+
ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
ret = ocfs2_reflink_xattr_header(handle, args->reflink,
@@ -6866,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
}
ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
+
ocfs2_xattr_bucket_relse(args->old_bucket);
ocfs2_xattr_bucket_relse(args->new_bucket);
}
@@ -6874,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
ocfs2_xattr_bucket_relse(args->new_bucket);
return ret;
}
+
+static int ocfs2_reflink_xattr_buckets(handle_t *handle,
+ struct inode *inode,
+ struct ocfs2_reflink_xattr_tree_args *args,
+ struct ocfs2_extent_tree *et,
+ struct ocfs2_alloc_context *meta_ac,
+ struct ocfs2_alloc_context *data_ac,
+ u64 blkno, u32 cpos, u32 len)
+{
+ int ret, first_inserted = 0;
+ u32 p_cluster, num_clusters, reflink_cpos = 0;
+ u64 new_blkno;
+ unsigned int num_buckets, reflink_buckets;
+ unsigned int bpc =
+ ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
+
+ ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+ num_buckets = le16_to_cpu(bucket_xh(args->old_bucket)->xh_num_buckets);
+ ocfs2_xattr_bucket_relse(args->old_bucket);
+
+ while (len && num_buckets) {
+ ret = ocfs2_claim_clusters(handle, data_ac,
+ 1, &p_cluster, &num_clusters);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ new_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
+ reflink_buckets = min(num_buckets, bpc * num_clusters);
+
+ ret = ocfs2_reflink_xattr_bucket(handle, blkno,
+ new_blkno, num_clusters,
+ &reflink_cpos, reflink_buckets,
+ meta_ac, data_ac, args);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ /*
+ * For the 1st allocated cluster, we make it use the same cpos
+ * so that the xattr tree looks the same as the original one
+ * in the most case.
+ */
+ if (!first_inserted) {
+ reflink_cpos = cpos;
+ first_inserted = 1;
+ }
+ ret = ocfs2_insert_extent(handle, et, reflink_cpos, new_blkno,
+ num_clusters, 0, meta_ac);
+ if (ret)
+ mlog_errno(ret);
+
+ mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
+ (unsigned long long)new_blkno, num_clusters, reflink_cpos);
+
+ len -= num_clusters;
+ blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters);
+ num_buckets -= reflink_buckets;
+ }
+out:
+ return ret;
+}
+
/*
* Create the same xattr extent record in the new inode's xattr tree.
*/
@@ -6885,8 +6974,6 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
void *para)
{
int ret, credits = 0;
- u32 p_cluster, num_clusters;
- u64 new_blkno;
handle_t *handle;
struct ocfs2_reflink_xattr_tree_args *args =
(struct ocfs2_reflink_xattr_tree_args *)para;
@@ -6895,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
struct ocfs2_alloc_context *data_ac = NULL;
struct ocfs2_extent_tree et;
+ mlog(0, "reflink xattr buckets %llu len %u\n",
+ (unsigned long long)blkno, len);
+
ocfs2_init_xattr_tree_extent_tree(&et,
INODE_CACHE(args->reflink->new_inode),
args->new_blk_bh);
@@ -6914,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
goto out;
}
- ret = ocfs2_claim_clusters(handle, data_ac,
- len, &p_cluster, &num_clusters);
- if (ret) {
- mlog_errno(ret);
- goto out_commit;
- }
-
- new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster);
-
- mlog(0, "reflink xattr buckets %llu to %llu, len %u\n",
- (unsigned long long)blkno, (unsigned long long)new_blkno, len);
- ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len,
- meta_ac, data_ac, args);
- if (ret) {
- mlog_errno(ret);
- goto out_commit;
- }
-
- mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
- (unsigned long long)new_blkno, len, cpos);
- ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno,
- len, 0, meta_ac);
+ ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et,
+ meta_ac, data_ac,
+ blkno, cpos, len);
if (ret)
mlog_errno(ret);
-out_commit:
ocfs2_commit_trans(osb, handle);
out:
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index b42d62419034..393f3f659da7 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -25,11 +25,10 @@ static struct buffer_head *omfs_get_bucket(struct inode *dir,
const char *name, int namelen, int *ofs)
{
int nbuckets = (dir->i_size - OMFS_DIR_START)/8;
- int block = clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino);
int bucket = omfs_hash(name, namelen, nbuckets);
*ofs = OMFS_DIR_START + bucket * 8;
- return sb_bread(dir->i_sb, block);
+ return omfs_bread(dir->i_sb, dir->i_ino);
}
static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block,
@@ -42,8 +41,7 @@ static struct buffer_head *omfs_scan_list(struct inode *dir, u64 block,
*prev_block = ~0;
while (block != ~0) {
- bh = sb_bread(dir->i_sb,
- clus_to_blk(OMFS_SB(dir->i_sb), block));
+ bh = omfs_bread(dir->i_sb, block);
if (!bh) {
err = -EIO;
goto err;
@@ -86,11 +84,10 @@ static struct buffer_head *omfs_find_entry(struct inode *dir,
int omfs_make_empty(struct inode *inode, struct super_block *sb)
{
struct omfs_sb_info *sbi = OMFS_SB(sb);
- int block = clus_to_blk(sbi, inode->i_ino);
struct buffer_head *bh;
struct omfs_inode *oi;
- bh = sb_bread(sb, block);
+ bh = omfs_bread(sb, inode->i_ino);
if (!bh)
return -ENOMEM;
@@ -134,7 +131,7 @@ static int omfs_add_link(struct dentry *dentry, struct inode *inode)
brelse(bh);
/* now set the sibling and parent pointers on the new inode */
- bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), inode->i_ino));
+ bh = omfs_bread(dir->i_sb, inode->i_ino);
if (!bh)
goto out;
@@ -190,8 +187,7 @@ static int omfs_delete_entry(struct dentry *dentry)
if (prev != ~0) {
/* found in middle of list, get list ptr */
brelse(bh);
- bh = sb_bread(dir->i_sb,
- clus_to_blk(OMFS_SB(dir->i_sb), prev));
+ bh = omfs_bread(dir->i_sb, prev);
if (!bh)
goto out;
@@ -224,8 +220,7 @@ static int omfs_dir_is_empty(struct inode *inode)
u64 *ptr;
int i;
- bh = sb_bread(inode->i_sb, clus_to_blk(OMFS_SB(inode->i_sb),
- inode->i_ino));
+ bh = omfs_bread(inode->i_sb, inode->i_ino);
if (!bh)
return 0;
@@ -353,8 +348,7 @@ static int omfs_fill_chain(struct file *filp, void *dirent, filldir_t filldir,
/* follow chain in this bucket */
while (fsblock != ~0) {
- bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb),
- fsblock));
+ bh = omfs_bread(dir->i_sb, fsblock);
if (!bh)
goto out;
@@ -466,7 +460,7 @@ static int omfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
hchain = (filp->f_pos >> 20) - 1;
hindex = filp->f_pos & 0xfffff;
- bh = sb_bread(dir->i_sb, clus_to_blk(OMFS_SB(dir->i_sb), dir->i_ino));
+ bh = omfs_bread(dir->i_sb, dir->i_ino);
if (!bh)
goto out;
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 6e7a3291bbe8..3f518de91c39 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -50,7 +50,7 @@ int omfs_shrink_inode(struct inode *inode)
if (inode->i_size != 0)
goto out;
- bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
+ bh = omfs_bread(inode->i_sb, next);
if (!bh)
goto out;
@@ -90,7 +90,7 @@ int omfs_shrink_inode(struct inode *inode)
if (next == ~0)
break;
- bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
+ bh = omfs_bread(inode->i_sb, next);
if (!bh)
goto out;
oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
@@ -232,7 +232,7 @@ static int omfs_get_block(struct inode *inode, sector_t block,
int remain;
ret = -EIO;
- bh = sb_bread(inode->i_sb, clus_to_blk(sbi, inode->i_ino));
+ bh = omfs_bread(inode->i_sb, inode->i_ino);
if (!bh)
goto out;
@@ -265,7 +265,7 @@ static int omfs_get_block(struct inode *inode, sector_t block,
break;
brelse(bh);
- bh = sb_bread(inode->i_sb, clus_to_blk(sbi, next));
+ bh = omfs_bread(inode->i_sb, next);
if (!bh)
goto out;
oe = (struct omfs_extent *) (&bh->b_data[OMFS_EXTENT_CONT]);
@@ -312,9 +312,17 @@ static int omfs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return block_write_begin(file, mapping, pos, len, flags,
- pagep, fsdata, omfs_get_block);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ omfs_get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t omfs_bmap(struct address_space *mapping, sector_t block)
@@ -333,7 +341,29 @@ const struct file_operations omfs_file_operations = {
.splice_read = generic_file_splice_read,
};
+static int omfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
const struct inode_operations omfs_file_inops = {
+ .setattr = omfs_setattr,
.truncate = omfs_truncate
};
diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c
index 089839a6cc64..14a22863291a 100644
--- a/fs/omfs/inode.c
+++ b/fs/omfs/inode.c
@@ -19,6 +19,15 @@ MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>");
MODULE_DESCRIPTION("OMFS (ReplayTV/Karma) Filesystem for Linux");
MODULE_LICENSE("GPL");
+struct buffer_head *omfs_bread(struct super_block *sb, sector_t block)
+{
+ struct omfs_sb_info *sbi = OMFS_SB(sb);
+ if (block >= sbi->s_num_blocks)
+ return NULL;
+
+ return sb_bread(sb, clus_to_blk(sbi, block));
+}
+
struct inode *omfs_new_inode(struct inode *dir, int mode)
{
struct inode *inode;
@@ -93,15 +102,13 @@ static int __omfs_write_inode(struct inode *inode, int wait)
struct omfs_inode *oi;
struct omfs_sb_info *sbi = OMFS_SB(inode->i_sb);
struct buffer_head *bh, *bh2;
- unsigned int block;
u64 ctime;
int i;
int ret = -EIO;
int sync_failed = 0;
/* get current inode since we may have written sibling ptrs etc. */
- block = clus_to_blk(sbi, inode->i_ino);
- bh = sb_bread(inode->i_sb, block);
+ bh = omfs_bread(inode->i_sb, inode->i_ino);
if (!bh)
goto out;
@@ -140,8 +147,7 @@ static int __omfs_write_inode(struct inode *inode, int wait)
/* if mirroring writes, copy to next fsblock */
for (i = 1; i < sbi->s_mirrors; i++) {
- bh2 = sb_bread(inode->i_sb, block + i *
- (sbi->s_blocksize / sbi->s_sys_blocksize));
+ bh2 = omfs_bread(inode->i_sb, inode->i_ino + i);
if (!bh2)
goto out_brelse;
@@ -175,9 +181,13 @@ int omfs_sync_inode(struct inode *inode)
* called when an entry is deleted, need to clear the bits in the
* bitmaps.
*/
-static void omfs_delete_inode(struct inode *inode)
+static void omfs_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
+
+ if (inode->i_nlink)
+ return;
if (S_ISREG(inode->i_mode)) {
inode->i_size = 0;
@@ -185,7 +195,6 @@ static void omfs_delete_inode(struct inode *inode)
}
omfs_clear_range(inode->i_sb, inode->i_ino, 2);
- clear_inode(inode);
}
struct inode *omfs_iget(struct super_block *sb, ino_t ino)
@@ -193,7 +202,6 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino)
struct omfs_sb_info *sbi = OMFS_SB(sb);
struct omfs_inode *oi;
struct buffer_head *bh;
- unsigned int block;
u64 ctime;
unsigned long nsecs;
struct inode *inode;
@@ -204,8 +212,7 @@ struct inode *omfs_iget(struct super_block *sb, ino_t ino)
if (!(inode->i_state & I_NEW))
return inode;
- block = clus_to_blk(sbi, ino);
- bh = sb_bread(inode->i_sb, block);
+ bh = omfs_bread(inode->i_sb, ino);
if (!bh)
goto iget_failed;
@@ -284,7 +291,7 @@ static int omfs_statfs(struct dentry *dentry, struct kstatfs *buf)
static const struct super_operations omfs_sops = {
.write_inode = omfs_write_inode,
- .delete_inode = omfs_delete_inode,
+ .evict_inode = omfs_evict_inode,
.put_super = omfs_put_super,
.statfs = omfs_statfs,
.show_options = generic_show_options,
@@ -319,6 +326,9 @@ static int omfs_get_imap(struct super_block *sb)
goto nomem;
block = clus_to_blk(sbi, sbi->s_bitmap_ino);
+ if (block >= sbi->s_num_blocks)
+ goto nomem;
+
ptr = sbi->s_imap;
for (count = bitmap_size; count > 0; count -= sb->s_blocksize) {
bh = sb_bread(sb, block++);
@@ -417,7 +427,6 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
struct omfs_root_block *omfs_rb;
struct omfs_sb_info *sbi;
struct inode *root;
- sector_t start;
int ret = -EINVAL;
save_mount_options(sb, (char *) data);
@@ -486,8 +495,7 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
sbi->s_block_shift = get_bitmask_order(sbi->s_blocksize) -
get_bitmask_order(sbi->s_sys_blocksize);
- start = clus_to_blk(sbi, be64_to_cpu(omfs_sb->s_root_block));
- bh2 = sb_bread(sb, start);
+ bh2 = omfs_bread(sb, be64_to_cpu(omfs_sb->s_root_block));
if (!bh2)
goto out_brelse_bh;
@@ -504,6 +512,21 @@ static int omfs_fill_super(struct super_block *sb, void *data, int silent)
goto out_brelse_bh2;
}
+ if (sbi->s_bitmap_ino != ~0ULL &&
+ sbi->s_bitmap_ino > sbi->s_num_blocks) {
+ printk(KERN_ERR "omfs: free space bitmap location is corrupt "
+ "(%llx, total blocks %llx)\n",
+ (unsigned long long) sbi->s_bitmap_ino,
+ (unsigned long long) sbi->s_num_blocks);
+ goto out_brelse_bh2;
+ }
+ if (sbi->s_clustersize < 1 ||
+ sbi->s_clustersize > OMFS_MAX_CLUSTER_SIZE) {
+ printk(KERN_ERR "omfs: cluster size out of range (%d)",
+ sbi->s_clustersize);
+ goto out_brelse_bh2;
+ }
+
ret = omfs_get_imap(sb);
if (ret)
goto out_brelse_bh2;
@@ -529,6 +552,8 @@ out_brelse_bh2:
out_brelse_bh:
brelse(bh);
end:
+ if (ret)
+ kfree(sbi);
return ret;
}
diff --git a/fs/omfs/omfs.h b/fs/omfs/omfs.h
index ebe2fdbe535e..7d414fef501a 100644
--- a/fs/omfs/omfs.h
+++ b/fs/omfs/omfs.h
@@ -58,6 +58,7 @@ extern void omfs_make_empty_table(struct buffer_head *bh, int offset);
extern int omfs_shrink_inode(struct inode *inode);
/* inode.c */
+extern struct buffer_head *omfs_bread(struct super_block *sb, sector_t block);
extern struct inode *omfs_iget(struct super_block *sb, ino_t inode);
extern struct inode *omfs_new_inode(struct inode *dir, int mode);
extern int omfs_reserve_block(struct super_block *sb, sector_t block);
diff --git a/fs/omfs/omfs_fs.h b/fs/omfs/omfs_fs.h
index 12cca245d6e8..ee5e4327de92 100644
--- a/fs/omfs/omfs_fs.h
+++ b/fs/omfs/omfs_fs.h
@@ -17,6 +17,7 @@
#define OMFS_EXTENT_CONT 0x40
#define OMFS_XOR_COUNT 19
#define OMFS_MAX_BLOCK_SIZE 8192
+#define OMFS_MAX_CLUSTER_SIZE 8
struct omfs_super_block {
char s_fill1[256];
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 3e73de5967ff..fc8497643fd0 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -74,6 +74,7 @@ int ibm_partition(struct parsed_partitions *state)
} *label;
unsigned char *data;
Sector sect;
+ sector_t labelsect;
res = 0;
blocksize = bdev_logical_block_size(bdev);
@@ -98,10 +99,19 @@ int ibm_partition(struct parsed_partitions *state)
goto out_freeall;
/*
+ * Special case for FBA disks: label sector does not depend on
+ * blocksize.
+ */
+ if ((info->cu_type == 0x6310 && info->dev_type == 0x9336) ||
+ (info->cu_type == 0x3880 && info->dev_type == 0x3370))
+ labelsect = info->label_block;
+ else
+ labelsect = info->label_block * (blocksize >> 9);
+
+ /*
* Get volume label, extract name and type.
*/
- data = read_part_sector(state, info->label_block*(blocksize/512),
- &sect);
+ data = read_part_sector(state, labelsect, &sect);
if (data == NULL)
goto out_readerr;
diff --git a/fs/proc/base.c b/fs/proc/base.c
index acb7ef80ea4f..a49d9dd06d1d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -561,9 +561,19 @@ static int proc_setattr(struct dentry *dentry, struct iattr *attr)
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error)
- error = inode_setattr(inode, attr);
- return error;
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
static const struct inode_operations proc_def_inode_operations = {
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 2791907744ed..dd29f0337661 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -12,6 +12,7 @@
#include <linux/time.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
+#include <linux/mm.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/mount.h>
@@ -258,17 +259,22 @@ static int proc_notify_change(struct dentry *dentry, struct iattr *iattr)
error = inode_change_ok(inode, iattr);
if (error)
- goto out;
+ return error;
- error = inode_setattr(inode, iattr);
- if (error)
- goto out;
+ if ((iattr->ia_valid & ATTR_SIZE) &&
+ iattr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, iattr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, iattr);
+ mark_inode_dirty(inode);
de->uid = inode->i_uid;
de->gid = inode->i_gid;
de->mode = inode->i_mode;
-out:
- return error;
+ return 0;
}
static int proc_getattr(struct vfsmount *mnt, struct dentry *dentry,
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index aea8502e58a3..23561cda7245 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -25,11 +25,12 @@
#include "internal.h"
-static void proc_delete_inode(struct inode *inode)
+static void proc_evict_inode(struct inode *inode)
{
struct proc_dir_entry *de;
truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
/* Stop tracking associated processes */
put_pid(PROC_I(inode)->pid);
@@ -40,7 +41,6 @@ static void proc_delete_inode(struct inode *inode)
pde_put(de);
if (PROC_I(inode)->sysctl)
sysctl_head_put(PROC_I(inode)->sysctl);
- clear_inode(inode);
}
struct vfsmount *proc_mnt;
@@ -91,7 +91,7 @@ static const struct super_operations proc_sops = {
.alloc_inode = proc_alloc_inode,
.destroy_inode = proc_destroy_inode,
.drop_inode = generic_delete_inode,
- .delete_inode = proc_delete_inode,
+ .evict_inode = proc_evict_inode,
.statfs = simple_statfs,
};
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 6ff9981f0a18..5be436ea088e 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -329,10 +329,19 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
return -EPERM;
error = inode_change_ok(inode, attr);
- if (!error)
- error = inode_setattr(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
- return error;
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 277575ddc05c..16829722be93 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -320,10 +320,19 @@ static int qnx4_write_begin(struct file *file, struct address_space *mapping,
struct page **pagep, void **fsdata)
{
struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
+ int ret;
+
*pagep = NULL;
- return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
+ ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
qnx4_get_block,
&qnx4_inode->mmu_private);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
{
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 12c233da1b6b..b4cc0f35b404 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -885,7 +885,7 @@ static void add_dquot_ref(struct super_block *sb, int type)
spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
- if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW))
+ if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW))
continue;
#ifdef CONFIG_QUOTA_DEBUG
if (unlikely(inode_get_rsv_space(inode) > 0))
@@ -986,6 +986,7 @@ static void remove_dquot_ref(struct super_block *sb, int type,
struct list_head *tofree_head)
{
struct inode *inode;
+ int reserved = 0;
spin_lock(&inode_lock);
list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
@@ -995,10 +996,20 @@ static void remove_dquot_ref(struct super_block *sb, int type,
* only quota pointers and these have separate locking
* (dqptr_sem).
*/
- if (!IS_NOQUOTA(inode))
+ if (!IS_NOQUOTA(inode)) {
+ if (unlikely(inode_get_rsv_space(inode) > 0))
+ reserved = 1;
remove_inode_dquot_ref(inode, type, tofree_head);
+ }
}
spin_unlock(&inode_lock);
+#ifdef CONFIG_QUOTA_DEBUG
+ if (reserved) {
+ printk(KERN_WARNING "VFS (%s): Writes happened after quota"
+ " was disabled thus quota information is probably "
+ "inconsistent. Please run quotacheck(8).\n", sb->s_id);
+ }
+#endif
}
/* Gather all references from inodes and drop them */
@@ -1304,6 +1315,15 @@ static int info_bdq_free(struct dquot *dquot, qsize_t space)
return QUOTA_NL_NOWARN;
}
+static int dquot_active(const struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+
+ if (IS_NOQUOTA(inode))
+ return 0;
+ return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
+}
+
/*
* Initialize quota pointers in inode
*
@@ -1323,7 +1343,7 @@ static void __dquot_initialize(struct inode *inode, int type)
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ if (!dquot_active(inode))
return;
/* First get references to structures we might need. */
@@ -1507,7 +1527,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex
*/
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
+ if (!dquot_active(inode)) {
inode_incr_space(inode, number, reserve);
goto out;
}
@@ -1559,7 +1579,7 @@ int dquot_alloc_inode(const struct inode *inode)
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ if (!dquot_active(inode))
return 0;
for (cnt = 0; cnt < MAXQUOTAS; cnt++)
warntype[cnt] = QUOTA_NL_NOWARN;
@@ -1596,7 +1616,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
{
int cnt;
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
+ if (!dquot_active(inode)) {
inode_claim_rsv_space(inode, number);
return 0;
}
@@ -1629,7 +1649,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode)) {
+ if (!dquot_active(inode)) {
inode_decr_space(inode, number, reserve);
return;
}
@@ -1667,7 +1687,7 @@ void dquot_free_inode(const struct inode *inode)
/* First test before acquiring mutex - solves deadlocks when we
* re-enter the quota code and are already holding the mutex */
- if (!sb_any_quota_active(inode->i_sb) || IS_NOQUOTA(inode))
+ if (!dquot_active(inode))
return;
down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
@@ -1790,7 +1810,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
struct super_block *sb = inode->i_sb;
int ret;
- if (!sb_any_quota_active(sb) || IS_NOQUOTA(inode))
+ if (!dquot_active(inode))
return 0;
if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid)
@@ -2270,7 +2290,7 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
memset(di, 0, sizeof(*di));
di->d_version = FS_DQUOT_VERSION;
di->d_flags = dquot->dq_type == USRQUOTA ?
- XFS_USER_QUOTA : XFS_GROUP_QUOTA;
+ FS_USER_QUOTA : FS_GROUP_QUOTA;
di->d_id = dquot->dq_id;
spin_lock(&dq_data_lock);
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index d532c20fc179..9eead2c796b7 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -146,9 +146,8 @@ static int ramfs_nommu_resize(struct inode *inode, loff_t newsize, loff_t size)
return ret;
}
- ret = simple_setsize(inode, newsize);
-
- return ret;
+ truncate_setsize(inode, newsize);
+ return 0;
}
/*****************************************************************************/
@@ -183,7 +182,7 @@ static int ramfs_nommu_setattr(struct dentry *dentry, struct iattr *ia)
}
}
- generic_setattr(inode, ia);
+ setattr_copy(inode, ia);
out:
ia->ia_valid = old_ia_valid;
return ret;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index b82cdd8a45dd..6846371498b6 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -38,20 +38,24 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
BUG_ON(!S_ISREG(inode->i_mode));
+ if (atomic_add_unless(&REISERFS_I(inode)->openers, -1, 1))
+ return 0;
+
+ mutex_lock(&(REISERFS_I(inode)->tailpack));
+
+ if (!atomic_dec_and_test(&REISERFS_I(inode)->openers)) {
+ mutex_unlock(&(REISERFS_I(inode)->tailpack));
+ return 0;
+ }
+
/* fast out for when nothing needs to be done */
- if ((atomic_read(&inode->i_count) > 1 ||
- !(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
+ if ((!(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) ||
!tail_has_to_be_packed(inode)) &&
REISERFS_I(inode)->i_prealloc_count <= 0) {
+ mutex_unlock(&(REISERFS_I(inode)->tailpack));
return 0;
}
- mutex_lock(&inode->i_mutex);
-
- mutex_lock(&(REISERFS_I(inode)->i_mmap));
- if (REISERFS_I(inode)->i_flags & i_ever_mapped)
- REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
-
reiserfs_write_lock(inode->i_sb);
/* freeing preallocation only involves relogging blocks that
* are already in the current transaction. preallocation gets
@@ -94,9 +98,10 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
if (!err)
err = jbegin_failure;
- if (!err && atomic_read(&inode->i_count) <= 1 &&
+ if (!err &&
(REISERFS_I(inode)->i_flags & i_pack_on_close_mask) &&
tail_has_to_be_packed(inode)) {
+
/* if regular file is released by last holder and it has been
appended (we append by unformatted node only) or its direct
item(s) had to be converted, then it may have to be
@@ -104,27 +109,28 @@ static int reiserfs_file_release(struct inode *inode, struct file *filp)
err = reiserfs_truncate_file(inode, 0);
}
out:
- mutex_unlock(&(REISERFS_I(inode)->i_mmap));
- mutex_unlock(&inode->i_mutex);
reiserfs_write_unlock(inode->i_sb);
+ mutex_unlock(&(REISERFS_I(inode)->tailpack));
return err;
}
-static int reiserfs_file_mmap(struct file *file, struct vm_area_struct *vma)
+static int reiserfs_file_open(struct inode *inode, struct file *file)
{
- struct inode *inode;
-
- inode = file->f_path.dentry->d_inode;
- mutex_lock(&(REISERFS_I(inode)->i_mmap));
- REISERFS_I(inode)->i_flags |= i_ever_mapped;
- mutex_unlock(&(REISERFS_I(inode)->i_mmap));
-
- return generic_file_mmap(file, vma);
+ int err = dquot_file_open(inode, file);
+ if (!atomic_inc_not_zero(&REISERFS_I(inode)->openers)) {
+ /* somebody might be tailpacking on final close; wait for it */
+ mutex_lock(&(REISERFS_I(inode)->tailpack));
+ atomic_inc(&REISERFS_I(inode)->openers);
+ mutex_unlock(&(REISERFS_I(inode)->tailpack));
+ }
+ return err;
}
static void reiserfs_vfs_truncate_file(struct inode *inode)
{
+ mutex_lock(&(REISERFS_I(inode)->tailpack));
reiserfs_truncate_file(inode, 1);
+ mutex_unlock(&(REISERFS_I(inode)->tailpack));
}
/* Sync a reiserfs file. */
@@ -288,8 +294,8 @@ const struct file_operations reiserfs_file_operations = {
#ifdef CONFIG_COMPAT
.compat_ioctl = reiserfs_compat_ioctl,
#endif
- .mmap = reiserfs_file_mmap,
- .open = dquot_file_open,
+ .mmap = generic_file_mmap,
+ .open = reiserfs_file_open,
.release = reiserfs_file_release,
.fsync = reiserfs_sync_file,
.aio_read = generic_file_aio_read,
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 0f22fdaf54ac..a94e08b339fc 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -25,7 +25,7 @@ int reiserfs_commit_write(struct file *f, struct page *page,
int reiserfs_prepare_write(struct file *f, struct page *page,
unsigned from, unsigned to);
-void reiserfs_delete_inode(struct inode *inode)
+void reiserfs_evict_inode(struct inode *inode)
{
/* We need blocks for transaction + (user+group) quota update (possibly delete) */
int jbegin_count =
@@ -35,10 +35,12 @@ void reiserfs_delete_inode(struct inode *inode)
int depth;
int err;
- if (!is_bad_inode(inode))
+ if (!inode->i_nlink && !is_bad_inode(inode))
dquot_initialize(inode);
truncate_inode_pages(&inode->i_data, 0);
+ if (inode->i_nlink)
+ goto no_delete;
depth = reiserfs_write_lock_once(inode->i_sb);
@@ -77,9 +79,14 @@ void reiserfs_delete_inode(struct inode *inode)
;
}
out:
- clear_inode(inode); /* note this must go after the journal_end to prevent deadlock */
+ end_writeback(inode); /* note this must go after the journal_end to prevent deadlock */
+ dquot_drop(inode);
inode->i_blocks = 0;
reiserfs_write_unlock_once(inode->i_sb, depth);
+
+no_delete:
+ end_writeback(inode);
+ dquot_drop(inode);
}
static void _make_cpu_key(struct cpu_key *key, int version, __u32 dirid,
@@ -1138,7 +1145,6 @@ static void init_inode(struct inode *inode, struct treepath *path)
REISERFS_I(inode)->i_prealloc_count = 0;
REISERFS_I(inode)->i_trans_id = 0;
REISERFS_I(inode)->i_jl = NULL;
- mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_xattr_rwsem(inode);
if (stat_data_v1(ih)) {
@@ -1841,7 +1847,6 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th,
REISERFS_I(inode)->i_attrs =
REISERFS_I(dir)->i_attrs & REISERFS_INHERIT_MASK;
sd_attrs_to_i_attrs(REISERFS_I(inode)->i_attrs, inode);
- mutex_init(&(REISERFS_I(inode)->i_mmap));
reiserfs_init_xattr_rwsem(inode);
/* key to search for correct place for new stat data */
@@ -2587,8 +2592,7 @@ static int reiserfs_write_begin(struct file *file,
old_ref = th->t_refcount;
th->t_refcount++;
}
- ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- reiserfs_get_block);
+ ret = __block_write_begin(page, pos, len, reiserfs_get_block);
if (ret && reiserfs_transaction_running(inode->i_sb)) {
struct reiserfs_transaction_handle *th = current->journal_info;
/* this gets a little ugly. If reiserfs_get_block returned an
@@ -3059,10 +3063,25 @@ static ssize_t reiserfs_direct_IO(int rw, struct kiocb *iocb,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
+ ssize_t ret;
- return blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
+ ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
offset, nr_segs,
reiserfs_get_blocks_direct_io, NULL);
+
+ /*
+ * In case of error extending write may have instantiated a few
+ * blocks outside i_size. Trim these off again.
+ */
+ if (unlikely((rw & WRITE) && ret < 0)) {
+ loff_t isize = i_size_read(inode);
+ loff_t end = offset + iov_length(iov, nr_segs);
+
+ if (end > isize)
+ vmtruncate(inode, isize);
+ }
+
+ return ret;
}
int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
@@ -3072,6 +3091,10 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
int depth;
int error;
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
/* must be turned off for recursive notify_change calls */
ia_valid = attr->ia_valid &= ~(ATTR_KILL_SUID|ATTR_KILL_SGID);
@@ -3121,55 +3144,58 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
goto out;
}
- error = inode_change_ok(inode, attr);
- if (!error) {
- if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
- (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
- error = reiserfs_chown_xattrs(inode, attr);
+ if ((ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ struct reiserfs_transaction_handle th;
+ int jbegin_count =
+ 2 *
+ (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
+ REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
+ 2;
- if (!error) {
- struct reiserfs_transaction_handle th;
- int jbegin_count =
- 2 *
- (REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb) +
- REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb)) +
- 2;
-
- /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
- error =
- journal_begin(&th, inode->i_sb,
- jbegin_count);
- if (error)
- goto out;
- error = dquot_transfer(inode, attr);
- if (error) {
- journal_end(&th, inode->i_sb,
- jbegin_count);
- goto out;
- }
- /* Update corresponding info in inode so that everything is in
- * one transaction */
- if (attr->ia_valid & ATTR_UID)
- inode->i_uid = attr->ia_uid;
- if (attr->ia_valid & ATTR_GID)
- inode->i_gid = attr->ia_gid;
- mark_inode_dirty(inode);
- error =
- journal_end(&th, inode->i_sb, jbegin_count);
- }
- }
- if (!error) {
- /*
- * Relax the lock here, as it might truncate the
- * inode pages and wait for inode pages locks.
- * To release such page lock, the owner needs the
- * reiserfs lock
- */
- reiserfs_write_unlock_once(inode->i_sb, depth);
- error = inode_setattr(inode, attr);
- depth = reiserfs_write_lock_once(inode->i_sb);
+ error = reiserfs_chown_xattrs(inode, attr);
+
+ if (error)
+ return error;
+
+ /* (user+group)*(old+new) structure - we count quota info and , inode write (sb, inode) */
+ error = journal_begin(&th, inode->i_sb, jbegin_count);
+ if (error)
+ goto out;
+ error = dquot_transfer(inode, attr);
+ if (error) {
+ journal_end(&th, inode->i_sb, jbegin_count);
+ goto out;
}
+
+ /* Update corresponding info in inode so that everything is in
+ * one transaction */
+ if (attr->ia_valid & ATTR_UID)
+ inode->i_uid = attr->ia_uid;
+ if (attr->ia_valid & ATTR_GID)
+ inode->i_gid = attr->ia_gid;
+ mark_inode_dirty(inode);
+ error = journal_end(&th, inode->i_sb, jbegin_count);
+ if (error)
+ goto out;
+ }
+
+ /*
+ * Relax the lock here, as it might truncate the
+ * inode pages and wait for inode pages locks.
+ * To release such page lock, the owner needs the
+ * reiserfs lock
+ */
+ reiserfs_write_unlock_once(inode->i_sb, depth);
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode))
+ error = vmtruncate(inode, attr->ia_size);
+
+ if (!error) {
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
}
+ depth = reiserfs_write_lock_once(inode->i_sb);
if (!error && reiserfs_posixacl(inode->i_sb)) {
if (attr->ia_valid & ATTR_MODE)
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 9822fa15118b..e15ff612002d 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -525,6 +525,8 @@ static struct inode *reiserfs_alloc_inode(struct super_block *sb)
kmem_cache_alloc(reiserfs_inode_cachep, GFP_KERNEL);
if (!ei)
return NULL;
+ atomic_set(&ei->openers, 0);
+ mutex_init(&ei->tailpack);
return &ei->vfs_inode;
}
@@ -589,11 +591,6 @@ out:
reiserfs_write_unlock_once(inode->i_sb, lock_depth);
}
-static void reiserfs_clear_inode(struct inode *inode)
-{
- dquot_drop(inode);
-}
-
#ifdef CONFIG_QUOTA
static ssize_t reiserfs_quota_write(struct super_block *, int, const char *,
size_t, loff_t);
@@ -606,8 +603,7 @@ static const struct super_operations reiserfs_sops = {
.destroy_inode = reiserfs_destroy_inode,
.write_inode = reiserfs_write_inode,
.dirty_inode = reiserfs_dirty_inode,
- .clear_inode = reiserfs_clear_inode,
- .delete_inode = reiserfs_delete_inode,
+ .evict_inode = reiserfs_evict_inode,
.put_super = reiserfs_put_super,
.write_super = reiserfs_write_super,
.sync_fs = reiserfs_sync_fs,
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 9551cb6f7fe4..450c91941988 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -46,7 +46,7 @@
#define SMB_TTL_DEFAULT 1000
-static void smb_delete_inode(struct inode *);
+static void smb_evict_inode(struct inode *);
static void smb_put_super(struct super_block *);
static int smb_statfs(struct dentry *, struct kstatfs *);
static int smb_show_options(struct seq_file *, struct vfsmount *);
@@ -102,7 +102,7 @@ static const struct super_operations smb_sops =
.alloc_inode = smb_alloc_inode,
.destroy_inode = smb_destroy_inode,
.drop_inode = generic_delete_inode,
- .delete_inode = smb_delete_inode,
+ .evict_inode = smb_evict_inode,
.put_super = smb_put_super,
.statfs = smb_statfs,
.show_options = smb_show_options,
@@ -324,15 +324,15 @@ out:
* All blocking cleanup operations need to go here to avoid races.
*/
static void
-smb_delete_inode(struct inode *ino)
+smb_evict_inode(struct inode *ino)
{
DEBUG1("ino=%ld\n", ino->i_ino);
truncate_inode_pages(&ino->i_data, 0);
+ end_writeback(ino);
lock_kernel();
if (smb_close(ino))
PARANOIA("could not close inode %ld\n", ino->i_ino);
unlock_kernel();
- clear_inode(ino);
}
static struct option opts[] = {
@@ -714,9 +714,7 @@ smb_notify_change(struct dentry *dentry, struct iattr *attr)
error = server->ops->truncate(inode, attr->ia_size);
if (error)
goto out;
- error = simple_setsize(inode, attr->ia_size);
- if (error)
- goto out;
+ truncate_setsize(inode, attr->ia_size);
refresh = 1;
}
diff --git a/fs/sync.c b/fs/sync.c
index 15aa6f03b2da..ba76b9623e7e 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -128,31 +128,6 @@ void emergency_sync(void)
}
}
-/*
- * Generic function to fsync a file.
- */
-int file_fsync(struct file *filp, int datasync)
-{
- struct inode *inode = filp->f_mapping->host;
- struct super_block * sb;
- int ret, err;
-
- /* sync the inode to buffers */
- ret = write_inode_now(inode, 0);
-
- /* sync the superblock to buffers */
- sb = inode->i_sb;
- if (sb->s_dirt && sb->s_op->write_super)
- sb->s_op->write_super(sb);
-
- /* .. finally sync the buffers to disk */
- err = sync_blockdev(sb->s_bdev);
- if (!ret)
- ret = err;
- return ret;
-}
-EXPORT_SYMBOL(file_fsync);
-
/**
* vfs_fsync_range - helper to sync a range of data & metadata to disk
* @file: file to sync
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 0835a3b70e03..cffb1fd8ba33 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -122,7 +122,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
goto out;
/* this ignores size changes */
- generic_setattr(inode, iattr);
+ setattr_copy(inode, iattr);
out:
mutex_unlock(&sysfs_mutex);
@@ -312,15 +312,15 @@ struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd)
* The sysfs_dirent serves as both an inode and a directory entry for sysfs.
* To prevent the sysfs inode numbers from being freed prematurely we take a
* reference to sysfs_dirent from the sysfs inode. A
- * super_operations.delete_inode() implementation is needed to drop that
+ * super_operations.evict_inode() implementation is needed to drop that
* reference upon inode destruction.
*/
-void sysfs_delete_inode(struct inode *inode)
+void sysfs_evict_inode(struct inode *inode)
{
struct sysfs_dirent *sd = inode->i_private;
truncate_inode_pages(&inode->i_data, 0);
- clear_inode(inode);
+ end_writeback(inode);
sysfs_put(sd);
}
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 281c0c9bc39f..f2af22574c50 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -29,7 +29,7 @@ struct kmem_cache *sysfs_dir_cachep;
static const struct super_operations sysfs_ops = {
.statfs = simple_statfs,
.drop_inode = generic_delete_inode,
- .delete_inode = sysfs_delete_inode,
+ .evict_inode = sysfs_evict_inode,
};
struct sysfs_dirent sysfs_root = {
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index f71246bebfe4..44bca5f49cd5 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -28,6 +28,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
struct sysfs_dirent *target_sd = NULL;
struct sysfs_dirent *sd = NULL;
struct sysfs_addrm_cxt acxt;
+ enum kobj_ns_type ns_type;
int error;
BUG_ON(!name);
@@ -58,16 +59,28 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
if (!sd)
goto out_put;
- if (sysfs_ns_type(parent_sd))
+ ns_type = sysfs_ns_type(parent_sd);
+ if (ns_type)
sd->s_ns = target->ktype->namespace(target);
sd->s_symlink.target_sd = target_sd;
target_sd = NULL; /* reference is now owned by the symlink */
sysfs_addrm_start(&acxt, parent_sd);
- if (warn)
- error = sysfs_add_one(&acxt, sd);
- else
- error = __sysfs_add_one(&acxt, sd);
+ /* Symlinks must be between directories with the same ns_type */
+ if (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent)) {
+ if (warn)
+ error = sysfs_add_one(&acxt, sd);
+ else
+ error = __sysfs_add_one(&acxt, sd);
+ } else {
+ error = -EINVAL;
+ WARN(1, KERN_WARNING
+ "sysfs: symlink across ns_types %s/%s -> %s/%s\n",
+ parent_sd->s_name,
+ sd->s_name,
+ sd->s_symlink.target_sd->s_parent->s_name,
+ sd->s_symlink.target_sd->s_name);
+ }
sysfs_addrm_finish(&acxt);
if (error)
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 6a13105b5594..d9be60a2e956 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -198,7 +198,7 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
* inode.c
*/
struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
-void sysfs_delete_inode(struct inode *inode);
+void sysfs_evict_inode(struct inode *inode);
int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
int sysfs_permission(struct inode *inode, int mask);
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 79941e4964a4..a77c42157620 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -218,8 +218,7 @@ got_it:
pos = page_offset(page) +
(char*)de - (char*)page_address(page);
lock_page(page);
- err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
if (err)
goto out_unlock;
memcpy (de->name, name, namelen);
@@ -239,15 +238,13 @@ out_unlock:
int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
{
- struct address_space *mapping = page->mapping;
- struct inode *inode = (struct inode*)mapping->host;
+ struct inode *inode = page->mapping->host;
char *kaddr = (char*)page_address(page);
loff_t pos = page_offset(page) + (char *)de - kaddr;
int err;
lock_page(page);
- err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
BUG_ON(err);
de->inode = 0;
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
@@ -259,16 +256,14 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
int sysv_make_empty(struct inode *inode, struct inode *dir)
{
- struct address_space *mapping = inode->i_mapping;
- struct page *page = grab_cache_page(mapping, 0);
+ struct page *page = grab_cache_page(inode->i_mapping, 0);
struct sysv_dir_entry * de;
char *base;
int err;
if (!page)
return -ENOMEM;
- err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = sysv_prepare_chunk(page, 0, 2 * SYSV_DIRSIZE);
if (err) {
unlock_page(page);
goto fail;
@@ -341,15 +336,13 @@ not_empty:
void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
struct inode *inode)
{
- struct address_space *mapping = page->mapping;
- struct inode *dir = mapping->host;
+ struct inode *dir = page->mapping->host;
loff_t pos = page_offset(page) +
(char *)de-(char*)page_address(page);
int err;
lock_page(page);
- err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = sysv_prepare_chunk(page, pos, SYSV_DIRSIZE);
BUG_ON(err);
de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
diff --git a/fs/sysv/file.c b/fs/sysv/file.c
index 750cc22349bd..0a65939508e9 100644
--- a/fs/sysv/file.c
+++ b/fs/sysv/file.c
@@ -30,7 +30,29 @@ const struct file_operations sysv_file_operations = {
.splice_read = generic_file_splice_read,
};
+static int sysv_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
const struct inode_operations sysv_file_inode_operations = {
.truncate = sysv_truncate,
+ .setattr = sysv_setattr,
.getattr = sysv_getattr,
};
diff --git a/fs/sysv/ialloc.c b/fs/sysv/ialloc.c
index fcc498ec9b33..0c96c98bd1db 100644
--- a/fs/sysv/ialloc.c
+++ b/fs/sysv/ialloc.c
@@ -113,7 +113,6 @@ void sysv_free_inode(struct inode * inode)
return;
}
raw_inode = sysv_raw_inode(sb, ino, &bh);
- clear_inode(inode);
if (!raw_inode) {
printk("sysv_free_inode: unable to read inode block on device "
"%s\n", inode->i_sb->s_id);
diff --git a/fs/sysv/inode.c b/fs/sysv/inode.c
index d4a5380b5669..613a5056e880 100644
--- a/fs/sysv/inode.c
+++ b/fs/sysv/inode.c
@@ -308,12 +308,17 @@ int sysv_sync_inode(struct inode *inode)
return __sysv_write_inode(inode, 1);
}
-static void sysv_delete_inode(struct inode *inode)
+static void sysv_evict_inode(struct inode *inode)
{
truncate_inode_pages(&inode->i_data, 0);
- inode->i_size = 0;
- sysv_truncate(inode);
- sysv_free_inode(inode);
+ if (!inode->i_nlink) {
+ inode->i_size = 0;
+ sysv_truncate(inode);
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
+ if (!inode->i_nlink)
+ sysv_free_inode(inode);
}
static struct kmem_cache *sysv_inode_cachep;
@@ -344,7 +349,7 @@ const struct super_operations sysv_sops = {
.alloc_inode = sysv_alloc_inode,
.destroy_inode = sysv_destroy_inode,
.write_inode = sysv_write_inode,
- .delete_inode = sysv_delete_inode,
+ .evict_inode = sysv_evict_inode,
.put_super = sysv_put_super,
.write_super = sysv_write_super,
.sync_fs = sysv_sync_fs,
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index f042eec464c2..9ca66276315e 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -459,20 +459,25 @@ static int sysv_readpage(struct file *file, struct page *page)
return block_read_full_page(page,get_block);
}
-int __sysv_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- get_block);
+ return __block_write_begin(page, pos, len, get_block);
}
static int sysv_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep, get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 94cb9b4d76c2..bb55cdb394bf 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -136,9 +136,7 @@ extern unsigned long sysv_count_free_blocks(struct super_block *);
/* itree.c */
extern void sysv_truncate(struct inode *);
-extern int __sysv_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
+extern int sysv_prepare_chunk(struct page *page, loff_t pos, unsigned len);
/* inode.c */
extern struct inode *sysv_iget(struct super_block *, unsigned int);
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 12f445cee9f7..03ae894c45de 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -967,14 +967,15 @@ static int do_writepage(struct page *page, int len)
* the page locked, and it locks @ui_mutex. However, write-back does take inode
* @i_mutex, which means other VFS operations may be run on this inode at the
* same time. And the problematic one is truncation to smaller size, from where
- * we have to call 'simple_setsize()', which first changes @inode->i_size, then
+ * we have to call 'truncate_setsize()', which first changes @inode->i_size, then
* drops the truncated pages. And while dropping the pages, it takes the page
- * lock. This means that 'do_truncation()' cannot call 'simple_setsize()' with
+ * lock. This means that 'do_truncation()' cannot call 'truncate_setsize()' with
* @ui_mutex locked, because it would deadlock with 'ubifs_writepage()'. This
* means that @inode->i_size is changed while @ui_mutex is unlocked.
*
- * XXX: with the new truncate the above is not true anymore, the simple_setsize
- * calls can be replaced with the individual components.
+ * XXX(truncate): with the new truncate sequence this is not true anymore,
+ * and the calls to truncate_setsize can be move around freely. They should
+ * be moved to the very end of the truncate sequence.
*
* But in 'ubifs_writepage()' we have to guarantee that we do not write beyond
* inode size. How do we do this if @inode->i_size may became smaller while we
@@ -1128,9 +1129,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
budgeted = 0;
}
- err = simple_setsize(inode, new_size);
- if (err)
- goto out_budg;
+ truncate_setsize(inode, new_size);
if (offset) {
pgoff_t index = new_size >> PAGE_CACHE_SHIFT;
@@ -1217,16 +1216,14 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
if (attr->ia_valid & ATTR_SIZE) {
dbg_gen("size %lld -> %lld", inode->i_size, new_size);
- err = simple_setsize(inode, new_size);
- if (err)
- goto out;
+ truncate_setsize(inode, new_size);
}
mutex_lock(&ui->ui_mutex);
if (attr->ia_valid & ATTR_SIZE) {
/* Truncation changes inode [mc]time */
inode->i_mtime = inode->i_ctime = ubifs_current_time(inode);
- /* 'simple_setsize()' changed @i_size, update @ui_size */
+ /* 'truncate_setsize()' changed @i_size, update @ui_size */
ui->ui_size = inode->i_size;
}
@@ -1248,10 +1245,6 @@ static int do_setattr(struct ubifs_info *c, struct inode *inode,
if (IS_SYNC(inode))
err = inode->i_sb->s_op->write_inode(inode, NULL);
return err;
-
-out:
- ubifs_release_budget(c, &req);
- return err;
}
int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index ad7f67b827ea..0084a33c4c69 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -1457,13 +1457,13 @@ struct ubifs_lprops *ubifs_lpt_lookup(struct ubifs_info *c, int lnum)
shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode))
- return ERR_PTR(PTR_ERR(nnode));
+ return ERR_CAST(nnode);
}
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
shft -= UBIFS_LPT_FANOUT_SHIFT;
pnode = ubifs_get_pnode(c, nnode, iip);
if (IS_ERR(pnode))
- return ERR_PTR(PTR_ERR(pnode));
+ return ERR_CAST(pnode);
iip = (i & (UBIFS_LPT_FANOUT - 1));
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty,
@@ -1586,7 +1586,7 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
nnode = c->nroot;
nnode = dirty_cow_nnode(c, nnode);
if (IS_ERR(nnode))
- return ERR_PTR(PTR_ERR(nnode));
+ return ERR_CAST(nnode);
i = lnum - c->main_first;
shft = c->lpt_hght * UBIFS_LPT_FANOUT_SHIFT;
for (h = 1; h < c->lpt_hght; h++) {
@@ -1594,19 +1594,19 @@ struct ubifs_lprops *ubifs_lpt_lookup_dirty(struct ubifs_info *c, int lnum)
shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode))
- return ERR_PTR(PTR_ERR(nnode));
+ return ERR_CAST(nnode);
nnode = dirty_cow_nnode(c, nnode);
if (IS_ERR(nnode))
- return ERR_PTR(PTR_ERR(nnode));
+ return ERR_CAST(nnode);
}
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
shft -= UBIFS_LPT_FANOUT_SHIFT;
pnode = ubifs_get_pnode(c, nnode, iip);
if (IS_ERR(pnode))
- return ERR_PTR(PTR_ERR(pnode));
+ return ERR_CAST(pnode);
pnode = dirty_cow_pnode(c, pnode);
if (IS_ERR(pnode))
- return ERR_PTR(PTR_ERR(pnode));
+ return ERR_CAST(pnode);
iip = (i & (UBIFS_LPT_FANOUT - 1));
dbg_lp("LEB %d, free %d, dirty %d, flags %d", lnum,
pnode->lprops[iip].free, pnode->lprops[iip].dirty,
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index 13cb7a4237bf..d12535b7fc78 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -646,7 +646,7 @@ static struct ubifs_pnode *pnode_lookup(struct ubifs_info *c, int i)
shft -= UBIFS_LPT_FANOUT_SHIFT;
nnode = ubifs_get_nnode(c, nnode, iip);
if (IS_ERR(nnode))
- return ERR_PTR(PTR_ERR(nnode));
+ return ERR_CAST(nnode);
}
iip = ((i >> shft) & (UBIFS_LPT_FANOUT - 1));
return ubifs_get_pnode(c, nnode, iip);
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 109c6ea03bb5..daae9e1f5382 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -24,7 +24,7 @@
* This file implements functions needed to recover from unclean un-mounts.
* When UBIFS is mounted, it checks a flag on the master node to determine if
* an un-mount was completed successfully. If not, the process of mounting
- * incorparates additional checking and fixing of on-flash data structures.
+ * incorporates additional checking and fixing of on-flash data structures.
* UBIFS always cleans away all remnants of an unclean un-mount, so that
* errors do not accumulate. However UBIFS defers recovery if it is mounted
* read-only, and the flash is not modified in that case.
@@ -1063,8 +1063,21 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
}
err = ubifs_find_dirty_leb(c, &lp, wbuf->offs, 2);
if (err) {
- if (err == -ENOSPC)
- dbg_err("could not find a dirty LEB");
+ /*
+ * There are no dirty or empty LEBs subject to here being
+ * enough for the index. Try to use
+ * 'ubifs_find_free_leb_for_idx()', which will return any empty
+ * LEBs (ignoring index requirements). If the index then
+ * doesn't have enough LEBs the recovery commit will fail -
+ * which is the same result anyway i.e. recovery fails. So
+ * there is no problem ignoring index requirements and just
+ * grabbing a free LEB since we have already established there
+ * is not a dirty LEB we could have used instead.
+ */
+ if (err == -ENOSPC) {
+ dbg_rcvry("could not find a dirty LEB");
+ goto find_free;
+ }
return err;
}
ubifs_assert(!(lp.flags & LPROPS_INDEX));
@@ -1139,8 +1152,8 @@ int ubifs_rcvry_gc_commit(struct ubifs_info *c)
find_free:
/*
* There is no GC head LEB or the free space in the GC head LEB is too
- * small. Allocate gc_lnum by calling 'ubifs_find_free_leb_for_idx()' so
- * GC is not run.
+ * small, or there are not dirty LEBs. Allocate gc_lnum by calling
+ * 'ubifs_find_free_leb_for_idx()' so GC is not run.
*/
lnum = ubifs_find_free_leb_for_idx(c);
if (lnum < 0) {
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 4d2f2157dd3f..8cb36b472e76 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -327,7 +327,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc)
return err;
}
-static void ubifs_delete_inode(struct inode *inode)
+static void ubifs_evict_inode(struct inode *inode)
{
int err;
struct ubifs_info *c = inode->i_sb->s_fs_info;
@@ -343,9 +343,12 @@ static void ubifs_delete_inode(struct inode *inode)
dbg_gen("inode %lu, mode %#x", inode->i_ino, (int)inode->i_mode);
ubifs_assert(!atomic_read(&inode->i_count));
- ubifs_assert(inode->i_nlink == 0);
truncate_inode_pages(&inode->i_data, 0);
+
+ if (inode->i_nlink)
+ goto done;
+
if (is_bad_inode(inode))
goto out;
@@ -367,7 +370,8 @@ out:
c->nospace = c->nospace_rp = 0;
smp_wmb();
}
- clear_inode(inode);
+done:
+ end_writeback(inode);
}
static void ubifs_dirty_inode(struct inode *inode)
@@ -1307,6 +1311,8 @@ static int mount_ubifs(struct ubifs_info *c)
if (err)
goto out_orphans;
err = ubifs_rcvry_gc_commit(c);
+ if (err)
+ goto out_orphans;
} else {
err = take_gc_lnum(c);
if (err)
@@ -1824,7 +1830,7 @@ const struct super_operations ubifs_super_operations = {
.destroy_inode = ubifs_destroy_inode,
.put_super = ubifs_put_super,
.write_inode = ubifs_write_inode,
- .delete_inode = ubifs_delete_inode,
+ .evict_inode = ubifs_evict_inode,
.statfs = ubifs_statfs,
.dirty_inode = ubifs_dirty_inode,
.remount_fs = ubifs_remount_fs,
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 2eef553d50c8..e40a4629e81b 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -379,7 +379,7 @@ struct ubifs_gced_idx_leb {
* The @ui_size is a "shadow" variable for @inode->i_size and UBIFS uses
* @ui_size instead of @inode->i_size. The reason for this is that UBIFS cannot
* make sure @inode->i_size is always changed under @ui_mutex, because it
- * cannot call 'simple_setsize()' with @ui_mutex locked, because it would deadlock
+ * cannot call 'truncate_setsize()' with @ui_mutex locked, because it would deadlock
* with 'ubifs_writepage()' (see file.c). All the other inode fields are
* changed under @ui_mutex, so they do not need "shadow" fields. Note, one
* could consider to rework locking and base it on "shadow" fields.
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 94e06d6bddbd..66b9e7e7e4c5 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -36,7 +36,6 @@
#include <linux/pagemap.h>
#include <linux/buffer_head.h>
#include <linux/aio.h>
-#include <linux/smp_lock.h>
#include "udf_i.h"
#include "udf_sb.h"
@@ -228,6 +227,28 @@ const struct file_operations udf_file_operations = {
.llseek = generic_file_llseek,
};
+static int udf_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
+ if ((attr->ia_valid & ATTR_SIZE) &&
+ attr->ia_size != i_size_read(inode)) {
+ error = vmtruncate(inode, attr->ia_size);
+ if (error)
+ return error;
+ }
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
+}
+
const struct inode_operations udf_file_inode_operations = {
+ .setattr = udf_setattr,
.truncate = udf_truncate,
};
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c
index 18cd7111185d..75d9304d0dc3 100644
--- a/fs/udf/ialloc.c
+++ b/fs/udf/ialloc.c
@@ -31,8 +31,6 @@ void udf_free_inode(struct inode *inode)
struct super_block *sb = inode->i_sb;
struct udf_sb_info *sbi = UDF_SB(sb);
- clear_inode(inode);
-
mutex_lock(&sbi->s_alloc_mutex);
if (sbi->s_lvid_bh) {
struct logicalVolIntegrityDescImpUse *lvidiu =
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 124852bcf6fe..fc48f37aa2dd 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -68,37 +68,23 @@ static void udf_update_extents(struct inode *,
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
-void udf_delete_inode(struct inode *inode)
-{
- truncate_inode_pages(&inode->i_data, 0);
-
- if (is_bad_inode(inode))
- goto no_delete;
-
- inode->i_size = 0;
- udf_truncate(inode);
- lock_kernel();
-
- udf_update_inode(inode, IS_SYNC(inode));
- udf_free_inode(inode);
-
- unlock_kernel();
- return;
-
-no_delete:
- clear_inode(inode);
-}
-
-/*
- * If we are going to release inode from memory, we truncate last inode extent
- * to proper length. We could use drop_inode() but it's called under inode_lock
- * and thus we cannot mark inode dirty there. We use clear_inode() but we have
- * to make sure to write inode as it's not written automatically.
- */
-void udf_clear_inode(struct inode *inode)
+void udf_evict_inode(struct inode *inode)
{
struct udf_inode_info *iinfo = UDF_I(inode);
+ int want_delete = 0;
+
+ truncate_inode_pages(&inode->i_data, 0);
+ if (!inode->i_nlink && !is_bad_inode(inode)) {
+ want_delete = 1;
+ inode->i_size = 0;
+ udf_truncate(inode);
+ lock_kernel();
+ udf_update_inode(inode, IS_SYNC(inode));
+ unlock_kernel();
+ }
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB &&
inode->i_size != iinfo->i_lenExtents) {
printk(KERN_WARNING "UDF-fs (%s): Inode %lu (mode %o) has "
@@ -108,9 +94,13 @@ void udf_clear_inode(struct inode *inode)
(unsigned long long)inode->i_size,
(unsigned long long)iinfo->i_lenExtents);
}
-
kfree(iinfo->i_ext.i_data);
iinfo->i_ext.i_data = NULL;
+ if (want_delete) {
+ lock_kernel();
+ udf_free_inode(inode);
+ unlock_kernel();
+ }
}
static int udf_writepage(struct page *page, struct writeback_control *wbc)
@@ -127,9 +117,16 @@ static int udf_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- udf_get_block);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep, udf_get_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t udf_bmap(struct address_space *mapping, sector_t block)
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 612d1e2e285a..65412d84a45d 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -175,8 +175,7 @@ static const struct super_operations udf_sb_ops = {
.alloc_inode = udf_alloc_inode,
.destroy_inode = udf_destroy_inode,
.write_inode = udf_write_inode,
- .delete_inode = udf_delete_inode,
- .clear_inode = udf_clear_inode,
+ .evict_inode = udf_evict_inode,
.put_super = udf_put_super,
.sync_fs = udf_sync_fs,
.statfs = udf_statfs,
@@ -1579,9 +1578,7 @@ static int udf_load_sequence(struct super_block *sb, struct buffer_head *bh,
{
struct anchorVolDescPtr *anchor;
long main_s, main_e, reserve_s, reserve_e;
- struct udf_sb_info *sbi;
- sbi = UDF_SB(sb);
anchor = (struct anchorVolDescPtr *)bh->b_data;
/* Locate the main sequence */
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 2bac0354891f..6995ab1f4305 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -139,8 +139,7 @@ extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
extern struct buffer_head *udf_bread(struct inode *, int, int, int *);
extern void udf_truncate(struct inode *);
extern void udf_read_inode(struct inode *);
-extern void udf_delete_inode(struct inode *);
-extern void udf_clear_inode(struct inode *);
+extern void udf_evict_inode(struct inode *);
extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
extern long udf_block_map(struct inode *, sector_t);
extern int udf_extend_file(struct inode *, struct extent_position *,
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index ec784756dc65..dbc90994715a 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -95,8 +95,7 @@ void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
int err;
lock_page(page);
- err = __ufs_write_begin(NULL, page->mapping, pos, len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = ufs_prepare_chunk(page, pos, len);
BUG_ON(err);
de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
@@ -381,8 +380,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
got_it:
pos = page_offset(page) +
(char*)de - (char*)page_address(page);
- err = __ufs_write_begin(NULL, page->mapping, pos, rec_len,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = ufs_prepare_chunk(page, pos, rec_len);
if (err)
goto out_unlock;
if (de->d_ino) {
@@ -518,7 +516,6 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
struct page * page)
{
struct super_block *sb = inode->i_sb;
- struct address_space *mapping = page->mapping;
char *kaddr = page_address(page);
unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
@@ -549,8 +546,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
pos = page_offset(page) + from;
lock_page(page);
- err = __ufs_write_begin(NULL, mapping, pos, to - from,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = ufs_prepare_chunk(page, pos, to - from);
BUG_ON(err);
if (pde)
pde->d_reclen = cpu_to_fs16(sb, to - from);
@@ -577,8 +573,7 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
if (!page)
return -ENOMEM;
- err = __ufs_write_begin(NULL, mapping, 0, chunk_size,
- AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
+ err = ufs_prepare_chunk(page, 0, chunk_size);
if (err) {
unlock_page(page);
goto fail;
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c
index 594480e537d2..428017e018fe 100644
--- a/fs/ufs/ialloc.c
+++ b/fs/ufs/ialloc.c
@@ -94,8 +94,6 @@ void ufs_free_inode (struct inode * inode)
is_directory = S_ISDIR(inode->i_mode);
- clear_inode (inode);
-
if (ubh_isclr (UCPI_UBH(ucpi), ucpi->c_iusedoff, bit))
ufs_error(sb, "ufs_free_inode", "bit already cleared for inode %u", ino);
else {
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 73fe773aa034..2b251f2093af 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -558,20 +558,26 @@ static int ufs_readpage(struct file *file, struct page *page)
return block_read_full_page(page,ufs_getfrag_block);
}
-int __ufs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len)
{
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- ufs_getfrag_block);
+ return __block_write_begin(page, pos, len, ufs_getfrag_block);
}
static int ufs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
struct page **pagep, void **fsdata)
{
- *pagep = NULL;
- return __ufs_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ ufs_getfrag_block);
+ if (unlikely(ret)) {
+ loff_t isize = mapping->host->i_size;
+ if (pos + len > isize)
+ vmtruncate(mapping->host, isize);
+ }
+
+ return ret;
}
static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
@@ -905,24 +911,33 @@ int ufs_sync_inode (struct inode *inode)
return ufs_update_inode (inode, 1);
}
-void ufs_delete_inode (struct inode * inode)
+void ufs_evict_inode(struct inode * inode)
{
- loff_t old_i_size;
+ int want_delete = 0;
+
+ if (!inode->i_nlink && !is_bad_inode(inode))
+ want_delete = 1;
truncate_inode_pages(&inode->i_data, 0);
- if (is_bad_inode(inode))
- goto no_delete;
- /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
- lock_kernel();
- mark_inode_dirty(inode);
- ufs_update_inode(inode, IS_SYNC(inode));
- old_i_size = inode->i_size;
- inode->i_size = 0;
- if (inode->i_blocks && ufs_truncate(inode, old_i_size))
- ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
- ufs_free_inode (inode);
- unlock_kernel();
- return;
-no_delete:
- clear_inode(inode); /* We must guarantee clearing of inode... */
+ if (want_delete) {
+ loff_t old_i_size;
+ /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
+ lock_kernel();
+ mark_inode_dirty(inode);
+ ufs_update_inode(inode, IS_SYNC(inode));
+ old_i_size = inode->i_size;
+ inode->i_size = 0;
+ if (inode->i_blocks && ufs_truncate(inode, old_i_size))
+ ufs_warning(inode->i_sb, __func__, "ufs_truncate failed\n");
+ unlock_kernel();
+ }
+
+ invalidate_inode_buffers(inode);
+ end_writeback(inode);
+
+ if (want_delete) {
+ lock_kernel();
+ ufs_free_inode (inode);
+ unlock_kernel();
+ }
}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 3ec5a9eb6efb..d510c1b91817 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1440,7 +1440,7 @@ static const struct super_operations ufs_super_ops = {
.alloc_inode = ufs_alloc_inode,
.destroy_inode = ufs_destroy_inode,
.write_inode = ufs_write_inode,
- .delete_inode = ufs_delete_inode,
+ .evict_inode = ufs_evict_inode,
.put_super = ufs_put_super,
.write_super = ufs_write_super,
.sync_fs = ufs_sync_fs,
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 589e01a465ba..34d5cb135320 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -500,11 +500,6 @@ out:
return err;
}
-/*
- * TODO:
- * - truncate case should use proper ordering instead of using
- * simple_setsize
- */
int ufs_setattr(struct dentry *dentry, struct iattr *attr)
{
struct inode *inode = dentry->d_inode;
@@ -518,14 +513,17 @@ int ufs_setattr(struct dentry *dentry, struct iattr *attr)
if (ia_valid & ATTR_SIZE && attr->ia_size != inode->i_size) {
loff_t old_i_size = inode->i_size;
- error = simple_setsize(inode, attr->ia_size);
- if (error)
- return error;
+ /* XXX(truncate): truncate_setsize should be called last */
+ truncate_setsize(inode, attr->ia_size);
+
error = ufs_truncate(inode, old_i_size);
if (error)
return error;
}
- return inode_setattr(inode, attr);
+
+ setattr_copy(inode, attr);
+ mark_inode_dirty(inode);
+ return 0;
}
const struct inode_operations ufs_file_inode_operations = {
diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h
index 179ae6b3180a..c08782e1b48a 100644
--- a/fs/ufs/ufs.h
+++ b/fs/ufs/ufs.h
@@ -108,7 +108,7 @@ extern struct inode * ufs_new_inode (struct inode *, int);
extern struct inode *ufs_iget(struct super_block *, unsigned long);
extern int ufs_write_inode (struct inode *, struct writeback_control *);
extern int ufs_sync_inode (struct inode *);
-extern void ufs_delete_inode (struct inode *);
+extern void ufs_evict_inode (struct inode *);
extern struct buffer_head * ufs_bread (struct inode *, unsigned, int, int *);
extern int ufs_getfrag_block (struct inode *inode, sector_t fragment, struct buffer_head *bh_result, int create);
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 23ceed8c8fb9..0466036912f1 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -257,9 +257,7 @@ ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
-extern int __ufs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata);
+extern int ufs_prepare_chunk(struct page *page, loff_t pos, unsigned len);
/*
* These functions manipulate ufs buffers
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile
index c8fb13f83b3f..0dce969d6cad 100644
--- a/fs/xfs/Makefile
+++ b/fs/xfs/Makefile
@@ -87,11 +87,9 @@ xfs-y += xfs_alloc.o \
xfs_trans_buf.o \
xfs_trans_extfree.o \
xfs_trans_inode.o \
- xfs_trans_item.o \
xfs_utils.o \
xfs_vnodeops.o \
- xfs_rw.o \
- xfs_dmops.o
+ xfs_rw.o
xfs-$(CONFIG_XFS_TRACE) += xfs_btree_trace.o
diff --git a/fs/xfs/linux-2.6/xfs_acl.c b/fs/xfs/linux-2.6/xfs_acl.c
index 9f769b5b38fc..b2771862fd3d 100644
--- a/fs/xfs/linux-2.6/xfs_acl.c
+++ b/fs/xfs/linux-2.6/xfs_acl.c
@@ -225,7 +225,7 @@ xfs_check_acl(struct inode *inode, int mask)
struct posix_acl *acl;
int error = -EAGAIN;
- xfs_itrace_entry(ip);
+ trace_xfs_check_acl(ip);
/*
* If there is no attribute fork no ACL exists on this inode and
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 34640d6dbdcb..62904867418a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -21,19 +21,12 @@
#include "xfs_inum.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_trans.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_alloc.h"
-#include "xfs_btree.h"
#include "xfs_error.h"
#include "xfs_rw.h"
#include "xfs_iomap.h"
@@ -92,18 +85,15 @@ void
xfs_count_page_state(
struct page *page,
int *delalloc,
- int *unmapped,
int *unwritten)
{
struct buffer_head *bh, *head;
- *delalloc = *unmapped = *unwritten = 0;
+ *delalloc = *unwritten = 0;
bh = head = page_buffers(page);
do {
- if (buffer_uptodate(bh) && !buffer_mapped(bh))
- (*unmapped) = 1;
- else if (buffer_unwritten(bh))
+ if (buffer_unwritten(bh))
(*unwritten) = 1;
else if (buffer_delay(bh))
(*delalloc) = 1;
@@ -614,31 +604,30 @@ xfs_map_at_offset(
STATIC unsigned int
xfs_probe_page(
struct page *page,
- unsigned int pg_offset,
- int mapped)
+ unsigned int pg_offset)
{
+ struct buffer_head *bh, *head;
int ret = 0;
if (PageWriteback(page))
return 0;
+ if (!PageDirty(page))
+ return 0;
+ if (!page->mapping)
+ return 0;
+ if (!page_has_buffers(page))
+ return 0;
- if (page->mapping && PageDirty(page)) {
- if (page_has_buffers(page)) {
- struct buffer_head *bh, *head;
-
- bh = head = page_buffers(page);
- do {
- if (!buffer_uptodate(bh))
- break;
- if (mapped != buffer_mapped(bh))
- break;
- ret += bh->b_size;
- if (ret >= pg_offset)
- break;
- } while ((bh = bh->b_this_page) != head);
- } else
- ret = mapped ? 0 : PAGE_CACHE_SIZE;
- }
+ bh = head = page_buffers(page);
+ do {
+ if (!buffer_uptodate(bh))
+ break;
+ if (!buffer_mapped(bh))
+ break;
+ ret += bh->b_size;
+ if (ret >= pg_offset)
+ break;
+ } while ((bh = bh->b_this_page) != head);
return ret;
}
@@ -648,8 +637,7 @@ xfs_probe_cluster(
struct inode *inode,
struct page *startpage,
struct buffer_head *bh,
- struct buffer_head *head,
- int mapped)
+ struct buffer_head *head)
{
struct pagevec pvec;
pgoff_t tindex, tlast, tloff;
@@ -658,7 +646,7 @@ xfs_probe_cluster(
/* First sum forwards in this page */
do {
- if (!buffer_uptodate(bh) || (mapped != buffer_mapped(bh)))
+ if (!buffer_uptodate(bh) || !buffer_mapped(bh))
return total;
total += bh->b_size;
} while ((bh = bh->b_this_page) != head);
@@ -692,7 +680,7 @@ xfs_probe_cluster(
pg_offset = PAGE_CACHE_SIZE;
if (page->index == tindex && trylock_page(page)) {
- pg_len = xfs_probe_page(page, pg_offset, mapped);
+ pg_len = xfs_probe_page(page, pg_offset);
unlock_page(page);
}
@@ -761,7 +749,6 @@ xfs_convert_page(
struct xfs_bmbt_irec *imap,
xfs_ioend_t **ioendp,
struct writeback_control *wbc,
- int startio,
int all_bh)
{
struct buffer_head *bh, *head;
@@ -832,19 +819,14 @@ xfs_convert_page(
ASSERT(imap->br_startblock != DELAYSTARTBLOCK);
xfs_map_at_offset(inode, bh, imap, offset);
- if (startio) {
- xfs_add_to_ioend(inode, bh, offset,
- type, ioendp, done);
- } else {
- set_buffer_dirty(bh);
- unlock_buffer(bh);
- mark_buffer_dirty(bh);
- }
+ xfs_add_to_ioend(inode, bh, offset, type,
+ ioendp, done);
+
page_dirty--;
count++;
} else {
type = IO_NEW;
- if (buffer_mapped(bh) && all_bh && startio) {
+ if (buffer_mapped(bh) && all_bh) {
lock_buffer(bh);
xfs_add_to_ioend(inode, bh, offset,
type, ioendp, done);
@@ -859,14 +841,12 @@ xfs_convert_page(
if (uptodate && bh == head)
SetPageUptodate(page);
- if (startio) {
- if (count) {
- wbc->nr_to_write--;
- if (wbc->nr_to_write <= 0)
- done = 1;
- }
- xfs_start_page_writeback(page, !page_dirty, count);
+ if (count) {
+ wbc->nr_to_write--;
+ if (wbc->nr_to_write <= 0)
+ done = 1;
}
+ xfs_start_page_writeback(page, !page_dirty, count);
return done;
fail_unlock_page:
@@ -886,7 +866,6 @@ xfs_cluster_write(
struct xfs_bmbt_irec *imap,
xfs_ioend_t **ioendp,
struct writeback_control *wbc,
- int startio,
int all_bh,
pgoff_t tlast)
{
@@ -902,7 +881,7 @@ xfs_cluster_write(
for (i = 0; i < pagevec_count(&pvec); i++) {
done = xfs_convert_page(inode, pvec.pages[i], tindex++,
- imap, ioendp, wbc, startio, all_bh);
+ imap, ioendp, wbc, all_bh);
if (done)
break;
}
@@ -981,7 +960,7 @@ xfs_aops_discard_page(
*/
error = xfs_bmapi(NULL, ip, offset_fsb, 1,
XFS_BMAPI_ENTIRE, NULL, 0, &imap,
- &nimaps, NULL, NULL);
+ &nimaps, NULL);
if (error) {
/* something screwed, just bail */
@@ -1009,7 +988,7 @@ xfs_aops_discard_page(
*/
xfs_bmap_init(&flist, &firstblock);
error = xfs_bunmapi(NULL, ip, offset_fsb, 1, 0, 1, &firstblock,
- &flist, NULL, &done);
+ &flist, &done);
ASSERT(!flist.xbf_count && !flist.xbf_first);
if (error) {
@@ -1032,50 +1011,66 @@ out_invalidate:
}
/*
- * Calling this without startio set means we are being asked to make a dirty
- * page ready for freeing it's buffers. When called with startio set then
- * we are coming from writepage.
+ * Write out a dirty page.
*
- * When called with startio set it is important that we write the WHOLE
- * page if possible.
- * The bh->b_state's cannot know if any of the blocks or which block for
- * that matter are dirty due to mmap writes, and therefore bh uptodate is
- * only valid if the page itself isn't completely uptodate. Some layers
- * may clear the page dirty flag prior to calling write page, under the
- * assumption the entire page will be written out; by not writing out the
- * whole page the page can be reused before all valid dirty data is
- * written out. Note: in the case of a page that has been dirty'd by
- * mapwrite and but partially setup by block_prepare_write the
- * bh->b_states's will not agree and only ones setup by BPW/BCW will have
- * valid state, thus the whole page must be written out thing.
+ * For delalloc space on the page we need to allocate space and flush it.
+ * For unwritten space on the page we need to start the conversion to
+ * regular allocated space.
+ * For any other dirty buffer heads on the page we should flush them.
+ *
+ * If we detect that a transaction would be required to flush the page, we
+ * have to check the process flags first, if we are already in a transaction
+ * or disk I/O during allocations is off, we need to fail the writepage and
+ * redirty the page.
*/
-
STATIC int
-xfs_page_state_convert(
- struct inode *inode,
- struct page *page,
- struct writeback_control *wbc,
- int startio,
- int unmapped) /* also implies page uptodate */
+xfs_vm_writepage(
+ struct page *page,
+ struct writeback_control *wbc)
{
+ struct inode *inode = page->mapping->host;
+ int delalloc, unwritten;
struct buffer_head *bh, *head;
struct xfs_bmbt_irec imap;
xfs_ioend_t *ioend = NULL, *iohead = NULL;
loff_t offset;
- unsigned long p_offset = 0;
unsigned int type;
__uint64_t end_offset;
pgoff_t end_index, last_index;
ssize_t size, len;
int flags, err, imap_valid = 0, uptodate = 1;
- int page_dirty, count = 0;
- int trylock = 0;
- int all_bh = unmapped;
+ int count = 0;
+ int all_bh = 0;
- if (startio) {
- if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking)
- trylock |= BMAPI_TRYLOCK;
- }
+ trace_xfs_writepage(inode, page, 0);
+
+ ASSERT(page_has_buffers(page));
+
+ /*
+ * Refuse to write the page out if we are called from reclaim context.
+ *
+ * This avoids stack overflows when called from deeply used stacks in
+ * random callers for direct reclaim or memcg reclaim. We explicitly
+ * allow reclaim from kswapd as the stack usage there is relatively low.
+ *
+ * This should really be done by the core VM, but until that happens
+ * filesystems like XFS, btrfs and ext4 have to take care of this
+ * by themselves.
+ */
+ if ((current->flags & (PF_MEMALLOC|PF_KSWAPD)) == PF_MEMALLOC)
+ goto out_fail;
+
+ /*
+ * We need a transaction if there are delalloc or unwritten buffers
+ * on the page.
+ *
+ * If we need a transaction and the process flags say we are already
+ * in a transaction, or no IO is allowed then mark the page dirty
+ * again and leave the page as is.
+ */
+ xfs_count_page_state(page, &delalloc, &unwritten);
+ if ((current->flags & PF_FSTRANS) && (delalloc || unwritten))
+ goto out_fail;
/* Is this page beyond the end of the file? */
offset = i_size_read(inode);
@@ -1084,50 +1079,33 @@ xfs_page_state_convert(
if (page->index >= end_index) {
if ((page->index >= end_index + 1) ||
!(i_size_read(inode) & (PAGE_CACHE_SIZE - 1))) {
- if (startio)
- unlock_page(page);
+ unlock_page(page);
return 0;
}
}
- /*
- * page_dirty is initially a count of buffers on the page before
- * EOF and is decremented as we move each into a cleanable state.
- *
- * Derivation:
- *
- * End offset is the highest offset that this page should represent.
- * If we are on the last page, (end_offset & (PAGE_CACHE_SIZE - 1))
- * will evaluate non-zero and be less than PAGE_CACHE_SIZE and
- * hence give us the correct page_dirty count. On any other page,
- * it will be zero and in that case we need page_dirty to be the
- * count of buffers on the page.
- */
end_offset = min_t(unsigned long long,
- (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset);
+ (xfs_off_t)(page->index + 1) << PAGE_CACHE_SHIFT,
+ offset);
len = 1 << inode->i_blkbits;
- p_offset = min_t(unsigned long, end_offset & (PAGE_CACHE_SIZE - 1),
- PAGE_CACHE_SIZE);
- p_offset = p_offset ? roundup(p_offset, len) : PAGE_CACHE_SIZE;
- page_dirty = p_offset / len;
bh = head = page_buffers(page);
offset = page_offset(page);
flags = BMAPI_READ;
type = IO_NEW;
- /* TODO: cleanup count and page_dirty */
-
do {
if (offset >= end_offset)
break;
if (!buffer_uptodate(bh))
uptodate = 0;
- if (!(PageUptodate(page) || buffer_uptodate(bh)) && !startio) {
- /*
- * the iomap is actually still valid, but the ioend
- * isn't. shouldn't happen too often.
- */
+
+ /*
+ * A hole may still be marked uptodate because discard_buffer
+ * leaves the flag set.
+ */
+ if (!buffer_mapped(bh) && buffer_uptodate(bh)) {
+ ASSERT(!buffer_dirty(bh));
imap_valid = 0;
continue;
}
@@ -1135,19 +1113,7 @@ xfs_page_state_convert(
if (imap_valid)
imap_valid = xfs_imap_valid(inode, &imap, offset);
- /*
- * First case, map an unwritten extent and prepare for
- * extent state conversion transaction on completion.
- *
- * Second case, allocate space for a delalloc buffer.
- * We can return EAGAIN here in the release page case.
- *
- * Third case, an unmapped buffer was found, and we are
- * in a path where we need to write the whole page out.
- */
- if (buffer_unwritten(bh) || buffer_delay(bh) ||
- ((buffer_uptodate(bh) || PageUptodate(page)) &&
- !buffer_mapped(bh) && (unmapped || startio))) {
+ if (buffer_unwritten(bh) || buffer_delay(bh)) {
int new_ioend = 0;
/*
@@ -1161,15 +1127,16 @@ xfs_page_state_convert(
flags = BMAPI_WRITE | BMAPI_IGNSTATE;
} else if (buffer_delay(bh)) {
type = IO_DELAY;
- flags = BMAPI_ALLOCATE | trylock;
- } else {
- type = IO_NEW;
- flags = BMAPI_WRITE | BMAPI_MMAP;
+ flags = BMAPI_ALLOCATE;
+
+ if (wbc->sync_mode == WB_SYNC_NONE &&
+ wbc->nonblocking)
+ flags |= BMAPI_TRYLOCK;
}
if (!imap_valid) {
/*
- * if we didn't have a valid mapping then we
+ * If we didn't have a valid mapping then we
* need to ensure that we put the new mapping
* in a new ioend structure. This needs to be
* done to ensure that the ioends correctly
@@ -1177,14 +1144,7 @@ xfs_page_state_convert(
* for unwritten extent conversion.
*/
new_ioend = 1;
- if (type == IO_NEW) {
- size = xfs_probe_cluster(inode,
- page, bh, head, 0);
- } else {
- size = len;
- }
-
- err = xfs_map_blocks(inode, offset, size,
+ err = xfs_map_blocks(inode, offset, len,
&imap, flags);
if (err)
goto error;
@@ -1193,19 +1153,11 @@ xfs_page_state_convert(
}
if (imap_valid) {
xfs_map_at_offset(inode, bh, &imap, offset);
- if (startio) {
- xfs_add_to_ioend(inode, bh, offset,
- type, &ioend,
- new_ioend);
- } else {
- set_buffer_dirty(bh);
- unlock_buffer(bh);
- mark_buffer_dirty(bh);
- }
- page_dirty--;
+ xfs_add_to_ioend(inode, bh, offset, type,
+ &ioend, new_ioend);
count++;
}
- } else if (buffer_uptodate(bh) && startio) {
+ } else if (buffer_uptodate(bh)) {
/*
* we got here because the buffer is already mapped.
* That means it must already have extents allocated
@@ -1213,8 +1165,7 @@ xfs_page_state_convert(
*/
if (!imap_valid || flags != BMAPI_READ) {
flags = BMAPI_READ;
- size = xfs_probe_cluster(inode, page, bh,
- head, 1);
+ size = xfs_probe_cluster(inode, page, bh, head);
err = xfs_map_blocks(inode, offset, size,
&imap, flags);
if (err)
@@ -1233,18 +1184,16 @@ xfs_page_state_convert(
*/
type = IO_NEW;
if (trylock_buffer(bh)) {
- ASSERT(buffer_mapped(bh));
if (imap_valid)
all_bh = 1;
xfs_add_to_ioend(inode, bh, offset, type,
&ioend, !imap_valid);
- page_dirty--;
count++;
} else {
imap_valid = 0;
}
- } else if ((buffer_uptodate(bh) || PageUptodate(page)) &&
- (unmapped || startio)) {
+ } else if (PageUptodate(page)) {
+ ASSERT(buffer_mapped(bh));
imap_valid = 0;
}
@@ -1256,8 +1205,7 @@ xfs_page_state_convert(
if (uptodate && bh == head)
SetPageUptodate(page);
- if (startio)
- xfs_start_page_writeback(page, 1, count);
+ xfs_start_page_writeback(page, 1, count);
if (ioend && imap_valid) {
xfs_off_t end_index;
@@ -1275,131 +1223,27 @@ xfs_page_state_convert(
end_index = last_index;
xfs_cluster_write(inode, page->index + 1, &imap, &ioend,
- wbc, startio, all_bh, end_index);
+ wbc, all_bh, end_index);
}
if (iohead)
xfs_submit_ioend(wbc, iohead);
- return page_dirty;
+ return 0;
error:
if (iohead)
xfs_cancel_ioend(iohead);
- /*
- * If it's delalloc and we have nowhere to put it,
- * throw it away, unless the lower layers told
- * us to try again.
- */
- if (err != -EAGAIN) {
- if (!unmapped)
- xfs_aops_discard_page(page);
- ClearPageUptodate(page);
- }
+ xfs_aops_discard_page(page);
+ ClearPageUptodate(page);
+ unlock_page(page);
return err;
-}
-
-/*
- * writepage: Called from one of two places:
- *
- * 1. we are flushing a delalloc buffer head.
- *
- * 2. we are writing out a dirty page. Typically the page dirty
- * state is cleared before we get here. In this case is it
- * conceivable we have no buffer heads.
- *
- * For delalloc space on the page we need to allocate space and
- * flush it. For unmapped buffer heads on the page we should
- * allocate space if the page is uptodate. For any other dirty
- * buffer heads on the page we should flush them.
- *
- * If we detect that a transaction would be required to flush
- * the page, we have to check the process flags first, if we
- * are already in a transaction or disk I/O during allocations
- * is off, we need to fail the writepage and redirty the page.
- */
-
-STATIC int
-xfs_vm_writepage(
- struct page *page,
- struct writeback_control *wbc)
-{
- int error;
- int need_trans;
- int delalloc, unmapped, unwritten;
- struct inode *inode = page->mapping->host;
-
- trace_xfs_writepage(inode, page, 0);
-
- /*
- * Refuse to write the page out if we are called from reclaim context.
- *
- * This is primarily to avoid stack overflows when called from deep
- * used stacks in random callers for direct reclaim, but disabling
- * reclaim for kswap is a nice side-effect as kswapd causes rather
- * suboptimal I/O patters, too.
- *
- * This should really be done by the core VM, but until that happens
- * filesystems like XFS, btrfs and ext4 have to take care of this
- * by themselves.
- */
- if (current->flags & PF_MEMALLOC)
- goto out_fail;
-
- /*
- * We need a transaction if:
- * 1. There are delalloc buffers on the page
- * 2. The page is uptodate and we have unmapped buffers
- * 3. The page is uptodate and we have no buffers
- * 4. There are unwritten buffers on the page
- */
-
- if (!page_has_buffers(page)) {
- unmapped = 1;
- need_trans = 1;
- } else {
- xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
- if (!PageUptodate(page))
- unmapped = 0;
- need_trans = delalloc + unmapped + unwritten;
- }
-
- /*
- * If we need a transaction and the process flags say
- * we are already in a transaction, or no IO is allowed
- * then mark the page dirty again and leave the page
- * as is.
- */
- if (current_test_flags(PF_FSTRANS) && need_trans)
- goto out_fail;
-
- /*
- * Delay hooking up buffer heads until we have
- * made our go/no-go decision.
- */
- if (!page_has_buffers(page))
- create_empty_buffers(page, 1 << inode->i_blkbits, 0);
-
- /*
- * Convert delayed allocate, unwritten or unmapped space
- * to real space and flush out to disk.
- */
- error = xfs_page_state_convert(inode, page, wbc, 1, unmapped);
- if (error == -EAGAIN)
- goto out_fail;
- if (unlikely(error < 0))
- goto out_unlock;
-
- return 0;
out_fail:
redirty_page_for_writepage(wbc, page);
unlock_page(page);
return 0;
-out_unlock:
- unlock_page(page);
- return error;
}
STATIC int
@@ -1413,65 +1257,27 @@ xfs_vm_writepages(
/*
* Called to move a page into cleanable state - and from there
- * to be released. Possibly the page is already clean. We always
+ * to be released. The page should already be clean. We always
* have buffer heads in this call.
*
- * Returns 0 if the page is ok to release, 1 otherwise.
- *
- * Possible scenarios are:
- *
- * 1. We are being called to release a page which has been written
- * to via regular I/O. buffer heads will be dirty and possibly
- * delalloc. If no delalloc buffer heads in this case then we
- * can just return zero.
- *
- * 2. We are called to release a page which has been written via
- * mmap, all we need to do is ensure there is no delalloc
- * state in the buffer heads, if not we can let the caller
- * free them and we should come back later via writepage.
+ * Returns 1 if the page is ok to release, 0 otherwise.
*/
STATIC int
xfs_vm_releasepage(
struct page *page,
gfp_t gfp_mask)
{
- struct inode *inode = page->mapping->host;
- int dirty, delalloc, unmapped, unwritten;
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = 1,
- };
+ int delalloc, unwritten;
- trace_xfs_releasepage(inode, page, 0);
-
- if (!page_has_buffers(page))
- return 0;
+ trace_xfs_releasepage(page->mapping->host, page, 0);
- xfs_count_page_state(page, &delalloc, &unmapped, &unwritten);
- if (!delalloc && !unwritten)
- goto free_buffers;
+ xfs_count_page_state(page, &delalloc, &unwritten);
- if (!(gfp_mask & __GFP_FS))
+ if (WARN_ON(delalloc))
return 0;
-
- /* If we are already inside a transaction or the thread cannot
- * do I/O, we cannot release this page.
- */
- if (current_test_flags(PF_FSTRANS))
+ if (WARN_ON(unwritten))
return 0;
- /*
- * Convert delalloc space to real space, do not flush the
- * data out to disk, that will be done by the caller.
- * Never need to allocate space here - we will always
- * come back to writepage in that case.
- */
- dirty = xfs_page_state_convert(inode, page, &wbc, 0, 0);
- if (dirty == 0 && !unwritten)
- goto free_buffers;
- return 0;
-
-free_buffers:
return try_to_free_buffers(page);
}
@@ -1481,9 +1287,9 @@ __xfs_get_blocks(
sector_t iblock,
struct buffer_head *bh_result,
int create,
- int direct,
- bmapi_flags_t flags)
+ int direct)
{
+ int flags = create ? BMAPI_WRITE : BMAPI_READ;
struct xfs_bmbt_irec imap;
xfs_off_t offset;
ssize_t size;
@@ -1498,8 +1304,11 @@ __xfs_get_blocks(
if (!create && direct && offset >= i_size_read(inode))
return 0;
- error = xfs_iomap(XFS_I(inode), offset, size,
- create ? flags : BMAPI_READ, &imap, &nimap, &new);
+ if (direct && create)
+ flags |= BMAPI_DIRECT;
+
+ error = xfs_iomap(XFS_I(inode), offset, size, flags, &imap, &nimap,
+ &new);
if (error)
return -error;
if (nimap == 0)
@@ -1579,8 +1388,7 @@ xfs_get_blocks(
struct buffer_head *bh_result,
int create)
{
- return __xfs_get_blocks(inode, iblock,
- bh_result, create, 0, BMAPI_WRITE);
+ return __xfs_get_blocks(inode, iblock, bh_result, create, 0);
}
STATIC int
@@ -1590,8 +1398,7 @@ xfs_get_blocks_direct(
struct buffer_head *bh_result,
int create)
{
- return __xfs_get_blocks(inode, iblock,
- bh_result, create, 1, BMAPI_WRITE|BMAPI_DIRECT);
+ return __xfs_get_blocks(inode, iblock, bh_result, create, 1);
}
STATIC void
@@ -1665,16 +1472,31 @@ xfs_vm_direct_IO(
iocb->private = xfs_alloc_ioend(inode, rw == WRITE ?
IO_UNWRITTEN : IO_READ);
- ret = blockdev_direct_IO_no_locking(rw, iocb, inode, bdev, iov,
- offset, nr_segs,
- xfs_get_blocks_direct,
- xfs_end_io_direct);
+ ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
+ nr_segs, xfs_get_blocks_direct,
+ xfs_end_io_direct, NULL, 0);
if (unlikely(ret != -EIOCBQUEUED && iocb->private))
xfs_destroy_ioend(iocb->private);
return ret;
}
+STATIC void
+xfs_vm_write_failed(
+ struct address_space *mapping,
+ loff_t to)
+{
+ struct inode *inode = mapping->host;
+
+ if (to > inode->i_size) {
+ struct iattr ia = {
+ .ia_valid = ATTR_SIZE | ATTR_FORCE,
+ .ia_size = inode->i_size,
+ };
+ xfs_setattr(XFS_I(inode), &ia, XFS_ATTR_NOLOCK);
+ }
+}
+
STATIC int
xfs_vm_write_begin(
struct file *file,
@@ -1685,9 +1507,31 @@ xfs_vm_write_begin(
struct page **pagep,
void **fsdata)
{
- *pagep = NULL;
- return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
- xfs_get_blocks);
+ int ret;
+
+ ret = block_write_begin(mapping, pos, len, flags, pagep,
+ xfs_get_blocks);
+ if (unlikely(ret))
+ xfs_vm_write_failed(mapping, pos + len);
+ return ret;
+}
+
+STATIC int
+xfs_vm_write_end(
+ struct file *file,
+ struct address_space *mapping,
+ loff_t pos,
+ unsigned len,
+ unsigned copied,
+ struct page *page,
+ void *fsdata)
+{
+ int ret;
+
+ ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
+ if (unlikely(ret < len))
+ xfs_vm_write_failed(mapping, pos + len);
+ return ret;
}
STATIC sector_t
@@ -1698,7 +1542,7 @@ xfs_vm_bmap(
struct inode *inode = (struct inode *)mapping->host;
struct xfs_inode *ip = XFS_I(inode);
- xfs_itrace_entry(XFS_I(inode));
+ trace_xfs_vm_bmap(XFS_I(inode));
xfs_ilock(ip, XFS_IOLOCK_SHARED);
xfs_flush_pages(ip, (xfs_off_t)0, -1, 0, FI_REMAPF);
xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -1732,7 +1576,7 @@ const struct address_space_operations xfs_address_space_operations = {
.releasepage = xfs_vm_releasepage,
.invalidatepage = xfs_vm_invalidatepage,
.write_begin = xfs_vm_write_begin,
- .write_end = generic_write_end,
+ .write_end = xfs_vm_write_end,
.bmap = xfs_vm_bmap,
.direct_IO = xfs_vm_direct_IO,
.migratepage = buffer_migrate_page,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 4cfc6ea87df8..319da173cc1a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -45,6 +45,6 @@ extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
extern void xfs_ioend_init(void);
extern void xfs_ioend_wait(struct xfs_inode *);
-extern void xfs_count_page_state(struct page *, int *, int *, int *);
+extern void xfs_count_page_state(struct page *, int *, int *);
#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 649ade8ef598..76bb13c69264 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -39,7 +39,6 @@
#include "xfs_inum.h"
#include "xfs_log.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trace.h"
@@ -897,36 +896,6 @@ xfs_buf_unlock(
trace_xfs_buf_unlock(bp, _RET_IP_);
}
-
-/*
- * Pinning Buffer Storage in Memory
- * Ensure that no attempt to force a buffer to disk will succeed.
- */
-void
-xfs_buf_pin(
- xfs_buf_t *bp)
-{
- trace_xfs_buf_pin(bp, _RET_IP_);
- atomic_inc(&bp->b_pin_count);
-}
-
-void
-xfs_buf_unpin(
- xfs_buf_t *bp)
-{
- trace_xfs_buf_unpin(bp, _RET_IP_);
-
- if (atomic_dec_and_test(&bp->b_pin_count))
- wake_up_all(&bp->b_waiters);
-}
-
-int
-xfs_buf_ispin(
- xfs_buf_t *bp)
-{
- return atomic_read(&bp->b_pin_count);
-}
-
STATIC void
xfs_buf_wait_unpin(
xfs_buf_t *bp)
@@ -1803,7 +1772,7 @@ xfs_buf_delwri_split(
trace_xfs_buf_delwri_split(bp, _RET_IP_);
ASSERT(bp->b_flags & XBF_DELWRI);
- if (!xfs_buf_ispin(bp) && !xfs_buf_cond_lock(bp)) {
+ if (!XFS_BUF_ISPINNED(bp) && !xfs_buf_cond_lock(bp)) {
if (!force &&
time_before(jiffies, bp->b_queuetime + age)) {
xfs_buf_unlock(bp);
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 5fbecefa5dfd..814f9e83b516 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -44,57 +44,57 @@ typedef enum {
XBRW_ZERO = 3, /* Zero target memory */
} xfs_buf_rw_t;
-typedef enum {
- XBF_READ = (1 << 0), /* buffer intended for reading from device */
- XBF_WRITE = (1 << 1), /* buffer intended for writing to device */
- XBF_MAPPED = (1 << 2), /* buffer mapped (b_addr valid) */
- XBF_ASYNC = (1 << 4), /* initiator will not wait for completion */
- XBF_DONE = (1 << 5), /* all pages in the buffer uptodate */
- XBF_DELWRI = (1 << 6), /* buffer has dirty pages */
- XBF_STALE = (1 << 7), /* buffer has been staled, do not find it */
- XBF_FS_MANAGED = (1 << 8), /* filesystem controls freeing memory */
- XBF_ORDERED = (1 << 11), /* use ordered writes */
- XBF_READ_AHEAD = (1 << 12), /* asynchronous read-ahead */
- XBF_LOG_BUFFER = (1 << 13), /* this is a buffer used for the log */
-
- /* flags used only as arguments to access routines */
- XBF_LOCK = (1 << 14), /* lock requested */
- XBF_TRYLOCK = (1 << 15), /* lock requested, but do not wait */
- XBF_DONT_BLOCK = (1 << 16), /* do not block in current thread */
-
- /* flags used only internally */
- _XBF_PAGE_CACHE = (1 << 17),/* backed by pagecache */
- _XBF_PAGES = (1 << 18), /* backed by refcounted pages */
- _XBF_RUN_QUEUES = (1 << 19),/* run block device task queue */
- _XBF_DELWRI_Q = (1 << 21), /* buffer on delwri queue */
-
- /*
- * Special flag for supporting metadata blocks smaller than a FSB.
- *
- * In this case we can have multiple xfs_buf_t on a single page and
- * need to lock out concurrent xfs_buf_t readers as they only
- * serialise access to the buffer.
- *
- * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation
- * between reads of the page. Hence we can have one thread read the
- * page and modify it, but then race with another thread that thinks
- * the page is not up-to-date and hence reads it again.
- *
- * The result is that the first modifcation to the page is lost.
- * This sort of AGF/AGI reading race can happen when unlinking inodes
- * that require truncation and results in the AGI unlinked list
- * modifications being lost.
- */
- _XBF_PAGE_LOCKED = (1 << 22),
-
- /*
- * If we try a barrier write, but it fails we have to communicate
- * this to the upper layers. Unfortunately b_error gets overwritten
- * when the buffer is re-issued so we have to add another flag to
- * keep this information.
- */
- _XFS_BARRIER_FAILED = (1 << 23),
-} xfs_buf_flags_t;
+#define XBF_READ (1 << 0) /* buffer intended for reading from device */
+#define XBF_WRITE (1 << 1) /* buffer intended for writing to device */
+#define XBF_MAPPED (1 << 2) /* buffer mapped (b_addr valid) */
+#define XBF_ASYNC (1 << 4) /* initiator will not wait for completion */
+#define XBF_DONE (1 << 5) /* all pages in the buffer uptodate */
+#define XBF_DELWRI (1 << 6) /* buffer has dirty pages */
+#define XBF_STALE (1 << 7) /* buffer has been staled, do not find it */
+#define XBF_FS_MANAGED (1 << 8) /* filesystem controls freeing memory */
+#define XBF_ORDERED (1 << 11)/* use ordered writes */
+#define XBF_READ_AHEAD (1 << 12)/* asynchronous read-ahead */
+#define XBF_LOG_BUFFER (1 << 13)/* this is a buffer used for the log */
+
+/* flags used only as arguments to access routines */
+#define XBF_LOCK (1 << 14)/* lock requested */
+#define XBF_TRYLOCK (1 << 15)/* lock requested, but do not wait */
+#define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */
+
+/* flags used only internally */
+#define _XBF_PAGE_CACHE (1 << 17)/* backed by pagecache */
+#define _XBF_PAGES (1 << 18)/* backed by refcounted pages */
+#define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */
+#define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */
+
+/*
+ * Special flag for supporting metadata blocks smaller than a FSB.
+ *
+ * In this case we can have multiple xfs_buf_t on a single page and
+ * need to lock out concurrent xfs_buf_t readers as they only
+ * serialise access to the buffer.
+ *
+ * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation
+ * between reads of the page. Hence we can have one thread read the
+ * page and modify it, but then race with another thread that thinks
+ * the page is not up-to-date and hence reads it again.
+ *
+ * The result is that the first modifcation to the page is lost.
+ * This sort of AGF/AGI reading race can happen when unlinking inodes
+ * that require truncation and results in the AGI unlinked list
+ * modifications being lost.
+ */
+#define _XBF_PAGE_LOCKED (1 << 22)
+
+/*
+ * If we try a barrier write, but it fails we have to communicate
+ * this to the upper layers. Unfortunately b_error gets overwritten
+ * when the buffer is re-issued so we have to add another flag to
+ * keep this information.
+ */
+#define _XFS_BARRIER_FAILED (1 << 23)
+
+typedef unsigned int xfs_buf_flags_t;
#define XFS_BUF_FLAGS \
{ XBF_READ, "READ" }, \
@@ -258,11 +258,6 @@ static inline int xfs_buf_geterror(xfs_buf_t *bp)
/* Buffer Utility Routines */
extern xfs_caddr_t xfs_buf_offset(xfs_buf_t *, size_t);
-/* Pinning Buffer Storage in Memory */
-extern void xfs_buf_pin(xfs_buf_t *);
-extern void xfs_buf_unpin(xfs_buf_t *);
-extern int xfs_buf_ispin(xfs_buf_t *);
-
/* Delayed Write Buffer Routines */
extern void xfs_buf_delwri_dequeue(xfs_buf_t *);
extern void xfs_buf_delwri_promote(xfs_buf_t *);
@@ -351,7 +346,7 @@ extern void xfs_buf_terminate(void);
#define XFS_BUF_SET_VTYPE(bp, type) do { } while (0)
#define XFS_BUF_SET_REF(bp, ref) do { } while (0)
-#define XFS_BUF_ISPINNED(bp) xfs_buf_ispin(bp)
+#define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count))
#define XFS_BUF_VALUSEMA(bp) xfs_buf_lock_value(bp)
#define XFS_BUF_CPSEMA(bp) (xfs_buf_cond_lock(bp) == 0)
@@ -370,8 +365,6 @@ static inline void xfs_buf_relse(xfs_buf_t *bp)
xfs_buf_rele(bp);
}
-#define xfs_bpin(bp) xfs_buf_pin(bp)
-#define xfs_bunpin(bp) xfs_buf_unpin(bp)
#define xfs_biodone(bp) xfs_buf_ioend(bp, 0)
#define xfs_biomove(bp, off, len, data, rw) \
diff --git a/fs/xfs/linux-2.6/xfs_dmapi_priv.h b/fs/xfs/linux-2.6/xfs_dmapi_priv.h
deleted file mode 100644
index a8b0b1685eed..000000000000
--- a/fs/xfs/linux-2.6/xfs_dmapi_priv.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DMAPI_PRIV_H__
-#define __XFS_DMAPI_PRIV_H__
-
-/*
- * Based on IO_ISDIRECT, decide which i_ flag is set.
- */
-#define DM_SEM_FLAG_RD(ioflags) (((ioflags) & IO_ISDIRECT) ? \
- DM_FLAGS_IMUX : 0)
-#define DM_SEM_FLAG_WR (DM_FLAGS_IALLOCSEM_WR | DM_FLAGS_IMUX)
-
-#endif /*__XFS_DMAPI_PRIV_H__*/
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index e7839ee49e43..3764d74790ec 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -23,13 +23,13 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_export.h"
#include "xfs_vnodeops.h"
#include "xfs_bmap_btree.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
+#include "xfs_trace.h"
/*
* Note that we only accept fileids which are long enough rather than allow
@@ -132,8 +132,7 @@ xfs_nfs_get_inode(
* fine and not an indication of a corrupted filesystem as clients can
* send invalid file handles and we have to handle it gracefully..
*/
- error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED,
- XFS_ILOCK_SHARED, &ip);
+ error = xfs_iget(mp, NULL, ino, XFS_IGET_UNTRUSTED, 0, &ip);
if (error) {
/*
* EINVAL means the inode cluster doesn't exist anymore.
@@ -148,11 +147,10 @@ xfs_nfs_get_inode(
}
if (ip->i_d.di_gen != generation) {
- xfs_iput_new(ip, XFS_ILOCK_SHARED);
+ IRELE(ip);
return ERR_PTR(-ENOENT);
}
- xfs_iunlock(ip, XFS_ILOCK_SHARED);
return VFS_I(ip);
}
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 257a56b127cf..ba8ad422a165 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -22,23 +22,15 @@
#include "xfs_inum.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_trans.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
-#include "xfs_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_vnodeops.h"
#include "xfs_da_btree.h"
#include "xfs_ioctl.h"
@@ -108,7 +100,7 @@ xfs_file_fsync(
int error = 0;
int log_flushed = 0;
- xfs_itrace_entry(ip);
+ trace_xfs_file_fsync(ip);
if (XFS_FORCED_SHUTDOWN(ip->i_mount))
return -XFS_ERROR(EIO);
@@ -166,8 +158,7 @@ xfs_file_fsync(
* transaction. So we play it safe and fire off the
* transaction anyway.
*/
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
error = _xfs_trans_commit(tp, 0, &log_flushed);
@@ -275,20 +266,6 @@ xfs_file_aio_read(
mutex_lock(&inode->i_mutex);
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
- int dmflags = FILP_DELAY_FLAG(file) | DM_SEM_FLAG_RD(ioflags);
- int iolock = XFS_IOLOCK_SHARED;
-
- ret = -XFS_SEND_DATA(mp, DM_EVENT_READ, ip, iocb->ki_pos, size,
- dmflags, &iolock);
- if (ret) {
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- if (unlikely(ioflags & IO_ISDIRECT))
- mutex_unlock(&inode->i_mutex);
- return ret;
- }
- }
-
if (unlikely(ioflags & IO_ISDIRECT)) {
if (inode->i_mapping->nrpages) {
ret = -xfs_flushinval_pages(ip,
@@ -321,7 +298,6 @@ xfs_file_splice_read(
unsigned int flags)
{
struct xfs_inode *ip = XFS_I(infilp->f_mapping->host);
- struct xfs_mount *mp = ip->i_mount;
int ioflags = 0;
ssize_t ret;
@@ -335,18 +311,6 @@ xfs_file_splice_read(
xfs_ilock(ip, XFS_IOLOCK_SHARED);
- if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) && !(ioflags & IO_INVIS)) {
- int iolock = XFS_IOLOCK_SHARED;
- int error;
-
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip, *ppos, count,
- FILP_DELAY_FLAG(infilp), &iolock);
- if (error) {
- xfs_iunlock(ip, XFS_IOLOCK_SHARED);
- return -error;
- }
- }
-
trace_xfs_file_splice_read(ip, count, *ppos, ioflags);
ret = generic_file_splice_read(infilp, ppos, pipe, count, flags);
@@ -367,7 +331,6 @@ xfs_file_splice_write(
{
struct inode *inode = outfilp->f_mapping->host;
struct xfs_inode *ip = XFS_I(inode);
- struct xfs_mount *mp = ip->i_mount;
xfs_fsize_t isize, new_size;
int ioflags = 0;
ssize_t ret;
@@ -382,18 +345,6 @@ xfs_file_splice_write(
xfs_ilock(ip, XFS_IOLOCK_EXCL);
- if (DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) && !(ioflags & IO_INVIS)) {
- int iolock = XFS_IOLOCK_EXCL;
- int error;
-
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, *ppos, count,
- FILP_DELAY_FLAG(outfilp), &iolock);
- if (error) {
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return -error;
- }
- }
-
new_size = *ppos + count;
xfs_ilock(ip, XFS_ILOCK_EXCL);
@@ -463,7 +414,7 @@ xfs_zero_last_block(
last_fsb = XFS_B_TO_FSBT(mp, isize);
nimaps = 1;
error = xfs_bmapi(NULL, ip, last_fsb, 1, 0, NULL, 0, &imap,
- &nimaps, NULL, NULL);
+ &nimaps, NULL);
if (error) {
return error;
}
@@ -558,7 +509,7 @@ xfs_zero_eof(
nimaps = 1;
zero_count_fsb = end_zero_fsb - start_zero_fsb + 1;
error = xfs_bmapi(NULL, ip, start_zero_fsb, zero_count_fsb,
- 0, NULL, 0, &imap, &nimaps, NULL, NULL);
+ 0, NULL, 0, &imap, &nimaps, NULL);
if (error) {
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_IOLOCK_EXCL));
return error;
@@ -627,7 +578,6 @@ xfs_file_aio_write(
int ioflags = 0;
xfs_fsize_t isize, new_size;
int iolock;
- int eventsent = 0;
size_t ocount = 0, count;
int need_i_mutex;
@@ -673,33 +623,6 @@ start:
goto out_unlock_mutex;
}
- if ((DM_EVENT_ENABLED(ip, DM_EVENT_WRITE) &&
- !(ioflags & IO_INVIS) && !eventsent)) {
- int dmflags = FILP_DELAY_FLAG(file);
-
- if (need_i_mutex)
- dmflags |= DM_FLAGS_IMUX;
-
- xfs_iunlock(ip, XFS_ILOCK_EXCL);
- error = XFS_SEND_DATA(ip->i_mount, DM_EVENT_WRITE, ip,
- pos, count, dmflags, &iolock);
- if (error) {
- goto out_unlock_internal;
- }
- xfs_ilock(ip, XFS_ILOCK_EXCL);
- eventsent = 1;
-
- /*
- * The iolock was dropped and reacquired in XFS_SEND_DATA
- * so we have to recheck the size when appending.
- * We will only "goto start;" once, since having sent the
- * event prevents another call to XFS_SEND_DATA, which is
- * what allows the size to change in the first place.
- */
- if ((file->f_flags & O_APPEND) && pos != ip->i_size)
- goto start;
- }
-
if (ioflags & IO_ISDIRECT) {
xfs_buftarg_t *target =
XFS_IS_REALTIME_INODE(ip) ?
@@ -830,22 +753,6 @@ write_retry:
xfs_iunlock(ip, XFS_ILOCK_EXCL);
}
- if (ret == -ENOSPC &&
- DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE) && !(ioflags & IO_INVIS)) {
- xfs_iunlock(ip, iolock);
- if (need_i_mutex)
- mutex_unlock(&inode->i_mutex);
- error = XFS_SEND_NAMESP(ip->i_mount, DM_EVENT_NOSPACE, ip,
- DM_RIGHT_NULL, ip, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, 0); /* Delay flag intentionally unused */
- if (need_i_mutex)
- mutex_lock(&inode->i_mutex);
- xfs_ilock(ip, iolock);
- if (error)
- goto out_unlock_internal;
- goto start;
- }
-
error = -ret;
if (ret <= 0)
goto out_unlock_internal;
@@ -1014,9 +921,6 @@ const struct file_operations xfs_file_operations = {
.open = xfs_file_open,
.release = xfs_file_release,
.fsync = xfs_file_fsync,
-#ifdef HAVE_FOP_OPEN_EXEC
- .open_exec = xfs_file_open_exec,
-#endif
};
const struct file_operations xfs_dir_file_operations = {
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.c b/fs/xfs/linux-2.6/xfs_fs_subr.c
index b6918d76bc7b..1f279b012f94 100644
--- a/fs/xfs/linux-2.6/xfs_fs_subr.c
+++ b/fs/xfs/linux-2.6/xfs_fs_subr.c
@@ -21,10 +21,6 @@
#include "xfs_inode.h"
#include "xfs_trace.h"
-int fs_noerr(void) { return 0; }
-int fs_nosys(void) { return ENOSYS; }
-void fs_noval(void) { return; }
-
/*
* note: all filemap functions return negative error codes. These
* need to be inverted before returning to the xfs core functions.
diff --git a/fs/xfs/linux-2.6/xfs_fs_subr.h b/fs/xfs/linux-2.6/xfs_fs_subr.h
deleted file mode 100644
index 82bb19b2599e..000000000000
--- a/fs/xfs/linux-2.6/xfs_fs_subr.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2000,2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_FS_SUBR_H__
-#define __XFS_FS_SUBR_H__
-
-extern int fs_noerr(void);
-extern int fs_nosys(void);
-extern void fs_noval(void);
-
-#endif /* __XFS_FS_SUBR_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index e59a81062830..237f5ffb2ee8 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -23,24 +23,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_ioctl.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_itable.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_bmap.h"
#include "xfs_buf_item.h"
@@ -908,7 +899,7 @@ xfs_ioctl_setattr(
struct xfs_dquot *olddquot = NULL;
int code;
- xfs_itrace_entry(ip);
+ trace_xfs_ioctl_setattr(ip);
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
@@ -1043,8 +1034,7 @@ xfs_ioctl_setattr(
}
}
- xfs_trans_ijoin(tp, ip, lock_flags);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* Change file ownership. Must be the owner or privileged.
@@ -1116,16 +1106,7 @@ xfs_ioctl_setattr(
xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp);
- if (code)
- return code;
-
- if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE)) {
- XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, NULL, NULL, 0, 0,
- (mask & FSX_NONBLOCK) ? DM_FLAGS_NDELAY : 0);
- }
-
- return 0;
+ return code;
error_return:
xfs_qm_dqrele(udqp);
@@ -1301,7 +1282,7 @@ xfs_file_ioctl(
if (filp->f_mode & FMODE_NOCMTIME)
ioflags |= IO_INVIS;
- xfs_itrace_entry(ip);
+ trace_xfs_file_ioctl(ip);
switch (cmd) {
case XFS_IOC_ALLOCSP:
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 52ed49e6465c..6c83f7f62dc9 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -28,12 +28,8 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir2_sf.h"
#include "xfs_vnode.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@@ -544,7 +540,7 @@ xfs_file_compat_ioctl(
if (filp->f_mode & FMODE_NOCMTIME)
ioflags |= IO_INVIS;
- xfs_itrace_entry(ip);
+ trace_xfs_file_compat_ioctl(ip);
switch (cmd) {
/* No size or alignment issues on any arch */
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 44f0b2de153e..68be25dcd301 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -24,21 +24,13 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
@@ -88,7 +80,7 @@ xfs_mark_inode_dirty_sync(
{
struct inode *inode = VFS_I(ip);
- if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
+ if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty_sync(inode);
}
@@ -98,7 +90,7 @@ xfs_mark_inode_dirty(
{
struct inode *inode = VFS_I(ip);
- if (!(inode->i_state & (I_WILL_FREE|I_FREEING|I_CLEAR)))
+ if (!(inode->i_state & (I_WILL_FREE|I_FREEING)))
mark_inode_dirty(inode);
}
@@ -496,7 +488,7 @@ xfs_vn_getattr(
struct xfs_inode *ip = XFS_I(inode);
struct xfs_mount *mp = ip->i_mount;
- xfs_itrace_entry(ip);
+ trace_xfs_getattr(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -548,21 +540,6 @@ xfs_vn_setattr(
return -xfs_setattr(XFS_I(dentry->d_inode), iattr, 0);
}
-/*
- * block_truncate_page can return an error, but we can't propagate it
- * at all here. Leave a complaint + stack trace in the syslog because
- * this could be bad. If it is bad, we need to propagate the error further.
- */
-STATIC void
-xfs_vn_truncate(
- struct inode *inode)
-{
- int error;
- error = block_truncate_page(inode->i_mapping, inode->i_size,
- xfs_get_blocks);
- WARN_ON(error);
-}
-
STATIC long
xfs_vn_fallocate(
struct inode *inode,
@@ -702,7 +679,6 @@ xfs_vn_fiemap(
static const struct inode_operations xfs_inode_operations = {
.check_acl = xfs_check_acl,
- .truncate = xfs_vn_truncate,
.getattr = xfs_vn_getattr,
.setattr = xfs_vn_setattr,
.setxattr = generic_setxattr,
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index facfb323a706..2fa0bd9ebc7f 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -87,7 +87,6 @@
#include <xfs_aops.h>
#include <xfs_super.h>
#include <xfs_globals.h>
-#include <xfs_fs_subr.h>
#include <xfs_buf.h>
/*
@@ -157,8 +156,6 @@
*/
#define xfs_sort(a,n,s,fn) sort(a,n,s,fn,NULL)
#define xfs_stack_trace() dump_stack()
-#define xfs_itruncate_data(ip, off) \
- (-vmtruncate(VFS_I(ip), (off)))
/* Move the kernel do_div definition off to one side */
diff --git a/fs/xfs/linux-2.6/xfs_quotaops.c b/fs/xfs/linux-2.6/xfs_quotaops.c
index 067cafbfc635..29b9d642e93d 100644
--- a/fs/xfs/linux-2.6/xfs_quotaops.c
+++ b/fs/xfs/linux-2.6/xfs_quotaops.c
@@ -16,7 +16,6 @@
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "xfs.h"
-#include "xfs_dmapi.h"
#include "xfs_sb.h"
#include "xfs_inum.h"
#include "xfs_log.h"
@@ -69,15 +68,15 @@ xfs_fs_set_xstate(
if (op != Q_XQUOTARM && !XFS_IS_QUOTA_RUNNING(mp))
return -ENOSYS;
- if (uflags & XFS_QUOTA_UDQ_ACCT)
+ if (uflags & FS_QUOTA_UDQ_ACCT)
flags |= XFS_UQUOTA_ACCT;
- if (uflags & XFS_QUOTA_PDQ_ACCT)
+ if (uflags & FS_QUOTA_PDQ_ACCT)
flags |= XFS_PQUOTA_ACCT;
- if (uflags & XFS_QUOTA_GDQ_ACCT)
+ if (uflags & FS_QUOTA_GDQ_ACCT)
flags |= XFS_GQUOTA_ACCT;
- if (uflags & XFS_QUOTA_UDQ_ENFD)
+ if (uflags & FS_QUOTA_UDQ_ENFD)
flags |= XFS_UQUOTA_ENFD;
- if (uflags & (XFS_QUOTA_PDQ_ENFD|XFS_QUOTA_GDQ_ENFD))
+ if (uflags & (FS_QUOTA_PDQ_ENFD|FS_QUOTA_GDQ_ENFD))
flags |= XFS_OQUOTA_ENFD;
switch (op) {
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index f2d1718c9165..7cbbea03dae4 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -25,14 +25,11 @@
#include "xfs_ag.h"
#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
@@ -43,7 +40,6 @@
#include "xfs_error.h"
#include "xfs_itable.h"
#include "xfs_fsops.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
@@ -116,9 +112,6 @@ mempool_t *xfs_ioend_pool;
#define MNTOPT_GQUOTANOENF "gqnoenforce"/* group quota limit enforcement */
#define MNTOPT_PQUOTANOENF "pqnoenforce"/* project quota limit enforcement */
#define MNTOPT_QUOTANOENF "qnoenforce" /* same as uqnoenforce */
-#define MNTOPT_DMAPI "dmapi" /* DMI enabled (DMAPI / XDSM) */
-#define MNTOPT_XDSM "xdsm" /* DMI enabled (DMAPI / XDSM) */
-#define MNTOPT_DMI "dmi" /* DMI enabled (DMAPI / XDSM) */
#define MNTOPT_DELAYLOG "delaylog" /* Delayed loging enabled */
#define MNTOPT_NODELAYLOG "nodelaylog" /* Delayed loging disabled */
@@ -172,15 +165,13 @@ suffix_strtoul(char *s, char **endp, unsigned int base)
STATIC int
xfs_parseargs(
struct xfs_mount *mp,
- char *options,
- char **mtpt)
+ char *options)
{
struct super_block *sb = mp->m_super;
char *this_char, *value, *eov;
int dsunit = 0;
int dswidth = 0;
int iosize = 0;
- int dmapi_implies_ikeep = 1;
__uint8_t iosizelog = 0;
/*
@@ -243,15 +234,10 @@ xfs_parseargs(
if (!mp->m_logname)
return ENOMEM;
} else if (!strcmp(this_char, MNTOPT_MTPT)) {
- if (!value || !*value) {
- cmn_err(CE_WARN,
- "XFS: %s option requires an argument",
- this_char);
- return EINVAL;
- }
- *mtpt = kstrndup(value, MAXNAMELEN, GFP_KERNEL);
- if (!*mtpt)
- return ENOMEM;
+ cmn_err(CE_WARN,
+ "XFS: %s option not allowed on this system",
+ this_char);
+ return EINVAL;
} else if (!strcmp(this_char, MNTOPT_RTDEV)) {
if (!value || !*value) {
cmn_err(CE_WARN,
@@ -329,7 +315,6 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_IKEEP)) {
mp->m_flags |= XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_NOIKEEP)) {
- dmapi_implies_ikeep = 0;
mp->m_flags &= ~XFS_MOUNT_IKEEP;
} else if (!strcmp(this_char, MNTOPT_LARGEIO)) {
mp->m_flags &= ~XFS_MOUNT_COMPAT_IOSIZE;
@@ -370,12 +355,6 @@ xfs_parseargs(
} else if (!strcmp(this_char, MNTOPT_GQUOTANOENF)) {
mp->m_qflags |= (XFS_GQUOTA_ACCT | XFS_GQUOTA_ACTIVE);
mp->m_qflags &= ~XFS_OQUOTA_ENFD;
- } else if (!strcmp(this_char, MNTOPT_DMAPI)) {
- mp->m_flags |= XFS_MOUNT_DMAPI;
- } else if (!strcmp(this_char, MNTOPT_XDSM)) {
- mp->m_flags |= XFS_MOUNT_DMAPI;
- } else if (!strcmp(this_char, MNTOPT_DMI)) {
- mp->m_flags |= XFS_MOUNT_DMAPI;
} else if (!strcmp(this_char, MNTOPT_DELAYLOG)) {
mp->m_flags |= XFS_MOUNT_DELAYLOG;
cmn_err(CE_WARN,
@@ -430,12 +409,6 @@ xfs_parseargs(
return EINVAL;
}
- if ((mp->m_flags & XFS_MOUNT_DMAPI) && (!*mtpt || *mtpt[0] == '\0')) {
- printk("XFS: %s option needs the mount point option as well\n",
- MNTOPT_DMAPI);
- return EINVAL;
- }
-
if ((dsunit && !dswidth) || (!dsunit && dswidth)) {
cmn_err(CE_WARN,
"XFS: sunit and swidth must be specified together");
@@ -449,18 +422,6 @@ xfs_parseargs(
return EINVAL;
}
- /*
- * Applications using DMI filesystems often expect the
- * inode generation number to be monotonically increasing.
- * If we delete inode chunks we break this assumption, so
- * keep unused inode chunks on disk for DMI filesystems
- * until we come up with a better solution.
- * Note that if "ikeep" or "noikeep" mount options are
- * supplied, then they are honored.
- */
- if ((mp->m_flags & XFS_MOUNT_DMAPI) && dmapi_implies_ikeep)
- mp->m_flags |= XFS_MOUNT_IKEEP;
-
done:
if (!(mp->m_flags & XFS_MOUNT_NOALIGN)) {
/*
@@ -542,7 +503,6 @@ xfs_showargs(
{ XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC },
{ XFS_MOUNT_ATTR2, "," MNTOPT_ATTR2 },
{ XFS_MOUNT_FILESTREAMS, "," MNTOPT_FILESTREAM },
- { XFS_MOUNT_DMAPI, "," MNTOPT_DMAPI },
{ XFS_MOUNT_GRPID, "," MNTOPT_GRPID },
{ XFS_MOUNT_DELAYLOG, "," MNTOPT_DELAYLOG },
{ 0, NULL }
@@ -947,7 +907,7 @@ xfs_fs_destroy_inode(
{
struct xfs_inode *ip = XFS_I(inode);
- xfs_itrace_entry(ip);
+ trace_xfs_destroy_inode(ip);
XFS_STATS_INC(vn_reclaim);
@@ -1063,10 +1023,8 @@ xfs_log_inode(
* an inode in another recent transaction. So we play it safe and
* fire off the transaction anyway.
*/
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0);
xfs_ilock_demote(ip, XFS_ILOCK_EXCL);
@@ -1082,27 +1040,18 @@ xfs_fs_write_inode(
struct xfs_mount *mp = ip->i_mount;
int error = EAGAIN;
- xfs_itrace_entry(ip);
+ trace_xfs_write_inode(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
if (wbc->sync_mode == WB_SYNC_ALL) {
/*
- * Make sure the inode has hit stable storage. By using the
- * log and the fsync transactions we reduce the IOs we have
- * to do here from two (log and inode) to just the log.
- *
- * Note: We still need to do a delwri write of the inode after
- * this to flush it to the backing buffer so that bulkstat
- * works properly if this is the first time the inode has been
- * written. Because we hold the ilock atomically over the
- * transaction commit and the inode flush we are guaranteed
- * that the inode is not pinned when it returns. If the flush
- * lock is already held, then the inode has already been
- * flushed once and we don't need to flush it again. Hence
- * the code will only flush the inode if it isn't already
- * being flushed.
+ * Make sure the inode has made it it into the log. Instead
+ * of forcing it all the way to stable storage using a
+ * synchronous transaction we let the log force inside the
+ * ->sync_fs call do that for thus, which reduces the number
+ * of synchronous log foces dramatically.
*/
xfs_ioend_wait(ip);
xfs_ilock(ip, XFS_ILOCK_SHARED);
@@ -1116,27 +1065,29 @@ xfs_fs_write_inode(
* We make this non-blocking if the inode is contended, return
* EAGAIN to indicate to the caller that they did not succeed.
* This prevents the flush path from blocking on inodes inside
- * another operation right now, they get caught later by xfs_sync.
+ * another operation right now, they get caught later by
+ * xfs_sync.
*/
if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
goto out;
- }
- if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
- goto out_unlock;
+ if (xfs_ipincount(ip) || !xfs_iflock_nowait(ip))
+ goto out_unlock;
- /*
- * Now we have the flush lock and the inode is not pinned, we can check
- * if the inode is really clean as we know that there are no pending
- * transaction completions, it is not waiting on the delayed write
- * queue and there is no IO in progress.
- */
- if (xfs_inode_clean(ip)) {
- xfs_ifunlock(ip);
- error = 0;
- goto out_unlock;
+ /*
+ * Now we have the flush lock and the inode is not pinned, we
+ * can check if the inode is really clean as we know that
+ * there are no pending transaction completions, it is not
+ * waiting on the delayed write queue and there is no IO in
+ * progress.
+ */
+ if (xfs_inode_clean(ip)) {
+ xfs_ifunlock(ip);
+ error = 0;
+ goto out_unlock;
+ }
+ error = xfs_iflush(ip, 0);
}
- error = xfs_iflush(ip, 0);
out_unlock:
xfs_iunlock(ip, XFS_ILOCK_SHARED);
@@ -1151,12 +1102,15 @@ xfs_fs_write_inode(
}
STATIC void
-xfs_fs_clear_inode(
+xfs_fs_evict_inode(
struct inode *inode)
{
xfs_inode_t *ip = XFS_I(inode);
- xfs_itrace_entry(ip);
+ trace_xfs_evict_inode(ip);
+
+ truncate_inode_pages(&inode->i_data, 0);
+ end_writeback(inode);
XFS_STATS_INC(vn_rele);
XFS_STATS_INC(vn_remove);
XFS_STATS_DEC(vn_active);
@@ -1193,22 +1147,13 @@ xfs_fs_put_super(
{
struct xfs_mount *mp = XFS_M(sb);
+ /*
+ * Unregister the memory shrinker before we tear down the mount
+ * structure so we don't have memory reclaim racing with us here.
+ */
+ xfs_inode_shrinker_unregister(mp);
xfs_syncd_stop(mp);
- if (!(sb->s_flags & MS_RDONLY)) {
- /*
- * XXX(hch): this should be SYNC_WAIT.
- *
- * Or more likely not needed at all because the VFS is already
- * calling ->sync_fs after shutting down all filestem
- * operations and just before calling ->put_super.
- */
- xfs_sync_data(mp, 0);
- xfs_sync_attr(mp, 0);
- }
-
- XFS_SEND_PREUNMOUNT(mp);
-
/*
* Blow away any referenced inode in the filestreams cache.
* This can and will cause log traffic as inodes go inactive
@@ -1218,14 +1163,10 @@ xfs_fs_put_super(
XFS_bflush(mp->m_ddev_targp);
- XFS_SEND_UNMOUNT(mp);
-
xfs_unmountfs(mp);
xfs_freesb(mp);
- xfs_inode_shrinker_unregister(mp);
xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp);
- xfs_dmops_put(mp);
xfs_free_fsname(mp);
kfree(mp);
}
@@ -1543,7 +1484,6 @@ xfs_fs_fill_super(
struct inode *root;
struct xfs_mount *mp = NULL;
int flags = 0, error = ENOMEM;
- char *mtpt = NULL;
mp = kzalloc(sizeof(struct xfs_mount), GFP_KERNEL);
if (!mp)
@@ -1559,7 +1499,7 @@ xfs_fs_fill_super(
mp->m_super = sb;
sb->s_fs_info = mp;
- error = xfs_parseargs(mp, (char *)data, &mtpt);
+ error = xfs_parseargs(mp, (char *)data);
if (error)
goto out_free_fsname;
@@ -1571,16 +1511,12 @@ xfs_fs_fill_super(
#endif
sb->s_op = &xfs_super_operations;
- error = xfs_dmops_get(mp);
- if (error)
- goto out_free_fsname;
-
if (silent)
flags |= XFS_MFSI_QUIET;
error = xfs_open_devices(mp);
if (error)
- goto out_put_dmops;
+ goto out_free_fsname;
if (xfs_icsb_init_counters(mp))
mp->m_flags |= XFS_MOUNT_NO_PERCPU_SB;
@@ -1608,8 +1544,6 @@ xfs_fs_fill_super(
if (error)
goto out_filestream_unmount;
- XFS_SEND_MOUNT(mp, DM_RIGHT_NULL, mtpt, mp->m_fsname);
-
sb->s_magic = XFS_SB_MAGIC;
sb->s_blocksize = mp->m_sb.sb_blocksize;
sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
@@ -1638,7 +1572,6 @@ xfs_fs_fill_super(
xfs_inode_shrinker_register(mp);
- kfree(mtpt);
return 0;
out_filestream_unmount:
@@ -1648,11 +1581,8 @@ xfs_fs_fill_super(
out_destroy_counters:
xfs_icsb_destroy_counters(mp);
xfs_close_devices(mp);
- out_put_dmops:
- xfs_dmops_put(mp);
out_free_fsname:
xfs_free_fsname(mp);
- kfree(mtpt);
kfree(mp);
out:
return -error;
@@ -1696,7 +1626,7 @@ static const struct super_operations xfs_super_operations = {
.destroy_inode = xfs_fs_destroy_inode,
.dirty_inode = xfs_fs_dirty_inode,
.write_inode = xfs_fs_write_inode,
- .clear_inode = xfs_fs_clear_inode,
+ .evict_inode = xfs_fs_evict_inode,
.put_super = xfs_fs_put_super,
.sync_fs = xfs_fs_sync_fs,
.freeze_fs = xfs_fs_freeze,
@@ -1759,6 +1689,12 @@ xfs_init_zones(void)
if (!xfs_trans_zone)
goto out_destroy_ifork_zone;
+ xfs_log_item_desc_zone =
+ kmem_zone_init(sizeof(struct xfs_log_item_desc),
+ "xfs_log_item_desc");
+ if (!xfs_log_item_desc_zone)
+ goto out_destroy_trans_zone;
+
/*
* The size of the zone allocated buf log item is the maximum
* size possible under XFS. This wastes a little bit of memory,
@@ -1768,7 +1704,7 @@ xfs_init_zones(void)
(((XFS_MAX_BLOCKSIZE / XFS_BLF_CHUNK) /
NBWORD) * sizeof(int))), "xfs_buf_item");
if (!xfs_buf_item_zone)
- goto out_destroy_trans_zone;
+ goto out_destroy_log_item_desc_zone;
xfs_efd_zone = kmem_zone_init((sizeof(xfs_efd_log_item_t) +
((XFS_EFD_MAX_FAST_EXTENTS - 1) *
@@ -1805,6 +1741,8 @@ xfs_init_zones(void)
kmem_zone_destroy(xfs_efd_zone);
out_destroy_buf_item_zone:
kmem_zone_destroy(xfs_buf_item_zone);
+ out_destroy_log_item_desc_zone:
+ kmem_zone_destroy(xfs_log_item_desc_zone);
out_destroy_trans_zone:
kmem_zone_destroy(xfs_trans_zone);
out_destroy_ifork_zone:
@@ -1835,6 +1773,7 @@ xfs_destroy_zones(void)
kmem_zone_destroy(xfs_efi_zone);
kmem_zone_destroy(xfs_efd_zone);
kmem_zone_destroy(xfs_buf_item_zone);
+ kmem_zone_destroy(xfs_log_item_desc_zone);
kmem_zone_destroy(xfs_trans_zone);
kmem_zone_destroy(xfs_ifork_zone);
kmem_zone_destroy(xfs_dabuf_zone);
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index 519618e9279e..1ef4a4d2d997 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -56,12 +56,6 @@ extern void xfs_qm_exit(void);
# define XFS_BIGFS_STRING
#endif
-#ifdef CONFIG_XFS_DMAPI
-# define XFS_DMAPI_STRING "dmapi support, "
-#else
-# define XFS_DMAPI_STRING
-#endif
-
#ifdef DEBUG
# define XFS_DBG_STRING "debug"
#else
@@ -72,7 +66,6 @@ extern void xfs_qm_exit(void);
XFS_SECURITY_STRING \
XFS_REALTIME_STRING \
XFS_BIGFS_STRING \
- XFS_DMAPI_STRING \
XFS_DBG_STRING /* DBG must be last */
struct xfs_inode;
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index ef7f0218bccb..56fed91f1ef9 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -24,25 +24,14 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_inode.h"
#include "xfs_dinode.h"
#include "xfs_error.h"
-#include "xfs_mru_cache.h"
#include "xfs_filestream.h"
#include "xfs_vnodeops.h"
-#include "xfs_utils.h"
-#include "xfs_buf_item.h"
#include "xfs_inode_item.h"
-#include "xfs_rw.h"
#include "xfs_quota.h"
#include "xfs_trace.h"
@@ -285,7 +274,7 @@ xfs_sync_inode_attr(
/*
* Write out pagecache data for the whole filesystem.
*/
-int
+STATIC int
xfs_sync_data(
struct xfs_mount *mp,
int flags)
@@ -306,7 +295,7 @@ xfs_sync_data(
/*
* Write out inode metadata (attributes) for the whole filesystem.
*/
-int
+STATIC int
xfs_sync_attr(
struct xfs_mount *mp,
int flags)
@@ -339,8 +328,7 @@ xfs_commit_dummy_trans(
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
error = xfs_trans_commit(tp, 0);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
diff --git a/fs/xfs/linux-2.6/xfs_sync.h b/fs/xfs/linux-2.6/xfs_sync.h
index cdcbaaca9880..168d9070c6b2 100644
--- a/fs/xfs/linux-2.6/xfs_sync.h
+++ b/fs/xfs/linux-2.6/xfs_sync.h
@@ -35,9 +35,6 @@ typedef struct xfs_sync_work {
int xfs_syncd_init(struct xfs_mount *mp);
void xfs_syncd_stop(struct xfs_mount *mp);
-int xfs_sync_attr(struct xfs_mount *mp, int flags);
-int xfs_sync_data(struct xfs_mount *mp, int flags);
-
int xfs_quiesce_data(struct xfs_mount *mp);
void xfs_quiesce_attr(struct xfs_mount *mp);
diff --git a/fs/xfs/linux-2.6/xfs_trace.c b/fs/xfs/linux-2.6/xfs_trace.c
index d12be8470cba..88d25d4aa56e 100644
--- a/fs/xfs/linux-2.6/xfs_trace.c
+++ b/fs/xfs/linux-2.6/xfs_trace.c
@@ -24,17 +24,13 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h
index 73d5aa117384..76de133f5898 100644
--- a/fs/xfs/linux-2.6/xfs_trace.h
+++ b/fs/xfs/linux-2.6/xfs_trace.h
@@ -314,8 +314,6 @@ DEFINE_BUF_EVENT(xfs_buf_init);
DEFINE_BUF_EVENT(xfs_buf_free);
DEFINE_BUF_EVENT(xfs_buf_hold);
DEFINE_BUF_EVENT(xfs_buf_rele);
-DEFINE_BUF_EVENT(xfs_buf_pin);
-DEFINE_BUF_EVENT(xfs_buf_unpin);
DEFINE_BUF_EVENT(xfs_buf_iodone);
DEFINE_BUF_EVENT(xfs_buf_iorequest);
DEFINE_BUF_EVENT(xfs_buf_bawrite);
@@ -538,7 +536,7 @@ DEFINE_LOCK_EVENT(xfs_ilock_nowait);
DEFINE_LOCK_EVENT(xfs_ilock_demote);
DEFINE_LOCK_EVENT(xfs_iunlock);
-DECLARE_EVENT_CLASS(xfs_iget_class,
+DECLARE_EVENT_CLASS(xfs_inode_class,
TP_PROTO(struct xfs_inode *ip),
TP_ARGS(ip),
TP_STRUCT__entry(
@@ -554,16 +552,36 @@ DECLARE_EVENT_CLASS(xfs_iget_class,
__entry->ino)
)
-#define DEFINE_IGET_EVENT(name) \
-DEFINE_EVENT(xfs_iget_class, name, \
+#define DEFINE_INODE_EVENT(name) \
+DEFINE_EVENT(xfs_inode_class, name, \
TP_PROTO(struct xfs_inode *ip), \
TP_ARGS(ip))
-DEFINE_IGET_EVENT(xfs_iget_skip);
-DEFINE_IGET_EVENT(xfs_iget_reclaim);
-DEFINE_IGET_EVENT(xfs_iget_found);
-DEFINE_IGET_EVENT(xfs_iget_alloc);
-
-DECLARE_EVENT_CLASS(xfs_inode_class,
+DEFINE_INODE_EVENT(xfs_iget_skip);
+DEFINE_INODE_EVENT(xfs_iget_reclaim);
+DEFINE_INODE_EVENT(xfs_iget_reclaim_fail);
+DEFINE_INODE_EVENT(xfs_iget_hit);
+DEFINE_INODE_EVENT(xfs_iget_miss);
+
+DEFINE_INODE_EVENT(xfs_getattr);
+DEFINE_INODE_EVENT(xfs_setattr);
+DEFINE_INODE_EVENT(xfs_readlink);
+DEFINE_INODE_EVENT(xfs_alloc_file_space);
+DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_readdir);
+DEFINE_INODE_EVENT(xfs_check_acl);
+DEFINE_INODE_EVENT(xfs_vm_bmap);
+DEFINE_INODE_EVENT(xfs_file_ioctl);
+DEFINE_INODE_EVENT(xfs_file_compat_ioctl);
+DEFINE_INODE_EVENT(xfs_ioctl_setattr);
+DEFINE_INODE_EVENT(xfs_file_fsync);
+DEFINE_INODE_EVENT(xfs_destroy_inode);
+DEFINE_INODE_EVENT(xfs_write_inode);
+DEFINE_INODE_EVENT(xfs_evict_inode);
+
+DEFINE_INODE_EVENT(xfs_dquot_dqalloc);
+DEFINE_INODE_EVENT(xfs_dquot_dqdetach);
+
+DECLARE_EVENT_CLASS(xfs_iref_class,
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip),
TP_ARGS(ip, caller_ip),
TP_STRUCT__entry(
@@ -588,20 +606,71 @@ DECLARE_EVENT_CLASS(xfs_inode_class,
(char *)__entry->caller_ip)
)
-#define DEFINE_INODE_EVENT(name) \
-DEFINE_EVENT(xfs_inode_class, name, \
+#define DEFINE_IREF_EVENT(name) \
+DEFINE_EVENT(xfs_iref_class, name, \
TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), \
TP_ARGS(ip, caller_ip))
-DEFINE_INODE_EVENT(xfs_ihold);
-DEFINE_INODE_EVENT(xfs_irele);
-DEFINE_INODE_EVENT(xfs_inode_pin);
-DEFINE_INODE_EVENT(xfs_inode_unpin);
-DEFINE_INODE_EVENT(xfs_inode_unpin_nowait);
+DEFINE_IREF_EVENT(xfs_ihold);
+DEFINE_IREF_EVENT(xfs_irele);
+DEFINE_IREF_EVENT(xfs_inode_pin);
+DEFINE_IREF_EVENT(xfs_inode_unpin);
+DEFINE_IREF_EVENT(xfs_inode_unpin_nowait);
+
+DECLARE_EVENT_CLASS(xfs_namespace_class,
+ TP_PROTO(struct xfs_inode *dp, struct xfs_name *name),
+ TP_ARGS(dp, name),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(xfs_ino_t, dp_ino)
+ __dynamic_array(char, name, name->len)
+ ),
+ TP_fast_assign(
+ __entry->dev = VFS_I(dp)->i_sb->s_dev;
+ __entry->dp_ino = dp->i_ino;
+ memcpy(__get_str(name), name->name, name->len);
+ ),
+ TP_printk("dev %d:%d dp ino 0x%llx name %s",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->dp_ino,
+ __get_str(name))
+)
-/* the old xfs_itrace_entry tracer - to be replaced by s.th. in the VFS */
-DEFINE_INODE_EVENT(xfs_inode);
-#define xfs_itrace_entry(ip) \
- trace_xfs_inode(ip, _THIS_IP_)
+#define DEFINE_NAMESPACE_EVENT(name) \
+DEFINE_EVENT(xfs_namespace_class, name, \
+ TP_PROTO(struct xfs_inode *dp, struct xfs_name *name), \
+ TP_ARGS(dp, name))
+DEFINE_NAMESPACE_EVENT(xfs_remove);
+DEFINE_NAMESPACE_EVENT(xfs_link);
+DEFINE_NAMESPACE_EVENT(xfs_lookup);
+DEFINE_NAMESPACE_EVENT(xfs_create);
+DEFINE_NAMESPACE_EVENT(xfs_symlink);
+
+TRACE_EVENT(xfs_rename,
+ TP_PROTO(struct xfs_inode *src_dp, struct xfs_inode *target_dp,
+ struct xfs_name *src_name, struct xfs_name *target_name),
+ TP_ARGS(src_dp, target_dp, src_name, target_name),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(xfs_ino_t, src_dp_ino)
+ __field(xfs_ino_t, target_dp_ino)
+ __dynamic_array(char, src_name, src_name->len)
+ __dynamic_array(char, target_name, target_name->len)
+ ),
+ TP_fast_assign(
+ __entry->dev = VFS_I(src_dp)->i_sb->s_dev;
+ __entry->src_dp_ino = src_dp->i_ino;
+ __entry->target_dp_ino = target_dp->i_ino;
+ memcpy(__get_str(src_name), src_name->name, src_name->len);
+ memcpy(__get_str(target_name), target_name->name, target_name->len);
+ ),
+ TP_printk("dev %d:%d src dp ino 0x%llx target dp ino 0x%llx"
+ " src name %s target name %s",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->src_dp_ino,
+ __entry->target_dp_ino,
+ __get_str(src_name),
+ __get_str(target_name))
+)
DECLARE_EVENT_CLASS(xfs_dquot_class,
TP_PROTO(struct xfs_dquot *dqp),
@@ -681,9 +750,6 @@ DEFINE_DQUOT_EVENT(xfs_dqrele);
DEFINE_DQUOT_EVENT(xfs_dqflush);
DEFINE_DQUOT_EVENT(xfs_dqflush_force);
DEFINE_DQUOT_EVENT(xfs_dqflush_done);
-/* not really iget events, but we re-use the format */
-DEFINE_IGET_EVENT(xfs_dquot_dqalloc);
-DEFINE_IGET_EVENT(xfs_dquot_dqdetach);
DECLARE_EVENT_CLASS(xfs_loggrant_class,
TP_PROTO(struct log *log, struct xlog_ticket *tic),
@@ -831,33 +897,29 @@ DECLARE_EVENT_CLASS(xfs_page_class,
__field(loff_t, size)
__field(unsigned long, offset)
__field(int, delalloc)
- __field(int, unmapped)
__field(int, unwritten)
),
TP_fast_assign(
- int delalloc = -1, unmapped = -1, unwritten = -1;
+ int delalloc = -1, unwritten = -1;
if (page_has_buffers(page))
- xfs_count_page_state(page, &delalloc,
- &unmapped, &unwritten);
+ xfs_count_page_state(page, &delalloc, &unwritten);
__entry->dev = inode->i_sb->s_dev;
__entry->ino = XFS_I(inode)->i_ino;
__entry->pgoff = page_offset(page);
__entry->size = i_size_read(inode);
__entry->offset = off;
__entry->delalloc = delalloc;
- __entry->unmapped = unmapped;
__entry->unwritten = unwritten;
),
TP_printk("dev %d:%d ino 0x%llx pgoff 0x%lx size 0x%llx offset %lx "
- "delalloc %d unmapped %d unwritten %d",
+ "delalloc %d unwritten %d",
MAJOR(__entry->dev), MINOR(__entry->dev),
__entry->ino,
__entry->pgoff,
__entry->size,
__entry->offset,
__entry->delalloc,
- __entry->unmapped,
__entry->unwritten)
)
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c
index 585e7633dfc7..e1a2f6800e01 100644
--- a/fs/xfs/quota/xfs_dquot.c
+++ b/fs/xfs/quota/xfs_dquot.c
@@ -23,25 +23,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
@@ -64,8 +54,6 @@
flush lock - ditto.
*/
-STATIC void xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *);
-
#ifdef DEBUG
xfs_buftarg_t *xfs_dqerror_target;
int xfs_do_dqerror;
@@ -390,21 +378,14 @@ xfs_qm_dqalloc(
return (ESRCH);
}
- /*
- * xfs_trans_commit normally decrements the vnode ref count
- * when it unlocks the inode. Since we want to keep the quota
- * inode around, we bump the vnode ref count now.
- */
- IHOLD(quotip);
-
- xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, quotip, XFS_ILOCK_EXCL);
nmaps = 1;
if ((error = xfs_bmapi(tp, quotip,
offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB,
XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
&firstblock,
XFS_QM_DQALLOC_SPACE_RES(mp),
- &map, &nmaps, &flist, NULL))) {
+ &map, &nmaps, &flist))) {
goto error0;
}
ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
@@ -520,7 +501,7 @@ xfs_qm_dqtobp(
error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
XFS_DQUOT_CLUSTER_SIZE_FSB,
XFS_BMAPI_METADATA,
- NULL, 0, &map, &nmaps, NULL, NULL);
+ NULL, 0, &map, &nmaps, NULL);
xfs_iunlock(quotip, XFS_ILOCK_SHARED);
if (error)
@@ -1141,6 +1122,46 @@ xfs_qm_dqrele(
xfs_qm_dqput(dqp);
}
+/*
+ * This is the dquot flushing I/O completion routine. It is called
+ * from interrupt level when the buffer containing the dquot is
+ * flushed to disk. It is responsible for removing the dquot logitem
+ * from the AIL if it has not been re-logged, and unlocking the dquot's
+ * flush lock. This behavior is very similar to that of inodes..
+ */
+STATIC void
+xfs_qm_dqflush_done(
+ struct xfs_buf *bp,
+ struct xfs_log_item *lip)
+{
+ xfs_dq_logitem_t *qip = (struct xfs_dq_logitem *)lip;
+ xfs_dquot_t *dqp = qip->qli_dquot;
+ struct xfs_ail *ailp = lip->li_ailp;
+
+ /*
+ * We only want to pull the item from the AIL if its
+ * location in the log has not changed since we started the flush.
+ * Thus, we only bother if the dquot's lsn has
+ * not changed. First we check the lsn outside the lock
+ * since it's cheaper, and then we recheck while
+ * holding the lock before removing the dquot from the AIL.
+ */
+ if ((lip->li_flags & XFS_LI_IN_AIL) &&
+ lip->li_lsn == qip->qli_flush_lsn) {
+
+ /* xfs_trans_ail_delete() drops the AIL lock. */
+ spin_lock(&ailp->xa_lock);
+ if (lip->li_lsn == qip->qli_flush_lsn)
+ xfs_trans_ail_delete(ailp, lip);
+ else
+ spin_unlock(&ailp->xa_lock);
+ }
+
+ /*
+ * Release the dq's flush lock since we're done with it.
+ */
+ xfs_dqfunlock(dqp);
+}
/*
* Write a modified dquot to disk.
@@ -1222,8 +1243,9 @@ xfs_qm_dqflush(
* Attach an iodone routine so that we can remove this dquot from the
* AIL and release the flush lock once the dquot is synced to disk.
*/
- xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t *, xfs_log_item_t *))
- xfs_qm_dqflush_done, &(dqp->q_logitem.qli_item));
+ xfs_buf_attach_iodone(bp, xfs_qm_dqflush_done,
+ &dqp->q_logitem.qli_item);
+
/*
* If the buffer is pinned then push on the log so we won't
* get stuck waiting in the write for too long.
@@ -1247,50 +1269,6 @@ xfs_qm_dqflush(
}
-/*
- * This is the dquot flushing I/O completion routine. It is called
- * from interrupt level when the buffer containing the dquot is
- * flushed to disk. It is responsible for removing the dquot logitem
- * from the AIL if it has not been re-logged, and unlocking the dquot's
- * flush lock. This behavior is very similar to that of inodes..
- */
-/*ARGSUSED*/
-STATIC void
-xfs_qm_dqflush_done(
- xfs_buf_t *bp,
- xfs_dq_logitem_t *qip)
-{
- xfs_dquot_t *dqp;
- struct xfs_ail *ailp;
-
- dqp = qip->qli_dquot;
- ailp = qip->qli_item.li_ailp;
-
- /*
- * We only want to pull the item from the AIL if its
- * location in the log has not changed since we started the flush.
- * Thus, we only bother if the dquot's lsn has
- * not changed. First we check the lsn outside the lock
- * since it's cheaper, and then we recheck while
- * holding the lock before removing the dquot from the AIL.
- */
- if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
- qip->qli_item.li_lsn == qip->qli_flush_lsn) {
-
- /* xfs_trans_ail_delete() drops the AIL lock. */
- spin_lock(&ailp->xa_lock);
- if (qip->qli_item.li_lsn == qip->qli_flush_lsn)
- xfs_trans_ail_delete(ailp, (xfs_log_item_t*)qip);
- else
- spin_unlock(&ailp->xa_lock);
- }
-
- /*
- * Release the dq's flush lock since we're done with it.
- */
- xfs_dqfunlock(dqp);
-}
-
int
xfs_qm_dqlock_nowait(
xfs_dquot_t *dqp)
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c
index 8d89a24ae324..2a1f3dc10a02 100644
--- a/fs/xfs/quota/xfs_dquot_item.c
+++ b/fs/xfs/quota/xfs_dquot_item.c
@@ -23,42 +23,36 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_itable.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
#include "xfs_qm.h"
+static inline struct xfs_dq_logitem *DQUOT_ITEM(struct xfs_log_item *lip)
+{
+ return container_of(lip, struct xfs_dq_logitem, qli_item);
+}
+
/*
* returns the number of iovecs needed to log the given dquot item.
*/
-/* ARGSUSED */
STATIC uint
xfs_qm_dquot_logitem_size(
- xfs_dq_logitem_t *logitem)
+ struct xfs_log_item *lip)
{
/*
* we need only two iovecs, one for the format, one for the real thing
*/
- return (2);
+ return 2;
}
/*
@@ -66,22 +60,21 @@ xfs_qm_dquot_logitem_size(
*/
STATIC void
xfs_qm_dquot_logitem_format(
- xfs_dq_logitem_t *logitem,
- xfs_log_iovec_t *logvec)
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *logvec)
{
- ASSERT(logitem);
- ASSERT(logitem->qli_dquot);
+ struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
- logvec->i_addr = (xfs_caddr_t)&logitem->qli_format;
+ logvec->i_addr = &qlip->qli_format;
logvec->i_len = sizeof(xfs_dq_logformat_t);
logvec->i_type = XLOG_REG_TYPE_QFORMAT;
logvec++;
- logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core;
+ logvec->i_addr = &qlip->qli_dquot->q_core;
logvec->i_len = sizeof(xfs_disk_dquot_t);
logvec->i_type = XLOG_REG_TYPE_DQUOT;
- ASSERT(2 == logitem->qli_item.li_desc->lid_size);
- logitem->qli_format.qlf_size = 2;
+ ASSERT(2 == lip->li_desc->lid_size);
+ qlip->qli_format.qlf_size = 2;
}
@@ -90,9 +83,9 @@ xfs_qm_dquot_logitem_format(
*/
STATIC void
xfs_qm_dquot_logitem_pin(
- xfs_dq_logitem_t *logitem)
+ struct xfs_log_item *lip)
{
- xfs_dquot_t *dqp = logitem->qli_dquot;
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
atomic_inc(&dqp->q_pincount);
@@ -104,27 +97,18 @@ xfs_qm_dquot_logitem_pin(
* dquot must have been previously pinned with a call to
* xfs_qm_dquot_logitem_pin().
*/
-/* ARGSUSED */
STATIC void
xfs_qm_dquot_logitem_unpin(
- xfs_dq_logitem_t *logitem)
+ struct xfs_log_item *lip,
+ int remove)
{
- xfs_dquot_t *dqp = logitem->qli_dquot;
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
ASSERT(atomic_read(&dqp->q_pincount) > 0);
if (atomic_dec_and_test(&dqp->q_pincount))
wake_up(&dqp->q_pinwait);
}
-/* ARGSUSED */
-STATIC void
-xfs_qm_dquot_logitem_unpin_remove(
- xfs_dq_logitem_t *logitem,
- xfs_trans_t *tp)
-{
- xfs_qm_dquot_logitem_unpin(logitem);
-}
-
/*
* Given the logitem, this writes the corresponding dquot entry to disk
* asynchronously. This is called with the dquot entry securely locked;
@@ -133,12 +117,10 @@ xfs_qm_dquot_logitem_unpin_remove(
*/
STATIC void
xfs_qm_dquot_logitem_push(
- xfs_dq_logitem_t *logitem)
+ struct xfs_log_item *lip)
{
- xfs_dquot_t *dqp;
- int error;
-
- dqp = logitem->qli_dquot;
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
+ int error;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
ASSERT(!completion_done(&dqp->q_flush));
@@ -160,27 +142,25 @@ xfs_qm_dquot_logitem_push(
xfs_dqunlock(dqp);
}
-/*ARGSUSED*/
STATIC xfs_lsn_t
xfs_qm_dquot_logitem_committed(
- xfs_dq_logitem_t *l,
+ struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
/*
* We always re-log the entire dquot when it becomes dirty,
* so, the latest copy _is_ the only one that matters.
*/
- return (lsn);
+ return lsn;
}
-
/*
* This is called to wait for the given dquot to be unpinned.
* Most of these pin/unpin routines are plagiarized from inode code.
*/
void
xfs_qm_dqunpin_wait(
- xfs_dquot_t *dqp)
+ struct xfs_dquot *dqp)
{
ASSERT(XFS_DQ_IS_LOCKED(dqp));
if (atomic_read(&dqp->q_pincount) == 0)
@@ -206,13 +186,12 @@ xfs_qm_dqunpin_wait(
*/
STATIC void
xfs_qm_dquot_logitem_pushbuf(
- xfs_dq_logitem_t *qip)
+ struct xfs_log_item *lip)
{
- xfs_dquot_t *dqp;
- xfs_mount_t *mp;
- xfs_buf_t *bp;
+ struct xfs_dq_logitem *qlip = DQUOT_ITEM(lip);
+ struct xfs_dquot *dqp = qlip->qli_dquot;
+ struct xfs_buf *bp;
- dqp = qip->qli_dquot;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
/*
@@ -220,22 +199,20 @@ xfs_qm_dquot_logitem_pushbuf(
* inode flush completed and the inode was taken off the AIL.
* So, just get out.
*/
- if (completion_done(&dqp->q_flush) ||
- ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
+ if (completion_done(&dqp->q_flush) ||
+ !(lip->li_flags & XFS_LI_IN_AIL)) {
xfs_dqunlock(dqp);
return;
}
- mp = dqp->q_mount;
- bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno,
- mp->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
+
+ bp = xfs_incore(dqp->q_mount->m_ddev_targp, qlip->qli_format.qlf_blkno,
+ dqp->q_mount->m_quotainfo->qi_dqchunklen, XBF_TRYLOCK);
xfs_dqunlock(dqp);
if (!bp)
return;
if (XFS_BUF_ISDELAYWRITE(bp))
xfs_buf_delwri_promote(bp);
xfs_buf_relse(bp);
- return;
-
}
/*
@@ -250,15 +227,14 @@ xfs_qm_dquot_logitem_pushbuf(
*/
STATIC uint
xfs_qm_dquot_logitem_trylock(
- xfs_dq_logitem_t *qip)
+ struct xfs_log_item *lip)
{
- xfs_dquot_t *dqp;
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
- dqp = qip->qli_dquot;
if (atomic_read(&dqp->q_pincount) > 0)
return XFS_ITEM_PINNED;
- if (! xfs_qm_dqlock_nowait(dqp))
+ if (!xfs_qm_dqlock_nowait(dqp))
return XFS_ITEM_LOCKED;
if (!xfs_dqflock_nowait(dqp)) {
@@ -269,11 +245,10 @@ xfs_qm_dquot_logitem_trylock(
return XFS_ITEM_PUSHBUF;
}
- ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
+ ASSERT(lip->li_flags & XFS_LI_IN_AIL);
return XFS_ITEM_SUCCESS;
}
-
/*
* Unlock the dquot associated with the log item.
* Clear the fields of the dquot and dquot log item that
@@ -282,12 +257,10 @@ xfs_qm_dquot_logitem_trylock(
*/
STATIC void
xfs_qm_dquot_logitem_unlock(
- xfs_dq_logitem_t *ql)
+ struct xfs_log_item *lip)
{
- xfs_dquot_t *dqp;
+ struct xfs_dquot *dqp = DQUOT_ITEM(lip)->qli_dquot;
- ASSERT(ql != NULL);
- dqp = ql->qli_dquot;
ASSERT(XFS_DQ_IS_LOCKED(dqp));
/*
@@ -304,43 +277,32 @@ xfs_qm_dquot_logitem_unlock(
xfs_dqunlock(dqp);
}
-
/*
* this needs to stamp an lsn into the dquot, I think.
* rpc's that look at user dquot's would then have to
* push on the dependency recorded in the dquot
*/
-/* ARGSUSED */
STATIC void
xfs_qm_dquot_logitem_committing(
- xfs_dq_logitem_t *l,
+ struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
- return;
}
-
/*
* This is the ops vector for dquots
*/
static struct xfs_item_ops xfs_dquot_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_qm_dquot_logitem_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
- xfs_qm_dquot_logitem_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))
- xfs_qm_dquot_logitem_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_dquot_logitem_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
- .iop_pushbuf = (void(*)(xfs_log_item_t*))
- xfs_qm_dquot_logitem_pushbuf,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_dquot_logitem_committing
+ .iop_size = xfs_qm_dquot_logitem_size,
+ .iop_format = xfs_qm_dquot_logitem_format,
+ .iop_pin = xfs_qm_dquot_logitem_pin,
+ .iop_unpin = xfs_qm_dquot_logitem_unpin,
+ .iop_trylock = xfs_qm_dquot_logitem_trylock,
+ .iop_unlock = xfs_qm_dquot_logitem_unlock,
+ .iop_committed = xfs_qm_dquot_logitem_committed,
+ .iop_push = xfs_qm_dquot_logitem_push,
+ .iop_pushbuf = xfs_qm_dquot_logitem_pushbuf,
+ .iop_committing = xfs_qm_dquot_logitem_committing
};
/*
@@ -350,10 +312,9 @@ static struct xfs_item_ops xfs_dquot_item_ops = {
*/
void
xfs_qm_dquot_logitem_init(
- struct xfs_dquot *dqp)
+ struct xfs_dquot *dqp)
{
- xfs_dq_logitem_t *lp;
- lp = &dqp->q_logitem;
+ struct xfs_dq_logitem *lp = &dqp->q_logitem;
xfs_log_item_init(dqp->q_mount, &lp->qli_item, XFS_LI_DQUOT,
&xfs_dquot_item_ops);
@@ -374,16 +335,22 @@ xfs_qm_dquot_logitem_init(
/*------------------ QUOTAOFF LOG ITEMS -------------------*/
+static inline struct xfs_qoff_logitem *QOFF_ITEM(struct xfs_log_item *lip)
+{
+ return container_of(lip, struct xfs_qoff_logitem, qql_item);
+}
+
+
/*
* This returns the number of iovecs needed to log the given quotaoff item.
* We only need 1 iovec for an quotaoff item. It just logs the
* quotaoff_log_format structure.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_size(
+ struct xfs_log_item *lip)
{
- return (1);
+ return 1;
}
/*
@@ -394,53 +361,46 @@ xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf)
* slots in the quotaoff item have been filled.
*/
STATIC void
-xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf,
- xfs_log_iovec_t *log_vector)
+xfs_qm_qoff_logitem_format(
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *log_vector)
{
- ASSERT(qf->qql_format.qf_type == XFS_LI_QUOTAOFF);
+ struct xfs_qoff_logitem *qflip = QOFF_ITEM(lip);
+
+ ASSERT(qflip->qql_format.qf_type == XFS_LI_QUOTAOFF);
- log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format);
+ log_vector->i_addr = &qflip->qql_format;
log_vector->i_len = sizeof(xfs_qoff_logitem_t);
log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF;
- qf->qql_format.qf_size = 1;
+ qflip->qql_format.qf_size = 1;
}
-
/*
* Pinning has no meaning for an quotaoff item, so just return.
*/
-/*ARGSUSED*/
STATIC void
-xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_pin(
+ struct xfs_log_item *lip)
{
- return;
}
-
/*
* Since pinning has no meaning for an quotaoff item, unpinning does
* not either.
*/
-/*ARGSUSED*/
STATIC void
-xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_unpin(
+ struct xfs_log_item *lip,
+ int remove)
{
- return;
-}
-
-/*ARGSUSED*/
-STATIC void
-xfs_qm_qoff_logitem_unpin_remove(xfs_qoff_logitem_t *qf, xfs_trans_t *tp)
-{
- return;
}
/*
* Quotaoff items have no locking, so just return success.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_trylock(
+ struct xfs_log_item *lip)
{
return XFS_ITEM_LOCKED;
}
@@ -449,53 +409,51 @@ xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf)
* Quotaoff items have no locking or pushing, so return failure
* so that the caller doesn't bother with us.
*/
-/*ARGSUSED*/
STATIC void
-xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_unlock(
+ struct xfs_log_item *lip)
{
- return;
}
/*
* The quotaoff-start-item is logged only once and cannot be moved in the log,
* so simply return the lsn at which it's been logged.
*/
-/*ARGSUSED*/
STATIC xfs_lsn_t
-xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
+xfs_qm_qoff_logitem_committed(
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
- return (lsn);
+ return lsn;
}
/*
* There isn't much you can do to push on an quotaoff item. It is simply
* stuck waiting for the log to be flushed to disk.
*/
-/*ARGSUSED*/
STATIC void
-xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf)
+xfs_qm_qoff_logitem_push(
+ struct xfs_log_item *lip)
{
- return;
}
-/*ARGSUSED*/
STATIC xfs_lsn_t
xfs_qm_qoffend_logitem_committed(
- xfs_qoff_logitem_t *qfe,
- xfs_lsn_t lsn)
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
- xfs_qoff_logitem_t *qfs;
- struct xfs_ail *ailp;
+ struct xfs_qoff_logitem *qfe = QOFF_ITEM(lip);
+ struct xfs_qoff_logitem *qfs = qfe->qql_start_lip;
+ struct xfs_ail *ailp = qfs->qql_item.li_ailp;
- qfs = qfe->qql_start_lip;
- ailp = qfs->qql_item.li_ailp;
- spin_lock(&ailp->xa_lock);
/*
* Delete the qoff-start logitem from the AIL.
* xfs_trans_ail_delete() drops the AIL lock.
*/
+ spin_lock(&ailp->xa_lock);
xfs_trans_ail_delete(ailp, (xfs_log_item_t *)qfs);
+
kmem_free(qfs);
kmem_free(qfe);
return (xfs_lsn_t)-1;
@@ -515,71 +473,52 @@ xfs_qm_qoffend_logitem_committed(
* (truly makes the quotaoff irrevocable). If we do something else,
* then maybe we don't need two.
*/
-/* ARGSUSED */
-STATIC void
-xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
-{
- return;
-}
-
-/* ARGSUSED */
STATIC void
-xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
+xfs_qm_qoff_logitem_committing(
+ struct xfs_log_item *lip,
+ xfs_lsn_t commit_lsn)
{
- return;
}
static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_qm_qoff_logitem_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
- xfs_qm_qoff_logitem_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_qoffend_logitem_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_qoffend_logitem_committing
+ .iop_size = xfs_qm_qoff_logitem_size,
+ .iop_format = xfs_qm_qoff_logitem_format,
+ .iop_pin = xfs_qm_qoff_logitem_pin,
+ .iop_unpin = xfs_qm_qoff_logitem_unpin,
+ .iop_trylock = xfs_qm_qoff_logitem_trylock,
+ .iop_unlock = xfs_qm_qoff_logitem_unlock,
+ .iop_committed = xfs_qm_qoffend_logitem_committed,
+ .iop_push = xfs_qm_qoff_logitem_push,
+ .iop_committing = xfs_qm_qoff_logitem_committing
};
/*
* This is the ops vector shared by all quotaoff-start log items.
*/
static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_qm_qoff_logitem_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
- xfs_qm_qoff_logitem_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_qoff_logitem_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_qm_qoff_logitem_committing
+ .iop_size = xfs_qm_qoff_logitem_size,
+ .iop_format = xfs_qm_qoff_logitem_format,
+ .iop_pin = xfs_qm_qoff_logitem_pin,
+ .iop_unpin = xfs_qm_qoff_logitem_unpin,
+ .iop_trylock = xfs_qm_qoff_logitem_trylock,
+ .iop_unlock = xfs_qm_qoff_logitem_unlock,
+ .iop_committed = xfs_qm_qoff_logitem_committed,
+ .iop_push = xfs_qm_qoff_logitem_push,
+ .iop_committing = xfs_qm_qoff_logitem_committing
};
/*
* Allocate and initialize an quotaoff item of the correct quota type(s).
*/
-xfs_qoff_logitem_t *
+struct xfs_qoff_logitem *
xfs_qm_qoff_logitem_init(
- struct xfs_mount *mp,
- xfs_qoff_logitem_t *start,
- uint flags)
+ struct xfs_mount *mp,
+ struct xfs_qoff_logitem *start,
+ uint flags)
{
- xfs_qoff_logitem_t *qf;
+ struct xfs_qoff_logitem *qf;
- qf = (xfs_qoff_logitem_t*) kmem_zalloc(sizeof(xfs_qoff_logitem_t), KM_SLEEP);
+ qf = kmem_zalloc(sizeof(struct xfs_qoff_logitem), KM_SLEEP);
xfs_log_item_init(mp, &qf->qql_item, XFS_LI_QUOTAOFF, start ?
&xfs_qm_qoffend_logitem_ops : &xfs_qm_qoff_logitem_ops);
@@ -587,5 +526,5 @@ xfs_qm_qoff_logitem_init(
qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
qf->qql_format.qf_flags = flags;
qf->qql_start_lip = start;
- return (qf);
+ return qf;
}
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 8c117ff2e3ab..21d659536c2a 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -23,25 +23,18 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
#include "xfs_bmap.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_space.h"
@@ -1497,7 +1490,7 @@ xfs_qm_dqiterate(
maxlblkcnt - lblkno,
XFS_BMAPI_METADATA,
NULL,
- 0, map, &nmaps, NULL, NULL);
+ 0, map, &nmaps, NULL);
xfs_iunlock(qip, XFS_ILOCK_SHARED);
if (error)
break;
@@ -1669,7 +1662,8 @@ xfs_qm_dqusage_adjust(
* making us disable quotas for the file system.
*/
if ((error = xfs_qm_dqget_noattach(ip, &udqp, &gdqp))) {
- xfs_iput(ip, XFS_ILOCK_EXCL);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ IRELE(ip);
*res = BULKSTAT_RV_GIVEUP;
return error;
}
@@ -1682,7 +1676,8 @@ xfs_qm_dqusage_adjust(
* Walk thru the extent list and count the realtime blocks.
*/
if ((error = xfs_qm_get_rtblks(ip, &rtblks))) {
- xfs_iput(ip, XFS_ILOCK_EXCL);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ IRELE(ip);
if (udqp)
xfs_qm_dqput(udqp);
if (gdqp)
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c
index 97b410c12794..bea02d786c5d 100644
--- a/fs/xfs/quota/xfs_qm_bhv.c
+++ b/fs/xfs/quota/xfs_qm_bhv.c
@@ -23,25 +23,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
-#include "xfs_btree.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_qm.h"
diff --git a/fs/xfs/quota/xfs_qm_stats.c b/fs/xfs/quota/xfs_qm_stats.c
index 3d1fc79532e2..8671a0b32644 100644
--- a/fs/xfs/quota/xfs_qm_stats.c
+++ b/fs/xfs/quota/xfs_qm_stats.c
@@ -23,25 +23,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_bmap.h"
-#include "xfs_btree.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_qm.h"
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index b4487764e923..b43b8ef262cd 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -26,25 +26,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_bmap.h"
-#include "xfs_btree.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_utils.h"
@@ -786,9 +776,9 @@ xfs_qm_export_dquot(
}
#ifdef DEBUG
- if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == XFS_USER_QUOTA) ||
+ if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) ||
(XFS_IS_OQUOTA_ENFORCED(mp) &&
- (dst->d_flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)))) &&
+ (dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
dst->d_id != 0) {
if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
(dst->d_blk_softlimit > 0)) {
@@ -809,17 +799,17 @@ xfs_qm_export_qtype_flags(
/*
* Can't be more than one, or none.
*/
- ASSERT((flags & (XFS_PROJ_QUOTA | XFS_USER_QUOTA)) !=
- (XFS_PROJ_QUOTA | XFS_USER_QUOTA));
- ASSERT((flags & (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA)) !=
- (XFS_PROJ_QUOTA | XFS_GROUP_QUOTA));
- ASSERT((flags & (XFS_USER_QUOTA | XFS_GROUP_QUOTA)) !=
- (XFS_USER_QUOTA | XFS_GROUP_QUOTA));
- ASSERT((flags & (XFS_PROJ_QUOTA|XFS_USER_QUOTA|XFS_GROUP_QUOTA)) != 0);
+ ASSERT((flags & (FS_PROJ_QUOTA | FS_USER_QUOTA)) !=
+ (FS_PROJ_QUOTA | FS_USER_QUOTA));
+ ASSERT((flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)) !=
+ (FS_PROJ_QUOTA | FS_GROUP_QUOTA));
+ ASSERT((flags & (FS_USER_QUOTA | FS_GROUP_QUOTA)) !=
+ (FS_USER_QUOTA | FS_GROUP_QUOTA));
+ ASSERT((flags & (FS_PROJ_QUOTA|FS_USER_QUOTA|FS_GROUP_QUOTA)) != 0);
return (flags & XFS_DQ_USER) ?
- XFS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
- XFS_PROJ_QUOTA : XFS_GROUP_QUOTA;
+ FS_USER_QUOTA : (flags & XFS_DQ_PROJ) ?
+ FS_PROJ_QUOTA : FS_GROUP_QUOTA;
}
STATIC uint
@@ -830,16 +820,16 @@ xfs_qm_export_flags(
uflags = 0;
if (flags & XFS_UQUOTA_ACCT)
- uflags |= XFS_QUOTA_UDQ_ACCT;
+ uflags |= FS_QUOTA_UDQ_ACCT;
if (flags & XFS_PQUOTA_ACCT)
- uflags |= XFS_QUOTA_PDQ_ACCT;
+ uflags |= FS_QUOTA_PDQ_ACCT;
if (flags & XFS_GQUOTA_ACCT)
- uflags |= XFS_QUOTA_GDQ_ACCT;
+ uflags |= FS_QUOTA_GDQ_ACCT;
if (flags & XFS_UQUOTA_ENFD)
- uflags |= XFS_QUOTA_UDQ_ENFD;
+ uflags |= FS_QUOTA_UDQ_ENFD;
if (flags & (XFS_OQUOTA_ENFD)) {
uflags |= (flags & XFS_GQUOTA_ACCT) ?
- XFS_QUOTA_GDQ_ENFD : XFS_QUOTA_PDQ_ENFD;
+ FS_QUOTA_GDQ_ENFD : FS_QUOTA_PDQ_ENFD;
}
return (uflags);
}
@@ -875,8 +865,9 @@ xfs_dqrele_inode(
xfs_qm_dqrele(ip->i_gdquot);
ip->i_gdquot = NULL;
}
- xfs_iput(ip, XFS_ILOCK_EXCL);
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ IRELE(ip);
return 0;
}
@@ -1143,7 +1134,8 @@ xfs_qm_internalqcheck_adjust(
* of those now.
*/
if (! ipreleased) {
- xfs_iput(ip, lock_flags);
+ xfs_iunlock(ip, lock_flags);
+ IRELE(ip);
ipreleased = B_TRUE;
goto again;
}
@@ -1160,7 +1152,8 @@ xfs_qm_internalqcheck_adjust(
ASSERT(gd);
xfs_qm_internalqcheck_dqadjust(ip, gd);
}
- xfs_iput(ip, lock_flags);
+ xfs_iunlock(ip, lock_flags);
+ IRELE(ip);
*res = BULKSTAT_RV_DIDONE;
return (0);
}
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index 061d827da33c..7de91d1b75c0 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -23,25 +23,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_attr_sf.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
-#include "xfs_btree.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_attr.h"
#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
@@ -59,16 +49,14 @@ xfs_trans_dqjoin(
xfs_trans_t *tp,
xfs_dquot_t *dqp)
{
- xfs_dq_logitem_t *lp = &dqp->q_logitem;
-
ASSERT(dqp->q_transp != tp);
ASSERT(XFS_DQ_IS_LOCKED(dqp));
- ASSERT(lp->qli_dquot == dqp);
+ ASSERT(dqp->q_logitem.qli_dquot == dqp);
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(lp));
+ xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
/*
* Initialize i_transp so we can later determine if this dquot is
@@ -93,16 +81,11 @@ xfs_trans_log_dquot(
xfs_trans_t *tp,
xfs_dquot_t *dqp)
{
- xfs_log_item_desc_t *lidp;
-
ASSERT(dqp->q_transp == tp);
ASSERT(XFS_DQ_IS_LOCKED(dqp));
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(&dqp->q_logitem));
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ dqp->q_logitem.qli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
}
/*
@@ -874,9 +857,8 @@ xfs_trans_get_qoff_item(
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)q);
-
- return (q);
+ xfs_trans_add_item(tp, &q->qql_item);
+ return q;
}
@@ -890,13 +872,8 @@ xfs_trans_log_quotaoff_item(
xfs_trans_t *tp,
xfs_qoff_logitem_t *qlp)
{
- xfs_log_item_desc_t *lidp;
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)qlp);
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ qlp->qql_item.li_desc->lid_flags |= XFS_LID_DIRTY;
}
STATIC void
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 3f3610a7ee05..975aa10e1a47 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -22,7 +22,6 @@
#include "xfs_sb.h"
#include "xfs_inum.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
index a7fbe8a99b12..6fe5c02ba19a 100644
--- a/fs/xfs/xfs_alloc.c
+++ b/fs/xfs/xfs_alloc.c
@@ -24,18 +24,13 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_error.h"
#include "xfs_trace.h"
diff --git a/fs/xfs/xfs_alloc.h b/fs/xfs/xfs_alloc.h
index 6d05199b667c..895009a97271 100644
--- a/fs/xfs/xfs_alloc.h
+++ b/fs/xfs/xfs_alloc.h
@@ -27,16 +27,16 @@ struct xfs_busy_extent;
/*
* Freespace allocation types. Argument to xfs_alloc_[v]extent.
*/
-typedef enum xfs_alloctype
-{
- XFS_ALLOCTYPE_ANY_AG, /* allocate anywhere, use rotor */
- XFS_ALLOCTYPE_FIRST_AG, /* ... start at ag 0 */
- XFS_ALLOCTYPE_START_AG, /* anywhere, start in this a.g. */
- XFS_ALLOCTYPE_THIS_AG, /* anywhere in this a.g. */
- XFS_ALLOCTYPE_START_BNO, /* near this block else anywhere */
- XFS_ALLOCTYPE_NEAR_BNO, /* in this a.g. and near this block */
- XFS_ALLOCTYPE_THIS_BNO /* at exactly this block */
-} xfs_alloctype_t;
+#define XFS_ALLOCTYPE_ANY_AG 0x01 /* allocate anywhere, use rotor */
+#define XFS_ALLOCTYPE_FIRST_AG 0x02 /* ... start at ag 0 */
+#define XFS_ALLOCTYPE_START_AG 0x04 /* anywhere, start in this a.g. */
+#define XFS_ALLOCTYPE_THIS_AG 0x08 /* anywhere in this a.g. */
+#define XFS_ALLOCTYPE_START_BNO 0x10 /* near this block else anywhere */
+#define XFS_ALLOCTYPE_NEAR_BNO 0x20 /* in this a.g. and near this block */
+#define XFS_ALLOCTYPE_THIS_BNO 0x40 /* at exactly this block */
+
+/* this should become an enum again when the tracing code is fixed */
+typedef unsigned int xfs_alloctype_t;
#define XFS_ALLOC_TYPES \
{ XFS_ALLOCTYPE_ANY_AG, "ANY_AG" }, \
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 83f494218759..97f7328967fd 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -24,19 +24,14 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
#include "xfs_btree_trace.h"
-#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_error.h"
#include "xfs_trace.h"
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c
index b9c196a53c42..c2568242a901 100644
--- a/fs/xfs/xfs_attr.c
+++ b/fs/xfs/xfs_attr.c
@@ -25,19 +25,13 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_alloc.h"
-#include "xfs_btree.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_attr.h"
@@ -325,8 +319,7 @@ xfs_attr_set_int(
return (error);
}
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
+ xfs_trans_ijoin(args.trans, dp);
/*
* If the attribute list is non-existent or a shortform list,
@@ -396,10 +389,8 @@ xfs_attr_set_int(
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args.trans, dp);
/*
* Commit the leaf transformation. We'll need another (linked)
@@ -544,8 +535,7 @@ xfs_attr_remove_int(xfs_inode_t *dp, struct xfs_name *name, int flags)
* No need to make quota reservations here. We expect to release some
* blocks not allocate in the common case.
*/
- xfs_trans_ijoin(args.trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args.trans, dp);
+ xfs_trans_ijoin(args.trans, dp);
/*
* Decide on what work routines to call based on the inode size.
@@ -821,8 +811,7 @@ xfs_attr_inactive(xfs_inode_t *dp)
* No need to make quota reservations here. We expect to release some
* blocks, not allocate, in the common case.
*/
- xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(trans, dp);
+ xfs_trans_ijoin(trans, dp);
/*
* Decide on what work routines to call based on the inode size.
@@ -981,10 +970,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
/*
* Commit the current trans (including the inode) and start
@@ -1085,10 +1072,8 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
* and started a new one. We need the inode to be
* in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
} else
xfs_da_buf_done(bp);
@@ -1161,10 +1146,8 @@ xfs_attr_leaf_removename(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
} else
xfs_da_buf_done(bp);
return(0);
@@ -1317,10 +1300,8 @@ restart:
* and started a new one. We need the inode to be
* in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
/*
* Commit the node conversion and start the next
@@ -1356,10 +1337,8 @@ restart:
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
} else {
/*
* Addition succeeded, update Btree hashvals.
@@ -1470,10 +1449,8 @@ restart:
* and started a new one. We need the inode to be
* in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
}
/*
@@ -1604,10 +1581,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
/*
* Commit the Btree join operation and start a new trans.
@@ -1658,10 +1633,8 @@ xfs_attr_node_removename(xfs_da_args_t *args)
* and started a new one. We need the inode to be
* in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
} else
xfs_da_brelse(args->trans, bp);
}
@@ -2004,7 +1977,7 @@ xfs_attr_rmtval_get(xfs_da_args_t *args)
error = xfs_bmapi(args->trans, args->dp, (xfs_fileoff_t)lblkno,
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- NULL, 0, map, &nmap, NULL, NULL);
+ NULL, 0, map, &nmap, NULL);
if (error)
return(error);
ASSERT(nmap >= 1);
@@ -2083,7 +2056,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA |
XFS_BMAPI_WRITE,
args->firstblock, args->total, &map, &nmap,
- args->flist, NULL);
+ args->flist);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
&committed);
@@ -2099,10 +2072,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, dp);
ASSERT(nmap == 1);
ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
@@ -2136,7 +2107,7 @@ xfs_attr_rmtval_set(xfs_da_args_t *args)
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
args->firstblock, 0, &map, &nmap,
- NULL, NULL);
+ NULL);
if (error) {
return(error);
}
@@ -2201,7 +2172,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
args->rmtblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
args->firstblock, 0, &map, &nmap,
- args->flist, NULL);
+ args->flist);
if (error) {
return(error);
}
@@ -2239,7 +2210,7 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
error = xfs_bunmapi(args->trans, args->dp, lblkno, blkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
1, args->firstblock, args->flist,
- NULL, &done);
+ &done);
if (!error) {
error = xfs_bmap_finish(&args->trans, args->flist,
&committed);
@@ -2255,10 +2226,8 @@ xfs_attr_rmtval_remove(xfs_da_args_t *args)
* bmap_finish() may have committed the last trans and started
* a new one. We need the inode to be in all transactions.
*/
- if (committed) {
- xfs_trans_ijoin(args->trans, args->dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(args->trans, args->dp);
- }
+ if (committed)
+ xfs_trans_ijoin(args->trans, args->dp);
/*
* Close out trans and start the next one in the chain.
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c
index a90ce74fc256..a6cff8edcdb6 100644
--- a/fs/xfs/xfs_attr_leaf.c
+++ b/fs/xfs/xfs_attr_leaf.c
@@ -24,8 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
@@ -33,7 +31,6 @@
#include "xfs_ialloc_btree.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
-#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@@ -2931,7 +2928,7 @@ xfs_attr_leaf_freextent(xfs_trans_t **trans, xfs_inode_t *dp,
nmap = 1;
error = xfs_bmapi(*trans, dp, (xfs_fileoff_t)tblkno, tblkcnt,
XFS_BMAPI_ATTRFORK | XFS_BMAPI_METADATA,
- NULL, 0, &map, &nmap, NULL, NULL);
+ NULL, 0, &map, &nmap, NULL);
if (error) {
return(error);
}
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 99587ded043f..d74fbec80622 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -30,13 +30,10 @@
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_dir2_data.h"
#include "xfs_dir2_leaf.h"
@@ -104,7 +101,6 @@ xfs_bmap_add_extent(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd); /* OK to allocate reserved blocks */
@@ -122,7 +118,6 @@ xfs_bmap_add_extent_delay_real(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd); /* OK to allocate reserved blocks */
/*
@@ -135,7 +130,6 @@ xfs_bmap_add_extent_hole_delay(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd); /* OK to allocate reserved blocks */
/*
@@ -149,7 +143,6 @@ xfs_bmap_add_extent_hole_real(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork); /* data or attr fork */
/*
@@ -162,8 +155,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta); /* Change made to incore extents */
+ int *logflagsp); /* inode logging flags */
/*
* xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file.
@@ -200,7 +192,6 @@ xfs_bmap_del_extent(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp,/* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd); /* OK to allocate reserved blocks */
@@ -489,7 +480,6 @@ xfs_bmap_add_extent(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd) /* OK to use reserved data blocks */
{
@@ -524,15 +514,6 @@ xfs_bmap_add_extent(
logflags = XFS_ILOG_CORE | xfs_ilog_fext(whichfork);
} else
logflags = 0;
- /* DELTA: single new extent */
- if (delta) {
- if (delta->xed_startoff > new->br_startoff)
- delta->xed_startoff = new->br_startoff;
- if (delta->xed_blockcount <
- new->br_startoff + new->br_blockcount)
- delta->xed_blockcount = new->br_startoff +
- new->br_blockcount;
- }
}
/*
* Any kind of new delayed allocation goes here.
@@ -542,7 +523,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_delay(ip, idx, new,
- &logflags, delta, rsvd)))
+ &logflags, rsvd)))
goto done;
}
/*
@@ -553,7 +534,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur, new,
- &logflags, delta, whichfork)))
+ &logflags, whichfork)))
goto done;
} else {
xfs_bmbt_irec_t prev; /* old extent at offset idx */
@@ -578,17 +559,17 @@ xfs_bmap_add_extent(
XFS_BTCUR_BPRV_WASDEL);
if ((error = xfs_bmap_add_extent_delay_real(ip,
idx, &cur, new, &da_new, first, flist,
- &logflags, delta, rsvd)))
+ &logflags, rsvd)))
goto done;
} else if (new->br_state == XFS_EXT_NORM) {
ASSERT(new->br_state == XFS_EXT_NORM);
if ((error = xfs_bmap_add_extent_unwritten_real(
- ip, idx, &cur, new, &logflags, delta)))
+ ip, idx, &cur, new, &logflags)))
goto done;
} else {
ASSERT(new->br_state == XFS_EXT_UNWRITTEN);
if ((error = xfs_bmap_add_extent_unwritten_real(
- ip, idx, &cur, new, &logflags, delta)))
+ ip, idx, &cur, new, &logflags)))
goto done;
}
ASSERT(*curp == cur || *curp == NULL);
@@ -601,7 +582,7 @@ xfs_bmap_add_extent(
ASSERT((cur->bc_private.b.flags &
XFS_BTCUR_BPRV_WASDEL) == 0);
if ((error = xfs_bmap_add_extent_hole_real(ip, idx, cur,
- new, &logflags, delta, whichfork)))
+ new, &logflags, whichfork)))
goto done;
}
}
@@ -666,7 +647,6 @@ xfs_bmap_add_extent_delay_real(
xfs_fsblock_t *first, /* pointer to firstblock variable */
xfs_bmap_free_t *flist, /* list of extents to be freed */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd) /* OK to use reserved data block allocation */
{
xfs_btree_cur_t *cur; /* btree cursor */
@@ -797,11 +777,6 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
- /* DELTA: Three in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
@@ -832,10 +807,6 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
- /* DELTA: Two in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -867,10 +838,6 @@ xfs_bmap_add_extent_delay_real(
goto done;
}
*dnew = 0;
- /* DELTA: Two in-core extents are replaced by one. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
@@ -900,9 +867,6 @@ xfs_bmap_add_extent_delay_real(
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
}
*dnew = 0;
- /* DELTA: The in-core extent described by new changed type. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
@@ -942,10 +906,6 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
*dnew = temp;
- /* DELTA: The boundary between two in-core extents moved. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING:
@@ -990,9 +950,6 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
trace_xfs_bmap_post_update(ip, idx + 1, state, _THIS_IP_);
*dnew = temp;
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -1031,10 +988,6 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
*dnew = temp;
- /* DELTA: The boundary between two in-core extents moved. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_RIGHT_FILLING:
@@ -1078,9 +1031,6 @@ xfs_bmap_add_extent_delay_real(
xfs_bmbt_set_startblock(ep, nullstartblock((int)temp));
trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
*dnew = temp;
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case 0:
@@ -1161,9 +1111,6 @@ xfs_bmap_add_extent_delay_real(
nullstartblock((int)temp2));
trace_xfs_bmap_post_update(ip, idx + 2, state, _THIS_IP_);
*dnew = temp + temp2;
- /* DELTA: One in-core extent is split in three. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
@@ -1179,13 +1126,6 @@ xfs_bmap_add_extent_delay_real(
ASSERT(0);
}
*curp = cur;
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
done:
*logflagsp = rval;
return error;
@@ -1204,8 +1144,7 @@ xfs_bmap_add_extent_unwritten_real(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_btree_cur_t **curp, /* if *curp is null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
- int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta) /* Change made to incore extents */
+ int *logflagsp) /* inode logging flags */
{
xfs_btree_cur_t *cur; /* btree cursor */
xfs_bmbt_rec_host_t *ep; /* extent entry for idx */
@@ -1219,8 +1158,6 @@ xfs_bmap_add_extent_unwritten_real(
/* left is 0, right is 1, prev is 2 */
int rval=0; /* return value (logging flags) */
int state = 0;/* state bits, accessed thru macros */
- xfs_filblks_t temp=0;
- xfs_filblks_t temp2=0;
#define LEFT r[0]
#define RIGHT r[1]
@@ -1341,11 +1278,6 @@ xfs_bmap_add_extent_unwritten_real(
RIGHT.br_blockcount, LEFT.br_state)))
goto done;
}
- /* DELTA: Three in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG:
@@ -1382,10 +1314,6 @@ xfs_bmap_add_extent_unwritten_real(
LEFT.br_state)))
goto done;
}
- /* DELTA: Two in-core extents are replaced by one. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -1422,10 +1350,6 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
- /* DELTA: Two in-core extents are replaced by one. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING:
@@ -1453,9 +1377,6 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
- /* DELTA: The in-core extent described by new changed type. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG:
@@ -1501,10 +1422,6 @@ xfs_bmap_add_extent_unwritten_real(
LEFT.br_state))
goto done;
}
- /* DELTA: The boundary between two in-core extents moved. */
- temp = LEFT.br_startoff;
- temp2 = LEFT.br_blockcount +
- PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING:
@@ -1544,9 +1461,6 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
}
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG:
@@ -1587,10 +1501,6 @@ xfs_bmap_add_extent_unwritten_real(
newext)))
goto done;
}
- /* DELTA: The boundary between two in-core extents moved. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount +
- RIGHT.br_blockcount;
break;
case BMAP_RIGHT_FILLING:
@@ -1630,9 +1540,6 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
}
- /* DELTA: One in-core extent is split in two. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case 0:
@@ -1692,9 +1599,6 @@ xfs_bmap_add_extent_unwritten_real(
goto done;
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
}
- /* DELTA: One in-core extent is split in three. */
- temp = PREV.br_startoff;
- temp2 = PREV.br_blockcount;
break;
case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG:
@@ -1710,13 +1614,6 @@ xfs_bmap_add_extent_unwritten_real(
ASSERT(0);
}
*curp = cur;
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
done:
*logflagsp = rval;
return error;
@@ -1736,7 +1633,6 @@ xfs_bmap_add_extent_hole_delay(
xfs_extnum_t idx, /* extent number to update/insert */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int rsvd) /* OK to allocate reserved blocks */
{
xfs_bmbt_rec_host_t *ep; /* extent record for idx */
@@ -1747,7 +1643,6 @@ xfs_bmap_add_extent_hole_delay(
xfs_bmbt_irec_t right; /* right neighbor extent entry */
int state; /* state bits, accessed thru macros */
xfs_filblks_t temp=0; /* temp for indirect calculations */
- xfs_filblks_t temp2=0;
ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
ep = xfs_iext_get_ext(ifp, idx);
@@ -1819,9 +1714,6 @@ xfs_bmap_add_extent_hole_delay(
xfs_iext_remove(ip, idx, 1, state);
ip->i_df.if_lastex = idx - 1;
- /* DELTA: Two in-core extents were replaced by one. */
- temp2 = temp;
- temp = left.br_startoff;
break;
case BMAP_LEFT_CONTIG:
@@ -1841,9 +1733,6 @@ xfs_bmap_add_extent_hole_delay(
trace_xfs_bmap_post_update(ip, idx - 1, state, _THIS_IP_);
ip->i_df.if_lastex = idx - 1;
- /* DELTA: One in-core extent grew into a hole. */
- temp2 = temp;
- temp = left.br_startoff;
break;
case BMAP_RIGHT_CONTIG:
@@ -1862,9 +1751,6 @@ xfs_bmap_add_extent_hole_delay(
trace_xfs_bmap_post_update(ip, idx, state, _THIS_IP_);
ip->i_df.if_lastex = idx;
- /* DELTA: One in-core extent grew into a hole. */
- temp2 = temp;
- temp = new->br_startoff;
break;
case 0:
@@ -1876,9 +1762,6 @@ xfs_bmap_add_extent_hole_delay(
oldlen = newlen = 0;
xfs_iext_insert(ip, idx, 1, new, state);
ip->i_df.if_lastex = idx;
- /* DELTA: A new in-core extent was added in a hole. */
- temp2 = new->br_blockcount;
- temp = new->br_startoff;
break;
}
if (oldlen != newlen) {
@@ -1889,13 +1772,6 @@ xfs_bmap_add_extent_hole_delay(
* Nothing to do for disk quota accounting here.
*/
}
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
*logflagsp = 0;
return 0;
}
@@ -1911,7 +1787,6 @@ xfs_bmap_add_extent_hole_real(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *new, /* new data to add to file extents */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork) /* data or attr fork */
{
xfs_bmbt_rec_host_t *ep; /* pointer to extent entry ins. point */
@@ -1922,8 +1797,6 @@ xfs_bmap_add_extent_hole_real(
xfs_bmbt_irec_t right; /* right neighbor extent entry */
int rval=0; /* return value (logging flags) */
int state; /* state bits, accessed thru macros */
- xfs_filblks_t temp=0;
- xfs_filblks_t temp2=0;
ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(idx <= ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t));
@@ -2020,11 +1893,6 @@ xfs_bmap_add_extent_hole_real(
left.br_state)))
goto done;
}
- /* DELTA: Two in-core extents were replaced by one. */
- temp = left.br_startoff;
- temp2 = left.br_blockcount +
- new->br_blockcount +
- right.br_blockcount;
break;
case BMAP_LEFT_CONTIG:
@@ -2056,10 +1924,6 @@ xfs_bmap_add_extent_hole_real(
left.br_state)))
goto done;
}
- /* DELTA: One in-core extent grew. */
- temp = left.br_startoff;
- temp2 = left.br_blockcount +
- new->br_blockcount;
break;
case BMAP_RIGHT_CONTIG:
@@ -2092,10 +1956,6 @@ xfs_bmap_add_extent_hole_real(
right.br_state)))
goto done;
}
- /* DELTA: One in-core extent grew. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount +
- right.br_blockcount;
break;
case 0:
@@ -2123,18 +1983,8 @@ xfs_bmap_add_extent_hole_real(
goto done;
XFS_WANT_CORRUPTED_GOTO(i == 1, done);
}
- /* DELTA: A new extent was added in a hole. */
- temp = new->br_startoff;
- temp2 = new->br_blockcount;
break;
}
- if (delta) {
- temp2 += temp;
- if (delta->xed_startoff > temp)
- delta->xed_startoff = temp;
- if (delta->xed_blockcount < temp2)
- delta->xed_blockcount = temp2;
- }
done:
*logflagsp = rval;
return error;
@@ -2959,7 +2809,6 @@ xfs_bmap_del_extent(
xfs_btree_cur_t *cur, /* if null, not a btree */
xfs_bmbt_irec_t *del, /* data to remove from extents */
int *logflagsp, /* inode logging flags */
- xfs_extdelta_t *delta, /* Change made to incore extents */
int whichfork, /* data or attr fork */
int rsvd) /* OK to allocate reserved blocks */
{
@@ -3265,14 +3114,6 @@ xfs_bmap_del_extent(
if (da_old > da_new)
xfs_mod_incore_sb(mp, XFS_SBS_FDBLOCKS, (int64_t)(da_old - da_new),
rsvd);
- if (delta) {
- /* DELTA: report the original extent. */
- if (delta->xed_startoff > got.br_startoff)
- delta->xed_startoff = got.br_startoff;
- if (delta->xed_blockcount < got.br_startoff+got.br_blockcount)
- delta->xed_blockcount = got.br_startoff +
- got.br_blockcount;
- }
done:
*logflagsp = flags;
return error;
@@ -3754,9 +3595,10 @@ xfs_bmap_add_attrfork(
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
}
ASSERT(ip->i_d.di_anextents == 0);
- IHOLD(ip);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+
+ xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+
switch (ip->i_d.di_format) {
case XFS_DINODE_FMT_DEV:
ip->i_d.di_forkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
@@ -4483,8 +4325,7 @@ xfs_bmapi(
xfs_extlen_t total, /* total blocks needed */
xfs_bmbt_irec_t *mval, /* output: map values */
int *nmap, /* i/o: mval size/count */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta) /* o: change made to incore extents */
+ xfs_bmap_free_t *flist) /* i/o: list extents to free */
{
xfs_fsblock_t abno; /* allocated block number */
xfs_extlen_t alen; /* allocated extent length */
@@ -4596,10 +4437,7 @@ xfs_bmapi(
end = bno + len;
obno = bno;
bma.ip = NULL;
- if (delta) {
- delta->xed_startoff = NULLFILEOFF;
- delta->xed_blockcount = 0;
- }
+
while (bno < end && n < *nmap) {
/*
* Reading past eof, act as though there's a hole
@@ -4620,19 +4458,13 @@ xfs_bmapi(
* allocate the stuff asked for in this bmap call
* but that wouldn't be as good.
*/
- if (wasdelay && !(flags & XFS_BMAPI_EXACT)) {
+ if (wasdelay) {
alen = (xfs_extlen_t)got.br_blockcount;
aoff = got.br_startoff;
if (lastx != NULLEXTNUM && lastx) {
ep = xfs_iext_get_ext(ifp, lastx - 1);
xfs_bmbt_get_all(ep, &prev);
}
- } else if (wasdelay) {
- alen = (xfs_extlen_t)
- XFS_FILBLKS_MIN(len,
- (got.br_startoff +
- got.br_blockcount) - bno);
- aoff = bno;
} else {
alen = (xfs_extlen_t)
XFS_FILBLKS_MIN(len, MAXEXTLEN);
@@ -4831,7 +4663,7 @@ xfs_bmapi(
got.br_state = XFS_EXT_UNWRITTEN;
}
error = xfs_bmap_add_extent(ip, lastx, &cur, &got,
- firstblock, flist, &tmp_logflags, delta,
+ firstblock, flist, &tmp_logflags,
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
logflags |= tmp_logflags;
if (error)
@@ -4927,7 +4759,7 @@ xfs_bmapi(
}
mval->br_state = XFS_EXT_NORM;
error = xfs_bmap_add_extent(ip, lastx, &cur, mval,
- firstblock, flist, &tmp_logflags, delta,
+ firstblock, flist, &tmp_logflags,
whichfork, (flags & XFS_BMAPI_RSVBLOCKS));
logflags |= tmp_logflags;
if (error)
@@ -5017,14 +4849,6 @@ xfs_bmapi(
ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_BTREE ||
XFS_IFORK_NEXTENTS(ip, whichfork) > ifp->if_ext_max);
error = 0;
- if (delta && delta->xed_startoff != NULLFILEOFF) {
- /* A change was actually made.
- * Note that delta->xed_blockount is an offset at this
- * point and needs to be converted to a block count.
- */
- ASSERT(delta->xed_blockcount > delta->xed_startoff);
- delta->xed_blockcount -= delta->xed_startoff;
- }
error0:
/*
* Log everything. Do this after conversion, there's no point in
@@ -5136,8 +4960,6 @@ xfs_bunmapi(
xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta, /* o: change made to incore
- extents */
int *done) /* set if not done yet */
{
xfs_btree_cur_t *cur; /* bmap btree cursor */
@@ -5196,10 +5018,7 @@ xfs_bunmapi(
bno = start + len - 1;
ep = xfs_bmap_search_extents(ip, bno, whichfork, &eof, &lastx, &got,
&prev);
- if (delta) {
- delta->xed_startoff = NULLFILEOFF;
- delta->xed_blockcount = 0;
- }
+
/*
* Check to see if the given block number is past the end of the
* file, back up to the last block if so...
@@ -5297,7 +5116,7 @@ xfs_bunmapi(
}
del.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx, &cur, &del,
- firstblock, flist, &logflags, delta,
+ firstblock, flist, &logflags,
XFS_DATA_FORK, 0);
if (error)
goto error0;
@@ -5352,7 +5171,7 @@ xfs_bunmapi(
prev.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx - 1, &cur,
&prev, firstblock, flist, &logflags,
- delta, XFS_DATA_FORK, 0);
+ XFS_DATA_FORK, 0);
if (error)
goto error0;
goto nodelete;
@@ -5361,7 +5180,7 @@ xfs_bunmapi(
del.br_state = XFS_EXT_UNWRITTEN;
error = xfs_bmap_add_extent(ip, lastx, &cur,
&del, firstblock, flist, &logflags,
- delta, XFS_DATA_FORK, 0);
+ XFS_DATA_FORK, 0);
if (error)
goto error0;
goto nodelete;
@@ -5414,7 +5233,7 @@ xfs_bunmapi(
goto error0;
}
error = xfs_bmap_del_extent(ip, tp, lastx, flist, cur, &del,
- &tmp_logflags, delta, whichfork, rsvd);
+ &tmp_logflags, whichfork, rsvd);
logflags |= tmp_logflags;
if (error)
goto error0;
@@ -5471,14 +5290,6 @@ nodelete:
ASSERT(ifp->if_ext_max ==
XFS_IFORK_SIZE(ip, whichfork) / (uint)sizeof(xfs_bmbt_rec_t));
error = 0;
- if (delta && delta->xed_startoff != NULLFILEOFF) {
- /* A change was actually made.
- * Note that delta->xed_blockount is an offset at this
- * point and needs to be converted to a block count.
- */
- ASSERT(delta->xed_blockcount > delta->xed_startoff);
- delta->xed_blockcount -= delta->xed_startoff;
- }
error0:
/*
* Log everything. Do this after conversion, there's no point in
@@ -5605,28 +5416,6 @@ xfs_getbmap(
prealloced = 0;
fixlen = 1LL << 32;
} else {
- /*
- * If the BMV_IF_NO_DMAPI_READ interface bit specified, do
- * not generate a DMAPI read event. Otherwise, if the
- * DM_EVENT_READ bit is set for the file, generate a read
- * event in order that the DMAPI application may do its thing
- * before we return the extents. Usually this means restoring
- * user file data to regions of the file that look like holes.
- *
- * The "old behavior" (from XFS_IOC_GETBMAP) is to not specify
- * BMV_IF_NO_DMAPI_READ so that read events are generated.
- * If this were not true, callers of ioctl(XFS_IOC_GETBMAP)
- * could misinterpret holes in a DMAPI file as true holes,
- * when in fact they may represent offline user data.
- */
- if (DM_EVENT_ENABLED(ip, DM_EVENT_READ) &&
- !(iflags & BMV_IF_NO_DMAPI_READ)) {
- error = XFS_SEND_DATA(mp, DM_EVENT_READ, ip,
- 0, 0, 0, NULL);
- if (error)
- return XFS_ERROR(error);
- }
-
if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
ip->i_d.di_format != XFS_DINODE_FMT_BTREE &&
ip->i_d.di_format != XFS_DINODE_FMT_LOCAL)
@@ -5713,7 +5502,7 @@ xfs_getbmap(
error = xfs_bmapi(NULL, ip, XFS_BB_TO_FSBT(mp, bmv->bmv_offset),
XFS_BB_TO_FSB(mp, bmv->bmv_length),
bmapi_flags, NULL, 0, map, &nmap,
- NULL, NULL);
+ NULL);
if (error)
goto out_free_map;
ASSERT(nmap <= subnex);
@@ -5882,43 +5671,18 @@ xfs_bmap_get_bp(
bp = NULL;
if (!bp) { /* Chase down all the log items to see if the bp is there */
- xfs_log_item_chunk_t *licp;
- xfs_trans_t *tp;
-
- tp = cur->bc_tp;
- licp = &tp->t_items;
- while (!bp && licp != NULL) {
- if (xfs_lic_are_all_free(licp)) {
- licp = licp->lic_next;
- continue;
- }
- for (i = 0; i < licp->lic_unused; i++) {
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- xfs_buf_log_item_t *bip;
- xfs_buf_t *lbp;
-
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
-
- lidp = xfs_lic_slot(licp, i);
- lip = lidp->lid_item;
- if (lip->li_type != XFS_LI_BUF)
- continue;
-
- bip = (xfs_buf_log_item_t *)lip;
- lbp = bip->bli_buf;
-
- if (XFS_BUF_ADDR(lbp) == bno) {
- bp = lbp;
- break; /* Found it */
- }
- }
- licp = licp->lic_next;
+ struct xfs_log_item_desc *lidp;
+ struct xfs_buf_log_item *bip;
+
+ list_for_each_entry(lidp, &cur->bc_tp->t_items, lid_trans) {
+ bip = (struct xfs_buf_log_item *)lidp->lid_item;
+ if (bip->bli_item.li_type == XFS_LI_BUF &&
+ XFS_BUF_ADDR(bip->bli_buf) == bno)
+ return bip->bli_buf;
}
}
- return(bp);
+
+ return bp;
}
STATIC void
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index 419dafb9d87d..b13569a6179b 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -28,20 +28,6 @@ struct xfs_trans;
extern kmem_zone_t *xfs_bmap_free_item_zone;
/*
- * DELTA: describe a change to the in-core extent list.
- *
- * Internally the use of xed_blockount is somewhat funky.
- * xed_blockcount contains an offset much of the time because this
- * makes merging changes easier. (xfs_fileoff_t and xfs_filblks_t are
- * the same underlying type).
- */
-typedef struct xfs_extdelta
-{
- xfs_fileoff_t xed_startoff; /* offset of range */
- xfs_filblks_t xed_blockcount; /* blocks in range */
-} xfs_extdelta_t;
-
-/*
* List of extents to be free "later".
* The list is kept sorted on xbf_startblock.
*/
@@ -82,16 +68,13 @@ typedef struct xfs_bmap_free
#define XFS_BMAPI_DELAY 0x002 /* delayed write operation */
#define XFS_BMAPI_ENTIRE 0x004 /* return entire extent, not trimmed */
#define XFS_BMAPI_METADATA 0x008 /* mapping metadata not user data */
-#define XFS_BMAPI_EXACT 0x010 /* allocate only to spec'd bounds */
-#define XFS_BMAPI_ATTRFORK 0x020 /* use attribute fork not data */
-#define XFS_BMAPI_ASYNC 0x040 /* bunmapi xactions can be async */
-#define XFS_BMAPI_RSVBLOCKS 0x080 /* OK to alloc. reserved data blocks */
-#define XFS_BMAPI_PREALLOC 0x100 /* preallocation op: unwritten space */
-#define XFS_BMAPI_IGSTATE 0x200 /* Ignore state - */
+#define XFS_BMAPI_ATTRFORK 0x010 /* use attribute fork not data */
+#define XFS_BMAPI_RSVBLOCKS 0x020 /* OK to alloc. reserved data blocks */
+#define XFS_BMAPI_PREALLOC 0x040 /* preallocation op: unwritten space */
+#define XFS_BMAPI_IGSTATE 0x080 /* Ignore state - */
/* combine contig. space */
-#define XFS_BMAPI_CONTIG 0x400 /* must allocate only one extent */
-/* XFS_BMAPI_DIRECT_IO 0x800 */
-#define XFS_BMAPI_CONVERT 0x1000 /* unwritten extent conversion - */
+#define XFS_BMAPI_CONTIG 0x100 /* must allocate only one extent */
+#define XFS_BMAPI_CONVERT 0x200 /* unwritten extent conversion - */
/* need write cache flushing and no */
/* additional allocation alignments */
@@ -100,9 +83,7 @@ typedef struct xfs_bmap_free
{ XFS_BMAPI_DELAY, "DELAY" }, \
{ XFS_BMAPI_ENTIRE, "ENTIRE" }, \
{ XFS_BMAPI_METADATA, "METADATA" }, \
- { XFS_BMAPI_EXACT, "EXACT" }, \
{ XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \
- { XFS_BMAPI_ASYNC, "ASYNC" }, \
{ XFS_BMAPI_RSVBLOCKS, "RSVBLOCKS" }, \
{ XFS_BMAPI_PREALLOC, "PREALLOC" }, \
{ XFS_BMAPI_IGSTATE, "IGSTATE" }, \
@@ -310,9 +291,7 @@ xfs_bmapi(
xfs_extlen_t total, /* total blocks needed */
struct xfs_bmbt_irec *mval, /* output: map values */
int *nmap, /* i/o: mval size/count */
- xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta); /* o: change made to incore
- extents */
+ xfs_bmap_free_t *flist); /* i/o: list extents to free */
/*
* Map file blocks to filesystem blocks, simple version.
@@ -346,8 +325,6 @@ xfs_bunmapi(
xfs_fsblock_t *firstblock, /* first allocated block
controls a.g. for allocs */
xfs_bmap_free_t *flist, /* i/o: list extents to free */
- xfs_extdelta_t *delta, /* o: change made to incore
- extents */
int *done); /* set if not done yet */
/*
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 416e47e54b83..87d3c10b6954 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -24,21 +24,16 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_alloc.h"
#include "xfs_btree.h"
#include "xfs_btree_trace.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 96be4b0f2496..829af92f0fba 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -24,20 +24,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_btree.h"
#include "xfs_btree_trace.h"
-#include "xfs_ialloc.h"
#include "xfs_error.h"
#include "xfs_trace.h"
diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c
index 02a80984aa05..2a9e4ef12110 100644
--- a/fs/xfs/xfs_buf_item.c
+++ b/fs/xfs/xfs_buf_item.c
@@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_buf_item.h"
#include "xfs_trans_priv.h"
@@ -34,6 +33,12 @@
kmem_zone_t *xfs_buf_item_zone;
+static inline struct xfs_buf_log_item *BUF_ITEM(struct xfs_log_item *lip)
+{
+ return container_of(lip, struct xfs_buf_log_item, bli_item);
+}
+
+
#ifdef XFS_TRANS_DEBUG
/*
* This function uses an alternate strategy for tracking the bytes
@@ -151,12 +156,13 @@ STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip);
*/
STATIC uint
xfs_buf_item_size(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- uint nvecs;
- int next_bit;
- int last_bit;
- xfs_buf_t *bp;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
+ uint nvecs;
+ int next_bit;
+ int last_bit;
ASSERT(atomic_read(&bip->bli_refcount) > 0);
if (bip->bli_flags & XFS_BLI_STALE) {
@@ -170,7 +176,6 @@ xfs_buf_item_size(
return 1;
}
- bp = bip->bli_buf;
ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
nvecs = 1;
last_bit = xfs_next_bit(bip->bli_format.blf_data_map,
@@ -219,13 +224,13 @@ xfs_buf_item_size(
*/
STATIC void
xfs_buf_item_format(
- xfs_buf_log_item_t *bip,
- xfs_log_iovec_t *log_vector)
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *vecp)
{
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
uint base_size;
uint nvecs;
- xfs_log_iovec_t *vecp;
- xfs_buf_t *bp;
int first_bit;
int last_bit;
int next_bit;
@@ -235,8 +240,6 @@ xfs_buf_item_format(
ASSERT(atomic_read(&bip->bli_refcount) > 0);
ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
(bip->bli_flags & XFS_BLI_STALE));
- bp = bip->bli_buf;
- vecp = log_vector;
/*
* The size of the base structure is the size of the
@@ -248,7 +251,7 @@ xfs_buf_item_format(
base_size =
(uint)(sizeof(xfs_buf_log_format_t) +
((bip->bli_format.blf_map_size - 1) * sizeof(uint)));
- vecp->i_addr = (xfs_caddr_t)&bip->bli_format;
+ vecp->i_addr = &bip->bli_format;
vecp->i_len = base_size;
vecp->i_type = XLOG_REG_TYPE_BFORMAT;
vecp++;
@@ -263,7 +266,7 @@ xfs_buf_item_format(
*/
if (bip->bli_flags & XFS_BLI_INODE_BUF) {
if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
- xfs_log_item_in_current_chkpt(&bip->bli_item)))
+ xfs_log_item_in_current_chkpt(lip)))
bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
bip->bli_flags &= ~XFS_BLI_INODE_BUF;
}
@@ -356,66 +359,90 @@ xfs_buf_item_format(
/*
* This is called to pin the buffer associated with the buf log item in memory
- * so it cannot be written out. Simply call bpin() on the buffer to do this.
+ * so it cannot be written out.
*
* We also always take a reference to the buffer log item here so that the bli
* is held while the item is pinned in memory. This means that we can
* unconditionally drop the reference count a transaction holds when the
* transaction is completed.
*/
-
STATIC void
xfs_buf_item_pin(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- xfs_buf_t *bp;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
- bp = bip->bli_buf;
- ASSERT(XFS_BUF_ISBUSY(bp));
+ ASSERT(XFS_BUF_ISBUSY(bip->bli_buf));
ASSERT(atomic_read(&bip->bli_refcount) > 0);
ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
(bip->bli_flags & XFS_BLI_STALE));
- atomic_inc(&bip->bli_refcount);
+
trace_xfs_buf_item_pin(bip);
- xfs_bpin(bp);
-}
+ atomic_inc(&bip->bli_refcount);
+ atomic_inc(&bip->bli_buf->b_pin_count);
+}
/*
* This is called to unpin the buffer associated with the buf log
* item which was previously pinned with a call to xfs_buf_item_pin().
- * Just call bunpin() on the buffer to do this.
*
* Also drop the reference to the buf item for the current transaction.
* If the XFS_BLI_STALE flag is set and we are the last reference,
* then free up the buf log item and unlock the buffer.
+ *
+ * If the remove flag is set we are called from uncommit in the
+ * forced-shutdown path. If that is true and the reference count on
+ * the log item is going to drop to zero we need to free the item's
+ * descriptor in the transaction.
*/
STATIC void
xfs_buf_item_unpin(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip,
+ int remove)
{
- struct xfs_ail *ailp;
- xfs_buf_t *bp;
- int freed;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ xfs_buf_t *bp = bip->bli_buf;
+ struct xfs_ail *ailp = lip->li_ailp;
int stale = bip->bli_flags & XFS_BLI_STALE;
+ int freed;
- bp = bip->bli_buf;
- ASSERT(bp != NULL);
ASSERT(XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *) == bip);
ASSERT(atomic_read(&bip->bli_refcount) > 0);
+
trace_xfs_buf_item_unpin(bip);
freed = atomic_dec_and_test(&bip->bli_refcount);
- ailp = bip->bli_item.li_ailp;
- xfs_bunpin(bp);
+
+ if (atomic_dec_and_test(&bp->b_pin_count))
+ wake_up_all(&bp->b_waiters);
+
if (freed && stale) {
ASSERT(bip->bli_flags & XFS_BLI_STALE);
ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
ASSERT(XFS_BUF_ISSTALE(bp));
ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
+
trace_xfs_buf_item_unpin_stale(bip);
+ if (remove) {
+ /*
+ * We have to remove the log item from the transaction
+ * as we are about to release our reference to the
+ * buffer. If we don't, the unlock that occurs later
+ * in xfs_trans_uncommit() will ry to reference the
+ * buffer which we no longer have a hold on.
+ */
+ xfs_trans_del_item(lip);
+
+ /*
+ * Since the transaction no longer refers to the buffer,
+ * the buffer should no longer refer to the transaction.
+ */
+ XFS_BUF_SET_FSPRIVATE2(bp, NULL);
+ }
+
/*
* If we get called here because of an IO error, we may
* or may not have the item on the AIL. xfs_trans_ail_delete()
@@ -437,48 +464,6 @@ xfs_buf_item_unpin(
}
/*
- * this is called from uncommit in the forced-shutdown path.
- * we need to check to see if the reference count on the log item
- * is going to drop to zero. If so, unpin will free the log item
- * so we need to free the item's descriptor (that points to the item)
- * in the transaction.
- */
-STATIC void
-xfs_buf_item_unpin_remove(
- xfs_buf_log_item_t *bip,
- xfs_trans_t *tp)
-{
- /* will xfs_buf_item_unpin() call xfs_buf_item_relse()? */
- if ((atomic_read(&bip->bli_refcount) == 1) &&
- (bip->bli_flags & XFS_BLI_STALE)) {
- /*
- * yes -- We can safely do some work here and then call
- * buf_item_unpin to do the rest because we are
- * are holding the buffer locked so no one else will be
- * able to bump up the refcount. We have to remove the
- * log item from the transaction as we are about to release
- * our reference to the buffer. If we don't, the unlock that
- * occurs later in the xfs_trans_uncommit() will try to
- * reference the buffer which we no longer have a hold on.
- */
- struct xfs_log_item_desc *lidp;
-
- ASSERT(XFS_BUF_VALUSEMA(bip->bli_buf) <= 0);
- trace_xfs_buf_item_unpin_stale(bip);
-
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)bip);
- xfs_trans_free_item(tp, lidp);
-
- /*
- * Since the transaction no longer refers to the buffer, the
- * buffer should no longer refer to the transaction.
- */
- XFS_BUF_SET_FSPRIVATE2(bip->bli_buf, NULL);
- }
- xfs_buf_item_unpin(bip);
-}
-
-/*
* This is called to attempt to lock the buffer associated with this
* buf log item. Don't sleep on the buffer lock. If we can't get
* the lock right away, return 0. If we can get the lock, take a
@@ -488,11 +473,11 @@ xfs_buf_item_unpin_remove(
*/
STATIC uint
xfs_buf_item_trylock(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- xfs_buf_t *bp;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
- bp = bip->bli_buf;
if (XFS_BUF_ISPINNED(bp))
return XFS_ITEM_PINNED;
if (!XFS_BUF_CPSEMA(bp))
@@ -529,13 +514,12 @@ xfs_buf_item_trylock(
*/
STATIC void
xfs_buf_item_unlock(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- int aborted;
- xfs_buf_t *bp;
- uint hold;
-
- bp = bip->bli_buf;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
+ int aborted;
+ uint hold;
/* Clear the buffer's association with this transaction. */
XFS_BUF_SET_FSPRIVATE2(bp, NULL);
@@ -546,7 +530,7 @@ xfs_buf_item_unlock(
* (cancelled) buffers at unpin time, but we'll never go through the
* pin/unpin cycle if we abort inside commit.
*/
- aborted = (bip->bli_item.li_flags & XFS_LI_ABORTED) != 0;
+ aborted = (lip->li_flags & XFS_LI_ABORTED) != 0;
/*
* Before possibly freeing the buf item, determine if we should
@@ -607,16 +591,16 @@ xfs_buf_item_unlock(
*/
STATIC xfs_lsn_t
xfs_buf_item_committed(
- xfs_buf_log_item_t *bip,
+ struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+
trace_xfs_buf_item_committed(bip);
- if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
- (bip->bli_item.li_lsn != 0)) {
- return bip->bli_item.li_lsn;
- }
- return (lsn);
+ if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && lip->li_lsn != 0)
+ return lip->li_lsn;
+ return lsn;
}
/*
@@ -626,15 +610,16 @@ xfs_buf_item_committed(
*/
STATIC void
xfs_buf_item_push(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- xfs_buf_t *bp;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
+ ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
+
trace_xfs_buf_item_push(bip);
- bp = bip->bli_buf;
- ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
xfs_buf_relse(bp);
}
@@ -646,22 +631,24 @@ xfs_buf_item_push(
*/
STATIC void
xfs_buf_item_pushbuf(
- xfs_buf_log_item_t *bip)
+ struct xfs_log_item *lip)
{
- xfs_buf_t *bp;
+ struct xfs_buf_log_item *bip = BUF_ITEM(lip);
+ struct xfs_buf *bp = bip->bli_buf;
ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
+ ASSERT(XFS_BUF_ISDELAYWRITE(bp));
+
trace_xfs_buf_item_pushbuf(bip);
- bp = bip->bli_buf;
- ASSERT(XFS_BUF_ISDELAYWRITE(bp));
xfs_buf_delwri_promote(bp);
xfs_buf_relse(bp);
}
-/* ARGSUSED */
STATIC void
-xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
+xfs_buf_item_committing(
+ struct xfs_log_item *lip,
+ xfs_lsn_t commit_lsn)
{
}
@@ -669,21 +656,16 @@ xfs_buf_item_committing(xfs_buf_log_item_t *bip, xfs_lsn_t commit_lsn)
* This is the ops vector shared by all buf log items.
*/
static struct xfs_item_ops xfs_buf_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_buf_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_buf_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_buf_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_buf_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
- xfs_buf_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_buf_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_buf_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_buf_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_buf_item_push,
- .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_buf_item_pushbuf,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_buf_item_committing
+ .iop_size = xfs_buf_item_size,
+ .iop_format = xfs_buf_item_format,
+ .iop_pin = xfs_buf_item_pin,
+ .iop_unpin = xfs_buf_item_unpin,
+ .iop_trylock = xfs_buf_item_trylock,
+ .iop_unlock = xfs_buf_item_unlock,
+ .iop_committed = xfs_buf_item_committed,
+ .iop_push = xfs_buf_item_push,
+ .iop_pushbuf = xfs_buf_item_pushbuf,
+ .iop_committing = xfs_buf_item_committing
};
@@ -1098,15 +1080,14 @@ xfs_buf_error_relse(
* It is called by xfs_buf_iodone_callbacks() above which will take
* care of cleaning up the buffer itself.
*/
-/* ARGSUSED */
void
xfs_buf_iodone(
- xfs_buf_t *bp,
- xfs_buf_log_item_t *bip)
+ struct xfs_buf *bp,
+ struct xfs_log_item *lip)
{
- struct xfs_ail *ailp = bip->bli_item.li_ailp;
+ struct xfs_ail *ailp = lip->li_ailp;
- ASSERT(bip->bli_buf == bp);
+ ASSERT(BUF_ITEM(lip)->bli_buf == bp);
xfs_buf_rele(bp);
@@ -1120,6 +1101,6 @@ xfs_buf_iodone(
* Either way, AIL is useless if we're forcing a shutdown.
*/
spin_lock(&ailp->xa_lock);
- xfs_trans_ail_delete(ailp, (xfs_log_item_t *)bip);
- xfs_buf_item_free(bip);
+ xfs_trans_ail_delete(ailp, lip);
+ xfs_buf_item_free(BUF_ITEM(lip));
}
diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h
index f20bb472d582..0e2ed43f16c7 100644
--- a/fs/xfs/xfs_buf_item.h
+++ b/fs/xfs/xfs_buf_item.h
@@ -124,7 +124,7 @@ void xfs_buf_attach_iodone(struct xfs_buf *,
void(*)(struct xfs_buf *, xfs_log_item_t *),
xfs_log_item_t *);
void xfs_buf_iodone_callbacks(struct xfs_buf *);
-void xfs_buf_iodone(struct xfs_buf *, xfs_buf_log_item_t *);
+void xfs_buf_iodone(struct xfs_buf *, struct xfs_log_item *);
#ifdef XFS_TRANS_DEBUG
void
diff --git a/fs/xfs/xfs_da_btree.c b/fs/xfs/xfs_da_btree.c
index 0ca556b4bf31..2adfb761ab13 100644
--- a/fs/xfs/xfs_da_btree.c
+++ b/fs/xfs/xfs_da_btree.c
@@ -25,19 +25,14 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_alloc.h"
-#include "xfs_btree.h"
#include "xfs_bmap.h"
#include "xfs_attr.h"
#include "xfs_attr_leaf.h"
@@ -1601,7 +1596,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|
XFS_BMAPI_CONTIG,
args->firstblock, args->total, &map, &nmap,
- args->flist, NULL))) {
+ args->flist))) {
return error;
}
ASSERT(nmap <= 1);
@@ -1622,8 +1617,7 @@ xfs_da_grow_inode(xfs_da_args_t *args, xfs_dablk_t *new_blkno)
xfs_bmapi_aflag(w)|XFS_BMAPI_WRITE|
XFS_BMAPI_METADATA,
args->firstblock, args->total,
- &mapp[mapi], &nmap, args->flist,
- NULL))) {
+ &mapp[mapi], &nmap, args->flist))) {
kmem_free(mapp);
return error;
}
@@ -1884,7 +1878,7 @@ xfs_da_shrink_inode(xfs_da_args_t *args, xfs_dablk_t dead_blkno,
*/
if ((error = xfs_bunmapi(tp, dp, dead_blkno, count,
xfs_bmapi_aflag(w)|XFS_BMAPI_METADATA,
- 0, args->firstblock, args->flist, NULL,
+ 0, args->firstblock, args->flist,
&done)) == ENOSPC) {
if (w != XFS_DATA_FORK)
break;
@@ -1989,7 +1983,7 @@ xfs_da_do_buf(
nfsb,
XFS_BMAPI_METADATA |
xfs_bmapi_aflag(whichfork),
- NULL, 0, mapp, &nmap, NULL, NULL)))
+ NULL, 0, mapp, &nmap, NULL)))
goto exit0;
}
} else {
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c
index 7f159d2a429a..3b9582c60a22 100644
--- a/fs/xfs/xfs_dfrag.c
+++ b/fs/xfs/xfs_dfrag.c
@@ -24,24 +24,15 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_dfrag.h"
#include "xfs_error.h"
-#include "xfs_rw.h"
#include "xfs_vnodeops.h"
#include "xfs_trace.h"
@@ -425,11 +416,8 @@ xfs_swap_extents(
}
- IHOLD(ip);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
-
- IHOLD(tip);
- xfs_trans_ijoin(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
xfs_trans_log_inode(tp, ip, ilf_fields);
xfs_trans_log_inode(tp, tip, tilf_fields);
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 42520f041265..a1321bc7f192 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -25,13 +25,11 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
@@ -382,7 +380,7 @@ xfs_readdir(
int rval; /* return value */
int v; /* type-checking value */
- xfs_itrace_entry(dp);
+ trace_xfs_readdir(dp);
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return XFS_ERROR(EIO);
@@ -549,7 +547,7 @@ xfs_dir2_grow_inode(
if ((error = xfs_bmapi(tp, dp, bno, count,
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA|XFS_BMAPI_CONTIG,
args->firstblock, args->total, &map, &nmap,
- args->flist, NULL)))
+ args->flist)))
return error;
ASSERT(nmap <= 1);
if (nmap == 1) {
@@ -581,8 +579,7 @@ xfs_dir2_grow_inode(
if ((error = xfs_bmapi(tp, dp, b, c,
XFS_BMAPI_WRITE|XFS_BMAPI_METADATA,
args->firstblock, args->total,
- &mapp[mapi], &nmap, args->flist,
- NULL))) {
+ &mapp[mapi], &nmap, args->flist))) {
kmem_free(mapp);
return error;
}
@@ -715,7 +712,7 @@ xfs_dir2_shrink_inode(
*/
if ((error = xfs_bunmapi(tp, dp, da, mp->m_dirblkfsbs,
XFS_BMAPI_METADATA, 0, args->firstblock, args->flist,
- NULL, &done))) {
+ &done))) {
/*
* ENOSPC actually can happen if we're in a removename with
* no space reservation, and the resulting block removal
diff --git a/fs/xfs/xfs_dir2_block.c b/fs/xfs/xfs_dir2_block.c
index 779a267b0a84..68f4926c7d16 100644
--- a/fs/xfs/xfs_dir2_block.c
+++ b/fs/xfs/xfs_dir2_block.c
@@ -24,12 +24,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
diff --git a/fs/xfs/xfs_dir2_data.c b/fs/xfs/xfs_dir2_data.c
index 498f8d694330..921595b84f5b 100644
--- a/fs/xfs/xfs_dir2_data.c
+++ b/fs/xfs/xfs_dir2_data.c
@@ -24,12 +24,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_dir2_data.h"
diff --git a/fs/xfs/xfs_dir2_leaf.c b/fs/xfs/xfs_dir2_leaf.c
index e2d89854ec9e..504be8640e91 100644
--- a/fs/xfs/xfs_dir2_leaf.c
+++ b/fs/xfs/xfs_dir2_leaf.c
@@ -25,11 +25,9 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_attr_sf.h"
#include "xfs_dir2_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@@ -875,7 +873,7 @@ xfs_dir2_leaf_getdents(
xfs_dir2_byte_to_da(mp,
XFS_DIR2_LEAF_OFFSET) - map_off,
XFS_BMAPI_METADATA, NULL, 0,
- &map[map_valid], &nmap, NULL, NULL);
+ &map[map_valid], &nmap, NULL);
/*
* Don't know if we should ignore this or
* try to return an error.
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index 78fc4d9ae756..f9a0864b696a 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -24,12 +24,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_bmap.h"
diff --git a/fs/xfs/xfs_dir2_sf.c b/fs/xfs/xfs_dir2_sf.c
index c1a5945d463a..b1bae6b1eed9 100644
--- a/fs/xfs/xfs_dir2_sf.c
+++ b/fs/xfs/xfs_dir2_sf.c
@@ -24,12 +24,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
diff --git a/fs/xfs/xfs_dmapi.h b/fs/xfs/xfs_dmapi.h
deleted file mode 100644
index 2813cdd72375..000000000000
--- a/fs/xfs/xfs_dmapi.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#ifndef __XFS_DMAPI_H__
-#define __XFS_DMAPI_H__
-
-/* Values used to define the on-disk version of dm_attrname_t. All
- * on-disk attribute names start with the 8-byte string "SGI_DMI_".
- *
- * In the on-disk inode, DMAPI attribute names consist of the user-provided
- * name with the DMATTR_PREFIXSTRING pre-pended. This string must NEVER be
- * changed.
- */
-
-#define DMATTR_PREFIXLEN 8
-#define DMATTR_PREFIXSTRING "SGI_DMI_"
-
-typedef enum {
- DM_EVENT_INVALID = -1,
- DM_EVENT_CANCEL = 0, /* not supported */
- DM_EVENT_MOUNT = 1,
- DM_EVENT_PREUNMOUNT = 2,
- DM_EVENT_UNMOUNT = 3,
- DM_EVENT_DEBUT = 4, /* not supported */
- DM_EVENT_CREATE = 5,
- DM_EVENT_CLOSE = 6, /* not supported */
- DM_EVENT_POSTCREATE = 7,
- DM_EVENT_REMOVE = 8,
- DM_EVENT_POSTREMOVE = 9,
- DM_EVENT_RENAME = 10,
- DM_EVENT_POSTRENAME = 11,
- DM_EVENT_LINK = 12,
- DM_EVENT_POSTLINK = 13,
- DM_EVENT_SYMLINK = 14,
- DM_EVENT_POSTSYMLINK = 15,
- DM_EVENT_READ = 16,
- DM_EVENT_WRITE = 17,
- DM_EVENT_TRUNCATE = 18,
- DM_EVENT_ATTRIBUTE = 19,
- DM_EVENT_DESTROY = 20,
- DM_EVENT_NOSPACE = 21,
- DM_EVENT_USER = 22,
- DM_EVENT_MAX = 23
-} dm_eventtype_t;
-#define HAVE_DM_EVENTTYPE_T
-
-typedef enum {
- DM_RIGHT_NULL,
- DM_RIGHT_SHARED,
- DM_RIGHT_EXCL
-} dm_right_t;
-#define HAVE_DM_RIGHT_T
-
-/* Defines for determining if an event message should be sent. */
-#ifdef HAVE_DMAPI
-#define DM_EVENT_ENABLED(ip, event) ( \
- unlikely ((ip)->i_mount->m_flags & XFS_MOUNT_DMAPI) && \
- ( ((ip)->i_d.di_dmevmask & (1 << event)) || \
- ((ip)->i_mount->m_dmevmask & (1 << event)) ) \
- )
-#else
-#define DM_EVENT_ENABLED(ip, event) (0)
-#endif
-
-#define DM_XFS_VALID_FS_EVENTS ( \
- (1 << DM_EVENT_PREUNMOUNT) | \
- (1 << DM_EVENT_UNMOUNT) | \
- (1 << DM_EVENT_NOSPACE) | \
- (1 << DM_EVENT_DEBUT) | \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events valid in dm_set_eventlist() when called with a file handle for
- a regular file or a symlink. These events are persistent.
-*/
-
-#define DM_XFS_VALID_FILE_EVENTS ( \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events valid in dm_set_eventlist() when called with a file handle for
- a directory. These events are persistent.
-*/
-
-#define DM_XFS_VALID_DIRECTORY_EVENTS ( \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-/* Events supported by the XFS filesystem. */
-#define DM_XFS_SUPPORTED_EVENTS ( \
- (1 << DM_EVENT_MOUNT) | \
- (1 << DM_EVENT_PREUNMOUNT) | \
- (1 << DM_EVENT_UNMOUNT) | \
- (1 << DM_EVENT_NOSPACE) | \
- (1 << DM_EVENT_CREATE) | \
- (1 << DM_EVENT_POSTCREATE) | \
- (1 << DM_EVENT_REMOVE) | \
- (1 << DM_EVENT_POSTREMOVE) | \
- (1 << DM_EVENT_RENAME) | \
- (1 << DM_EVENT_POSTRENAME) | \
- (1 << DM_EVENT_LINK) | \
- (1 << DM_EVENT_POSTLINK) | \
- (1 << DM_EVENT_SYMLINK) | \
- (1 << DM_EVENT_POSTSYMLINK) | \
- (1 << DM_EVENT_READ) | \
- (1 << DM_EVENT_WRITE) | \
- (1 << DM_EVENT_TRUNCATE) | \
- (1 << DM_EVENT_ATTRIBUTE) | \
- (1 << DM_EVENT_DESTROY) )
-
-
-/*
- * Definitions used for the flags field on dm_send_*_event().
- */
-
-#define DM_FLAGS_NDELAY 0x001 /* return EAGAIN after dm_pending() */
-#define DM_FLAGS_UNWANTED 0x002 /* event not in fsys dm_eventset_t */
-#define DM_FLAGS_IMUX 0x004 /* thread holds i_mutex */
-#define DM_FLAGS_IALLOCSEM_RD 0x010 /* thread holds i_alloc_sem rd */
-#define DM_FLAGS_IALLOCSEM_WR 0x020 /* thread holds i_alloc_sem wr */
-
-/*
- * Pull in platform specific event flags defines
- */
-#include "xfs_dmapi_priv.h"
-
-/*
- * Macros to turn caller specified delay/block flags into
- * dm_send_xxxx_event flag DM_FLAGS_NDELAY.
- */
-
-#define FILP_DELAY_FLAG(filp) ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) ? \
- DM_FLAGS_NDELAY : 0)
-#define AT_DELAY_FLAG(f) ((f & XFS_ATTR_NONBLOCK) ? DM_FLAGS_NDELAY : 0)
-
-#endif /* __XFS_DMAPI_H__ */
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c
deleted file mode 100644
index e71e2581c0c3..000000000000
--- a/fs/xfs/xfs_dmops.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_trans.h"
-#include "xfs_sb.h"
-#include "xfs_dmapi.h"
-#include "xfs_inum.h"
-#include "xfs_ag.h"
-#include "xfs_mount.h"
-
-
-static struct xfs_dmops xfs_dmcore_stub = {
- .xfs_send_data = (xfs_send_data_t)fs_nosys,
- .xfs_send_mmap = (xfs_send_mmap_t)fs_noerr,
- .xfs_send_destroy = (xfs_send_destroy_t)fs_nosys,
- .xfs_send_namesp = (xfs_send_namesp_t)fs_nosys,
- .xfs_send_mount = (xfs_send_mount_t)fs_nosys,
- .xfs_send_unmount = (xfs_send_unmount_t)fs_noerr,
-};
-
-int
-xfs_dmops_get(struct xfs_mount *mp)
-{
- if (mp->m_flags & XFS_MOUNT_DMAPI) {
- cmn_err(CE_WARN,
- "XFS: dmapi support not available in this kernel.");
- return EINVAL;
- }
-
- mp->m_dm_ops = &xfs_dmcore_stub;
- return 0;
-}
-
-void
-xfs_dmops_put(struct xfs_mount *mp)
-{
-}
diff --git a/fs/xfs/xfs_error.c b/fs/xfs/xfs_error.c
index 047b8a8e5c29..ed9990267661 100644
--- a/fs/xfs/xfs_error.c
+++ b/fs/xfs/xfs_error.c
@@ -23,12 +23,8 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_utils.h"
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c
index 409fe81585fd..a55e687bf562 100644
--- a/fs/xfs/xfs_extfree_item.c
+++ b/fs/xfs/xfs_extfree_item.c
@@ -24,7 +24,6 @@
#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
#include "xfs_extfree_item.h"
@@ -33,18 +32,19 @@
kmem_zone_t *xfs_efi_zone;
kmem_zone_t *xfs_efd_zone;
-STATIC void xfs_efi_item_unlock(xfs_efi_log_item_t *);
+static inline struct xfs_efi_log_item *EFI_ITEM(struct xfs_log_item *lip)
+{
+ return container_of(lip, struct xfs_efi_log_item, efi_item);
+}
void
-xfs_efi_item_free(xfs_efi_log_item_t *efip)
+xfs_efi_item_free(
+ struct xfs_efi_log_item *efip)
{
- int nexts = efip->efi_format.efi_nextents;
-
- if (nexts > XFS_EFI_MAX_FAST_EXTENTS) {
+ if (efip->efi_format.efi_nextents > XFS_EFI_MAX_FAST_EXTENTS)
kmem_free(efip);
- } else {
+ else
kmem_zone_free(xfs_efi_zone, efip);
- }
}
/*
@@ -52,9 +52,9 @@ xfs_efi_item_free(xfs_efi_log_item_t *efip)
* We only need 1 iovec for an efi item. It just logs the efi_log_format
* structure.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_efi_item_size(xfs_efi_log_item_t *efip)
+xfs_efi_item_size(
+ struct xfs_log_item *lip)
{
return 1;
}
@@ -67,10 +67,12 @@ xfs_efi_item_size(xfs_efi_log_item_t *efip)
* slots in the efi item have been filled.
*/
STATIC void
-xfs_efi_item_format(xfs_efi_log_item_t *efip,
- xfs_log_iovec_t *log_vector)
+xfs_efi_item_format(
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *log_vector)
{
- uint size;
+ struct xfs_efi_log_item *efip = EFI_ITEM(lip);
+ uint size;
ASSERT(efip->efi_next_extent == efip->efi_format.efi_nextents);
@@ -80,7 +82,7 @@ xfs_efi_item_format(xfs_efi_log_item_t *efip,
size += (efip->efi_format.efi_nextents - 1) * sizeof(xfs_extent_t);
efip->efi_format.efi_size = 1;
- log_vector->i_addr = (xfs_caddr_t)&(efip->efi_format);
+ log_vector->i_addr = &efip->efi_format;
log_vector->i_len = size;
log_vector->i_type = XLOG_REG_TYPE_EFI_FORMAT;
ASSERT(size >= sizeof(xfs_efi_log_format_t));
@@ -90,60 +92,33 @@ xfs_efi_item_format(xfs_efi_log_item_t *efip,
/*
* Pinning has no meaning for an efi item, so just return.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efi_item_pin(xfs_efi_log_item_t *efip)
+xfs_efi_item_pin(
+ struct xfs_log_item *lip)
{
- return;
}
-
/*
* While EFIs cannot really be pinned, the unpin operation is the
* last place at which the EFI is manipulated during a transaction.
* Here we coordinate with xfs_efi_cancel() to determine who gets to
* free the EFI.
*/
-/*ARGSUSED*/
-STATIC void
-xfs_efi_item_unpin(xfs_efi_log_item_t *efip)
-{
- struct xfs_ail *ailp = efip->efi_item.li_ailp;
-
- spin_lock(&ailp->xa_lock);
- if (efip->efi_flags & XFS_EFI_CANCELED) {
- /* xfs_trans_ail_delete() drops the AIL lock. */
- xfs_trans_ail_delete(ailp, (xfs_log_item_t *)efip);
- xfs_efi_item_free(efip);
- } else {
- efip->efi_flags |= XFS_EFI_COMMITTED;
- spin_unlock(&ailp->xa_lock);
- }
-}
-
-/*
- * like unpin only we have to also clear the xaction descriptor
- * pointing the log item if we free the item. This routine duplicates
- * unpin because efi_flags is protected by the AIL lock. Freeing
- * the descriptor and then calling unpin would force us to drop the AIL
- * lock which would open up a race condition.
- */
STATIC void
-xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
+xfs_efi_item_unpin(
+ struct xfs_log_item *lip,
+ int remove)
{
- struct xfs_ail *ailp = efip->efi_item.li_ailp;
- xfs_log_item_desc_t *lidp;
+ struct xfs_efi_log_item *efip = EFI_ITEM(lip);
+ struct xfs_ail *ailp = lip->li_ailp;
spin_lock(&ailp->xa_lock);
if (efip->efi_flags & XFS_EFI_CANCELED) {
- /*
- * free the xaction descriptor pointing to this item
- */
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t *) efip);
- xfs_trans_free_item(tp, lidp);
+ if (remove)
+ xfs_trans_del_item(lip);
/* xfs_trans_ail_delete() drops the AIL lock. */
- xfs_trans_ail_delete(ailp, (xfs_log_item_t *)efip);
+ xfs_trans_ail_delete(ailp, lip);
xfs_efi_item_free(efip);
} else {
efip->efi_flags |= XFS_EFI_COMMITTED;
@@ -158,9 +133,9 @@ xfs_efi_item_unpin_remove(xfs_efi_log_item_t *efip, xfs_trans_t *tp)
* XFS_ITEM_PINNED so that the caller will eventually flush the log.
* This should help in getting the EFI out of the AIL.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_efi_item_trylock(xfs_efi_log_item_t *efip)
+xfs_efi_item_trylock(
+ struct xfs_log_item *lip)
{
return XFS_ITEM_PINNED;
}
@@ -168,13 +143,12 @@ xfs_efi_item_trylock(xfs_efi_log_item_t *efip)
/*
* Efi items have no locking, so just return.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
+xfs_efi_item_unlock(
+ struct xfs_log_item *lip)
{
- if (efip->efi_item.li_flags & XFS_LI_ABORTED)
- xfs_efi_item_free(efip);
- return;
+ if (lip->li_flags & XFS_LI_ABORTED)
+ xfs_efi_item_free(EFI_ITEM(lip));
}
/*
@@ -183,9 +157,10 @@ xfs_efi_item_unlock(xfs_efi_log_item_t *efip)
* flag is not paid any attention here. Checking for that is delayed
* until the EFI is unpinned.
*/
-/*ARGSUSED*/
STATIC xfs_lsn_t
-xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
+xfs_efi_item_committed(
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
return lsn;
}
@@ -195,11 +170,10 @@ xfs_efi_item_committed(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
* stuck waiting for all of its corresponding efd items to be
* committed to disk.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efi_item_push(xfs_efi_log_item_t *efip)
+xfs_efi_item_push(
+ struct xfs_log_item *lip)
{
- return;
}
/*
@@ -209,61 +183,55 @@ xfs_efi_item_push(xfs_efi_log_item_t *efip)
* example, for inodes, the inode is locked throughout the extent freeing
* so the dependency should be recorded there.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efi_item_committing(xfs_efi_log_item_t *efip, xfs_lsn_t lsn)
+xfs_efi_item_committing(
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
- return;
}
/*
* This is the ops vector shared by all efi log items.
*/
static struct xfs_item_ops xfs_efi_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_efi_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_efi_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_efi_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efi_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t *))
- xfs_efi_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efi_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_efi_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efi_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_efi_item_push,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efi_item_committing
+ .iop_size = xfs_efi_item_size,
+ .iop_format = xfs_efi_item_format,
+ .iop_pin = xfs_efi_item_pin,
+ .iop_unpin = xfs_efi_item_unpin,
+ .iop_trylock = xfs_efi_item_trylock,
+ .iop_unlock = xfs_efi_item_unlock,
+ .iop_committed = xfs_efi_item_committed,
+ .iop_push = xfs_efi_item_push,
+ .iop_committing = xfs_efi_item_committing
};
/*
* Allocate and initialize an efi item with the given number of extents.
*/
-xfs_efi_log_item_t *
-xfs_efi_init(xfs_mount_t *mp,
- uint nextents)
+struct xfs_efi_log_item *
+xfs_efi_init(
+ struct xfs_mount *mp,
+ uint nextents)
{
- xfs_efi_log_item_t *efip;
+ struct xfs_efi_log_item *efip;
uint size;
ASSERT(nextents > 0);
if (nextents > XFS_EFI_MAX_FAST_EXTENTS) {
size = (uint)(sizeof(xfs_efi_log_item_t) +
((nextents - 1) * sizeof(xfs_extent_t)));
- efip = (xfs_efi_log_item_t*)kmem_zalloc(size, KM_SLEEP);
+ efip = kmem_zalloc(size, KM_SLEEP);
} else {
- efip = (xfs_efi_log_item_t*)kmem_zone_zalloc(xfs_efi_zone,
- KM_SLEEP);
+ efip = kmem_zone_zalloc(xfs_efi_zone, KM_SLEEP);
}
xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops);
efip->efi_format.efi_nextents = nextents;
efip->efi_format.efi_id = (__psint_t)(void*)efip;
- return (efip);
+ return efip;
}
/*
@@ -276,7 +244,7 @@ xfs_efi_init(xfs_mount_t *mp,
int
xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
{
- xfs_efi_log_format_t *src_efi_fmt = (xfs_efi_log_format_t *)buf->i_addr;
+ xfs_efi_log_format_t *src_efi_fmt = buf->i_addr;
uint i;
uint len = sizeof(xfs_efi_log_format_t) +
(src_efi_fmt->efi_nextents - 1) * sizeof(xfs_extent_t);
@@ -289,8 +257,7 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
memcpy((char *)dst_efi_fmt, (char*)src_efi_fmt, len);
return 0;
} else if (buf->i_len == len32) {
- xfs_efi_log_format_32_t *src_efi_fmt_32 =
- (xfs_efi_log_format_32_t *)buf->i_addr;
+ xfs_efi_log_format_32_t *src_efi_fmt_32 = buf->i_addr;
dst_efi_fmt->efi_type = src_efi_fmt_32->efi_type;
dst_efi_fmt->efi_size = src_efi_fmt_32->efi_size;
@@ -304,8 +271,7 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt)
}
return 0;
} else if (buf->i_len == len64) {
- xfs_efi_log_format_64_t *src_efi_fmt_64 =
- (xfs_efi_log_format_64_t *)buf->i_addr;
+ xfs_efi_log_format_64_t *src_efi_fmt_64 = buf->i_addr;
dst_efi_fmt->efi_type = src_efi_fmt_64->efi_type;
dst_efi_fmt->efi_size = src_efi_fmt_64->efi_size;
@@ -356,16 +322,18 @@ xfs_efi_release(xfs_efi_log_item_t *efip,
}
}
-STATIC void
-xfs_efd_item_free(xfs_efd_log_item_t *efdp)
+static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip)
{
- int nexts = efdp->efd_format.efd_nextents;
+ return container_of(lip, struct xfs_efd_log_item, efd_item);
+}
- if (nexts > XFS_EFD_MAX_FAST_EXTENTS) {
+STATIC void
+xfs_efd_item_free(struct xfs_efd_log_item *efdp)
+{
+ if (efdp->efd_format.efd_nextents > XFS_EFD_MAX_FAST_EXTENTS)
kmem_free(efdp);
- } else {
+ else
kmem_zone_free(xfs_efd_zone, efdp);
- }
}
/*
@@ -373,9 +341,9 @@ xfs_efd_item_free(xfs_efd_log_item_t *efdp)
* We only need 1 iovec for an efd item. It just logs the efd_log_format
* structure.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_efd_item_size(xfs_efd_log_item_t *efdp)
+xfs_efd_item_size(
+ struct xfs_log_item *lip)
{
return 1;
}
@@ -388,10 +356,12 @@ xfs_efd_item_size(xfs_efd_log_item_t *efdp)
* slots in the efd item have been filled.
*/
STATIC void
-xfs_efd_item_format(xfs_efd_log_item_t *efdp,
- xfs_log_iovec_t *log_vector)
+xfs_efd_item_format(
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *log_vector)
{
- uint size;
+ struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
+ uint size;
ASSERT(efdp->efd_next_extent == efdp->efd_format.efd_nextents);
@@ -401,48 +371,38 @@ xfs_efd_item_format(xfs_efd_log_item_t *efdp,
size += (efdp->efd_format.efd_nextents - 1) * sizeof(xfs_extent_t);
efdp->efd_format.efd_size = 1;
- log_vector->i_addr = (xfs_caddr_t)&(efdp->efd_format);
+ log_vector->i_addr = &efdp->efd_format;
log_vector->i_len = size;
log_vector->i_type = XLOG_REG_TYPE_EFD_FORMAT;
ASSERT(size >= sizeof(xfs_efd_log_format_t));
}
-
/*
* Pinning has no meaning for an efd item, so just return.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efd_item_pin(xfs_efd_log_item_t *efdp)
+xfs_efd_item_pin(
+ struct xfs_log_item *lip)
{
- return;
}
-
/*
* Since pinning has no meaning for an efd item, unpinning does
* not either.
*/
-/*ARGSUSED*/
-STATIC void
-xfs_efd_item_unpin(xfs_efd_log_item_t *efdp)
-{
- return;
-}
-
-/*ARGSUSED*/
STATIC void
-xfs_efd_item_unpin_remove(xfs_efd_log_item_t *efdp, xfs_trans_t *tp)
+xfs_efd_item_unpin(
+ struct xfs_log_item *lip,
+ int remove)
{
- return;
}
/*
* Efd items have no locking, so just return success.
*/
-/*ARGSUSED*/
STATIC uint
-xfs_efd_item_trylock(xfs_efd_log_item_t *efdp)
+xfs_efd_item_trylock(
+ struct xfs_log_item *lip)
{
return XFS_ITEM_LOCKED;
}
@@ -451,13 +411,12 @@ xfs_efd_item_trylock(xfs_efd_log_item_t *efdp)
* Efd items have no locking or pushing, so return failure
* so that the caller doesn't bother with us.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
+xfs_efd_item_unlock(
+ struct xfs_log_item *lip)
{
- if (efdp->efd_item.li_flags & XFS_LI_ABORTED)
- xfs_efd_item_free(efdp);
- return;
+ if (lip->li_flags & XFS_LI_ABORTED)
+ xfs_efd_item_free(EFD_ITEM(lip));
}
/*
@@ -467,15 +426,18 @@ xfs_efd_item_unlock(xfs_efd_log_item_t *efdp)
* return -1 to keep the transaction code from further referencing
* this item.
*/
-/*ARGSUSED*/
STATIC xfs_lsn_t
-xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
+xfs_efd_item_committed(
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
+ struct xfs_efd_log_item *efdp = EFD_ITEM(lip);
+
/*
* If we got a log I/O error, it's always the case that the LR with the
* EFI got unpinned and freed before the EFD got aborted.
*/
- if ((efdp->efd_item.li_flags & XFS_LI_ABORTED) == 0)
+ if (!(lip->li_flags & XFS_LI_ABORTED))
xfs_efi_release(efdp->efd_efip, efdp->efd_format.efd_nextents);
xfs_efd_item_free(efdp);
@@ -486,11 +448,10 @@ xfs_efd_item_committed(xfs_efd_log_item_t *efdp, xfs_lsn_t lsn)
* There isn't much you can do to push on an efd item. It is simply
* stuck waiting for the log to be flushed to disk.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efd_item_push(xfs_efd_log_item_t *efdp)
+xfs_efd_item_push(
+ struct xfs_log_item *lip)
{
- return;
}
/*
@@ -500,55 +461,48 @@ xfs_efd_item_push(xfs_efd_log_item_t *efdp)
* example, for inodes, the inode is locked throughout the extent freeing
* so the dependency should be recorded there.
*/
-/*ARGSUSED*/
STATIC void
-xfs_efd_item_committing(xfs_efd_log_item_t *efip, xfs_lsn_t lsn)
+xfs_efd_item_committing(
+ struct xfs_log_item *lip,
+ xfs_lsn_t lsn)
{
- return;
}
/*
* This is the ops vector shared by all efd log items.
*/
static struct xfs_item_ops xfs_efd_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_efd_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_efd_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_efd_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_efd_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
- xfs_efd_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_efd_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_efd_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efd_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_efd_item_push,
- .iop_pushbuf = NULL,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_efd_item_committing
+ .iop_size = xfs_efd_item_size,
+ .iop_format = xfs_efd_item_format,
+ .iop_pin = xfs_efd_item_pin,
+ .iop_unpin = xfs_efd_item_unpin,
+ .iop_trylock = xfs_efd_item_trylock,
+ .iop_unlock = xfs_efd_item_unlock,
+ .iop_committed = xfs_efd_item_committed,
+ .iop_push = xfs_efd_item_push,
+ .iop_committing = xfs_efd_item_committing
};
-
/*
* Allocate and initialize an efd item with the given number of extents.
*/
-xfs_efd_log_item_t *
-xfs_efd_init(xfs_mount_t *mp,
- xfs_efi_log_item_t *efip,
- uint nextents)
+struct xfs_efd_log_item *
+xfs_efd_init(
+ struct xfs_mount *mp,
+ struct xfs_efi_log_item *efip,
+ uint nextents)
{
- xfs_efd_log_item_t *efdp;
+ struct xfs_efd_log_item *efdp;
uint size;
ASSERT(nextents > 0);
if (nextents > XFS_EFD_MAX_FAST_EXTENTS) {
size = (uint)(sizeof(xfs_efd_log_item_t) +
((nextents - 1) * sizeof(xfs_extent_t)));
- efdp = (xfs_efd_log_item_t*)kmem_zalloc(size, KM_SLEEP);
+ efdp = kmem_zalloc(size, KM_SLEEP);
} else {
- efdp = (xfs_efd_log_item_t*)kmem_zone_zalloc(xfs_efd_zone,
- KM_SLEEP);
+ efdp = kmem_zone_zalloc(xfs_efd_zone, KM_SLEEP);
}
xfs_log_item_init(mp, &efdp->efd_item, XFS_LI_EFD, &xfs_efd_item_ops);
@@ -556,5 +510,5 @@ xfs_efd_init(xfs_mount_t *mp,
efdp->efd_format.efd_nextents = nextents;
efdp->efd_format.efd_efi_id = efip->efi_format.efi_id;
- return (efdp);
+ return efdp;
}
diff --git a/fs/xfs/xfs_filestream.c b/fs/xfs/xfs_filestream.c
index 390850ee6603..d34b9e8d2d37 100644
--- a/fs/xfs/xfs_filestream.c
+++ b/fs/xfs/xfs_filestream.c
@@ -18,13 +18,9 @@
#include "xfs.h"
#include "xfs_bmap_btree.h"
#include "xfs_inum.h"
-#include "xfs_dir2.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_log.h"
#include "xfs_trans.h"
#include "xfs_sb.h"
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 37a6f62c57b6..dbca5f5c37ba 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -24,14 +24,10 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
@@ -626,8 +622,7 @@ xfs_fs_log_dummy(
ip = mp->m_rootip;
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0);
diff --git a/fs/xfs/xfs_ialloc.c b/fs/xfs/xfs_ialloc.c
index c7142a064c48..abf80ae1e95b 100644
--- a/fs/xfs/xfs_ialloc.c
+++ b/fs/xfs/xfs_ialloc.c
@@ -24,14 +24,10 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index c282a9af5393..d352862cefa0 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -24,14 +24,10 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 8f8b91be2c99..9e86f2116aa8 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -25,14 +25,10 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
@@ -212,7 +208,7 @@ xfs_iget_cache_hit(
ip->i_flags &= ~XFS_INEW;
ip->i_flags |= XFS_IRECLAIMABLE;
__xfs_inode_set_reclaim_tag(pag, ip);
- trace_xfs_iget_reclaim(ip);
+ trace_xfs_iget_reclaim_fail(ip);
goto out_error;
}
@@ -227,6 +223,7 @@ xfs_iget_cache_hit(
} else {
/* If the VFS inode is being torn down, pause and try again. */
if (!igrab(inode)) {
+ trace_xfs_iget_skip(ip);
error = EAGAIN;
goto out_error;
}
@@ -234,6 +231,7 @@ xfs_iget_cache_hit(
/* We've got a live one. */
spin_unlock(&ip->i_flags_lock);
read_unlock(&pag->pag_ici_lock);
+ trace_xfs_iget_hit(ip);
}
if (lock_flags != 0)
@@ -242,7 +240,6 @@ xfs_iget_cache_hit(
xfs_iflags_clear(ip, XFS_ISTALE);
XFS_STATS_INC(xs_ig_found);
- trace_xfs_iget_found(ip);
return 0;
out_error:
@@ -275,7 +272,7 @@ xfs_iget_cache_miss(
if (error)
goto out_destroy;
- xfs_itrace_entry(ip);
+ trace_xfs_iget_miss(ip);
if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
error = ENOENT;
@@ -321,7 +318,6 @@ xfs_iget_cache_miss(
write_unlock(&pag->pag_ici_lock);
radix_tree_preload_end();
- trace_xfs_iget_alloc(ip);
*ipp = ip;
return 0;
@@ -422,46 +418,6 @@ out_error_or_again:
}
/*
- * Decrement reference count of an inode structure and unlock it.
- *
- * ip -- the inode being released
- * lock_flags -- this parameter indicates the inode's locks to be
- * to be released. See the comment on xfs_iunlock() for a list
- * of valid values.
- */
-void
-xfs_iput(xfs_inode_t *ip,
- uint lock_flags)
-{
- xfs_itrace_entry(ip);
- xfs_iunlock(ip, lock_flags);
- IRELE(ip);
-}
-
-/*
- * Special iput for brand-new inodes that are still locked
- */
-void
-xfs_iput_new(
- xfs_inode_t *ip,
- uint lock_flags)
-{
- struct inode *inode = VFS_I(ip);
-
- xfs_itrace_entry(ip);
-
- if ((ip->i_d.di_mode == 0)) {
- ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
- make_bad_inode(inode);
- }
- if (inode->i_state & I_NEW)
- unlock_new_inode(inode);
- if (lock_flags)
- xfs_iunlock(ip, lock_flags);
- IRELE(ip);
-}
-
-/*
* This is called free all the memory associated with an inode.
* It must free the inode itself and any buffers allocated for
* if_extents/if_data and if_broot. It must also free the lock
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index b76a829d7e20..5715a9d8bcd6 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -27,13 +27,10 @@
#include "xfs_trans_priv.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
@@ -44,7 +41,6 @@
#include "xfs_alloc.h"
#include "xfs_ialloc.h"
#include "xfs_bmap.h"
-#include "xfs_rw.h"
#include "xfs_error.h"
#include "xfs_utils.h"
#include "xfs_quota.h"
@@ -1226,7 +1222,7 @@ xfs_isize_check(
(xfs_ufsize_t)XFS_MAXIOFFSET(mp)) -
map_first),
XFS_BMAPI_ENTIRE, NULL, 0, imaps, &nimaps,
- NULL, NULL))
+ NULL))
return;
ASSERT(nimaps == 1);
ASSERT(imaps[0].br_startblock == HOLESTARTBLOCK);
@@ -1460,7 +1456,7 @@ xfs_itruncate_finish(
ASSERT((*tp)->t_flags & XFS_TRANS_PERM_LOG_RES);
ASSERT(ip->i_transp == *tp);
ASSERT(ip->i_itemp != NULL);
- ASSERT(ip->i_itemp->ili_flags & XFS_ILI_HOLD);
+ ASSERT(ip->i_itemp->ili_lock_flags == 0);
ntp = *tp;
@@ -1589,11 +1585,10 @@ xfs_itruncate_finish(
xfs_bmap_init(&free_list, &first_block);
error = xfs_bunmapi(ntp, ip,
first_unmap_block, unmap_len,
- xfs_bmapi_aflag(fork) |
- (sync ? 0 : XFS_BMAPI_ASYNC),
+ xfs_bmapi_aflag(fork),
XFS_ITRUNC_MAX_EXTENTS,
&first_block, &free_list,
- NULL, &done);
+ &done);
if (error) {
/*
* If the bunmapi call encounters an error,
@@ -1612,12 +1607,8 @@ xfs_itruncate_finish(
*/
error = xfs_bmap_finish(tp, &free_list, &committed);
ntp = *tp;
- if (committed) {
- /* link the inode into the next xact in the chain */
- xfs_trans_ijoin(ntp, ip,
- XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(ntp, ip);
- }
+ if (committed)
+ xfs_trans_ijoin(ntp, ip);
if (error) {
/*
@@ -1646,9 +1637,7 @@ xfs_itruncate_finish(
error = xfs_trans_commit(*tp, 0);
*tp = ntp;
- /* link the inode into the next transaction in the chain */
- xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(ntp, ip);
+ xfs_trans_ijoin(ntp, ip);
if (error)
return error;
@@ -1985,7 +1974,7 @@ xfs_ifree_cluster(
if (lip->li_type == XFS_LI_INODE) {
iip = (xfs_inode_log_item_t *)lip;
ASSERT(iip->ili_logged == 1);
- lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done;
+ lip->li_cb = xfs_istale_done;
xfs_trans_ail_copy_lsn(mp->m_ail,
&iip->ili_flush_lsn,
&iip->ili_item.li_lsn);
@@ -2055,9 +2044,8 @@ xfs_ifree_cluster(
xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn,
&iip->ili_item.li_lsn);
- xfs_buf_attach_iodone(bp,
- (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_istale_done, (xfs_log_item_t *)iip);
+ xfs_buf_attach_iodone(bp, xfs_istale_done,
+ &iip->ili_item);
if (ip != free_ip)
xfs_iunlock(ip, XFS_ILOCK_EXCL);
@@ -3069,8 +3057,7 @@ xfs_iflush_int(
* and unlock the inode's flush lock when the inode is
* completely written to disk.
*/
- xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_iflush_done, (xfs_log_item_t *)iip);
+ xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item);
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
ASSERT(XFS_BUF_IODONE_FUNC(bp) != NULL);
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 78550df13cd6..eb41559ea8cd 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -443,8 +443,6 @@ static inline void xfs_ifunlock(xfs_inode_t *ip)
*/
int xfs_iget(struct xfs_mount *, struct xfs_trans *, xfs_ino_t,
uint, uint, xfs_inode_t **);
-void xfs_iput(xfs_inode_t *, uint);
-void xfs_iput_new(xfs_inode_t *, uint);
void xfs_ilock(xfs_inode_t *, uint);
int xfs_ilock_nowait(xfs_inode_t *, uint);
void xfs_iunlock(xfs_inode_t *, uint);
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index cf8249a60004..065c1ad9b708 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -22,30 +22,26 @@
#include "xfs_log.h"
#include "xfs_inum.h"
#include "xfs_trans.h"
-#include "xfs_buf_item.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
-#include "xfs_rw.h"
#include "xfs_error.h"
#include "xfs_trace.h"
kmem_zone_t *xfs_ili_zone; /* inode log item zone */
+static inline struct xfs_inode_log_item *INODE_ITEM(struct xfs_log_item *lip)
+{
+ return container_of(lip, struct xfs_inode_log_item, ili_item);
+}
+
+
/*
* This returns the number of iovecs needed to log the given inode item.
*
@@ -55,13 +51,11 @@ kmem_zone_t *xfs_ili_zone; /* inode log item zone */
*/
STATIC uint
xfs_inode_item_size(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- uint nvecs;
- xfs_inode_t *ip;
-
- ip = iip->ili_inode;
- nvecs = 2;
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
+ uint nvecs = 2;
/*
* Only log the data/extents/b-tree root if there is something
@@ -212,21 +206,18 @@ xfs_inode_item_size(
*/
STATIC void
xfs_inode_item_format(
- xfs_inode_log_item_t *iip,
- xfs_log_iovec_t *log_vector)
+ struct xfs_log_item *lip,
+ struct xfs_log_iovec *vecp)
{
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
uint nvecs;
- xfs_log_iovec_t *vecp;
- xfs_inode_t *ip;
size_t data_bytes;
xfs_bmbt_rec_t *ext_buffer;
int nrecs;
xfs_mount_t *mp;
- ip = iip->ili_inode;
- vecp = log_vector;
-
- vecp->i_addr = (xfs_caddr_t)&iip->ili_format;
+ vecp->i_addr = &iip->ili_format;
vecp->i_len = sizeof(xfs_inode_log_format_t);
vecp->i_type = XLOG_REG_TYPE_IFORMAT;
vecp++;
@@ -277,7 +268,7 @@ xfs_inode_item_format(
*/
xfs_synchronize_times(ip);
- vecp->i_addr = (xfs_caddr_t)&ip->i_d;
+ vecp->i_addr = &ip->i_d;
vecp->i_len = sizeof(struct xfs_icdinode);
vecp->i_type = XLOG_REG_TYPE_ICORE;
vecp++;
@@ -333,8 +324,7 @@ xfs_inode_item_format(
* extents, so just point to the
* real extents array.
*/
- vecp->i_addr =
- (char *)(ip->i_df.if_u1.if_extents);
+ vecp->i_addr = ip->i_df.if_u1.if_extents;
vecp->i_len = ip->i_df.if_bytes;
vecp->i_type = XLOG_REG_TYPE_IEXT;
} else
@@ -352,7 +342,7 @@ xfs_inode_item_format(
ext_buffer = kmem_alloc(ip->i_df.if_bytes,
KM_SLEEP);
iip->ili_extents_buf = ext_buffer;
- vecp->i_addr = (xfs_caddr_t)ext_buffer;
+ vecp->i_addr = ext_buffer;
vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
XFS_DATA_FORK);
vecp->i_type = XLOG_REG_TYPE_IEXT;
@@ -371,7 +361,7 @@ xfs_inode_item_format(
if (iip->ili_format.ilf_fields & XFS_ILOG_DBROOT) {
ASSERT(ip->i_df.if_broot_bytes > 0);
ASSERT(ip->i_df.if_broot != NULL);
- vecp->i_addr = (xfs_caddr_t)ip->i_df.if_broot;
+ vecp->i_addr = ip->i_df.if_broot;
vecp->i_len = ip->i_df.if_broot_bytes;
vecp->i_type = XLOG_REG_TYPE_IBROOT;
vecp++;
@@ -389,7 +379,7 @@ xfs_inode_item_format(
ASSERT(ip->i_df.if_u1.if_data != NULL);
ASSERT(ip->i_d.di_size > 0);
- vecp->i_addr = (xfs_caddr_t)ip->i_df.if_u1.if_data;
+ vecp->i_addr = ip->i_df.if_u1.if_data;
/*
* Round i_bytes up to a word boundary.
* The underlying memory is guaranteed to
@@ -437,7 +427,7 @@ xfs_inode_item_format(
* Assert that no attribute-related log flags are set.
*/
if (!XFS_IFORK_Q(ip)) {
- ASSERT(nvecs == iip->ili_item.li_desc->lid_size);
+ ASSERT(nvecs == lip->li_desc->lid_size);
iip->ili_format.ilf_size = nvecs;
ASSERT(!(iip->ili_format.ilf_fields &
(XFS_ILOG_ADATA | XFS_ILOG_ABROOT | XFS_ILOG_AEXT)));
@@ -463,7 +453,7 @@ xfs_inode_item_format(
* There are not delayed allocation extents
* for attributes, so just point at the array.
*/
- vecp->i_addr = (char *)(ip->i_afp->if_u1.if_extents);
+ vecp->i_addr = ip->i_afp->if_u1.if_extents;
vecp->i_len = ip->i_afp->if_bytes;
#else
ASSERT(iip->ili_aextents_buf == NULL);
@@ -473,7 +463,7 @@ xfs_inode_item_format(
ext_buffer = kmem_alloc(ip->i_afp->if_bytes,
KM_SLEEP);
iip->ili_aextents_buf = ext_buffer;
- vecp->i_addr = (xfs_caddr_t)ext_buffer;
+ vecp->i_addr = ext_buffer;
vecp->i_len = xfs_iextents_copy(ip, ext_buffer,
XFS_ATTR_FORK);
#endif
@@ -490,7 +480,7 @@ xfs_inode_item_format(
if (iip->ili_format.ilf_fields & XFS_ILOG_ABROOT) {
ASSERT(ip->i_afp->if_broot_bytes > 0);
ASSERT(ip->i_afp->if_broot != NULL);
- vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_broot;
+ vecp->i_addr = ip->i_afp->if_broot;
vecp->i_len = ip->i_afp->if_broot_bytes;
vecp->i_type = XLOG_REG_TYPE_IATTR_BROOT;
vecp++;
@@ -506,7 +496,7 @@ xfs_inode_item_format(
ASSERT(ip->i_afp->if_bytes > 0);
ASSERT(ip->i_afp->if_u1.if_data != NULL);
- vecp->i_addr = (xfs_caddr_t)ip->i_afp->if_u1.if_data;
+ vecp->i_addr = ip->i_afp->if_u1.if_data;
/*
* Round i_bytes up to a word boundary.
* The underlying memory is guaranteed to
@@ -528,7 +518,7 @@ xfs_inode_item_format(
break;
}
- ASSERT(nvecs == iip->ili_item.li_desc->lid_size);
+ ASSERT(nvecs == lip->li_desc->lid_size);
iip->ili_format.ilf_size = nvecs;
}
@@ -539,12 +529,14 @@ xfs_inode_item_format(
*/
STATIC void
xfs_inode_item_pin(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL));
+ struct xfs_inode *ip = INODE_ITEM(lip)->ili_inode;
- trace_xfs_inode_pin(iip->ili_inode, _RET_IP_);
- atomic_inc(&iip->ili_inode->i_pincount);
+ ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+ trace_xfs_inode_pin(ip, _RET_IP_);
+ atomic_inc(&ip->i_pincount);
}
@@ -554,12 +546,12 @@ xfs_inode_item_pin(
*
* Also wake up anyone in xfs_iunpin_wait() if the count goes to 0.
*/
-/* ARGSUSED */
STATIC void
xfs_inode_item_unpin(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip,
+ int remove)
{
- struct xfs_inode *ip = iip->ili_inode;
+ struct xfs_inode *ip = INODE_ITEM(lip)->ili_inode;
trace_xfs_inode_unpin(ip, _RET_IP_);
ASSERT(atomic_read(&ip->i_pincount) > 0);
@@ -567,15 +559,6 @@ xfs_inode_item_unpin(
wake_up(&ip->i_ipin_wait);
}
-/* ARGSUSED */
-STATIC void
-xfs_inode_item_unpin_remove(
- xfs_inode_log_item_t *iip,
- xfs_trans_t *tp)
-{
- xfs_inode_item_unpin(iip);
-}
-
/*
* This is called to attempt to lock the inode associated with this
* inode log item, in preparation for the push routine which does the actual
@@ -591,19 +574,16 @@ xfs_inode_item_unpin_remove(
*/
STATIC uint
xfs_inode_item_trylock(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- register xfs_inode_t *ip;
-
- ip = iip->ili_inode;
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
- if (xfs_ipincount(ip) > 0) {
+ if (xfs_ipincount(ip) > 0)
return XFS_ITEM_PINNED;
- }
- if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) {
+ if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED))
return XFS_ITEM_LOCKED;
- }
if (!xfs_iflock_nowait(ip)) {
/*
@@ -629,7 +609,7 @@ xfs_inode_item_trylock(
if (!XFS_FORCED_SHUTDOWN(ip->i_mount)) {
ASSERT(iip->ili_format.ilf_fields != 0);
ASSERT(iip->ili_logged == 0);
- ASSERT(iip->ili_item.li_flags & XFS_LI_IN_AIL);
+ ASSERT(lip->li_flags & XFS_LI_IN_AIL);
}
#endif
return XFS_ITEM_SUCCESS;
@@ -643,26 +623,18 @@ xfs_inode_item_trylock(
*/
STATIC void
xfs_inode_item_unlock(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- uint hold;
- uint iolocked;
- uint lock_flags;
- xfs_inode_t *ip;
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
+ unsigned short lock_flags;
- ASSERT(iip != NULL);
ASSERT(iip->ili_inode->i_itemp != NULL);
ASSERT(xfs_isilocked(iip->ili_inode, XFS_ILOCK_EXCL));
- ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
- XFS_ILI_IOLOCKED_EXCL)) ||
- xfs_isilocked(iip->ili_inode, XFS_IOLOCK_EXCL));
- ASSERT((!(iip->ili_inode->i_itemp->ili_flags &
- XFS_ILI_IOLOCKED_SHARED)) ||
- xfs_isilocked(iip->ili_inode, XFS_IOLOCK_SHARED));
+
/*
* Clear the transaction pointer in the inode.
*/
- ip = iip->ili_inode;
ip->i_transp = NULL;
/*
@@ -686,34 +658,11 @@ xfs_inode_item_unlock(
iip->ili_aextents_buf = NULL;
}
- /*
- * Figure out if we should unlock the inode or not.
- */
- hold = iip->ili_flags & XFS_ILI_HOLD;
-
- /*
- * Before clearing out the flags, remember whether we
- * are holding the inode's IO lock.
- */
- iolocked = iip->ili_flags & XFS_ILI_IOLOCKED_ANY;
-
- /*
- * Clear out the fields of the inode log item particular
- * to the current transaction.
- */
- iip->ili_flags = 0;
-
- /*
- * Unlock the inode if XFS_ILI_HOLD was not set.
- */
- if (!hold) {
- lock_flags = XFS_ILOCK_EXCL;
- if (iolocked & XFS_ILI_IOLOCKED_EXCL) {
- lock_flags |= XFS_IOLOCK_EXCL;
- } else if (iolocked & XFS_ILI_IOLOCKED_SHARED) {
- lock_flags |= XFS_IOLOCK_SHARED;
- }
- xfs_iput(iip->ili_inode, lock_flags);
+ lock_flags = iip->ili_lock_flags;
+ iip->ili_lock_flags = 0;
+ if (lock_flags) {
+ xfs_iunlock(iip->ili_inode, lock_flags);
+ IRELE(iip->ili_inode);
}
}
@@ -725,13 +674,12 @@ xfs_inode_item_unlock(
* is the only one that matters. Therefore, simply return the
* given lsn.
*/
-/*ARGSUSED*/
STATIC xfs_lsn_t
xfs_inode_item_committed(
- xfs_inode_log_item_t *iip,
+ struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
- return (lsn);
+ return lsn;
}
/*
@@ -743,13 +691,12 @@ xfs_inode_item_committed(
*/
STATIC void
xfs_inode_item_pushbuf(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- xfs_inode_t *ip;
- xfs_mount_t *mp;
- xfs_buf_t *bp;
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
+ struct xfs_buf *bp;
- ip = iip->ili_inode;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
/*
@@ -757,14 +704,13 @@ xfs_inode_item_pushbuf(
* inode was taken off the AIL. So, just get out.
*/
if (completion_done(&ip->i_flush) ||
- ((iip->ili_item.li_flags & XFS_LI_IN_AIL) == 0)) {
+ !(lip->li_flags & XFS_LI_IN_AIL)) {
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return;
}
- mp = ip->i_mount;
- bp = xfs_incore(mp->m_ddev_targp, iip->ili_format.ilf_blkno,
- iip->ili_format.ilf_len, XBF_TRYLOCK);
+ bp = xfs_incore(ip->i_mount->m_ddev_targp, iip->ili_format.ilf_blkno,
+ iip->ili_format.ilf_len, XBF_TRYLOCK);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (!bp)
@@ -772,10 +718,8 @@ xfs_inode_item_pushbuf(
if (XFS_BUF_ISDELAYWRITE(bp))
xfs_buf_delwri_promote(bp);
xfs_buf_relse(bp);
- return;
}
-
/*
* This is called to asynchronously write the inode associated with this
* inode log item out to disk. The inode will already have been locked by
@@ -783,14 +727,14 @@ xfs_inode_item_pushbuf(
*/
STATIC void
xfs_inode_item_push(
- xfs_inode_log_item_t *iip)
+ struct xfs_log_item *lip)
{
- xfs_inode_t *ip;
-
- ip = iip->ili_inode;
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
+ struct xfs_inode *ip = iip->ili_inode;
ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED));
ASSERT(!completion_done(&ip->i_flush));
+
/*
* Since we were able to lock the inode's flush lock and
* we found it on the AIL, the inode must be dirty. This
@@ -813,43 +757,34 @@ xfs_inode_item_push(
*/
(void) xfs_iflush(ip, 0);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
-
- return;
}
/*
* XXX rcc - this one really has to do something. Probably needs
* to stamp in a new field in the incore inode.
*/
-/* ARGSUSED */
STATIC void
xfs_inode_item_committing(
- xfs_inode_log_item_t *iip,
+ struct xfs_log_item *lip,
xfs_lsn_t lsn)
{
- iip->ili_last_lsn = lsn;
- return;
+ INODE_ITEM(lip)->ili_last_lsn = lsn;
}
/*
* This is the ops vector shared by all buf log items.
*/
static struct xfs_item_ops xfs_inode_item_ops = {
- .iop_size = (uint(*)(xfs_log_item_t*))xfs_inode_item_size,
- .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
- xfs_inode_item_format,
- .iop_pin = (void(*)(xfs_log_item_t*))xfs_inode_item_pin,
- .iop_unpin = (void(*)(xfs_log_item_t*))xfs_inode_item_unpin,
- .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
- xfs_inode_item_unpin_remove,
- .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_inode_item_trylock,
- .iop_unlock = (void(*)(xfs_log_item_t*))xfs_inode_item_unlock,
- .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_inode_item_committed,
- .iop_push = (void(*)(xfs_log_item_t*))xfs_inode_item_push,
- .iop_pushbuf = (void(*)(xfs_log_item_t*))xfs_inode_item_pushbuf,
- .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
- xfs_inode_item_committing
+ .iop_size = xfs_inode_item_size,
+ .iop_format = xfs_inode_item_format,
+ .iop_pin = xfs_inode_item_pin,
+ .iop_unpin = xfs_inode_item_unpin,
+ .iop_trylock = xfs_inode_item_trylock,
+ .iop_unlock = xfs_inode_item_unlock,
+ .iop_committed = xfs_inode_item_committed,
+ .iop_push = xfs_inode_item_push,
+ .iop_pushbuf = xfs_inode_item_pushbuf,
+ .iop_committing = xfs_inode_item_committing
};
@@ -858,10 +793,10 @@ static struct xfs_item_ops xfs_inode_item_ops = {
*/
void
xfs_inode_item_init(
- xfs_inode_t *ip,
- xfs_mount_t *mp)
+ struct xfs_inode *ip,
+ struct xfs_mount *mp)
{
- xfs_inode_log_item_t *iip;
+ struct xfs_inode_log_item *iip;
ASSERT(ip->i_itemp == NULL);
iip = ip->i_itemp = kmem_zone_zalloc(xfs_ili_zone, KM_SLEEP);
@@ -899,14 +834,14 @@ xfs_inode_item_destroy(
* from the AIL if it has not been re-logged, and unlocking the inode's
* flush lock.
*/
-/*ARGSUSED*/
void
xfs_iflush_done(
- xfs_buf_t *bp,
- xfs_inode_log_item_t *iip)
+ struct xfs_buf *bp,
+ struct xfs_log_item *lip)
{
+ struct xfs_inode_log_item *iip = INODE_ITEM(lip);
xfs_inode_t *ip = iip->ili_inode;
- struct xfs_ail *ailp = iip->ili_item.li_ailp;
+ struct xfs_ail *ailp = lip->li_ailp;
/*
* We only want to pull the item from the AIL if it is
@@ -917,12 +852,11 @@ xfs_iflush_done(
* the lock since it's cheaper, and then we recheck while
* holding the lock before removing the inode from the AIL.
*/
- if (iip->ili_logged &&
- (iip->ili_item.li_lsn == iip->ili_flush_lsn)) {
+ if (iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) {
spin_lock(&ailp->xa_lock);
- if (iip->ili_item.li_lsn == iip->ili_flush_lsn) {
+ if (lip->li_lsn == iip->ili_flush_lsn) {
/* xfs_trans_ail_delete() drops the AIL lock. */
- xfs_trans_ail_delete(ailp, (xfs_log_item_t*)iip);
+ xfs_trans_ail_delete(ailp, lip);
} else {
spin_unlock(&ailp->xa_lock);
}
@@ -940,8 +874,6 @@ xfs_iflush_done(
* Release the inode's flush lock since we're done with it.
*/
xfs_ifunlock(ip);
-
- return;
}
/*
@@ -991,10 +923,10 @@ xfs_iflush_abort(
void
xfs_istale_done(
- xfs_buf_t *bp,
- xfs_inode_log_item_t *iip)
+ struct xfs_buf *bp,
+ struct xfs_log_item *lip)
{
- xfs_iflush_abort(iip->ili_inode);
+ xfs_iflush_abort(INODE_ITEM(lip)->ili_inode);
}
/*
@@ -1007,9 +939,8 @@ xfs_inode_item_format_convert(
xfs_inode_log_format_t *in_f)
{
if (buf->i_len == sizeof(xfs_inode_log_format_32_t)) {
- xfs_inode_log_format_32_t *in_f32;
+ xfs_inode_log_format_32_t *in_f32 = buf->i_addr;
- in_f32 = (xfs_inode_log_format_32_t *)buf->i_addr;
in_f->ilf_type = in_f32->ilf_type;
in_f->ilf_size = in_f32->ilf_size;
in_f->ilf_fields = in_f32->ilf_fields;
@@ -1025,9 +956,8 @@ xfs_inode_item_format_convert(
in_f->ilf_boffset = in_f32->ilf_boffset;
return 0;
} else if (buf->i_len == sizeof(xfs_inode_log_format_64_t)){
- xfs_inode_log_format_64_t *in_f64;
+ xfs_inode_log_format_64_t *in_f64 = buf->i_addr;
- in_f64 = (xfs_inode_log_format_64_t *)buf->i_addr;
in_f->ilf_type = in_f64->ilf_type;
in_f->ilf_size = in_f64->ilf_size;
in_f->ilf_fields = in_f64->ilf_fields;
diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h
index 9a467958ecdd..d3dee61e6d91 100644
--- a/fs/xfs/xfs_inode_item.h
+++ b/fs/xfs/xfs_inode_item.h
@@ -103,12 +103,6 @@ typedef struct xfs_inode_log_format_64 {
XFS_ILOG_ADATA | XFS_ILOG_AEXT | \
XFS_ILOG_ABROOT)
-#define XFS_ILI_HOLD 0x1
-#define XFS_ILI_IOLOCKED_EXCL 0x2
-#define XFS_ILI_IOLOCKED_SHARED 0x4
-
-#define XFS_ILI_IOLOCKED_ANY (XFS_ILI_IOLOCKED_EXCL | XFS_ILI_IOLOCKED_SHARED)
-
static inline int xfs_ilog_fbroot(int w)
{
return (w == XFS_DATA_FORK ? XFS_ILOG_DBROOT : XFS_ILOG_ABROOT);
@@ -137,7 +131,7 @@ typedef struct xfs_inode_log_item {
struct xfs_inode *ili_inode; /* inode ptr */
xfs_lsn_t ili_flush_lsn; /* lsn at last flush */
xfs_lsn_t ili_last_lsn; /* lsn at last transaction */
- unsigned short ili_flags; /* misc flags */
+ unsigned short ili_lock_flags; /* lock flags */
unsigned short ili_logged; /* flushed logged data */
unsigned int ili_last_fields; /* fields when flushed */
struct xfs_bmbt_rec *ili_extents_buf; /* array of logged
@@ -161,8 +155,8 @@ static inline int xfs_inode_clean(xfs_inode_t *ip)
extern void xfs_inode_item_init(struct xfs_inode *, struct xfs_mount *);
extern void xfs_inode_item_destroy(struct xfs_inode *);
-extern void xfs_iflush_done(struct xfs_buf *, xfs_inode_log_item_t *);
-extern void xfs_istale_done(struct xfs_buf *, xfs_inode_log_item_t *);
+extern void xfs_iflush_done(struct xfs_buf *, struct xfs_log_item *);
+extern void xfs_istale_done(struct xfs_buf *, struct xfs_log_item *);
extern void xfs_iflush_abort(struct xfs_inode *);
extern int xfs_inode_item_format_convert(xfs_log_iovec_t *,
xfs_inode_log_format_t *);
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index ef14943829da..20576146369f 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -23,19 +23,14 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
#include "xfs_alloc.h"
-#include "xfs_dmapi.h"
#include "xfs_quota.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_ialloc.h"
#include "xfs_btree.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
@@ -123,7 +118,7 @@ xfs_iomap(
error = xfs_bmapi(NULL, ip, offset_fsb,
(xfs_filblks_t)(end_fsb - offset_fsb),
bmapi_flags, NULL, 0, imap,
- nimaps, NULL, NULL);
+ nimaps, NULL);
if (error)
goto out;
@@ -138,7 +133,7 @@ xfs_iomap(
break;
}
- if (flags & (BMAPI_DIRECT|BMAPI_MMAP)) {
+ if (flags & BMAPI_DIRECT) {
error = xfs_iomap_write_direct(ip, offset, count, flags,
imap, nimaps);
} else {
@@ -247,7 +242,7 @@ xfs_iomap_write_direct(
xfs_off_t offset,
size_t count,
int flags,
- xfs_bmbt_irec_t *ret_imap,
+ xfs_bmbt_irec_t *imap,
int *nmaps)
{
xfs_mount_t *mp = ip->i_mount;
@@ -261,7 +256,6 @@ xfs_iomap_write_direct(
int quota_flag;
int rt;
xfs_trans_t *tp;
- xfs_bmbt_irec_t imap;
xfs_bmap_free_t free_list;
uint qblocks, resblks, resrtextents;
int committed;
@@ -285,10 +279,10 @@ xfs_iomap_write_direct(
if (error)
goto error_out;
} else {
- if (*nmaps && (ret_imap->br_startblock == HOLESTARTBLOCK))
+ if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK))
last_fsb = MIN(last_fsb, (xfs_fileoff_t)
- ret_imap->br_blockcount +
- ret_imap->br_startoff);
+ imap->br_blockcount +
+ imap->br_startoff);
}
count_fsb = last_fsb - offset_fsb;
ASSERT(count_fsb > 0);
@@ -334,20 +328,22 @@ xfs_iomap_write_direct(
if (error)
goto error1;
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
bmapi_flag = XFS_BMAPI_WRITE;
if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz))
bmapi_flag |= XFS_BMAPI_PREALLOC;
/*
- * Issue the xfs_bmapi() call to allocate the blocks
+ * Issue the xfs_bmapi() call to allocate the blocks.
+ *
+ * From this point onwards we overwrite the imap pointer that the
+ * caller gave to us.
*/
xfs_bmap_init(&free_list, &firstfsb);
nimaps = 1;
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb, bmapi_flag,
- &firstfsb, 0, &imap, &nimaps, &free_list, NULL);
+ &firstfsb, 0, imap, &nimaps, &free_list);
if (error)
goto error0;
@@ -369,12 +365,11 @@ xfs_iomap_write_direct(
goto error_out;
}
- if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip))) {
- error = xfs_cmn_err_fsblock_zero(ip, &imap);
+ if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip))) {
+ error = xfs_cmn_err_fsblock_zero(ip, imap);
goto error_out;
}
- *ret_imap = imap;
*nmaps = 1;
return 0;
@@ -425,7 +420,7 @@ xfs_iomap_eof_want_preallocate(
imaps = nimaps;
firstblock = NULLFSBLOCK;
error = xfs_bmapi(NULL, ip, start_fsb, count_fsb, 0,
- &firstblock, 0, imap, &imaps, NULL, NULL);
+ &firstblock, 0, imap, &imaps, NULL);
if (error)
return error;
for (n = 0; n < imaps; n++) {
@@ -500,7 +495,7 @@ retry:
(xfs_filblks_t)(last_fsb - offset_fsb),
XFS_BMAPI_DELAY | XFS_BMAPI_WRITE |
XFS_BMAPI_ENTIRE, &firstblock, 1, imap,
- &nimaps, NULL, NULL);
+ &nimaps, NULL);
if (error && (error != ENOSPC))
return XFS_ERROR(error);
@@ -548,7 +543,7 @@ xfs_iomap_write_allocate(
xfs_inode_t *ip,
xfs_off_t offset,
size_t count,
- xfs_bmbt_irec_t *map,
+ xfs_bmbt_irec_t *imap,
int *retmap)
{
xfs_mount_t *mp = ip->i_mount;
@@ -557,7 +552,6 @@ xfs_iomap_write_allocate(
xfs_fsblock_t first_block;
xfs_bmap_free_t free_list;
xfs_filblks_t count_fsb;
- xfs_bmbt_irec_t imap;
xfs_trans_t *tp;
int nimaps, committed;
int error = 0;
@@ -573,8 +567,8 @@ xfs_iomap_write_allocate(
return XFS_ERROR(error);
offset_fsb = XFS_B_TO_FSBT(mp, offset);
- count_fsb = map->br_blockcount;
- map_start_fsb = map->br_startoff;
+ count_fsb = imap->br_blockcount;
+ map_start_fsb = imap->br_startoff;
XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb));
@@ -602,8 +596,7 @@ xfs_iomap_write_allocate(
return XFS_ERROR(error);
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_bmap_init(&free_list, &first_block);
@@ -654,10 +647,15 @@ xfs_iomap_write_allocate(
}
}
- /* Go get the actual blocks */
+ /*
+ * Go get the actual blocks.
+ *
+ * From this point onwards we overwrite the imap
+ * pointer that the caller gave to us.
+ */
error = xfs_bmapi(tp, ip, map_start_fsb, count_fsb,
XFS_BMAPI_WRITE, &first_block, 1,
- &imap, &nimaps, &free_list, NULL);
+ imap, &nimaps, &free_list);
if (error)
goto trans_cancel;
@@ -676,13 +674,12 @@ xfs_iomap_write_allocate(
* See if we were able to allocate an extent that
* covers at least part of the callers request
*/
- if (!(imap.br_startblock || XFS_IS_REALTIME_INODE(ip)))
- return xfs_cmn_err_fsblock_zero(ip, &imap);
+ if (!(imap->br_startblock || XFS_IS_REALTIME_INODE(ip)))
+ return xfs_cmn_err_fsblock_zero(ip, imap);
- if ((offset_fsb >= imap.br_startoff) &&
- (offset_fsb < (imap.br_startoff +
- imap.br_blockcount))) {
- *map = imap;
+ if ((offset_fsb >= imap->br_startoff) &&
+ (offset_fsb < (imap->br_startoff +
+ imap->br_blockcount))) {
*retmap = 1;
XFS_STATS_INC(xs_xstrat_quick);
return 0;
@@ -692,8 +689,8 @@ xfs_iomap_write_allocate(
* So far we have not mapped the requested part of the
* file, just surrounding data, try again.
*/
- count_fsb -= imap.br_blockcount;
- map_start_fsb = imap.br_startoff + imap.br_blockcount;
+ count_fsb -= imap->br_blockcount;
+ map_start_fsb = imap->br_startoff + imap->br_blockcount;
}
trans_cancel:
@@ -766,8 +763,7 @@ xfs_iomap_write_unwritten(
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* Modify the unwritten extent state of the buffer.
@@ -776,7 +772,7 @@ xfs_iomap_write_unwritten(
nimaps = 1;
error = xfs_bmapi(tp, ip, offset_fsb, count_fsb,
XFS_BMAPI_WRITE|XFS_BMAPI_CONVERT, &firstfsb,
- 1, &imap, &nimaps, &free_list, NULL);
+ 1, &imap, &nimaps, &free_list);
if (error)
goto error_on_bmapi_transaction;
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h
index 81ac4afd45b3..7748a430f50d 100644
--- a/fs/xfs/xfs_iomap.h
+++ b/fs/xfs/xfs_iomap.h
@@ -18,17 +18,16 @@
#ifndef __XFS_IOMAP_H__
#define __XFS_IOMAP_H__
-typedef enum {
- /* base extent manipulation calls */
- BMAPI_READ = (1 << 0), /* read extents */
- BMAPI_WRITE = (1 << 1), /* create extents */
- BMAPI_ALLOCATE = (1 << 2), /* delayed allocate to real extents */
- /* modifiers */
- BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */
- BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */
- BMAPI_MMAP = (1 << 6), /* allocate for mmap write */
- BMAPI_TRYLOCK = (1 << 7), /* non-blocking request */
-} bmapi_flags_t;
+/* base extent manipulation calls */
+#define BMAPI_READ (1 << 0) /* read extents */
+#define BMAPI_WRITE (1 << 1) /* create extents */
+#define BMAPI_ALLOCATE (1 << 2) /* delayed allocate to real extents */
+
+/* modifiers */
+#define BMAPI_IGNSTATE (1 << 4) /* ignore unwritten state on read */
+#define BMAPI_DIRECT (1 << 5) /* direct instead of buffered write */
+#define BMAPI_MMA (1 << 6) /* allocate for mmap write */
+#define BMAPI_TRYLOCK (1 << 7) /* non-blocking request */
#define BMAPI_FLAGS \
{ BMAPI_READ, "READ" }, \
@@ -36,7 +35,6 @@ typedef enum {
{ BMAPI_ALLOCATE, "ALLOCATE" }, \
{ BMAPI_IGNSTATE, "IGNSTATE" }, \
{ BMAPI_DIRECT, "DIRECT" }, \
- { BMAPI_MMAP, "MMAP" }, \
{ BMAPI_TRYLOCK, "TRYLOCK" }
struct xfs_inode;
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 2b86f8610512..7e3626e5925c 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -24,20 +24,17 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_ialloc.h"
#include "xfs_itable.h"
#include "xfs_error.h"
#include "xfs_btree.h"
+#include "xfs_trace.h"
STATIC int
xfs_internal_inum(
@@ -143,7 +140,8 @@ xfs_bulkstat_one_int(
buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks;
break;
}
- xfs_iput(ip, XFS_ILOCK_SHARED);
+ xfs_iunlock(ip, XFS_ILOCK_SHARED);
+ IRELE(ip);
error = formatter(buffer, ubsize, ubused, buf);
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 5215abc8023a..f309e1404fd6 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -24,8 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_log_priv.h"
@@ -35,8 +33,6 @@
#include "xfs_ialloc_btree.h"
#include "xfs_log_recover.h"
#include "xfs_trans_priv.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_rw.h"
@@ -337,7 +333,6 @@ xfs_log_reserve(
int retval = 0;
ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
- ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
if (XLOG_FORCED_SHUTDOWN(log))
return XFS_ERROR(EIO);
@@ -552,7 +547,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
.magic = XLOG_UNMOUNT_TYPE,
};
struct xfs_log_iovec reg = {
- .i_addr = (void *)&magic,
+ .i_addr = &magic,
.i_len = sizeof(magic),
.i_type = XLOG_REG_TYPE_UNMOUNT,
};
@@ -1428,11 +1423,8 @@ xlog_sync(xlog_t *log,
XFS_BUF_BUSY(bp);
XFS_BUF_ASYNC(bp);
bp->b_flags |= XBF_LOG_BUFFER;
- /*
- * Do an ordered write for the log block.
- * Its unnecessary to flush the first split block in the log wrap case.
- */
- if (!split && (log->l_mp->m_flags & XFS_MOUNT_BARRIER))
+
+ if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
XFS_BUF_ORDERED(bp);
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
diff --git a/fs/xfs/xfs_log.h b/fs/xfs/xfs_log.h
index 04c78e642cc8..916eb7db14d9 100644
--- a/fs/xfs/xfs_log.h
+++ b/fs/xfs/xfs_log.h
@@ -55,14 +55,10 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
/*
* Flags to xfs_log_reserve()
*
- * XFS_LOG_SLEEP: If space is not available, sleep (default)
- * XFS_LOG_NOSLEEP: If space is not available, return error
* XFS_LOG_PERM_RESERV: Permanent reservation. When writes are
* performed against this type of reservation, the reservation
* is not decreased. Long running transactions should use this.
*/
-#define XFS_LOG_SLEEP 0x0
-#define XFS_LOG_NOSLEEP 0x1
#define XFS_LOG_PERM_RESERV 0x2
/*
@@ -104,7 +100,7 @@ static inline xfs_lsn_t _lsn_cmp(xfs_lsn_t lsn1, xfs_lsn_t lsn2)
#define XLOG_REG_TYPE_MAX 19
typedef struct xfs_log_iovec {
- xfs_caddr_t i_addr; /* beginning address of region */
+ void *i_addr; /* beginning address of region */
int i_len; /* length in bytes of region */
uint i_type; /* type of region */
} xfs_log_iovec_t;
@@ -201,9 +197,4 @@ int xfs_log_commit_cil(struct xfs_mount *mp, struct xfs_trans *tp,
bool xfs_log_item_in_current_chkpt(struct xfs_log_item *lip);
#endif
-
-
-extern int xlog_debug; /* set to 1 to enable real log */
-
-
#endif /* __XFS_LOG_H__ */
diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
index bb17cc044bf3..31e4ea2d19ac 100644
--- a/fs/xfs/xfs_log_cil.c
+++ b/fs/xfs/xfs_log_cil.c
@@ -26,8 +26,6 @@
#include "xfs_log_priv.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_alloc.h"
@@ -554,7 +552,7 @@ xlog_cil_push(
thdr.th_type = XFS_TRANS_CHECKPOINT;
thdr.th_tid = tic->t_tid;
thdr.th_num_items = num_iovecs;
- lhdr.i_addr = (xfs_caddr_t)&thdr;
+ lhdr.i_addr = &thdr;
lhdr.i_len = sizeof(xfs_trans_header_t);
lhdr.i_type = XLOG_REG_TYPE_TRANSHDR;
tic->t_curr_res -= lhdr.i_len + sizeof(xlog_op_header_t);
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 9ac5cfab27b9..6f3f5fa37acf 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -24,15 +24,11 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
@@ -1565,9 +1561,7 @@ xlog_recover_reorder_trans(
list_splice_init(&trans->r_itemq, &sort_list);
list_for_each_entry_safe(item, n, &sort_list, ri_list) {
- xfs_buf_log_format_t *buf_f;
-
- buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
+ xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
switch (ITEM_TYPE(item)) {
case XFS_LI_BUF:
@@ -1892,9 +1886,8 @@ xlog_recover_do_inode_buffer(
* current di_next_unlinked field. Extract its value
* and copy it to the buffer copy.
*/
- logged_nextp = (xfs_agino_t *)
- ((char *)(item->ri_buf[item_index].i_addr) +
- (next_unlinked_offset - reg_buf_offset));
+ logged_nextp = item->ri_buf[item_index].i_addr +
+ next_unlinked_offset - reg_buf_offset;
if (unlikely(*logged_nextp == 0)) {
xfs_fs_cmn_err(CE_ALERT, mp,
"bad inode buffer log record (ptr = 0x%p, bp = 0x%p). XFS trying to replay bad (0) inode di_next_unlinked field",
@@ -1973,8 +1966,7 @@ xlog_recover_do_reg_buffer(
item->ri_buf[i].i_len, __func__);
goto next;
}
- error = xfs_qm_dqcheck((xfs_disk_dquot_t *)
- item->ri_buf[i].i_addr,
+ error = xfs_qm_dqcheck(item->ri_buf[i].i_addr,
-1, 0, XFS_QMOPT_DOWARN,
"dquot_buf_recover");
if (error)
@@ -2187,7 +2179,7 @@ xlog_recover_do_buffer_trans(
xlog_recover_item_t *item,
int pass)
{
- xfs_buf_log_format_t *buf_f;
+ xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr;
xfs_mount_t *mp;
xfs_buf_t *bp;
int error;
@@ -2197,8 +2189,6 @@ xlog_recover_do_buffer_trans(
ushort flags;
uint buf_flags;
- buf_f = (xfs_buf_log_format_t *)item->ri_buf[0].i_addr;
-
if (pass == XLOG_RECOVER_PASS1) {
/*
* In this pass we're only looking for buf items
@@ -2319,10 +2309,9 @@ xlog_recover_do_inode_trans(
}
if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) {
- in_f = (xfs_inode_log_format_t *)item->ri_buf[0].i_addr;
+ in_f = item->ri_buf[0].i_addr;
} else {
- in_f = (xfs_inode_log_format_t *)kmem_alloc(
- sizeof(xfs_inode_log_format_t), KM_SLEEP);
+ in_f = kmem_alloc(sizeof(xfs_inode_log_format_t), KM_SLEEP);
need_free = 1;
error = xfs_inode_item_format_convert(&item->ri_buf[0], in_f);
if (error)
@@ -2370,7 +2359,7 @@ xlog_recover_do_inode_trans(
error = EFSCORRUPTED;
goto error;
}
- dicp = (xfs_icdinode_t *)(item->ri_buf[1].i_addr);
+ dicp = item->ri_buf[1].i_addr;
if (unlikely(dicp->di_magic != XFS_DINODE_MAGIC)) {
xfs_buf_relse(bp);
xfs_fs_cmn_err(CE_ALERT, mp,
@@ -2461,7 +2450,7 @@ xlog_recover_do_inode_trans(
}
/* The core is in in-core format */
- xfs_dinode_to_disk(dip, (xfs_icdinode_t *)item->ri_buf[1].i_addr);
+ xfs_dinode_to_disk(dip, item->ri_buf[1].i_addr);
/* the rest is in on-disk format */
if (item->ri_buf[1].i_len > sizeof(struct xfs_icdinode)) {
@@ -2578,7 +2567,7 @@ xlog_recover_do_quotaoff_trans(
return (0);
}
- qoff_f = (xfs_qoff_logformat_t *)item->ri_buf[0].i_addr;
+ qoff_f = item->ri_buf[0].i_addr;
ASSERT(qoff_f);
/*
@@ -2622,9 +2611,8 @@ xlog_recover_do_dquot_trans(
if (mp->m_qflags == 0)
return (0);
- recddq = (xfs_disk_dquot_t *)item->ri_buf[1].i_addr;
-
- if (item->ri_buf[1].i_addr == NULL) {
+ recddq = item->ri_buf[1].i_addr;
+ if (recddq == NULL) {
cmn_err(CE_ALERT,
"XFS: NULL dquot in %s.", __func__);
return XFS_ERROR(EIO);
@@ -2654,7 +2642,7 @@ xlog_recover_do_dquot_trans(
* The other possibility, of course, is that the quota subsystem was
* removed since the last mount - ENOSYS.
*/
- dq_f = (xfs_dq_logformat_t *)item->ri_buf[0].i_addr;
+ dq_f = item->ri_buf[0].i_addr;
ASSERT(dq_f);
if ((error = xfs_qm_dqcheck(recddq,
dq_f->qlf_id,
@@ -2721,7 +2709,7 @@ xlog_recover_do_efi_trans(
return 0;
}
- efi_formatp = (xfs_efi_log_format_t *)item->ri_buf[0].i_addr;
+ efi_formatp = item->ri_buf[0].i_addr;
mp = log->l_mp;
efip = xfs_efi_init(mp, efi_formatp->efi_nextents);
@@ -2767,7 +2755,7 @@ xlog_recover_do_efd_trans(
return;
}
- efd_formatp = (xfs_efd_log_format_t *)item->ri_buf[0].i_addr;
+ efd_formatp = item->ri_buf[0].i_addr;
ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) +
((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) ||
(item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_64_t) +
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 69f62d8b2816..aeb9d72ebf6e 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -25,13 +25,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 1d2c7eed4eda..4491b510a75f 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -66,65 +66,6 @@ struct xfs_nameops;
struct xfs_ail;
struct xfs_quotainfo;
-
-/*
- * Prototypes and functions for the Data Migration subsystem.
- */
-
-typedef int (*xfs_send_data_t)(int, struct xfs_inode *,
- xfs_off_t, size_t, int, int *);
-typedef int (*xfs_send_mmap_t)(struct vm_area_struct *, uint);
-typedef int (*xfs_send_destroy_t)(struct xfs_inode *, dm_right_t);
-typedef int (*xfs_send_namesp_t)(dm_eventtype_t, struct xfs_mount *,
- struct xfs_inode *, dm_right_t,
- struct xfs_inode *, dm_right_t,
- const unsigned char *, const unsigned char *,
- mode_t, int, int);
-typedef int (*xfs_send_mount_t)(struct xfs_mount *, dm_right_t,
- char *, char *);
-typedef void (*xfs_send_unmount_t)(struct xfs_mount *, struct xfs_inode *,
- dm_right_t, mode_t, int, int);
-
-typedef struct xfs_dmops {
- xfs_send_data_t xfs_send_data;
- xfs_send_mmap_t xfs_send_mmap;
- xfs_send_destroy_t xfs_send_destroy;
- xfs_send_namesp_t xfs_send_namesp;
- xfs_send_mount_t xfs_send_mount;
- xfs_send_unmount_t xfs_send_unmount;
-} xfs_dmops_t;
-
-#define XFS_DMAPI_UNMOUNT_FLAGS(mp) \
- (((mp)->m_dmevmask & (1 << DM_EVENT_UNMOUNT)) ? 0 : DM_FLAGS_UNWANTED)
-
-#define XFS_SEND_DATA(mp, ev,ip,off,len,fl,lock) \
- (*(mp)->m_dm_ops->xfs_send_data)(ev,ip,off,len,fl,lock)
-#define XFS_SEND_MMAP(mp, vma,fl) \
- (*(mp)->m_dm_ops->xfs_send_mmap)(vma,fl)
-#define XFS_SEND_DESTROY(mp, ip,right) \
- (*(mp)->m_dm_ops->xfs_send_destroy)(ip,right)
-#define XFS_SEND_NAMESP(mp, ev,b1,r1,b2,r2,n1,n2,mode,rval,fl) \
- (*(mp)->m_dm_ops->xfs_send_namesp)(ev,NULL,b1,r1,b2,r2,n1,n2,mode,rval,fl)
-#define XFS_SEND_MOUNT(mp,right,path,name) \
- (*(mp)->m_dm_ops->xfs_send_mount)(mp,right,path,name)
-#define XFS_SEND_PREUNMOUNT(mp) \
-do { \
- if (mp->m_flags & XFS_MOUNT_DMAPI) { \
- (*(mp)->m_dm_ops->xfs_send_namesp)(DM_EVENT_PREUNMOUNT, mp, \
- (mp)->m_rootip, DM_RIGHT_NULL, \
- (mp)->m_rootip, DM_RIGHT_NULL, \
- NULL, NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \
- } \
-} while (0)
-#define XFS_SEND_UNMOUNT(mp) \
-do { \
- if (mp->m_flags & XFS_MOUNT_DMAPI) { \
- (*(mp)->m_dm_ops->xfs_send_unmount)(mp, (mp)->m_rootip, \
- DM_RIGHT_NULL, 0, 0, XFS_DMAPI_UNMOUNT_FLAGS(mp)); \
- } \
-} while (0)
-
-
#ifdef HAVE_PERCPU_SB
/*
@@ -241,8 +182,6 @@ typedef struct xfs_mount {
uint m_chsize; /* size of next field */
struct xfs_chash *m_chash; /* fs private inode per-cluster
* hash table */
- struct xfs_dmops *m_dm_ops; /* vector of DMI ops */
- struct xfs_qmops *m_qm_ops; /* vector of XQM ops */
atomic_t m_active_trans; /* number trans frozen */
#ifdef HAVE_PERCPU_SB
xfs_icsb_cnts_t __percpu *m_sb_cnts; /* per-cpu superblock counters */
@@ -269,7 +208,6 @@ typedef struct xfs_mount {
must be synchronous except
for space allocations */
#define XFS_MOUNT_DELAYLOG (1ULL << 1) /* delayed logging is enabled */
-#define XFS_MOUNT_DMAPI (1ULL << 2) /* dmapi is enabled */
#define XFS_MOUNT_WAS_CLEAN (1ULL << 3)
#define XFS_MOUNT_FS_SHUTDOWN (1ULL << 4) /* atomic stop of all filesystem
operations, typically for
@@ -440,11 +378,6 @@ extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t);
extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
-extern int xfs_dmops_get(struct xfs_mount *);
-extern void xfs_dmops_put(struct xfs_mount *);
-
-extern struct xfs_dmops xfs_dmcore_xfs;
-
#endif /* __KERNEL__ */
extern void xfs_mod_sb(struct xfs_trans *, __int64_t);
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c
index fc1cda23b817..8fca957200df 100644
--- a/fs/xfs/xfs_rename.c
+++ b/fs/xfs/xfs_rename.c
@@ -24,12 +24,9 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
@@ -116,20 +113,7 @@ xfs_rename(
int spaceres;
int num_inodes;
- xfs_itrace_entry(src_dp);
- xfs_itrace_entry(target_dp);
-
- if (DM_EVENT_ENABLED(src_dp, DM_EVENT_RENAME) ||
- DM_EVENT_ENABLED(target_dp, DM_EVENT_RENAME)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_RENAME,
- src_dp, DM_RIGHT_NULL,
- target_dp, DM_RIGHT_NULL,
- src_name->name, target_name->name,
- 0, 0, 0);
- if (error)
- return error;
- }
- /* Return through std_return after this point. */
+ trace_xfs_rename(src_dp, target_dp, src_name, target_name);
new_parent = (src_dp != target_dp);
src_is_directory = ((src_ip->i_d.di_mode & S_IFMT) == S_IFDIR);
@@ -184,26 +168,14 @@ xfs_rename(
/*
* Join all the inodes to the transaction. From this point on,
* we can rely on either trans_commit or trans_cancel to unlock
- * them. Note that we need to add a vnode reference to the
- * directories since trans_commit & trans_cancel will decrement
- * them when they unlock the inodes. Also, we need to be careful
- * not to add an inode to the transaction more than once.
+ * them.
*/
- IHOLD(src_dp);
- xfs_trans_ijoin(tp, src_dp, XFS_ILOCK_EXCL);
-
- if (new_parent) {
- IHOLD(target_dp);
- xfs_trans_ijoin(tp, target_dp, XFS_ILOCK_EXCL);
- }
-
- IHOLD(src_ip);
- xfs_trans_ijoin(tp, src_ip, XFS_ILOCK_EXCL);
-
- if (target_ip) {
- IHOLD(target_ip);
- xfs_trans_ijoin(tp, target_ip, XFS_ILOCK_EXCL);
- }
+ xfs_trans_ijoin_ref(tp, src_dp, XFS_ILOCK_EXCL);
+ if (new_parent)
+ xfs_trans_ijoin_ref(tp, target_dp, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, src_ip, XFS_ILOCK_EXCL);
+ if (target_ip)
+ xfs_trans_ijoin_ref(tp, target_ip, XFS_ILOCK_EXCL);
/*
* If we are using project inheritance, we only allow renames
@@ -369,26 +341,13 @@ xfs_rename(
* trans_commit will unlock src_ip, target_ip & decrement
* the vnode references.
*/
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
-
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit */
-std_return:
- if (DM_EVENT_ENABLED(src_dp, DM_EVENT_POSTRENAME) ||
- DM_EVENT_ENABLED(target_dp, DM_EVENT_POSTRENAME)) {
- (void) XFS_SEND_NAMESP (mp, DM_EVENT_POSTRENAME,
- src_dp, DM_RIGHT_NULL,
- target_dp, DM_RIGHT_NULL,
- src_name->name, target_name->name,
- 0, error, 0);
- }
- return error;
+ return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
abort_return:
cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
error_return:
xfs_bmap_cancel(&free_list);
xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
+ std_return:
+ return error;
}
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index a2d32ce335aa..891260fea11e 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -25,17 +25,10 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
#include "xfs_rtalloc.h"
@@ -129,7 +122,7 @@ xfs_growfs_rt_alloc(
cancelflags |= XFS_TRANS_ABORT;
error = xfs_bmapi(tp, ip, oblocks, nblocks - oblocks,
XFS_BMAPI_WRITE | XFS_BMAPI_METADATA, &firstblock,
- resblks, &map, &nmap, &flist, NULL);
+ resblks, &map, &nmap, &flist);
if (!error && nmap < 1)
error = XFS_ERROR(ENOSPC);
if (error)
diff --git a/fs/xfs/xfs_rw.c b/fs/xfs/xfs_rw.c
index e336742a58a4..56861d5daaef 100644
--- a/fs/xfs/xfs_rw.c
+++ b/fs/xfs/xfs_rw.c
@@ -24,27 +24,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
-#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
-#include "xfs_inode_item.h"
-#include "xfs_itable.h"
-#include "xfs_btree.h"
-#include "xfs_alloc.h"
-#include "xfs_ialloc.h"
-#include "xfs_attr.h"
-#include "xfs_bmap.h"
#include "xfs_error.h"
-#include "xfs_buf_item.h"
#include "xfs_rw.h"
-#include "xfs_trace.h"
/*
* Force a shutdown of the filesystem instantly while keeping
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 28547dfce037..f2065ccb6c2d 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2000-2003,2005 Silicon Graphics, Inc.
+ * Copyright (C) 2010 Red Hat, Inc.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
@@ -24,16 +25,12 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_error.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
@@ -47,6 +44,7 @@
#include "xfs_trace.h"
kmem_zone_t *xfs_trans_zone;
+kmem_zone_t *xfs_log_item_desc_zone;
/*
@@ -597,8 +595,7 @@ _xfs_trans_alloc(
tp->t_magic = XFS_TRANS_MAGIC;
tp->t_type = type;
tp->t_mountp = mp;
- tp->t_items_free = XFS_LIC_NUM_SLOTS;
- xfs_lic_init(&(tp->t_items));
+ INIT_LIST_HEAD(&tp->t_items);
INIT_LIST_HEAD(&tp->t_busy);
return tp;
}
@@ -643,8 +640,7 @@ xfs_trans_dup(
ntp->t_magic = XFS_TRANS_MAGIC;
ntp->t_type = tp->t_type;
ntp->t_mountp = tp->t_mountp;
- ntp->t_items_free = XFS_LIC_NUM_SLOTS;
- xfs_lic_init(&(ntp->t_items));
+ INIT_LIST_HEAD(&ntp->t_items);
INIT_LIST_HEAD(&ntp->t_busy);
ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
@@ -1124,6 +1120,108 @@ xfs_trans_unreserve_and_mod_sb(
}
/*
+ * Add the given log item to the transaction's list of log items.
+ *
+ * The log item will now point to its new descriptor with its li_desc field.
+ */
+void
+xfs_trans_add_item(
+ struct xfs_trans *tp,
+ struct xfs_log_item *lip)
+{
+ struct xfs_log_item_desc *lidp;
+
+ ASSERT(lip->li_mountp = tp->t_mountp);
+ ASSERT(lip->li_ailp = tp->t_mountp->m_ail);
+
+ lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP);
+
+ lidp->lid_item = lip;
+ lidp->lid_flags = 0;
+ lidp->lid_size = 0;
+ list_add_tail(&lidp->lid_trans, &tp->t_items);
+
+ lip->li_desc = lidp;
+}
+
+STATIC void
+xfs_trans_free_item_desc(
+ struct xfs_log_item_desc *lidp)
+{
+ list_del_init(&lidp->lid_trans);
+ kmem_zone_free(xfs_log_item_desc_zone, lidp);
+}
+
+/*
+ * Unlink and free the given descriptor.
+ */
+void
+xfs_trans_del_item(
+ struct xfs_log_item *lip)
+{
+ xfs_trans_free_item_desc(lip->li_desc);
+ lip->li_desc = NULL;
+}
+
+/*
+ * Unlock all of the items of a transaction and free all the descriptors
+ * of that transaction.
+ */
+STATIC void
+xfs_trans_free_items(
+ struct xfs_trans *tp,
+ xfs_lsn_t commit_lsn,
+ int flags)
+{
+ struct xfs_log_item_desc *lidp, *next;
+
+ list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) {
+ struct xfs_log_item *lip = lidp->lid_item;
+
+ lip->li_desc = NULL;
+
+ if (commit_lsn != NULLCOMMITLSN)
+ IOP_COMMITTING(lip, commit_lsn);
+ if (flags & XFS_TRANS_ABORT)
+ lip->li_flags |= XFS_LI_ABORTED;
+ IOP_UNLOCK(lip);
+
+ xfs_trans_free_item_desc(lidp);
+ }
+}
+
+/*
+ * Unlock the items associated with a transaction.
+ *
+ * Items which were not logged should be freed. Those which were logged must
+ * still be tracked so they can be unpinned when the transaction commits.
+ */
+STATIC void
+xfs_trans_unlock_items(
+ struct xfs_trans *tp,
+ xfs_lsn_t commit_lsn)
+{
+ struct xfs_log_item_desc *lidp, *next;
+
+ list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) {
+ struct xfs_log_item *lip = lidp->lid_item;
+
+ lip->li_desc = NULL;
+
+ if (commit_lsn != NULLCOMMITLSN)
+ IOP_COMMITTING(lip, commit_lsn);
+ IOP_UNLOCK(lip);
+
+ /*
+ * Free the descriptor if the item is not dirty
+ * within this transaction.
+ */
+ if (!(lidp->lid_flags & XFS_LID_DIRTY))
+ xfs_trans_free_item_desc(lidp);
+ }
+}
+
+/*
* Total up the number of log iovecs needed to commit this
* transaction. The transaction itself needs one for the
* transaction header. Ask each dirty item in turn how many
@@ -1134,30 +1232,27 @@ xfs_trans_count_vecs(
struct xfs_trans *tp)
{
int nvecs;
- xfs_log_item_desc_t *lidp;
+ struct xfs_log_item_desc *lidp;
nvecs = 1;
- lidp = xfs_trans_first_item(tp);
- ASSERT(lidp != NULL);
/* In the non-debug case we need to start bailing out if we
* didn't find a log_item here, return zero and let trans_commit
* deal with it.
*/
- if (lidp == NULL)
+ if (list_empty(&tp->t_items)) {
+ ASSERT(0);
return 0;
+ }
- while (lidp != NULL) {
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
/*
* Skip items which aren't dirty in this transaction.
*/
- if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
- lidp = xfs_trans_next_item(tp, lidp);
+ if (!(lidp->lid_flags & XFS_LID_DIRTY))
continue;
- }
lidp->lid_size = IOP_SIZE(lidp->lid_item);
nvecs += lidp->lid_size;
- lidp = xfs_trans_next_item(tp, lidp);
}
return nvecs;
@@ -1177,7 +1272,7 @@ xfs_trans_fill_vecs(
struct xfs_trans *tp,
struct xfs_log_iovec *log_vector)
{
- xfs_log_item_desc_t *lidp;
+ struct xfs_log_item_desc *lidp;
struct xfs_log_iovec *vecp;
uint nitems;
@@ -1188,14 +1283,11 @@ xfs_trans_fill_vecs(
vecp = log_vector + 1;
nitems = 0;
- lidp = xfs_trans_first_item(tp);
- ASSERT(lidp);
- while (lidp) {
+ ASSERT(!list_empty(&tp->t_items));
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
/* Skip items which aren't dirty in this transaction. */
- if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
- lidp = xfs_trans_next_item(tp, lidp);
+ if (!(lidp->lid_flags & XFS_LID_DIRTY))
continue;
- }
/*
* The item may be marked dirty but not log anything. This can
@@ -1206,7 +1298,6 @@ xfs_trans_fill_vecs(
IOP_FORMAT(lidp->lid_item, vecp);
vecp += lidp->lid_size;
IOP_PIN(lidp->lid_item);
- lidp = xfs_trans_next_item(tp, lidp);
}
/*
@@ -1284,7 +1375,7 @@ xfs_trans_item_committed(
* log item flags, if anyone else stales the buffer we do not want to
* pay any attention to it.
*/
- IOP_UNPIN(lip);
+ IOP_UNPIN(lip, 0);
}
/*
@@ -1301,24 +1392,15 @@ xfs_trans_committed(
struct xfs_trans *tp,
int abortflag)
{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
+ struct xfs_log_item_desc *lidp, *next;
/* Call the transaction's completion callback if there is one. */
if (tp->t_callback != NULL)
tp->t_callback(tp, tp->t_callarg);
- for (lidp = xfs_trans_first_item(tp);
- lidp != NULL;
- lidp = xfs_trans_next_item(tp, lidp)) {
+ list_for_each_entry_safe(lidp, next, &tp->t_items, lid_trans) {
xfs_trans_item_committed(lidp->lid_item, tp->t_lsn, abortflag);
- }
-
- /* free the item chunks, ignoring the embedded chunk */
- for (licp = tp->t_items.lic_next; licp != NULL; licp = next_licp) {
- next_licp = licp->lic_next;
- kmem_free(licp);
+ xfs_trans_free_item_desc(lidp);
}
xfs_trans_free(tp);
@@ -1333,16 +1415,14 @@ xfs_trans_uncommit(
struct xfs_trans *tp,
uint flags)
{
- xfs_log_item_desc_t *lidp;
+ struct xfs_log_item_desc *lidp;
- for (lidp = xfs_trans_first_item(tp);
- lidp != NULL;
- lidp = xfs_trans_next_item(tp, lidp)) {
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
/*
* Unpin all but those that aren't dirty.
*/
if (lidp->lid_flags & XFS_LID_DIRTY)
- IOP_UNPIN_REMOVE(lidp->lid_item, tp);
+ IOP_UNPIN(lidp->lid_item, 1);
}
xfs_trans_unreserve_and_mod_sb(tp);
@@ -1508,33 +1588,28 @@ STATIC struct xfs_log_vec *
xfs_trans_alloc_log_vecs(
xfs_trans_t *tp)
{
- xfs_log_item_desc_t *lidp;
+ struct xfs_log_item_desc *lidp;
struct xfs_log_vec *lv = NULL;
struct xfs_log_vec *ret_lv = NULL;
- lidp = xfs_trans_first_item(tp);
/* Bail out if we didn't find a log item. */
- if (!lidp) {
+ if (list_empty(&tp->t_items)) {
ASSERT(0);
return NULL;
}
- while (lidp != NULL) {
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
struct xfs_log_vec *new_lv;
/* Skip items which aren't dirty in this transaction. */
- if (!(lidp->lid_flags & XFS_LID_DIRTY)) {
- lidp = xfs_trans_next_item(tp, lidp);
+ if (!(lidp->lid_flags & XFS_LID_DIRTY))
continue;
- }
/* Skip items that do not have any vectors for writing */
lidp->lid_size = IOP_SIZE(lidp->lid_item);
- if (!lidp->lid_size) {
- lidp = xfs_trans_next_item(tp, lidp);
+ if (!lidp->lid_size)
continue;
- }
new_lv = kmem_zalloc(sizeof(*new_lv) +
lidp->lid_size * sizeof(struct xfs_log_iovec),
@@ -1549,7 +1624,6 @@ xfs_trans_alloc_log_vecs(
else
lv->lv_next = new_lv;
lv = new_lv;
- lidp = xfs_trans_next_item(tp, lidp);
}
return ret_lv;
@@ -1708,12 +1782,6 @@ xfs_trans_cancel(
int flags)
{
int log_flags;
-#ifdef DEBUG
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- int i;
-#endif
xfs_mount_t *mp = tp->t_mountp;
/*
@@ -1732,21 +1800,11 @@ xfs_trans_cancel(
xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
}
#ifdef DEBUG
- if (!(flags & XFS_TRANS_ABORT)) {
- licp = &(tp->t_items);
- while (licp != NULL) {
- lidp = licp->lic_descs;
- for (i = 0; i < licp->lic_unused; i++, lidp++) {
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
-
- lip = lidp->lid_item;
- if (!XFS_FORCED_SHUTDOWN(mp))
- ASSERT(!(lip->li_type == XFS_LI_EFD));
- }
- licp = licp->lic_next;
- }
+ if (!(flags & XFS_TRANS_ABORT) && !XFS_FORCED_SHUTDOWN(mp)) {
+ struct xfs_log_item_desc *lidp;
+
+ list_for_each_entry(lidp, &tp->t_items, lid_trans)
+ ASSERT(!(lidp->lid_item->li_type == XFS_LI_EFD));
}
#endif
xfs_trans_unreserve_and_mod_sb(tp);
@@ -1834,7 +1892,6 @@ xfs_trans_roll(
if (error)
return error;
- xfs_trans_ijoin(trans, dp, XFS_ILOCK_EXCL);
- xfs_trans_ihold(trans, dp);
+ xfs_trans_ijoin(trans, dp);
return 0;
}
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index e639e8e9a2a9..c13c0f97b494 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -161,105 +161,14 @@ typedef struct xfs_trans_header {
* the amount of space needed to log the item it describes
* once we get to commit processing (see xfs_trans_commit()).
*/
-typedef struct xfs_log_item_desc {
+struct xfs_log_item_desc {
struct xfs_log_item *lid_item;
- ushort lid_size;
- unsigned char lid_flags;
- unsigned char lid_index;
-} xfs_log_item_desc_t;
+ ushort lid_size;
+ unsigned char lid_flags;
+ struct list_head lid_trans;
+};
#define XFS_LID_DIRTY 0x1
-#define XFS_LID_PINNED 0x2
-
-/*
- * This structure is used to maintain a chunk list of log_item_desc
- * structures. The free field is a bitmask indicating which descriptors
- * in this chunk's array are free. The unused field is the first value
- * not used since this chunk was allocated.
- */
-#define XFS_LIC_NUM_SLOTS 15
-typedef struct xfs_log_item_chunk {
- struct xfs_log_item_chunk *lic_next;
- ushort lic_free;
- ushort lic_unused;
- xfs_log_item_desc_t lic_descs[XFS_LIC_NUM_SLOTS];
-} xfs_log_item_chunk_t;
-
-#define XFS_LIC_MAX_SLOT (XFS_LIC_NUM_SLOTS - 1)
-#define XFS_LIC_FREEMASK ((1 << XFS_LIC_NUM_SLOTS) - 1)
-
-
-/*
- * Initialize the given chunk. Set the chunk's free descriptor mask
- * to indicate that all descriptors are free. The caller gets to set
- * lic_unused to the right value (0 matches all free). The
- * lic_descs.lid_index values are set up as each desc is allocated.
- */
-static inline void xfs_lic_init(xfs_log_item_chunk_t *cp)
-{
- cp->lic_free = XFS_LIC_FREEMASK;
-}
-
-static inline void xfs_lic_init_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_descs[slot].lid_index = (unsigned char)(slot);
-}
-
-static inline int xfs_lic_vacancy(xfs_log_item_chunk_t *cp)
-{
- return cp->lic_free & XFS_LIC_FREEMASK;
-}
-
-static inline void xfs_lic_all_free(xfs_log_item_chunk_t *cp)
-{
- cp->lic_free = XFS_LIC_FREEMASK;
-}
-
-static inline int xfs_lic_are_all_free(xfs_log_item_chunk_t *cp)
-{
- return ((cp->lic_free & XFS_LIC_FREEMASK) == XFS_LIC_FREEMASK);
-}
-
-static inline int xfs_lic_isfree(xfs_log_item_chunk_t *cp, int slot)
-{
- return (cp->lic_free & (1 << slot));
-}
-
-static inline void xfs_lic_claim(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_free &= ~(1 << slot);
-}
-
-static inline void xfs_lic_relse(xfs_log_item_chunk_t *cp, int slot)
-{
- cp->lic_free |= 1 << slot;
-}
-
-static inline xfs_log_item_desc_t *
-xfs_lic_slot(xfs_log_item_chunk_t *cp, int slot)
-{
- return &(cp->lic_descs[slot]);
-}
-
-static inline int xfs_lic_desc_to_slot(xfs_log_item_desc_t *dp)
-{
- return (uint)dp->lid_index;
-}
-
-/*
- * Calculate the address of a chunk given a descriptor pointer:
- * dp - dp->lid_index give the address of the start of the lic_descs array.
- * From this we subtract the offset of the lic_descs field in a chunk.
- * All of this yields the address of the chunk, which is
- * cast to a chunk pointer.
- */
-static inline xfs_log_item_chunk_t *
-xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
-{
- return (xfs_log_item_chunk_t*) \
- (((xfs_caddr_t)((dp) - (dp)->lid_index)) - \
- (xfs_caddr_t)(((xfs_log_item_chunk_t*)0)->lic_descs));
-}
#define XFS_TRANS_MAGIC 0x5452414E /* 'TRAN' */
/*
@@ -275,8 +184,6 @@ xfs_lic_desc_to_chunk(xfs_log_item_desc_t *dp)
/*
* Values for call flags parameter.
*/
-#define XFS_TRANS_NOSLEEP 0x1
-#define XFS_TRANS_WAIT 0x2
#define XFS_TRANS_RELEASE_LOG_RES 0x4
#define XFS_TRANS_ABORT 0x8
@@ -438,8 +345,7 @@ typedef struct xfs_item_ops {
uint (*iop_size)(xfs_log_item_t *);
void (*iop_format)(xfs_log_item_t *, struct xfs_log_iovec *);
void (*iop_pin)(xfs_log_item_t *);
- void (*iop_unpin)(xfs_log_item_t *);
- void (*iop_unpin_remove)(xfs_log_item_t *, struct xfs_trans *);
+ void (*iop_unpin)(xfs_log_item_t *, int remove);
uint (*iop_trylock)(xfs_log_item_t *);
void (*iop_unlock)(xfs_log_item_t *);
xfs_lsn_t (*iop_committed)(xfs_log_item_t *, xfs_lsn_t);
@@ -451,8 +357,7 @@ typedef struct xfs_item_ops {
#define IOP_SIZE(ip) (*(ip)->li_ops->iop_size)(ip)
#define IOP_FORMAT(ip,vp) (*(ip)->li_ops->iop_format)(ip, vp)
#define IOP_PIN(ip) (*(ip)->li_ops->iop_pin)(ip)
-#define IOP_UNPIN(ip) (*(ip)->li_ops->iop_unpin)(ip)
-#define IOP_UNPIN_REMOVE(ip,tp) (*(ip)->li_ops->iop_unpin_remove)(ip, tp)
+#define IOP_UNPIN(ip, remove) (*(ip)->li_ops->iop_unpin)(ip, remove)
#define IOP_TRYLOCK(ip) (*(ip)->li_ops->iop_trylock)(ip)
#define IOP_UNLOCK(ip) (*(ip)->li_ops->iop_unlock)(ip)
#define IOP_COMMITTED(ip, lsn) (*(ip)->li_ops->iop_committed)(ip, lsn)
@@ -516,8 +421,7 @@ typedef struct xfs_trans {
int64_t t_rblocks_delta;/* superblock rblocks change */
int64_t t_rextents_delta;/* superblocks rextents chg */
int64_t t_rextslog_delta;/* superblocks rextslog chg */
- unsigned int t_items_free; /* log item descs free */
- xfs_log_item_chunk_t t_items; /* first log item desc chunk */
+ struct list_head t_items; /* log item descriptors */
xfs_trans_header_t t_header; /* header for in-log trans */
struct list_head t_busy; /* list of busy extents */
unsigned long t_pflags; /* saved process flags state */
@@ -569,8 +473,8 @@ void xfs_trans_dquot_buf(xfs_trans_t *, struct xfs_buf *, uint);
void xfs_trans_inode_alloc_buf(xfs_trans_t *, struct xfs_buf *);
int xfs_trans_iget(struct xfs_mount *, xfs_trans_t *,
xfs_ino_t , uint, uint, struct xfs_inode **);
-void xfs_trans_ijoin(xfs_trans_t *, struct xfs_inode *, uint);
-void xfs_trans_ihold(xfs_trans_t *, struct xfs_inode *);
+void xfs_trans_ijoin_ref(struct xfs_trans *, struct xfs_inode *, uint);
+void xfs_trans_ijoin(struct xfs_trans *, struct xfs_inode *);
void xfs_trans_log_buf(xfs_trans_t *, struct xfs_buf *, uint, uint);
void xfs_trans_log_inode(xfs_trans_t *, struct xfs_inode *, uint);
struct xfs_efi_log_item *xfs_trans_get_efi(xfs_trans_t *, uint);
@@ -595,6 +499,7 @@ int xfs_trans_ail_init(struct xfs_mount *);
void xfs_trans_ail_destroy(struct xfs_mount *);
extern kmem_zone_t *xfs_trans_zone;
+extern kmem_zone_t *xfs_log_item_desc_zone;
#endif /* __KERNEL__ */
diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c
index e799824f7245..dc9069568ff7 100644
--- a/fs/xfs/xfs_trans_ail.c
+++ b/fs/xfs/xfs_trans_ail.c
@@ -24,7 +24,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
#include "xfs_error.h"
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 63d81a22f4fd..90af025e6839 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -24,14 +24,10 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_buf_item.h"
@@ -51,36 +47,17 @@ xfs_trans_buf_item_match(
xfs_daddr_t blkno,
int len)
{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_desc_t *lidp;
- xfs_buf_log_item_t *blip;
- int i;
+ struct xfs_log_item_desc *lidp;
+ struct xfs_buf_log_item *blip;
len = BBTOB(len);
- for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) {
- if (xfs_lic_are_all_free(licp)) {
- ASSERT(licp == &tp->t_items);
- ASSERT(licp->lic_next == NULL);
- return NULL;
- }
-
- for (i = 0; i < licp->lic_unused; i++) {
- /*
- * Skip unoccupied slots.
- */
- if (xfs_lic_isfree(licp, i))
- continue;
-
- lidp = xfs_lic_slot(licp, i);
- blip = (xfs_buf_log_item_t *)lidp->lid_item;
- if (blip->bli_item.li_type != XFS_LI_BUF)
- continue;
-
- if (XFS_BUF_TARGET(blip->bli_buf) == target &&
- XFS_BUF_ADDR(blip->bli_buf) == blkno &&
- XFS_BUF_COUNT(blip->bli_buf) == len)
- return blip->bli_buf;
- }
+ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
+ blip = (struct xfs_buf_log_item *)lidp->lid_item;
+ if (blip->bli_item.li_type == XFS_LI_BUF &&
+ XFS_BUF_TARGET(blip->bli_buf) == target &&
+ XFS_BUF_ADDR(blip->bli_buf) == blkno &&
+ XFS_BUF_COUNT(blip->bli_buf) == len)
+ return blip->bli_buf;
}
return NULL;
@@ -127,7 +104,7 @@ _xfs_trans_bjoin(
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
+ xfs_trans_add_item(tp, &bip->bli_item);
/*
* Initialize b_fsprivate2 so we can find it with incore_match()
@@ -483,7 +460,6 @@ xfs_trans_brelse(xfs_trans_t *tp,
{
xfs_buf_log_item_t *bip;
xfs_log_item_t *lip;
- xfs_log_item_desc_t *lidp;
/*
* Default to a normal brelse() call if the tp is NULL.
@@ -514,13 +490,6 @@ xfs_trans_brelse(xfs_trans_t *tp,
ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL));
ASSERT(atomic_read(&bip->bli_refcount) > 0);
- /*
- * Find the item descriptor pointing to this buffer's
- * log item. It must be there.
- */
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
-
trace_xfs_trans_brelse(bip);
/*
@@ -536,7 +505,7 @@ xfs_trans_brelse(xfs_trans_t *tp,
* If the buffer is dirty within this transaction, we can't
* release it until we commit.
*/
- if (lidp->lid_flags & XFS_LID_DIRTY)
+ if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY)
return;
/*
@@ -553,7 +522,7 @@ xfs_trans_brelse(xfs_trans_t *tp,
/*
* Free up the log item descriptor tracking the released item.
*/
- xfs_trans_free_item(tp, lidp);
+ xfs_trans_del_item(&bip->bli_item);
/*
* Clear the hold flag in the buf log item if it is set.
@@ -665,7 +634,6 @@ xfs_trans_log_buf(xfs_trans_t *tp,
uint last)
{
xfs_buf_log_item_t *bip;
- xfs_log_item_desc_t *lidp;
ASSERT(XFS_BUF_ISBUSY(bp));
ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
@@ -690,7 +658,7 @@ xfs_trans_log_buf(xfs_trans_t *tp,
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
ASSERT(atomic_read(&bip->bli_refcount) > 0);
XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks);
- bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))xfs_buf_iodone;
+ bip->bli_item.li_cb = xfs_buf_iodone;
trace_xfs_trans_log_buf(bip);
@@ -707,11 +675,8 @@ xfs_trans_log_buf(xfs_trans_t *tp,
bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL;
}
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
bip->bli_flags |= XFS_BLI_LOGGED;
xfs_buf_item_log(bip, first, last);
}
@@ -740,7 +705,6 @@ xfs_trans_binval(
xfs_trans_t *tp,
xfs_buf_t *bp)
{
- xfs_log_item_desc_t *lidp;
xfs_buf_log_item_t *bip;
ASSERT(XFS_BUF_ISBUSY(bp));
@@ -748,8 +712,6 @@ xfs_trans_binval(
ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
- ASSERT(lidp != NULL);
ASSERT(atomic_read(&bip->bli_refcount) > 0);
trace_xfs_trans_binval(bip);
@@ -764,7 +726,7 @@ xfs_trans_binval(
ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF));
ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
- ASSERT(lidp->lid_flags & XFS_LID_DIRTY);
+ ASSERT(bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY);
ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
return;
}
@@ -797,7 +759,7 @@ xfs_trans_binval(
bip->bli_format.blf_flags |= XFS_BLF_CANCEL;
memset((char *)(bip->bli_format.blf_data_map), 0,
(bip->bli_format.blf_map_size * sizeof(uint)));
- lidp->lid_flags |= XFS_LID_DIRTY;
+ bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
tp->t_flags |= XFS_TRANS_DIRTY;
}
@@ -853,12 +815,9 @@ xfs_trans_stale_inode_buf(
ASSERT(atomic_read(&bip->bli_refcount) > 0);
bip->bli_flags |= XFS_BLI_STALE_INODE;
- bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))
- xfs_buf_iodone;
+ bip->bli_item.li_cb = xfs_buf_iodone;
}
-
-
/*
* Mark the buffer as being one which contains newly allocated
* inodes. We need to make sure that even if this buffer is
diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c
index 27cce2a9c7e9..f783d5e9fa70 100644
--- a/fs/xfs/xfs_trans_extfree.c
+++ b/fs/xfs/xfs_trans_extfree.c
@@ -23,7 +23,6 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_trans_priv.h"
#include "xfs_extfree_item.h"
@@ -49,9 +48,8 @@ xfs_trans_get_efi(xfs_trans_t *tp,
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efip);
-
- return (efip);
+ xfs_trans_add_item(tp, &efip->efi_item);
+ return efip;
}
/*
@@ -65,15 +63,11 @@ xfs_trans_log_efi_extent(xfs_trans_t *tp,
xfs_fsblock_t start_block,
xfs_extlen_t ext_len)
{
- xfs_log_item_desc_t *lidp;
uint next_extent;
xfs_extent_t *extp;
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efip);
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ efip->efi_item.li_desc->lid_flags |= XFS_LID_DIRTY;
next_extent = efip->efi_next_extent;
ASSERT(next_extent < efip->efi_format.efi_nextents);
@@ -106,9 +100,8 @@ xfs_trans_get_efd(xfs_trans_t *tp,
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)efdp);
-
- return (efdp);
+ xfs_trans_add_item(tp, &efdp->efd_item);
+ return efdp;
}
/*
@@ -122,15 +115,11 @@ xfs_trans_log_efd_extent(xfs_trans_t *tp,
xfs_fsblock_t start_block,
xfs_extlen_t ext_len)
{
- xfs_log_item_desc_t *lidp;
uint next_extent;
xfs_extent_t *extp;
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)efdp);
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ efdp->efd_item.li_desc->lid_flags |= XFS_LID_DIRTY;
next_extent = efdp->efd_next_extent;
ASSERT(next_extent < efdp->efd_format.efd_nextents);
diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c
index 2559dfec946b..cdc53a1050c5 100644
--- a/fs/xfs/xfs_trans_inode.c
+++ b/fs/xfs/xfs_trans_inode.c
@@ -24,20 +24,16 @@
#include "xfs_trans.h"
#include "xfs_sb.h"
#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_btree.h"
-#include "xfs_ialloc.h"
#include "xfs_trans_priv.h"
#include "xfs_inode_item.h"
+#include "xfs_trace.h"
#ifdef XFS_TRANS_DEBUG
STATIC void
@@ -47,7 +43,6 @@ xfs_trans_inode_broot_debug(
#define xfs_trans_inode_broot_debug(ip)
#endif
-
/*
* Get an inode and join it to the transaction.
*/
@@ -63,77 +58,65 @@ xfs_trans_iget(
int error;
error = xfs_iget(mp, tp, ino, flags, lock_flags, ipp);
- if (!error && tp)
- xfs_trans_ijoin(tp, *ipp, lock_flags);
+ if (!error && tp) {
+ xfs_trans_ijoin(tp, *ipp);
+ (*ipp)->i_itemp->ili_lock_flags = lock_flags;
+ }
return error;
}
/*
- * Add the locked inode to the transaction.
- * The inode must be locked, and it cannot be associated with any
- * transaction. The caller must specify the locks already held
- * on the inode.
+ * Add a locked inode to the transaction.
+ *
+ * The inode must be locked, and it cannot be associated with any transaction.
*/
void
xfs_trans_ijoin(
- xfs_trans_t *tp,
- xfs_inode_t *ip,
- uint lock_flags)
+ struct xfs_trans *tp,
+ struct xfs_inode *ip)
{
xfs_inode_log_item_t *iip;
ASSERT(ip->i_transp == NULL);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
- ASSERT(lock_flags & XFS_ILOCK_EXCL);
if (ip->i_itemp == NULL)
xfs_inode_item_init(ip, ip->i_mount);
iip = ip->i_itemp;
- ASSERT(iip->ili_flags == 0);
+ ASSERT(iip->ili_lock_flags == 0);
/*
* Get a log_item_desc to point at the new item.
*/
- (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(iip));
+ xfs_trans_add_item(tp, &iip->ili_item);
xfs_trans_inode_broot_debug(ip);
/*
- * If the IO lock is already held, mark that in the inode log item.
- */
- if (lock_flags & XFS_IOLOCK_EXCL) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_EXCL;
- } else if (lock_flags & XFS_IOLOCK_SHARED) {
- iip->ili_flags |= XFS_ILI_IOLOCKED_SHARED;
- }
-
- /*
* Initialize i_transp so we can find it with xfs_inode_incore()
* in xfs_trans_iget() above.
*/
ip->i_transp = tp;
}
-
-
/*
- * Mark the inode as not needing to be unlocked when the inode item's
- * IOP_UNLOCK() routine is called. The inode must already be locked
- * and associated with the given transaction.
+ * Add a locked inode to the transaction.
+ *
+ *
+ * Grabs a reference to the inode which will be dropped when the transaction
+ * is commited. The inode will also be unlocked at that point. The inode
+ * must be locked, and it cannot be associated with any transaction.
*/
-/*ARGSUSED*/
void
-xfs_trans_ihold(
- xfs_trans_t *tp,
- xfs_inode_t *ip)
+xfs_trans_ijoin_ref(
+ struct xfs_trans *tp,
+ struct xfs_inode *ip,
+ uint lock_flags)
{
- ASSERT(ip->i_transp == tp);
- ASSERT(ip->i_itemp != NULL);
- ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
-
- ip->i_itemp->ili_flags |= XFS_ILI_HOLD;
+ xfs_trans_ijoin(tp, ip);
+ IHOLD(ip);
+ ip->i_itemp->ili_lock_flags = lock_flags;
}
-
/*
* This is called to mark the fields indicated in fieldmask as needing
* to be logged when the transaction is committed. The inode must
@@ -149,17 +132,12 @@ xfs_trans_log_inode(
xfs_inode_t *ip,
uint flags)
{
- xfs_log_item_desc_t *lidp;
-
ASSERT(ip->i_transp == tp);
ASSERT(ip->i_itemp != NULL);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
- lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(ip->i_itemp));
- ASSERT(lidp != NULL);
-
tp->t_flags |= XFS_TRANS_DIRTY;
- lidp->lid_flags |= XFS_LID_DIRTY;
+ ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY;
/*
* Always OR in the bits from the ili_last_fields field.
diff --git a/fs/xfs/xfs_trans_item.c b/fs/xfs/xfs_trans_item.c
deleted file mode 100644
index f11d37d06dcc..000000000000
--- a/fs/xfs/xfs_trans_item.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would 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 the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-#include "xfs.h"
-#include "xfs_fs.h"
-#include "xfs_types.h"
-#include "xfs_log.h"
-#include "xfs_inum.h"
-#include "xfs_trans.h"
-#include "xfs_trans_priv.h"
-/* XXX: from here down needed until struct xfs_trans has its own ailp */
-#include "xfs_bit.h"
-#include "xfs_buf_item.h"
-#include "xfs_sb.h"
-#include "xfs_ag.h"
-#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
-#include "xfs_mount.h"
-
-STATIC int xfs_trans_unlock_chunk(xfs_log_item_chunk_t *,
- int, int, xfs_lsn_t);
-
-/*
- * This is called to add the given log item to the transaction's
- * list of log items. It must find a free log item descriptor
- * or allocate a new one and add the item to that descriptor.
- * The function returns a pointer to item descriptor used to point
- * to the new item. The log item will now point to its new descriptor
- * with its li_desc field.
- */
-xfs_log_item_desc_t *
-xfs_trans_add_item(xfs_trans_t *tp, xfs_log_item_t *lip)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_chunk_t *licp;
- int i=0;
-
- /*
- * If there are no free descriptors, allocate a new chunk
- * of them and put it at the front of the chunk list.
- */
- if (tp->t_items_free == 0) {
- licp = (xfs_log_item_chunk_t*)
- kmem_alloc(sizeof(xfs_log_item_chunk_t), KM_SLEEP);
- ASSERT(licp != NULL);
- /*
- * Initialize the chunk, and then
- * claim the first slot in the newly allocated chunk.
- */
- xfs_lic_init(licp);
- xfs_lic_claim(licp, 0);
- licp->lic_unused = 1;
- xfs_lic_init_slot(licp, 0);
- lidp = xfs_lic_slot(licp, 0);
-
- /*
- * Link in the new chunk and update the free count.
- */
- licp->lic_next = tp->t_items.lic_next;
- tp->t_items.lic_next = licp;
- tp->t_items_free = XFS_LIC_NUM_SLOTS - 1;
-
- /*
- * Initialize the descriptor and the generic portion
- * of the log item.
- *
- * Point the new slot at this item and return it.
- * Also point the log item at its currently active
- * descriptor and set the item's mount pointer.
- */
- lidp->lid_item = lip;
- lidp->lid_flags = 0;
- lidp->lid_size = 0;
- lip->li_desc = lidp;
- lip->li_mountp = tp->t_mountp;
- lip->li_ailp = tp->t_mountp->m_ail;
- return lidp;
- }
-
- /*
- * Find the free descriptor. It is somewhere in the chunklist
- * of descriptors.
- */
- licp = &tp->t_items;
- while (licp != NULL) {
- if (xfs_lic_vacancy(licp)) {
- if (licp->lic_unused <= XFS_LIC_MAX_SLOT) {
- i = licp->lic_unused;
- ASSERT(xfs_lic_isfree(licp, i));
- break;
- }
- for (i = 0; i <= XFS_LIC_MAX_SLOT; i++) {
- if (xfs_lic_isfree(licp, i))
- break;
- }
- ASSERT(i <= XFS_LIC_MAX_SLOT);
- break;
- }
- licp = licp->lic_next;
- }
- ASSERT(licp != NULL);
- /*
- * If we find a free descriptor, claim it,
- * initialize it, and return it.
- */
- xfs_lic_claim(licp, i);
- if (licp->lic_unused <= i) {
- licp->lic_unused = i + 1;
- xfs_lic_init_slot(licp, i);
- }
- lidp = xfs_lic_slot(licp, i);
- tp->t_items_free--;
- lidp->lid_item = lip;
- lidp->lid_flags = 0;
- lidp->lid_size = 0;
- lip->li_desc = lidp;
- lip->li_mountp = tp->t_mountp;
- lip->li_ailp = tp->t_mountp->m_ail;
- return lidp;
-}
-
-/*
- * Free the given descriptor.
- *
- * This requires setting the bit in the chunk's free mask corresponding
- * to the given slot.
- */
-void
-xfs_trans_free_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
-{
- uint slot;
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t **licpp;
-
- slot = xfs_lic_desc_to_slot(lidp);
- licp = xfs_lic_desc_to_chunk(lidp);
- xfs_lic_relse(licp, slot);
- lidp->lid_item->li_desc = NULL;
- tp->t_items_free++;
-
- /*
- * If there are no more used items in the chunk and this is not
- * the chunk embedded in the transaction structure, then free
- * the chunk. First pull it from the chunk list and then
- * free it back to the heap. We didn't bother with a doubly
- * linked list here because the lists should be very short
- * and this is not a performance path. It's better to save
- * the memory of the extra pointer.
- *
- * Also decrement the transaction structure's count of free items
- * by the number in a chunk since we are freeing an empty chunk.
- */
- if (xfs_lic_are_all_free(licp) && (licp != &(tp->t_items))) {
- licpp = &(tp->t_items.lic_next);
- while (*licpp != licp) {
- ASSERT(*licpp != NULL);
- licpp = &((*licpp)->lic_next);
- }
- *licpp = licp->lic_next;
- kmem_free(licp);
- tp->t_items_free -= XFS_LIC_NUM_SLOTS;
- }
-}
-
-/*
- * This is called to find the descriptor corresponding to the given
- * log item. It returns a pointer to the descriptor.
- * The log item MUST have a corresponding descriptor in the given
- * transaction. This routine does not return NULL, it panics.
- *
- * The descriptor pointer is kept in the log item's li_desc field.
- * Just return it.
- */
-/*ARGSUSED*/
-xfs_log_item_desc_t *
-xfs_trans_find_item(xfs_trans_t *tp, xfs_log_item_t *lip)
-{
- ASSERT(lip->li_desc != NULL);
-
- return lip->li_desc;
-}
-
-
-/*
- * Return a pointer to the first descriptor in the chunk list.
- * This does not return NULL if there are none, it panics.
- *
- * The first descriptor must be in either the first or second chunk.
- * This is because the only chunk allowed to be empty is the first.
- * All others are freed when they become empty.
- *
- * At some point this and xfs_trans_next_item() should be optimized
- * to quickly look at the mask to determine if there is anything to
- * look at.
- */
-xfs_log_item_desc_t *
-xfs_trans_first_item(xfs_trans_t *tp)
-{
- xfs_log_item_chunk_t *licp;
- int i;
-
- licp = &tp->t_items;
- /*
- * If it's not in the first chunk, skip to the second.
- */
- if (xfs_lic_are_all_free(licp)) {
- licp = licp->lic_next;
- }
-
- /*
- * Return the first non-free descriptor in the chunk.
- */
- ASSERT(!xfs_lic_are_all_free(licp));
- for (i = 0; i < licp->lic_unused; i++) {
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
-
- return xfs_lic_slot(licp, i);
- }
- cmn_err(CE_WARN, "xfs_trans_first_item() -- no first item");
- return NULL;
-}
-
-
-/*
- * Given a descriptor, return the next descriptor in the chunk list.
- * This returns NULL if there are no more used descriptors in the list.
- *
- * We do this by first locating the chunk in which the descriptor resides,
- * and then scanning forward in the chunk and the list for the next
- * used descriptor.
- */
-/*ARGSUSED*/
-xfs_log_item_desc_t *
-xfs_trans_next_item(xfs_trans_t *tp, xfs_log_item_desc_t *lidp)
-{
- xfs_log_item_chunk_t *licp;
- int i;
-
- licp = xfs_lic_desc_to_chunk(lidp);
-
- /*
- * First search the rest of the chunk. The for loop keeps us
- * from referencing things beyond the end of the chunk.
- */
- for (i = (int)xfs_lic_desc_to_slot(lidp) + 1; i < licp->lic_unused; i++) {
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
-
- return xfs_lic_slot(licp, i);
- }
-
- /*
- * Now search the next chunk. It must be there, because the
- * next chunk would have been freed if it were empty.
- * If there is no next chunk, return NULL.
- */
- if (licp->lic_next == NULL) {
- return NULL;
- }
-
- licp = licp->lic_next;
- ASSERT(!xfs_lic_are_all_free(licp));
- for (i = 0; i < licp->lic_unused; i++) {
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
-
- return xfs_lic_slot(licp, i);
- }
- ASSERT(0);
- /* NOTREACHED */
- return NULL; /* keep gcc quite */
-}
-
-/*
- * This is called to unlock all of the items of a transaction and to free
- * all the descriptors of that transaction.
- *
- * It walks the list of descriptors and unlocks each item. It frees
- * each chunk except that embedded in the transaction as it goes along.
- */
-void
-xfs_trans_free_items(
- xfs_trans_t *tp,
- xfs_lsn_t commit_lsn,
- int flags)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
- int abort;
-
- abort = flags & XFS_TRANS_ABORT;
- licp = &tp->t_items;
- /*
- * Special case the embedded chunk so we don't free it below.
- */
- if (!xfs_lic_are_all_free(licp)) {
- (void) xfs_trans_unlock_chunk(licp, 1, abort, commit_lsn);
- xfs_lic_all_free(licp);
- licp->lic_unused = 0;
- }
- licp = licp->lic_next;
-
- /*
- * Unlock each item in each chunk and free the chunks.
- */
- while (licp != NULL) {
- ASSERT(!xfs_lic_are_all_free(licp));
- (void) xfs_trans_unlock_chunk(licp, 1, abort, commit_lsn);
- next_licp = licp->lic_next;
- kmem_free(licp);
- licp = next_licp;
- }
-
- /*
- * Reset the transaction structure's free item count.
- */
- tp->t_items_free = XFS_LIC_NUM_SLOTS;
- tp->t_items.lic_next = NULL;
-}
-
-
-
-/*
- * This is called to unlock the items associated with a transaction.
- * Items which were not logged should be freed.
- * Those which were logged must still be tracked so they can be unpinned
- * when the transaction commits.
- */
-void
-xfs_trans_unlock_items(xfs_trans_t *tp, xfs_lsn_t commit_lsn)
-{
- xfs_log_item_chunk_t *licp;
- xfs_log_item_chunk_t *next_licp;
- xfs_log_item_chunk_t **licpp;
- int freed;
-
- freed = 0;
- licp = &tp->t_items;
-
- /*
- * Special case the embedded chunk so we don't free.
- */
- if (!xfs_lic_are_all_free(licp)) {
- freed = xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
- }
- licpp = &(tp->t_items.lic_next);
- licp = licp->lic_next;
-
- /*
- * Unlock each item in each chunk, free non-dirty descriptors,
- * and free empty chunks.
- */
- while (licp != NULL) {
- ASSERT(!xfs_lic_are_all_free(licp));
- freed += xfs_trans_unlock_chunk(licp, 0, 0, commit_lsn);
- next_licp = licp->lic_next;
- if (xfs_lic_are_all_free(licp)) {
- *licpp = next_licp;
- kmem_free(licp);
- freed -= XFS_LIC_NUM_SLOTS;
- } else {
- licpp = &(licp->lic_next);
- }
- ASSERT(*licpp == next_licp);
- licp = next_licp;
- }
-
- /*
- * Fix the free descriptor count in the transaction.
- */
- tp->t_items_free += freed;
-}
-
-/*
- * Unlock each item pointed to by a descriptor in the given chunk.
- * Stamp the commit lsn into each item if necessary.
- * Free descriptors pointing to items which are not dirty if freeing_chunk
- * is zero. If freeing_chunk is non-zero, then we need to unlock all
- * items in the chunk.
- *
- * Return the number of descriptors freed.
- */
-STATIC int
-xfs_trans_unlock_chunk(
- xfs_log_item_chunk_t *licp,
- int freeing_chunk,
- int abort,
- xfs_lsn_t commit_lsn)
-{
- xfs_log_item_desc_t *lidp;
- xfs_log_item_t *lip;
- int i;
- int freed;
-
- freed = 0;
- lidp = licp->lic_descs;
- for (i = 0; i < licp->lic_unused; i++, lidp++) {
- if (xfs_lic_isfree(licp, i)) {
- continue;
- }
- lip = lidp->lid_item;
- lip->li_desc = NULL;
-
- if (commit_lsn != NULLCOMMITLSN)
- IOP_COMMITTING(lip, commit_lsn);
- if (abort)
- lip->li_flags |= XFS_LI_ABORTED;
- IOP_UNLOCK(lip);
-
- /*
- * Free the descriptor if the item is not dirty
- * within this transaction and the caller is not
- * going to just free the entire thing regardless.
- */
- if (!(freeing_chunk) &&
- (!(lidp->lid_flags & XFS_LID_DIRTY) || abort)) {
- xfs_lic_relse(licp, i);
- freed++;
- }
- }
-
- return freed;
-}
diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h
index c6e4f2c8de6e..e2d93d8ead7b 100644
--- a/fs/xfs/xfs_trans_priv.h
+++ b/fs/xfs/xfs_trans_priv.h
@@ -23,22 +23,8 @@ struct xfs_log_item_desc;
struct xfs_mount;
struct xfs_trans;
-/*
- * From xfs_trans_item.c
- */
-struct xfs_log_item_desc *xfs_trans_add_item(struct xfs_trans *,
- struct xfs_log_item *);
-void xfs_trans_free_item(struct xfs_trans *,
- struct xfs_log_item_desc *);
-struct xfs_log_item_desc *xfs_trans_find_item(struct xfs_trans *,
- struct xfs_log_item *);
-struct xfs_log_item_desc *xfs_trans_first_item(struct xfs_trans *);
-struct xfs_log_item_desc *xfs_trans_next_item(struct xfs_trans *,
- struct xfs_log_item_desc *);
-
-void xfs_trans_unlock_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn);
-void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn,
- int flags);
+void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *);
+void xfs_trans_del_item(struct xfs_log_item *);
void xfs_trans_item_committed(struct xfs_log_item *lip,
xfs_lsn_t commit_lsn, int aborted);
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c
index 4d88616bde91..102ce4898ab7 100644
--- a/fs/xfs/xfs_utils.c
+++ b/fs/xfs/xfs_utils.c
@@ -25,18 +25,14 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_bmap_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_bmap.h"
#include "xfs_error.h"
#include "xfs_quota.h"
-#include "xfs_rw.h"
#include "xfs_itable.h"
#include "xfs_utils.h"
@@ -378,8 +374,8 @@ xfs_truncate_file(
* of references will stay constant.
*/
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
+
/*
* Signal a sync xaction. The only case where that isn't
* the case is if we're truncating an already unlinked file
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index c1646838898f..65e087936558 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -26,19 +26,14 @@
#include "xfs_sb.h"
#include "xfs_ag.h"
#include "xfs_dir2.h"
-#include "xfs_dmapi.h"
#include "xfs_mount.h"
#include "xfs_da_btree.h"
#include "xfs_bmap_btree.h"
-#include "xfs_alloc_btree.h"
#include "xfs_ialloc_btree.h"
-#include "xfs_dir2_sf.h"
-#include "xfs_attr_sf.h"
#include "xfs_dinode.h"
#include "xfs_inode.h"
#include "xfs_inode_item.h"
#include "xfs_itable.h"
-#include "xfs_btree.h"
#include "xfs_ialloc.h"
#include "xfs_alloc.h"
#include "xfs_bmap.h"
@@ -73,7 +68,7 @@ xfs_setattr(
struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2;
int need_iolock = 1;
- xfs_itrace_entry(ip);
+ trace_xfs_setattr(ip);
if (mp->m_flags & XFS_MOUNT_RDONLY)
return XFS_ERROR(EROFS);
@@ -143,16 +138,6 @@ xfs_setattr(
goto error_return;
}
} else {
- if (DM_EVENT_ENABLED(ip, DM_EVENT_TRUNCATE) &&
- !(flags & XFS_ATTR_DMI)) {
- int dmflags = AT_DELAY_FLAG(flags) | DM_SEM_FLAG_WR;
- code = XFS_SEND_DATA(mp, DM_EVENT_TRUNCATE, ip,
- iattr->ia_size, 0, dmflags, NULL);
- if (code) {
- lock_flags = 0;
- goto error_return;
- }
- }
if (need_iolock)
lock_flags |= XFS_IOLOCK_EXCL;
}
@@ -236,8 +221,11 @@ xfs_setattr(
* transaction to modify the i_size.
*/
code = xfs_zero_eof(ip, iattr->ia_size, ip->i_size);
+ if (code)
+ goto error_return;
}
xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ lock_flags &= ~XFS_ILOCK_EXCL;
/*
* We are going to log the inode size change in this
@@ -251,40 +239,38 @@ xfs_setattr(
* really care about here and prevents waiting for other data
* not within the range we care about here.
*/
- if (!code &&
- ip->i_size != ip->i_d.di_size &&
+ if (ip->i_size != ip->i_d.di_size &&
iattr->ia_size > ip->i_d.di_size) {
code = xfs_flush_pages(ip,
ip->i_d.di_size, iattr->ia_size,
XBF_ASYNC, FI_NONE);
+ if (code)
+ goto error_return;
}
/* wait for all I/O to complete */
xfs_ioend_wait(ip);
- if (!code)
- code = xfs_itruncate_data(ip, iattr->ia_size);
- if (code) {
- ASSERT(tp == NULL);
- lock_flags &= ~XFS_ILOCK_EXCL;
- ASSERT(lock_flags == XFS_IOLOCK_EXCL || !need_iolock);
+ code = -block_truncate_page(inode->i_mapping, iattr->ia_size,
+ xfs_get_blocks);
+ if (code)
goto error_return;
- }
+
tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE);
- if ((code = xfs_trans_reserve(tp, 0,
- XFS_ITRUNCATE_LOG_RES(mp), 0,
- XFS_TRANS_PERM_LOG_RES,
- XFS_ITRUNCATE_LOG_COUNT))) {
- xfs_trans_cancel(tp, 0);
- if (need_iolock)
- xfs_iunlock(ip, XFS_IOLOCK_EXCL);
- return code;
- }
+ code = xfs_trans_reserve(tp, 0, XFS_ITRUNCATE_LOG_RES(mp), 0,
+ XFS_TRANS_PERM_LOG_RES,
+ XFS_ITRUNCATE_LOG_COUNT);
+ if (code)
+ goto error_return;
+
+ truncate_setsize(inode, iattr->ia_size);
+
commit_flags = XFS_TRANS_RELEASE_LOG_RES;
+ lock_flags |= XFS_ILOCK_EXCL;
+
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, lock_flags);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* Only change the c/mtime if we are changing the size
@@ -334,8 +320,7 @@ xfs_setattr(
xfs_iflags_set(ip, XFS_ITRUNCATED);
}
} else if (tp) {
- xfs_trans_ijoin(tp, ip, lock_flags);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
}
/*
@@ -470,17 +455,10 @@ xfs_setattr(
return XFS_ERROR(code);
}
- if (DM_EVENT_ENABLED(ip, DM_EVENT_ATTRIBUTE) &&
- !(flags & XFS_ATTR_DMI)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_ATTRIBUTE, ip, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, NULL, NULL,
- 0, 0, AT_DELAY_FLAG(flags));
- }
return 0;
abort_return:
commit_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
error_return:
xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp);
@@ -516,7 +494,7 @@ xfs_readlink_bmap(
int error = 0;
error = xfs_bmapi(NULL, ip, 0, XFS_B_TO_FSB(mp, pathlen), 0, NULL, 0,
- mval, &nmaps, NULL, NULL);
+ mval, &nmaps, NULL);
if (error)
goto out;
@@ -557,7 +535,7 @@ xfs_readlink(
int pathlen;
int error = 0;
- xfs_itrace_entry(ip);
+ trace_xfs_readlink(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -620,7 +598,7 @@ xfs_free_eofblocks(
nimaps = 1;
xfs_ilock(ip, XFS_ILOCK_SHARED);
error = xfs_bmapi(NULL, ip, end_fsb, map_len, 0,
- NULL, 0, &imap, &nimaps, NULL, NULL);
+ NULL, 0, &imap, &nimaps, NULL);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
if (!error && (nimaps != 0) &&
@@ -675,10 +653,7 @@ xfs_free_eofblocks(
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip,
- XFS_IOLOCK_EXCL |
- XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
error = xfs_itruncate_finish(&tp, ip,
ip->i_size,
@@ -750,8 +725,7 @@ xfs_inactive_symlink_rmt(
xfs_ilock(ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
size = (int)ip->i_d.di_size;
ip->i_d.di_size = 0;
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
/*
* Find the block(s) so we can inval and unmap them.
@@ -761,7 +735,7 @@ xfs_inactive_symlink_rmt(
nmaps = ARRAY_SIZE(mval);
if ((error = xfs_bmapi(tp, ip, 0, XFS_B_TO_FSB(mp, size),
XFS_BMAPI_METADATA, &first_block, 0, mval, &nmaps,
- &free_list, NULL)))
+ &free_list)))
goto error0;
/*
* Invalidate the block(s).
@@ -776,7 +750,7 @@ xfs_inactive_symlink_rmt(
* Unmap the dead block(s) to the free_list.
*/
if ((error = xfs_bunmapi(tp, ip, 0, size, XFS_BMAPI_METADATA, nmaps,
- &first_block, &free_list, NULL, &done)))
+ &first_block, &free_list, &done)))
goto error1;
ASSERT(done);
/*
@@ -795,8 +769,7 @@ xfs_inactive_symlink_rmt(
* Mark it dirty so it will be logged and moved forward in the log as
* part of every commit.
*/
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
/*
* Get a new, empty transaction to return to our caller.
@@ -929,8 +902,7 @@ xfs_inactive_attrs(
goto error_cancel;
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
xfs_idestroy_fork(ip, XFS_ATTR_FORK);
ASSERT(ip->i_d.di_anextents == 0);
@@ -1035,8 +1007,6 @@ xfs_inactive(
int error;
int truncate;
- xfs_itrace_entry(ip);
-
/*
* If the inode is already free, then there can be nothing
* to clean up here.
@@ -1060,9 +1030,6 @@ xfs_inactive(
mp = ip->i_mount;
- if (ip->i_d.di_nlink == 0 && DM_EVENT_ENABLED(ip, DM_EVENT_DESTROY))
- XFS_SEND_DESTROY(mp, ip, DM_RIGHT_NULL);
-
error = 0;
/* If this is a read-only mount, don't do this (would generate I/O) */
@@ -1120,8 +1087,7 @@ xfs_inactive(
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* normally, we have to run xfs_itruncate_finish sync.
@@ -1154,8 +1120,7 @@ xfs_inactive(
return VN_INACTIVE_CACHE;
}
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
} else {
error = xfs_trans_reserve(tp, 0,
XFS_IFREE_LOG_RES(mp),
@@ -1168,8 +1133,7 @@ xfs_inactive(
}
xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_IOLOCK_EXCL | XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
}
/*
@@ -1257,7 +1221,7 @@ xfs_lookup(
int error;
uint lock_mode;
- xfs_itrace_entry(dp);
+ trace_xfs_lookup(dp, name);
if (XFS_FORCED_SHUTDOWN(dp->i_mount))
return XFS_ERROR(EIO);
@@ -1309,21 +1273,11 @@ xfs_create(
uint log_res;
uint log_count;
- xfs_itrace_entry(dp);
+ trace_xfs_create(dp, name);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- if (DM_EVENT_ENABLED(dp, DM_EVENT_CREATE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_CREATE,
- dp, DM_RIGHT_NULL, NULL,
- DM_RIGHT_NULL, name->name, NULL,
- mode, 0, 0);
-
- if (error)
- return error;
- }
-
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
else
@@ -1427,8 +1381,7 @@ xfs_create(
* the transaction cancel unlocking dp so don't do it explicitly in the
* error path.
*/
- IHOLD(dp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = B_FALSE;
error = xfs_dir_createname(tp, dp, name, ip->i_ino,
@@ -1487,16 +1440,7 @@ xfs_create(
xfs_qm_dqrele(gdqp);
*ipp = ip;
-
- /* Fallthrough to std_return with error = 0 */
- std_return:
- if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTCREATE)) {
- XFS_SEND_NAMESP(mp, DM_EVENT_POSTCREATE, dp, DM_RIGHT_NULL,
- ip, DM_RIGHT_NULL, name->name, NULL, mode,
- error, 0);
- }
-
- return error;
+ return 0;
out_bmap_cancel:
xfs_bmap_cancel(&free_list);
@@ -1510,8 +1454,8 @@ xfs_create(
if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- goto std_return;
+ std_return:
+ return error;
out_abort_rele:
/*
@@ -1726,20 +1670,11 @@ xfs_remove(
uint resblks;
uint log_count;
- xfs_itrace_entry(dp);
- xfs_itrace_entry(ip);
+ trace_xfs_remove(dp, name);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- if (DM_EVENT_ENABLED(dp, DM_EVENT_REMOVE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_REMOVE, dp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, name->name, NULL,
- ip->i_d.di_mode, 0, 0);
- if (error)
- return error;
- }
-
error = xfs_qm_dqattach(dp, 0);
if (error)
goto std_return;
@@ -1782,15 +1717,8 @@ xfs_remove(
xfs_lock_two_inodes(dp, ip, XFS_ILOCK_EXCL);
- /*
- * At this point, we've gotten both the directory and the entry
- * inodes locked.
- */
- IHOLD(ip);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
-
- IHOLD(dp);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
/*
* If we're removing a directory perform some additional validation.
@@ -1877,21 +1805,15 @@ xfs_remove(
if (!is_dir && link_zero && xfs_inode_is_filestream(ip))
xfs_filestream_deassociate(ip);
- std_return:
- if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTREMOVE)) {
- XFS_SEND_NAMESP(mp, DM_EVENT_POSTREMOVE, dp, DM_RIGHT_NULL,
- NULL, DM_RIGHT_NULL, name->name, NULL,
- ip->i_d.di_mode, error, 0);
- }
-
- return error;
+ return 0;
out_bmap_cancel:
xfs_bmap_cancel(&free_list);
cancel_flags |= XFS_TRANS_ABORT;
out_trans_cancel:
xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
+ std_return:
+ return error;
}
int
@@ -1909,25 +1831,13 @@ xfs_link(
int committed;
int resblks;
- xfs_itrace_entry(tdp);
- xfs_itrace_entry(sip);
+ trace_xfs_link(tdp, target_name);
ASSERT(!S_ISDIR(sip->i_d.di_mode));
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
- if (DM_EVENT_ENABLED(tdp, DM_EVENT_LINK)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_LINK,
- tdp, DM_RIGHT_NULL,
- sip, DM_RIGHT_NULL,
- target_name->name, NULL, 0, 0, 0);
- if (error)
- return error;
- }
-
- /* Return through std_return after this point. */
-
error = xfs_qm_dqattach(sip, 0);
if (error)
goto std_return;
@@ -1953,15 +1863,8 @@ xfs_link(
xfs_lock_two_inodes(sip, tdp, XFS_ILOCK_EXCL);
- /*
- * Increment vnode ref counts since xfs_trans_commit &
- * xfs_trans_cancel will both unlock the inodes and
- * decrement the associated ref counts.
- */
- IHOLD(sip);
- IHOLD(tdp);
- xfs_trans_ijoin(tp, sip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, tdp, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, sip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, tdp, XFS_ILOCK_EXCL);
/*
* If the source has too many links, we can't make any more to it.
@@ -2014,27 +1917,14 @@ xfs_link(
goto abort_return;
}
- error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
- if (error)
- goto std_return;
-
- /* Fall through to std_return with error = 0. */
-std_return:
- if (DM_EVENT_ENABLED(sip, DM_EVENT_POSTLINK)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTLINK,
- tdp, DM_RIGHT_NULL,
- sip, DM_RIGHT_NULL,
- target_name->name, NULL, 0, error, 0);
- }
- return error;
+ return xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
abort_return:
cancel_flags |= XFS_TRANS_ABORT;
- /* FALLTHROUGH */
-
error_return:
xfs_trans_cancel(tp, cancel_flags);
- goto std_return;
+ std_return:
+ return error;
}
int
@@ -2074,7 +1964,7 @@ xfs_symlink(
ip = NULL;
tp = NULL;
- xfs_itrace_entry(dp);
+ trace_xfs_symlink(dp, link_name);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -2086,17 +1976,6 @@ xfs_symlink(
if (pathlen >= MAXPATHLEN) /* total string too long */
return XFS_ERROR(ENAMETOOLONG);
- if (DM_EVENT_ENABLED(dp, DM_EVENT_SYMLINK)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_SYMLINK, dp,
- DM_RIGHT_NULL, NULL, DM_RIGHT_NULL,
- link_name->name,
- (unsigned char *)target_path, 0, 0, 0);
- if (error)
- return error;
- }
-
- /* Return through std_return after this point. */
-
udqp = gdqp = NULL;
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
prid = dp->i_d.di_projid;
@@ -2180,8 +2059,7 @@ xfs_symlink(
* transaction cancel unlocking dp so don't do it explicitly in the
* error path.
*/
- IHOLD(dp);
- xfs_trans_ijoin(tp, dp, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, dp, XFS_ILOCK_EXCL);
unlock_dp_on_error = B_FALSE;
/*
@@ -2215,7 +2093,7 @@ xfs_symlink(
error = xfs_bmapi(tp, ip, first_fsb, fs_blocks,
XFS_BMAPI_WRITE | XFS_BMAPI_METADATA,
&first_block, resblks, mval, &nmaps,
- &free_list, NULL);
+ &free_list);
if (error) {
goto error1;
}
@@ -2278,21 +2156,8 @@ xfs_symlink(
xfs_qm_dqrele(udqp);
xfs_qm_dqrele(gdqp);
- /* Fall through to std_return with error = 0 or errno from
- * xfs_trans_commit */
-std_return:
- if (DM_EVENT_ENABLED(dp, DM_EVENT_POSTSYMLINK)) {
- (void) XFS_SEND_NAMESP(mp, DM_EVENT_POSTSYMLINK,
- dp, DM_RIGHT_NULL,
- error ? NULL : ip,
- DM_RIGHT_NULL, link_name->name,
- (unsigned char *)target_path,
- 0, error, 0);
- }
-
- if (!error)
- *ipp = ip;
- return error;
+ *ipp = ip;
+ return 0;
error2:
IRELE(ip);
@@ -2306,8 +2171,8 @@ std_return:
if (unlock_dp_on_error)
xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
- goto std_return;
+ std_return:
+ return error;
}
int
@@ -2333,13 +2198,12 @@ xfs_set_dmattrs(
return error;
}
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
+ xfs_trans_ijoin_ref(tp, ip, XFS_ILOCK_EXCL);
ip->i_d.di_dmevmask = evmask;
ip->i_d.di_dmstate = state;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- IHOLD(ip);
error = xfs_trans_commit(tp, 0);
return error;
@@ -2390,7 +2254,7 @@ xfs_alloc_file_space(
int committed;
int error;
- xfs_itrace_entry(ip);
+ trace_xfs_alloc_file_space(ip);
if (XFS_FORCED_SHUTDOWN(mp))
return XFS_ERROR(EIO);
@@ -2412,25 +2276,9 @@ xfs_alloc_file_space(
startoffset_fsb = XFS_B_TO_FSBT(mp, offset);
allocatesize_fsb = XFS_B_TO_FSB(mp, count);
- /* Generate a DMAPI event if needed. */
- if (alloc_type != 0 && offset < ip->i_size &&
- (attr_flags & XFS_ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
- xfs_off_t end_dmi_offset;
-
- end_dmi_offset = offset+len;
- if (end_dmi_offset > ip->i_size)
- end_dmi_offset = ip->i_size;
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip, offset,
- end_dmi_offset - offset, 0, NULL);
- if (error)
- return error;
- }
-
/*
* Allocate file space until done or until there is an error
*/
-retry:
while (allocatesize_fsb && !error) {
xfs_fileoff_t s, e;
@@ -2488,8 +2336,7 @@ retry:
if (error)
goto error1;
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* Issue the xfs_bmapi() call to allocate the blocks
@@ -2498,7 +2345,7 @@ retry:
error = xfs_bmapi(tp, ip, startoffset_fsb,
allocatesize_fsb, bmapi_flag,
&firstfsb, 0, imapp, &nimaps,
- &free_list, NULL);
+ &free_list);
if (error) {
goto error0;
}
@@ -2527,17 +2374,6 @@ retry:
startoffset_fsb += allocated_fsb;
allocatesize_fsb -= allocated_fsb;
}
-dmapi_enospc_check:
- if (error == ENOSPC && (attr_flags & XFS_ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(ip, DM_EVENT_NOSPACE)) {
- error = XFS_SEND_NAMESP(mp, DM_EVENT_NOSPACE,
- ip, DM_RIGHT_NULL,
- ip, DM_RIGHT_NULL,
- NULL, NULL, 0, 0, 0); /* Delay flag intentionally unused */
- if (error == 0)
- goto retry; /* Maybe DMAPI app. has made space */
- /* else fall through with error from XFS_SEND_DATA */
- }
return error;
@@ -2548,7 +2384,7 @@ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */
error1: /* Just cancel transaction */
xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT);
xfs_iunlock(ip, XFS_ILOCK_EXCL);
- goto dmapi_enospc_check;
+ return error;
}
/*
@@ -2598,7 +2434,7 @@ xfs_zero_remaining_bytes(
offset_fsb = XFS_B_TO_FSBT(mp, offset);
nimap = 1;
error = xfs_bmapi(NULL, ip, offset_fsb, 1, 0,
- NULL, 0, &imap, &nimap, NULL, NULL);
+ NULL, 0, &imap, &nimap, NULL);
if (error || nimap < 1)
break;
ASSERT(imap.br_blockcount >= 1);
@@ -2661,7 +2497,6 @@ xfs_free_file_space(
{
int committed;
int done;
- xfs_off_t end_dmi_offset;
xfs_fileoff_t endoffset_fsb;
int error;
xfs_fsblock_t firstfsb;
@@ -2680,7 +2515,7 @@ xfs_free_file_space(
mp = ip->i_mount;
- xfs_itrace_entry(ip);
+ trace_xfs_free_file_space(ip);
error = xfs_qm_dqattach(ip, 0);
if (error)
@@ -2691,19 +2526,7 @@ xfs_free_file_space(
return error;
rt = XFS_IS_REALTIME_INODE(ip);
startoffset_fsb = XFS_B_TO_FSB(mp, offset);
- end_dmi_offset = offset + len;
- endoffset_fsb = XFS_B_TO_FSBT(mp, end_dmi_offset);
-
- if (offset < ip->i_size && (attr_flags & XFS_ATTR_DMI) == 0 &&
- DM_EVENT_ENABLED(ip, DM_EVENT_WRITE)) {
- if (end_dmi_offset > ip->i_size)
- end_dmi_offset = ip->i_size;
- error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, ip,
- offset, end_dmi_offset - offset,
- AT_DELAY_FLAG(attr_flags), NULL);
- if (error)
- return error;
- }
+ endoffset_fsb = XFS_B_TO_FSBT(mp, offset + len);
if (attr_flags & XFS_ATTR_NOLOCK)
need_iolock = 0;
@@ -2731,7 +2554,7 @@ xfs_free_file_space(
if (rt && !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
nimap = 1;
error = xfs_bmapi(NULL, ip, startoffset_fsb,
- 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
+ 1, 0, NULL, 0, &imap, &nimap, NULL);
if (error)
goto out_unlock_iolock;
ASSERT(nimap == 0 || nimap == 1);
@@ -2746,7 +2569,7 @@ xfs_free_file_space(
}
nimap = 1;
error = xfs_bmapi(NULL, ip, endoffset_fsb - 1,
- 1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
+ 1, 0, NULL, 0, &imap, &nimap, NULL);
if (error)
goto out_unlock_iolock;
ASSERT(nimap == 0 || nimap == 1);
@@ -2814,8 +2637,7 @@ xfs_free_file_space(
if (error)
goto error1;
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
/*
* issue the bunmapi() call to free the blocks
@@ -2823,7 +2645,7 @@ xfs_free_file_space(
xfs_bmap_init(&free_list, &firstfsb);
error = xfs_bunmapi(tp, ip, startoffset_fsb,
endoffset_fsb - startoffset_fsb,
- 0, 2, &firstfsb, &free_list, NULL, &done);
+ 0, 2, &firstfsb, &free_list, &done);
if (error) {
goto error0;
}
@@ -2883,8 +2705,6 @@ xfs_change_file_space(
xfs_trans_t *tp;
struct iattr iattr;
- xfs_itrace_entry(ip);
-
if (!S_ISREG(ip->i_d.di_mode))
return XFS_ERROR(EINVAL);
@@ -2985,8 +2805,7 @@ xfs_change_file_space(
xfs_ilock(ip, XFS_ILOCK_EXCL);
- xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
- xfs_trans_ihold(tp, ip);
+ xfs_trans_ijoin(tp, ip);
if ((attr_flags & XFS_ATTR_DMI) == 0) {
ip->i_d.di_mode &= ~S_ISUID;
diff --git a/include/asm-generic/atomic.h b/include/asm-generic/atomic.h
index 058129e9b04c..e53347fbf1da 100644
--- a/include/asm-generic/atomic.h
+++ b/include/asm-generic/atomic.h
@@ -57,11 +57,11 @@ static inline int atomic_add_return(int i, atomic_t *v)
unsigned long flags;
int temp;
- local_irq_save(flags);
+ raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
temp = v->counter;
temp += i;
v->counter = temp;
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
return temp;
}
@@ -78,11 +78,11 @@ static inline int atomic_sub_return(int i, atomic_t *v)
unsigned long flags;
int temp;
- local_irq_save(flags);
+ raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
temp = v->counter;
temp -= i;
v->counter = temp;
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
return temp;
}
@@ -135,9 +135,9 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
unsigned long flags;
mask = ~mask;
- local_irq_save(flags);
+ raw_local_irq_save(flags); /* Don't trace it in a irqsoff handler */
*addr &= mask;
- local_irq_restore(flags);
+ raw_local_irq_restore(flags);
}
#define atomic_xchg(ptr, v) (xchg(&(ptr)->counter, (v)))
diff --git a/include/asm-generic/unistd.h b/include/asm-generic/unistd.h
index 6a0b30f78a62..c17cebc49952 100644
--- a/include/asm-generic/unistd.h
+++ b/include/asm-generic/unistd.h
@@ -18,7 +18,7 @@
#define __SYSCALL(x, y)
#endif
-#if __BITS_PER_LONG == 32
+#if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32)
#else
#define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _64)
@@ -241,8 +241,13 @@ __SYSCALL(__NR_sync, sys_sync)
__SYSCALL(__NR_fsync, sys_fsync)
#define __NR_fdatasync 83
__SYSCALL(__NR_fdatasync, sys_fdatasync)
+#ifdef __ARCH_WANT_SYNC_FILE_RANGE2
+#define __NR_sync_file_range2 84
+__SYSCALL(__NR_sync_file_range2, sys_sync_file_range2)
+#else
#define __NR_sync_file_range 84
-__SYSCALL(__NR_sync_file_range, sys_sync_file_range) /* .long sys_sync_file_range2, */
+__SYSCALL(__NR_sync_file_range, sys_sync_file_range)
+#endif
/* fs/timerfd.c */
#define __NR_timerfd_create 85
@@ -580,7 +585,7 @@ __SYSCALL(__NR_execve, sys_execve) /* .long sys_execve_wrapper */
__SC_3264(__NR3264_mmap, sys_mmap2, sys_mmap)
/* mm/fadvise.c */
#define __NR3264_fadvise64 223
-__SC_3264(__NR3264_fadvise64, sys_fadvise64_64, sys_fadvise64)
+__SYSCALL(__NR3264_fadvise64, sys_fadvise64_64)
/* mm/, CONFIG_MMU only */
#ifndef __ARCH_NOMMU
@@ -627,8 +632,17 @@ __SYSCALL(__NR_accept4, sys_accept4)
#define __NR_recvmmsg 243
__SYSCALL(__NR_recvmmsg, sys_recvmmsg)
+/*
+ * Architectures may provide up to 16 syscalls of their own
+ * starting with this value.
+ */
+#define __NR_arch_specific_syscall 244
+
+#define __NR_wait4 260
+__SYSCALL(__NR_wait4, sys_wait4)
+
#undef __NR_syscalls
-#define __NR_syscalls 244
+#define __NR_syscalls 261
/*
* All syscalls below here should go away really,
@@ -694,7 +708,8 @@ __SYSCALL(__NR_signalfd, sys_signalfd)
#define __NR_syscalls (__NR_signalfd+1)
#endif /* __ARCH_WANT_SYSCALL_NO_FLAGS */
-#if __BITS_PER_LONG == 32 && defined(__ARCH_WANT_SYSCALL_OFF_T)
+#if (__BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT)) && \
+ defined(__ARCH_WANT_SYSCALL_OFF_T)
#define __NR_sendfile 1046
__SYSCALL(__NR_sendfile, sys_sendfile)
#define __NR_ftruncate 1047
@@ -740,6 +755,7 @@ __SYSCALL(__NR_getpgrp, sys_getpgrp)
__SYSCALL(__NR_pause, sys_pause)
#define __NR_time 1062
#define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_COMPAT_SYS_TIME
__SYSCALL(__NR_time, sys_time)
#define __NR_utime 1063
#define __ARCH_WANT_SYS_UTIME
@@ -763,8 +779,8 @@ __SYSCALL(__NR_epoll_wait, sys_epoll_wait)
__SYSCALL(__NR_ustat, sys_ustat)
#define __NR_vfork 1071
__SYSCALL(__NR_vfork, sys_vfork)
-#define __NR_wait4 1072
-__SYSCALL(__NR_wait4, sys_wait4)
+#define __NR_oldwait4 1072
+__SYSCALL(__NR_oldwait4, sys_wait4)
#define __NR_recv 1073
__SYSCALL(__NR_recv, sys_recv)
#define __NR_send 1074
@@ -801,7 +817,7 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
* Here we map the numbers so that both versions
* use the same syscall table layout.
*/
-#if __BITS_PER_LONG == 64
+#if __BITS_PER_LONG == 64 && !defined(__SYSCALL_COMPAT)
#define __NR_fcntl __NR3264_fcntl
#define __NR_statfs __NR3264_statfs
#define __NR_fstatfs __NR3264_fstatfs
@@ -848,6 +864,7 @@ __SYSCALL(__NR_fork, sys_ni_syscall)
#endif
#define __ARCH_WANT_SYS_RT_SIGACTION
#define __ARCH_WANT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
/*
* "Conditional" syscalls
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 1b9ba193b789..620f1d1088cb 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -203,12 +203,10 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block,
int block_read_full_page(struct page*, get_block_t*);
int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
unsigned long from);
-int block_write_begin_newtrunc(struct file *, struct address_space *,
- loff_t, unsigned, unsigned,
- struct page **, void **, get_block_t*);
-int block_write_begin(struct file *, struct address_space *,
- loff_t, unsigned, unsigned,
- struct page **, void **, get_block_t*);
+int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len,
+ unsigned flags, struct page **pagep, get_block_t *get_block);
+int __block_write_begin(struct page *page, loff_t pos, unsigned len,
+ get_block_t *get_block);
int block_write_end(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
struct page *, void *);
@@ -217,9 +215,6 @@ int generic_write_end(struct file *, struct address_space *,
struct page *, void *);
void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
-int cont_write_begin_newtrunc(struct file *, struct address_space *, loff_t,
- unsigned, unsigned, struct page **, void **,
- get_block_t *, loff_t *);
int cont_write_begin(struct file *, struct address_space *, loff_t,
unsigned, unsigned, struct page **, void **,
get_block_t *, loff_t *);
@@ -230,12 +225,7 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
void block_sync_page(struct page *);
sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
-int file_fsync(struct file *, int);
-int nobh_write_begin_newtrunc(struct file *, struct address_space *,
- loff_t, unsigned, unsigned,
- struct page **, void **, get_block_t*);
-int nobh_write_begin(struct file *, struct address_space *,
- loff_t, unsigned, unsigned,
+int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned,
struct page **, void **, get_block_t*);
int nobh_write_end(struct file *, struct address_space *,
loff_t, unsigned, unsigned,
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index eebb617c17d8..d23be0386e2d 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -315,6 +315,7 @@ extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...);
extern char *__d_path(const struct path *path, struct path *root, char *, int);
extern char *d_path(const struct path *, char *, int);
+extern char *__dentry_path(struct dentry *, char *, int);
extern char *dentry_path(struct dentry *, char *, int);
/* Allocation counts.. */
diff --git a/include/linux/dqblk_xfs.h b/include/linux/dqblk_xfs.h
index 4389ae72024e..86552807aed9 100644
--- a/include/linux/dqblk_xfs.h
+++ b/include/linux/dqblk_xfs.h
@@ -49,7 +49,7 @@
#define FS_DQUOT_VERSION 1 /* fs_disk_quota.d_version */
typedef struct fs_disk_quota {
__s8 d_version; /* version of this structure */
- __s8 d_flags; /* XFS_{USER,PROJ,GROUP}_QUOTA */
+ __s8 d_flags; /* FS_{USER,PROJ,GROUP}_QUOTA */
__u16 d_fieldmask; /* field specifier */
__u32 d_id; /* user, project, or group ID */
__u64 d_blk_hardlimit;/* absolute limit on disk blks */
@@ -119,18 +119,18 @@ typedef struct fs_disk_quota {
#define FS_DQ_ACCT_MASK (FS_DQ_BCOUNT | FS_DQ_ICOUNT | FS_DQ_RTBCOUNT)
/*
- * Various flags related to quotactl(2). Only relevant to XFS filesystems.
+ * Various flags related to quotactl(2).
*/
-#define XFS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
-#define XFS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
-#define XFS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
-#define XFS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
-#define XFS_QUOTA_PDQ_ACCT (1<<4) /* project quota accounting */
-#define XFS_QUOTA_PDQ_ENFD (1<<5) /* project quota limits enforcement */
+#define FS_QUOTA_UDQ_ACCT (1<<0) /* user quota accounting */
+#define FS_QUOTA_UDQ_ENFD (1<<1) /* user quota limits enforcement */
+#define FS_QUOTA_GDQ_ACCT (1<<2) /* group quota accounting */
+#define FS_QUOTA_GDQ_ENFD (1<<3) /* group quota limits enforcement */
+#define FS_QUOTA_PDQ_ACCT (1<<4) /* project quota accounting */
+#define FS_QUOTA_PDQ_ENFD (1<<5) /* project quota limits enforcement */
-#define XFS_USER_QUOTA (1<<0) /* user quota type */
-#define XFS_PROJ_QUOTA (1<<1) /* project quota type */
-#define XFS_GROUP_QUOTA (1<<2) /* group quota type */
+#define FS_USER_QUOTA (1<<0) /* user quota type */
+#define FS_PROJ_QUOTA (1<<1) /* project quota type */
+#define FS_GROUP_QUOTA (1<<2) /* group quota type */
/*
* fs_quota_stat is the struct returned in Q_XGETQSTAT for a given file system.
@@ -151,7 +151,7 @@ typedef struct fs_qfilestat {
typedef struct fs_quota_stat {
__s8 qs_version; /* version number for future changes */
- __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
+ __u16 qs_flags; /* FS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
__s8 qs_pad; /* unused */
fs_qfilestat_t qs_uquota; /* user quota storage information */
fs_qfilestat_t qs_gquota; /* group quota storage information */
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index b6cb5425cde3..493a2bf85f62 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -62,6 +62,7 @@ typedef enum fe_caps {
FE_CAN_8VSB = 0x200000,
FE_CAN_16VSB = 0x400000,
FE_HAS_EXTENDED_CAPS = 0x800000, /* We need more bitspace for newer APIs, indicate this. */
+ FE_CAN_TURBO_FEC = 0x8000000, /* frontend supports "turbo fec modulation" */
FE_CAN_2G_MODULATION = 0x10000000, /* frontend supports "2nd generation modulation" (DVB-S2) */
FE_NEEDS_BENDING = 0x20000000, /* not supported anymore, don't use (frontend requires frequency bending) */
FE_CAN_RECOVER = 0x40000000, /* frontend can recover from a cable unplug automatically */
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 540b0583d9fb..5a7546c12688 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
#define _DVBVERSION_H_
#define DVB_API_VERSION 5
-#define DVB_API_VERSION_MINOR 1
+#define DVB_API_VERSION_MINOR 2
#endif /*_DVBVERSION_H_*/
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 7fc62d4550b2..6ce1bca01724 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -400,7 +400,6 @@ struct ext3_inode {
#define EXT3_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */
#define EXT3_MOUNT_RESERVATION 0x10000 /* Preallocation */
#define EXT3_MOUNT_BARRIER 0x20000 /* Use block barriers */
-#define EXT3_MOUNT_NOBH 0x40000 /* No bufferheads */
#define EXT3_MOUNT_QUOTA 0x80000 /* Some quota option set */
#define EXT3_MOUNT_USRQUOTA 0x100000 /* "old" user quota */
#define EXT3_MOUNT_GRPQUOTA 0x200000 /* "old" group quota */
@@ -896,7 +895,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode,
extern struct inode *ext3_iget(struct super_block *, unsigned long);
extern int ext3_write_inode (struct inode *, struct writeback_control *);
extern int ext3_setattr (struct dentry *, struct iattr *);
-extern void ext3_delete_inode (struct inode *);
+extern void ext3_evict_inode (struct inode *);
extern int ext3_sync_inode (handle_t *, struct inode *);
extern void ext3_discard_reservation (struct inode *);
extern void ext3_dirty_inode(struct inode *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 68ca1b0491af..da6d7dc13ce7 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1562,7 +1562,7 @@ struct super_operations {
void (*dirty_inode) (struct inode *);
int (*write_inode) (struct inode *, struct writeback_control *wbc);
void (*drop_inode) (struct inode *);
- void (*delete_inode) (struct inode *);
+ void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
@@ -1570,7 +1570,6 @@ struct super_operations {
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
- void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct vfsmount *);
@@ -1615,8 +1614,8 @@ struct super_operations {
* I_FREEING Set when inode is about to be freed but still has dirty
* pages or buffers attached or the inode itself is still
* dirty.
- * I_CLEAR Set by clear_inode(). In this state the inode is clean
- * and can be destroyed.
+ * I_CLEAR Added by end_writeback(). In this state the inode is clean
+ * and can be destroyed. Inode keeps I_FREEING.
*
* Inodes that are I_WILL_FREE, I_FREEING or I_CLEAR are
* prohibited for many purposes. iget() must wait for
@@ -2165,7 +2164,6 @@ extern ino_t iunique(struct super_block *, ino_t);
extern int inode_needs_sync(struct inode *inode);
extern void generic_delete_inode(struct inode *inode);
extern void generic_drop_inode(struct inode *inode);
-extern int generic_detach_inode(struct inode *inode);
extern struct inode *ilookup5_nowait(struct super_block *sb,
unsigned long hashval, int (*test)(struct inode *, void *),
@@ -2182,7 +2180,7 @@ extern void unlock_new_inode(struct inode *);
extern void __iget(struct inode * inode);
extern void iget_failed(struct inode *);
-extern void clear_inode(struct inode *);
+extern void end_writeback(struct inode *);
extern void destroy_inode(struct inode *);
extern void __destroy_inode(struct inode *);
extern struct inode *new_inode(struct super_block *);
@@ -2268,16 +2266,6 @@ static inline int xip_truncate_page(struct address_space *mapping, loff_t from)
struct bio;
typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode,
loff_t file_offset);
-void dio_end_io(struct bio *bio, int error);
-
-ssize_t __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
- struct block_device *bdev, const struct iovec *iov, loff_t offset,
- unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
- dio_submit_t submit_io, int lock_type);
-ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
- struct block_device *bdev, const struct iovec *iov, loff_t offset,
- unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
- dio_submit_t submit_io, int lock_type);
enum {
/* need locking between buffered and direct access */
@@ -2287,24 +2275,13 @@ enum {
DIO_SKIP_HOLES = 0x02,
};
-static inline ssize_t blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb,
- struct inode *inode, struct block_device *bdev, const struct iovec *iov,
- loff_t offset, unsigned long nr_segs, get_block_t get_block,
- dio_iodone_t end_io)
-{
- return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
- nr_segs, get_block, end_io, NULL,
- DIO_LOCKING | DIO_SKIP_HOLES);
-}
+void dio_end_io(struct bio *bio, int error);
+
+ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
+ struct block_device *bdev, const struct iovec *iov, loff_t offset,
+ unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
+ dio_submit_t submit_io, int flags);
-static inline ssize_t blockdev_direct_IO_no_locking_newtrunc(int rw, struct kiocb *iocb,
- struct inode *inode, struct block_device *bdev, const struct iovec *iov,
- loff_t offset, unsigned long nr_segs, get_block_t get_block,
- dio_iodone_t end_io)
-{
- return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
- nr_segs, get_block, end_io, NULL, 0);
-}
static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
struct inode *inode, struct block_device *bdev, const struct iovec *iov,
loff_t offset, unsigned long nr_segs, get_block_t get_block,
@@ -2314,15 +2291,6 @@ static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
nr_segs, get_block, end_io, NULL,
DIO_LOCKING | DIO_SKIP_HOLES);
}
-
-static inline ssize_t blockdev_direct_IO_no_locking(int rw, struct kiocb *iocb,
- struct inode *inode, struct block_device *bdev, const struct iovec *iov,
- loff_t offset, unsigned long nr_segs, get_block_t get_block,
- dio_iodone_t end_io)
-{
- return __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset,
- nr_segs, get_block, end_io, NULL, 0);
-}
#endif
extern const struct file_operations generic_ro_fops;
@@ -2384,7 +2352,6 @@ extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
-extern int simple_setsize(struct inode *, loff_t);
extern int noop_fsync(struct file *, int);
extern int simple_empty(struct dentry *);
extern int simple_readpage(struct file *file, struct page *page);
@@ -2421,8 +2388,7 @@ extern int buffer_migrate_page(struct address_space *,
extern int inode_change_ok(const struct inode *, struct iattr *);
extern int inode_newsize_ok(const struct inode *, loff_t offset);
-extern int __must_check inode_setattr(struct inode *, const struct iattr *);
-extern void generic_setattr(struct inode *inode, const struct iattr *attr);
+extern void setattr_copy(struct inode *inode, const struct iattr *attr);
extern void file_update_time(struct file *file);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 88e0eb596919..c3c578e09833 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -37,6 +37,10 @@
*
* 7.14
* - add splice support to fuse device
+ *
+ * 7.15
+ * - add store notify
+ * - add retrieve notify
*/
#ifndef _LINUX_FUSE_H
@@ -68,7 +72,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 14
+#define FUSE_KERNEL_MINOR_VERSION 15
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
@@ -251,6 +255,7 @@ enum fuse_opcode {
FUSE_DESTROY = 38,
FUSE_IOCTL = 39,
FUSE_POLL = 40,
+ FUSE_NOTIFY_REPLY = 41,
/* CUSE specific operations */
CUSE_INIT = 4096,
@@ -260,6 +265,8 @@ enum fuse_notify_code {
FUSE_NOTIFY_POLL = 1,
FUSE_NOTIFY_INVAL_INODE = 2,
FUSE_NOTIFY_INVAL_ENTRY = 3,
+ FUSE_NOTIFY_STORE = 4,
+ FUSE_NOTIFY_RETRIEVE = 5,
FUSE_NOTIFY_CODE_MAX,
};
@@ -568,4 +575,29 @@ struct fuse_notify_inval_entry_out {
__u32 padding;
};
+struct fuse_notify_store_out {
+ __u64 nodeid;
+ __u64 offset;
+ __u32 size;
+ __u32 padding;
+};
+
+struct fuse_notify_retrieve_out {
+ __u64 notify_unique;
+ __u64 nodeid;
+ __u64 offset;
+ __u32 size;
+ __u32 padding;
+};
+
+/* Matches the size of fuse_write_in */
+struct fuse_notify_retrieve_in {
+ __u64 dummy1;
+ __u64 offset;
+ __u32 size;
+ __u32 dummy2;
+ __u64 dummy3;
+ __u64 dummy4;
+};
+
#endif /* _LINUX_FUSE_H */
diff --git a/include/linux/hid.h b/include/linux/hid.h
index 895001f7f4b2..e6796c54a62e 100644
--- a/include/linux/hid.h
+++ b/include/linux/hid.h
@@ -502,6 +502,9 @@ struct hid_device { /* device report descriptor */
struct hid_usage *, __s32);
void (*hiddev_report_event) (struct hid_device *, struct hid_report *);
+ /* handler for raw input (Get_Report) data, used by hidraw */
+ int (*hid_get_raw_report) (struct hid_device *, unsigned char, __u8 *, size_t, unsigned char);
+
/* handler for raw output data, used by hidraw */
int (*hid_output_raw_report) (struct hid_device *, __u8 *, size_t, unsigned char);
diff --git a/include/linux/hidraw.h b/include/linux/hidraw.h
index dd8d69269176..4b88e697c4e9 100644
--- a/include/linux/hidraw.h
+++ b/include/linux/hidraw.h
@@ -35,6 +35,9 @@ struct hidraw_devinfo {
#define HIDIOCGRAWINFO _IOR('H', 0x03, struct hidraw_devinfo)
#define HIDIOCGRAWNAME(len) _IOC(_IOC_READ, 'H', 0x04, len)
#define HIDIOCGRAWPHYS(len) _IOC(_IOC_READ, 'H', 0x05, len)
+/* The first byte of SFEATURE and GFEATURE is the report number */
+#define HIDIOCSFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
+#define HIDIOCGFEATURE(len) _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
#define HIDRAW_FIRST_MINOR 0
#define HIDRAW_MAX_DEVICES 64
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 21067b418536..c936a27098ef 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -282,12 +282,18 @@ i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
/* If you don't know the exact address of an I2C device, use this variant
* instead, which can probe for device presence in a list of possible
- * addresses.
+ * addresses. The "probe" callback function is optional. If it is provided,
+ * it must return 1 on successful probe, 0 otherwise. If it is not provided,
+ * a default probing method is used.
*/
extern struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
- unsigned short const *addr_list);
+ unsigned short const *addr_list,
+ int (*probe)(struct i2c_adapter *, unsigned short addr));
+
+/* Common custom probe functions */
+extern int i2c_probe_func_quick_read(struct i2c_adapter *, unsigned short addr);
/* For devices that use several addresses, use i2c_new_dummy() to make
* client handles for the extra addresses.
@@ -374,23 +380,9 @@ static inline void i2c_set_adapdata(struct i2c_adapter *dev, void *data)
dev_set_drvdata(&dev->dev, data);
}
-/**
- * i2c_lock_adapter - Prevent access to an I2C bus segment
- * @adapter: Target I2C bus segment
- */
-static inline void i2c_lock_adapter(struct i2c_adapter *adapter)
-{
- rt_mutex_lock(&adapter->bus_lock);
-}
-
-/**
- * i2c_unlock_adapter - Reauthorize access to an I2C bus segment
- * @adapter: Target I2C bus segment
- */
-static inline void i2c_unlock_adapter(struct i2c_adapter *adapter)
-{
- rt_mutex_unlock(&adapter->bus_lock);
-}
+/* Adapter locking functions, exported for shared pin cases */
+void i2c_lock_adapter(struct i2c_adapter *);
+void i2c_unlock_adapter(struct i2c_adapter *);
/*flags for the client struct: */
#define I2C_CLIENT_PEC 0x04 /* Use Packet Error Checking */
diff --git a/include/linux/i2c/ltc4245.h b/include/linux/i2c/ltc4245.h
new file mode 100644
index 000000000000..56bda4be0016
--- /dev/null
+++ b/include/linux/i2c/ltc4245.h
@@ -0,0 +1,21 @@
+/*
+ * Platform Data for LTC4245 hardware monitor chip
+ *
+ * Copyright (c) 2010 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * 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_LTC4245_H
+#define LINUX_LTC4245_H
+
+#include <linux/types.h>
+
+struct ltc4245_platform_data {
+ bool use_extra_gpios;
+};
+
+#endif /* LINUX_LTC4245_H */
diff --git a/include/linux/i8042.h b/include/linux/i8042.h
index 9bf6870ee5f4..a986ff588944 100644
--- a/include/linux/i8042.h
+++ b/include/linux/i8042.h
@@ -46,31 +46,31 @@ int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
#else
-void i8042_lock_chip(void)
+static inline void i8042_lock_chip(void)
{
}
-void i8042_unlock_chip(void)
+static inline void i8042_unlock_chip(void)
{
}
-int i8042_command(unsigned char *param, int command)
+static inline int i8042_command(unsigned char *param, int command)
{
return -ENODEV;
}
-bool i8042_check_port_owner(const struct serio *serio)
+static inline bool i8042_check_port_owner(const struct serio *serio)
{
return false;
}
-int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
+static inline int i8042_install_filter(bool (*filter)(unsigned char data, unsigned char str,
struct serio *serio))
{
return -ENODEV;
}
-int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
+static inline int i8042_remove_filter(bool (*filter)(unsigned char data, unsigned char str,
struct serio *serio))
{
return -ENODEV;
diff --git a/include/linux/input.h b/include/linux/input.h
index 6fcc9101beeb..fe2633c20350 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -34,7 +34,7 @@ struct input_event {
* Protocol version.
*/
-#define EV_VERSION 0x010000
+#define EV_VERSION 0x010001
/*
* IOCTLs (0x00 - 0x7f)
@@ -56,12 +56,22 @@ struct input_absinfo {
__s32 resolution;
};
+struct keycode_table_entry {
+ __u32 keycode; /* e.g. KEY_A */
+ __u32 index; /* Index for the given scan/key table, on EVIOCGKEYCODEBIG */
+ __u32 len; /* Length of the scancode */
+ __u32 reserved[2]; /* Reserved for future usage */
+ char *scancode; /* scancode, in machine-endian */
+};
+
#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */
#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */
#define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */
#define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */
#define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */
#define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */
+#define EVIOCGKEYCODEBIG _IOR('E', 0x04, struct keycode_table_entry) /* get keycode */
+#define EVIOCSKEYCODEBIG _IOW('E', 0x04, struct keycode_table_entry) /* set keycode */
#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */
#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */
@@ -1066,13 +1076,22 @@ struct ff_effect {
* @keycodemax: size of keycode table
* @keycodesize: size of elements in keycode table
* @keycode: map of scancodes to keycodes for this device
- * @setkeycode: optional method to alter current keymap, used to implement
+ * @setkeycode: optional legacy method to alter current keymap, used to
+ * implement sparse keymaps. Shouldn't be used on new drivers
+ * @getkeycode: optional legacy method to retrieve current keymap.
+ * Shouldn't be used on new drivers.
+ * @setkeycodebig: optional method to alter current keymap, used to implement
* sparse keymaps. If not supplied default mechanism will be used.
* The method is being called while holding event_lock and thus must
* not sleep
- * @getkeycode: optional method to retrieve current keymap. If not supplied
- * default mechanism will be used. The method is being called while
- * holding event_lock and thus must not sleep
+ * @getkeycodebig_from_index: optional method to retrieve current keymap from
+ * an array index. If not supplied default mechanism will be used.
+ * The method is being called while holding event_lock and thus must
+ * not sleep
+ * @getkeycodebig_from_scancode: optional method to retrieve current keymap
+ * from an scancode. If not supplied default mechanism will be used.
+ * The method is being called while holding event_lock and thus must
+ * not sleep
* @ff: force feedback structure associated with the device if device
* supports force feedback effects
* @repeat_key: stores key code of the last key pressed; used to implement
@@ -1147,6 +1166,12 @@ struct input_dev {
unsigned int scancode, unsigned int keycode);
int (*getkeycode)(struct input_dev *dev,
unsigned int scancode, unsigned int *keycode);
+ int (*setkeycodebig)(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry);
+ int (*getkeycodebig_from_index)(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry);
+ int (*getkeycodebig_from_scancode)(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry);
struct ff_device *ff;
@@ -1422,6 +1447,10 @@ int input_get_keycode(struct input_dev *dev,
unsigned int scancode, unsigned int *keycode);
int input_set_keycode(struct input_dev *dev,
unsigned int scancode, unsigned int keycode);
+int input_get_keycode_big(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry);
+int input_set_keycode_big(struct input_dev *dev,
+ struct keycode_table_entry *kt_entry);
extern struct class input_class;
diff --git a/include/linux/list.h b/include/linux/list.h
index 5d57a3a1fa1b..d167b5d7c0ac 100644
--- a/include/linux/list.h
+++ b/include/linux/list.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
+#include <linux/types.h>
#include <linux/stddef.h>
#include <linux/poison.h>
#include <linux/prefetch.h>
@@ -16,10 +17,6 @@
* using the generic single-entry routines.
*/
-struct list_head {
- struct list_head *next, *prev;
-};
-
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
@@ -566,14 +563,6 @@ static inline void list_splice_tail_init(struct list_head *list,
* You lose the ability to access the tail in O(1).
*/
-struct hlist_head {
- struct hlist_node *first;
-};
-
-struct hlist_node {
- struct hlist_node *next, **pprev;
-};
-
#define HLIST_HEAD_INIT { .first = NULL }
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b969efb03787..c34e35e2ecce 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -815,6 +815,7 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping,
}
extern void truncate_pagecache(struct inode *inode, loff_t old, loff_t new);
+extern void truncate_setsize(struct inode *inode, loff_t newsize);
extern int vmtruncate(struct inode *inode, loff_t offset);
extern int vmtruncate_range(struct inode *inode, loff_t offset, loff_t end);
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 9b8299af3741..07e40c625972 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -523,6 +523,7 @@ enum {
NFSPROC4_CLNT_GETACL,
NFSPROC4_CLNT_SETACL,
NFSPROC4_CLNT_FS_LOCATIONS,
+ NFSPROC4_CLNT_RELEASE_LOCKOWNER,
/* nfs41 */
NFSPROC4_CLNT_EXCHANGE_ID,
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 77c2ae53431c..a9d802615082 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -72,13 +72,20 @@ struct nfs_access_entry {
int mask;
};
+struct nfs_lock_context {
+ atomic_t count;
+ struct list_head list;
+ struct nfs_open_context *open_context;
+ fl_owner_t lockowner;
+ pid_t pid;
+};
+
struct nfs4_state;
struct nfs_open_context {
- atomic_t count;
+ struct nfs_lock_context lock_context;
struct path path;
struct rpc_cred *cred;
struct nfs4_state *state;
- fl_owner_t lockowner;
fmode_t mode;
unsigned long flags;
@@ -353,6 +360,8 @@ extern void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr);
extern struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx);
extern void put_nfs_open_context(struct nfs_open_context *ctx);
extern struct nfs_open_context *nfs_find_open_context(struct inode *inode, struct rpc_cred *cred, fmode_t mode);
+extern struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx);
+extern void nfs_put_lock_context(struct nfs_lock_context *l_ctx);
extern u64 nfs_compat_user_ino64(u64 fileid);
extern void nfs_fattr_init(struct nfs_fattr *fattr);
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index d6e10a4c06e5..c82ee7cd6288 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -15,6 +15,7 @@ struct nlm_host;
struct nfs4_sequence_args;
struct nfs4_sequence_res;
struct nfs_server;
+struct nfs4_minor_version_ops;
/*
* The nfs_client identifies our client state to the server.
@@ -70,11 +71,7 @@ struct nfs_client {
*/
char cl_ipaddr[48];
unsigned char cl_id_uniquifier;
- int (* cl_call_sync)(struct nfs_server *server,
- struct rpc_message *msg,
- struct nfs4_sequence_args *args,
- struct nfs4_sequence_res *res,
- int cache_reply);
+ const struct nfs4_minor_version_ops *cl_mvops;
#endif /* CONFIG_NFS_V4 */
#ifdef CONFIG_NFS_V4_1
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 3c60685d972b..f8b60e7f4c44 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -39,6 +39,7 @@ struct nfs_page {
struct list_head wb_list; /* Defines state of page: */
struct page *wb_page; /* page to read in/write out */
struct nfs_open_context *wb_context; /* File state context info */
+ struct nfs_lock_context *wb_lock_context; /* lock context info */
atomic_t wb_complete; /* i/os we're waiting for */
pgoff_t wb_index; /* Offset >> PAGE_CACHE_SHIFT */
unsigned int wb_offset, /* Offset & ~PAGE_CACHE_MASK */
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 51914d7d6cc4..fc461926c412 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -196,8 +196,10 @@ struct nfs_openargs {
__u64 clientid;
__u64 id;
union {
- struct iattr * attrs; /* UNCHECKED, GUARDED */
- nfs4_verifier verifier; /* EXCLUSIVE */
+ struct {
+ struct iattr * attrs; /* UNCHECKED, GUARDED */
+ nfs4_verifier verifier; /* EXCLUSIVE */
+ };
nfs4_stateid delegation; /* CLAIM_DELEGATE_CUR */
fmode_t delegation_type; /* CLAIM_PREVIOUS */
} u;
@@ -313,6 +315,10 @@ struct nfs_lockt_res {
struct nfs4_sequence_res seq_res;
};
+struct nfs_release_lockowner_args {
+ struct nfs_lowner lock_owner;
+};
+
struct nfs4_delegreturnargs {
const struct nfs_fh *fhandle;
const nfs4_stateid *stateid;
@@ -332,6 +338,7 @@ struct nfs4_delegreturnres {
struct nfs_readargs {
struct nfs_fh * fh;
struct nfs_open_context *context;
+ struct nfs_lock_context *lock_context;
__u64 offset;
__u32 count;
unsigned int pgbase;
@@ -352,6 +359,7 @@ struct nfs_readres {
struct nfs_writeargs {
struct nfs_fh * fh;
struct nfs_open_context *context;
+ struct nfs_lock_context *lock_context;
__u64 offset;
__u32 count;
enum nfs3_stable_how stable;
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 9bdd91486b49..45707bed8c19 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -253,7 +253,7 @@ struct omapfb_platform_data {
/* in arch/arm/plat-omap/fb.c */
extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
extern void omapfb_set_ctrl_platform_data(void *pdata);
-extern void omapfb_reserve_sdram(void);
+extern void omapfb_reserve_sdram_lmb(void);
#endif
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index aa36793b48bd..126193c1a5ce 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -145,11 +145,6 @@ static inline bool sb_has_quota_active(struct super_block *sb, int type)
!sb_has_quota_suspended(sb, type);
}
-static inline unsigned sb_any_quota_active(struct super_block *sb)
-{
- return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
-}
-
/*
* Operations supported for diskquotas.
*/
@@ -194,11 +189,6 @@ static inline int sb_has_quota_active(struct super_block *sb, int type)
return 0;
}
-static inline int sb_any_quota_active(struct super_block *sb)
-{
- return 0;
-}
-
static inline void dquot_initialize(struct inode *inode)
{
}
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 3b603f474186..2a464ae147ce 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -2033,7 +2033,7 @@ void reiserfs_read_locked_inode(struct inode *inode,
struct reiserfs_iget_args *args);
int reiserfs_find_actor(struct inode *inode, void *p);
int reiserfs_init_locked_inode(struct inode *inode, void *p);
-void reiserfs_delete_inode(struct inode *inode);
+void reiserfs_evict_inode(struct inode *inode);
int reiserfs_write_inode(struct inode *inode, struct writeback_control *wbc);
int reiserfs_get_block(struct inode *inode, sector_t block,
struct buffer_head *bh_result, int create);
diff --git a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
index 89f4d3abbf5a..97959bdfe214 100644
--- a/include/linux/reiserfs_fs_i.h
+++ b/include/linux/reiserfs_fs_i.h
@@ -25,7 +25,6 @@ typedef enum {
i_link_saved_truncate_mask = 0x0020,
i_has_xattr_dir = 0x0040,
i_data_log = 0x0080,
- i_ever_mapped = 0x0100
} reiserfs_inode_flags;
struct reiserfs_inode_info {
@@ -53,7 +52,8 @@ struct reiserfs_inode_info {
** flushed */
unsigned int i_trans_id;
struct reiserfs_journal_list *i_jl;
- struct mutex i_mmap;
+ atomic_t openers;
+ struct mutex tailpack;
#ifdef CONFIG_REISERFS_FS_XATTR
struct rw_semaphore i_xattr_sem;
#endif
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index f10db6e5f3b5..522832023a69 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -186,6 +186,9 @@
#define PORT_ALTERA_JTAGUART 91
#define PORT_ALTERA_UART 92
+/* SH-SCI */
+#define PORT_SCIFB 93
+
#ifdef __KERNEL__
#include <linux/compiler.h>
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index 6f52b4d7c447..7bf3e84b92f4 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -192,6 +192,7 @@ extern int cache_check(struct cache_detail *detail,
extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
#define NEVER (0x7FFFFFFF)
+extern void __init cache_initialize(void);
extern int cache_register(struct cache_detail *cd);
extern void cache_unregister(struct cache_detail *cd);
diff --git a/include/linux/types.h b/include/linux/types.h
index 23d237a075e2..336cc39c46f1 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -197,6 +197,18 @@ typedef struct {
} atomic64_t;
#endif
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+struct hlist_head {
+ struct hlist_node *first;
+};
+
+struct hlist_node {
+ struct hlist_node *next, **pprev;
+};
+
struct ustat {
__kernel_daddr_t f_tfree;
__kernel_ino_t f_tinode;
diff --git a/include/linux/usb/video.h b/include/linux/usb/video.h
index be436d9ee479..2d5b7fc6a265 100644
--- a/include/linux/usb/video.h
+++ b/include/linux/usb/video.h
@@ -160,5 +160,12 @@
#define UVC_STATUS_TYPE_CONTROL 1
#define UVC_STATUS_TYPE_STREAMING 2
+/* 4.1.2. Control Capabilities */
+#define UVC_CONTROL_CAP_GET (1 << 0)
+#define UVC_CONTROL_CAP_SET (1 << 1)
+#define UVC_CONTROL_CAP_DISABLED (1 << 2)
+#define UVC_CONTROL_CAP_AUTOUPDATE (1 << 3)
+#define UVC_CONTROL_CAP_ASYNCHRONOUS (1 << 4)
+
#endif /* __LINUX_USB_VIDEO_H */
diff --git a/include/linux/virtio_9p.h b/include/linux/virtio_9p.h
index 5cf11765146b..395c38a47adb 100644
--- a/include/linux/virtio_9p.h
+++ b/include/linux/virtio_9p.h
@@ -4,6 +4,7 @@
* compatible drivers/servers. */
#include <linux/virtio_ids.h>
#include <linux/virtio_config.h>
+#include <linux/types.h>
/* The feature bitmap for virtio 9P */
diff --git a/include/media/ir-core.h b/include/media/ir-core.h
index ad1303f20e00..513e60dd1010 100644
--- a/include/media/ir-core.h
+++ b/include/media/ir-core.h
@@ -47,15 +47,21 @@ enum rc_driver_type {
* is opened.
* @close: callback to allow drivers to disable polling/irq when IR input device
* is opened.
+ * @s_tx_mask: set transmitter mask (for devices with multiple tx outputs)
+ * @s_tx_carrier: set transmit carrier frequency
+ * @tx_ir: transmit IR
*/
struct ir_dev_props {
enum rc_driver_type driver_type;
unsigned long allowed_protos;
u32 scanmask;
- void *priv;
+ void *priv;
int (*change_protocol)(void *priv, u64 ir_type);
int (*open)(void *priv);
void (*close)(void *priv);
+ int (*s_tx_mask)(void *priv, u32 mask);
+ int (*s_tx_carrier)(void *priv, u32 carrier);
+ int (*tx_ir)(void *priv, int *txbuf, u32 n);
};
struct ir_input_dev {
diff --git a/include/media/ir-kbd-i2c.h b/include/media/ir-kbd-i2c.h
index 0506e45c9a4f..5e96d7a430be 100644
--- a/include/media/ir-kbd-i2c.h
+++ b/include/media/ir-kbd-i2c.h
@@ -11,7 +11,7 @@ struct IR_i2c {
struct i2c_client *c;
struct input_dev *input;
struct ir_input_state ir;
-
+ u64 ir_type;
/* Used to avoid fast repeating */
unsigned char old;
diff --git a/include/media/lirc.h b/include/media/lirc.h
new file mode 100644
index 000000000000..8dffd4f47bf6
--- /dev/null
+++ b/include/media/lirc.h
@@ -0,0 +1,163 @@
+/*
+ * lirc.h - linux infrared remote control header file
+ * last modified 2010/06/03 by Jarod Wilson
+ */
+
+#ifndef _LINUX_LIRC_H
+#define _LINUX_LIRC_H
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#define PULSE_BIT 0x01000000
+#define PULSE_MASK 0x00FFFFFF
+
+#define LIRC_MODE2_SPACE 0x00000000
+#define LIRC_MODE2_PULSE 0x01000000
+#define LIRC_MODE2_FREQUENCY 0x02000000
+#define LIRC_MODE2_TIMEOUT 0x03000000
+
+#define LIRC_VALUE_MASK 0x00FFFFFF
+#define LIRC_MODE2_MASK 0xFF000000
+
+#define LIRC_SPACE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_SPACE)
+#define LIRC_PULSE(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_PULSE)
+#define LIRC_FREQUENCY(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_FREQUENCY)
+#define LIRC_TIMEOUT(val) (((val)&LIRC_VALUE_MASK) | LIRC_MODE2_TIMEOUT)
+
+#define LIRC_VALUE(val) ((val)&LIRC_VALUE_MASK)
+#define LIRC_MODE2(val) ((val)&LIRC_MODE2_MASK)
+
+#define LIRC_IS_SPACE(val) (LIRC_MODE2(val) == LIRC_MODE2_SPACE)
+#define LIRC_IS_PULSE(val) (LIRC_MODE2(val) == LIRC_MODE2_PULSE)
+#define LIRC_IS_FREQUENCY(val) (LIRC_MODE2(val) == LIRC_MODE2_FREQUENCY)
+#define LIRC_IS_TIMEOUT(val) (LIRC_MODE2(val) == LIRC_MODE2_TIMEOUT)
+
+/*** lirc compatible hardware features ***/
+
+#define LIRC_MODE2SEND(x) (x)
+#define LIRC_SEND2MODE(x) (x)
+#define LIRC_MODE2REC(x) ((x) << 16)
+#define LIRC_REC2MODE(x) ((x) >> 16)
+
+#define LIRC_MODE_RAW 0x00000001
+#define LIRC_MODE_PULSE 0x00000002
+#define LIRC_MODE_MODE2 0x00000004
+#define LIRC_MODE_LIRCCODE 0x00000010
+
+
+#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW)
+#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE)
+#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2)
+#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE)
+
+#define LIRC_CAN_SEND_MASK 0x0000003f
+
+#define LIRC_CAN_SET_SEND_CARRIER 0x00000100
+#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200
+#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400
+
+#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW)
+#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE)
+#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2)
+#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE)
+
+#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK)
+
+#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16)
+#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16)
+
+#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000
+#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000
+#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000
+#define LIRC_CAN_SET_REC_TIMEOUT 0x10000000
+#define LIRC_CAN_SET_REC_FILTER 0x08000000
+
+#define LIRC_CAN_MEASURE_CARRIER 0x02000000
+
+#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK)
+#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK)
+
+#define LIRC_CAN_NOTIFY_DECODE 0x01000000
+
+/*** IOCTL commands for lirc driver ***/
+
+#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32)
+
+#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32)
+#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32)
+#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32)
+#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32)
+#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32)
+#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32)
+#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32)
+
+#define LIRC_GET_MIN_TIMEOUT _IOR('i', 0x00000008, __u32)
+#define LIRC_GET_MAX_TIMEOUT _IOR('i', 0x00000009, __u32)
+
+#if 0 /* these ioctls are not used at the moment */
+#define LIRC_GET_MIN_FILTER_PULSE _IOR('i', 0x0000000a, __u32)
+#define LIRC_GET_MAX_FILTER_PULSE _IOR('i', 0x0000000b, __u32)
+#define LIRC_GET_MIN_FILTER_SPACE _IOR('i', 0x0000000c, __u32)
+#define LIRC_GET_MAX_FILTER_SPACE _IOR('i', 0x0000000d, __u32)
+#endif
+
+/* code length in bits, currently only for LIRC_MODE_LIRCCODE */
+#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32)
+
+#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32)
+#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32)
+/* Note: these can reset the according pulse_width */
+#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32)
+#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32)
+#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32)
+#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32)
+#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32)
+
+/*
+ * when a timeout != 0 is set the driver will send a
+ * LIRC_MODE2_TIMEOUT data packet, otherwise LIRC_MODE2_TIMEOUT is
+ * never sent, timeout is disabled by default
+ */
+#define LIRC_SET_REC_TIMEOUT _IOW('i', 0x00000018, __u32)
+
+#if 0 /* these ioctls are not used at the moment */
+/*
+ * pulses shorter than this are filtered out by hardware (software
+ * emulation in lirc_dev?)
+ */
+#define LIRC_SET_REC_FILTER_PULSE _IOW('i', 0x00000019, __u32)
+/*
+ * spaces shorter than this are filtered out by hardware (software
+ * emulation in lirc_dev?)
+ */
+#define LIRC_SET_REC_FILTER_SPACE _IOW('i', 0x0000001a, __u32)
+/*
+ * if filter cannot be set independantly for pulse/space, this should
+ * be used
+ */
+#define LIRC_SET_REC_FILTER _IOW('i', 0x0000001b, __u32)
+#endif
+
+/*
+ * to set a range use
+ * LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the
+ * lower bound first and later
+ * LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound
+ */
+
+#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32)
+#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32)
+
+#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020)
+
+#if 0 /* these ioctls are not used at the moment */
+/*
+ * from the next key press on the driver will send
+ * LIRC_MODE2_FREQUENCY packets
+ */
+#define LIRC_MEASURE_CARRIER_ENABLE _IO('i', 0x00000021)
+#define LIRC_MEASURE_CARRIER_DISABLE _IO('i', 0x00000022)
+#endif
+
+#endif
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index c78e99a435b6..a329858c4b42 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -17,8 +17,13 @@
#define IR_TYPE_RC6 (1 << 2) /* Philips RC6 protocol */
#define IR_TYPE_JVC (1 << 3) /* JVC protocol */
#define IR_TYPE_SONY (1 << 4) /* Sony12/15/20 protocol */
+#define IR_TYPE_LIRC (1 << 30) /* Pass raw IR to lirc userspace */
#define IR_TYPE_OTHER (1u << 31)
+#define IR_TYPE_ALL (IR_TYPE_RC5 | IR_TYPE_NEC | IR_TYPE_RC6 | \
+ IR_TYPE_JVC | IR_TYPE_SONY | IR_TYPE_LIRC | \
+ IR_TYPE_OTHER)
+
struct ir_scancode {
u32 scancode;
u32 keycode;
@@ -87,6 +92,7 @@ void rc_map_init(void);
#define RC_MAP_KAIOMY "rc-kaiomy"
#define RC_MAP_KWORLD_315U "rc-kworld-315u"
#define RC_MAP_KWORLD_PLUS_TV_ANALOG "rc-kworld-plus-tv-analog"
+#define RC_MAP_LIRC "rc-lirc"
#define RC_MAP_MANLI "rc-manli"
#define RC_MAP_MSI_TVANYWHERE_PLUS "rc-msi-tvanywhere-plus"
#define RC_MAP_MSI_TVANYWHERE "rc-msi-tvanywhere"
@@ -107,6 +113,7 @@ void rc_map_init(void);
#define RC_MAP_PV951 "rc-pv951"
#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new"
#define RC_MAP_RC5_TV "rc-rc5-tv"
+#define RC_MAP_RC6_MCE "rc-rc6-mce"
#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
#define RC_MAP_TBS_NEC "rc-tbs-nec"
#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
diff --git a/include/media/videobuf-core.h b/include/media/videobuf-core.h
index f91a736c133d..f2c41cebf453 100644
--- a/include/media/videobuf-core.h
+++ b/include/media/videobuf-core.h
@@ -54,8 +54,6 @@ struct videobuf_queue;
struct videobuf_mapping {
unsigned int count;
- unsigned long start;
- unsigned long end;
struct videobuf_queue *q;
};
@@ -127,7 +125,7 @@ struct videobuf_queue_ops {
struct videobuf_qtype_ops {
u32 magic;
- struct videobuf_buffer *(*alloc)(size_t size);
+ struct videobuf_buffer *(*alloc_vb)(size_t size);
void *(*vaddr) (struct videobuf_buffer *buf);
int (*iolock) (struct videobuf_queue *q,
struct videobuf_buffer *vb,
@@ -173,7 +171,7 @@ int videobuf_waiton(struct videobuf_buffer *vb, int non_blocking, int intr);
int videobuf_iolock(struct videobuf_queue *q, struct videobuf_buffer *vb,
struct v4l2_framebuffer *fbuf);
-struct videobuf_buffer *videobuf_alloc(struct videobuf_queue *q);
+struct videobuf_buffer *videobuf_alloc_vb(struct videobuf_queue *q);
/* Used on videobuf-dvb */
void *videobuf_queue_to_vaddr(struct videobuf_queue *q,
diff --git a/include/media/videobuf-dma-sg.h b/include/media/videobuf-dma-sg.h
index a195f3b9c00a..97e07f46a0fa 100644
--- a/include/media/videobuf-dma-sg.h
+++ b/include/media/videobuf-dma-sg.h
@@ -25,23 +25,6 @@
/* --------------------------------------------------------------------- */
/*
- * Return a scatterlist for some page-aligned vmalloc()'ed memory
- * block (NULL on errors). Memory for the scatterlist is allocated
- * using kmalloc. The caller must free the memory.
- */
-struct scatterlist *videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages);
-
-/*
- * Return a scatterlist for a an array of userpages (NULL on errors).
- * Memory for the scatterlist is allocated using kmalloc. The caller
- * must free the memory.
- */
-struct scatterlist *videobuf_pages_to_sg(struct page **pages, int nr_pages,
- int offset);
-
-/* --------------------------------------------------------------------- */
-
-/*
* A small set of helper functions to manage buffers (both userland
* and kernel) for DMA.
*
@@ -68,7 +51,7 @@ struct videobuf_dmabuf {
struct page **pages;
/* for kernel buffers */
- void *vmalloc;
+ void *vaddr;
/* for overlay buffers (pci-pci dma) */
dma_addr_t bus_addr;
@@ -87,6 +70,16 @@ struct videobuf_dma_sg_memory {
struct videobuf_dmabuf dma;
};
+/*
+ * Scatter-gather DMA buffer API.
+ *
+ * These functions provide a simple way to create a page list and a
+ * scatter-gather list from a kernel, userspace of physical address and map the
+ * memory for DMA operation.
+ *
+ * Despite the name, this is totally unrelated to videobuf, except that
+ * videobuf-dma-sg uses the same API internally.
+ */
void videobuf_dma_init(struct videobuf_dmabuf *dma);
int videobuf_dma_init_user(struct videobuf_dmabuf *dma, int direction,
unsigned long data, unsigned long size);
@@ -96,8 +89,8 @@ int videobuf_dma_init_overlay(struct videobuf_dmabuf *dma, int direction,
dma_addr_t addr, int nr_pages);
int videobuf_dma_free(struct videobuf_dmabuf *dma);
-int videobuf_dma_map(struct videobuf_queue *q, struct videobuf_dmabuf *dma);
-int videobuf_dma_unmap(struct videobuf_queue *q, struct videobuf_dmabuf *dma);
+int videobuf_dma_map(struct device *dev, struct videobuf_dmabuf *dma);
+int videobuf_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma);
struct videobuf_dmabuf *videobuf_to_dma(struct videobuf_buffer *buf);
void *videobuf_sg_alloc(size_t size);
@@ -111,11 +104,5 @@ void videobuf_queue_sg_init(struct videobuf_queue *q,
unsigned int msize,
void *priv);
-/*FIXME: these variants are used only on *-alsa code, where videobuf is
- * used without queue
- */
-int videobuf_sg_dma_map(struct device *dev, struct videobuf_dmabuf *dma);
-int videobuf_sg_dma_unmap(struct device *dev, struct videobuf_dmabuf *dma);
-
#endif /* _VIDEOBUF_DMA_SG_H */
diff --git a/include/media/videobuf-vmalloc.h b/include/media/videobuf-vmalloc.h
index 851eb1a2ff2a..e19403c18dae 100644
--- a/include/media/videobuf-vmalloc.h
+++ b/include/media/videobuf-vmalloc.h
@@ -22,7 +22,7 @@
struct videobuf_vmalloc_memory {
u32 magic;
- void *vmalloc;
+ void *vaddr;
/* remap_vmalloc_range seems to need to run
* after mmap() on some cases */
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 156c26bb8bd7..c035e2917cc2 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -133,6 +133,12 @@ enum p9_msg_t {
P9_RSTATFS,
P9_TRENAME = 20,
P9_RRENAME,
+ P9_TGETATTR = 24,
+ P9_RGETATTR,
+ P9_TSETATTR = 26,
+ P9_RSETATTR,
+ P9_TREADDIR = 40,
+ P9_RREADDIR,
P9_TVERSION = 100,
P9_RVERSION,
P9_TAUTH = 102,
@@ -275,6 +281,9 @@ enum p9_qid_t {
/* ample room for Twrite/Rread header */
#define P9_IOHDRSZ 24
+/* Room for readdir header */
+#define P9_READDIRHDRSZ 24
+
/**
* struct p9_str - length prefixed string type
* @len: length of the string
@@ -357,6 +366,50 @@ struct p9_wstat {
u32 n_muid; /* 9p2000.u extensions */
};
+struct p9_stat_dotl {
+ struct p9_qid qid;
+ u32 st_mode;
+ u64 st_nlink;
+ u32 st_uid;
+ u32 st_gid;
+ u64 st_rdev;
+ u64 st_size;
+ u64 st_blksize;
+ u64 st_blocks;
+ u64 st_atime_sec;
+ u64 st_atime_nsec;
+ u64 st_mtime_sec;
+ u64 st_mtime_nsec;
+ u64 st_ctime_sec;
+ u64 st_ctime_nsec;
+};
+
+/**
+ * struct p9_iattr_dotl - P9 inode attribute for setattr
+ * @valid: bitfield specifying which fields are valid
+ * same as in struct iattr
+ * @mode: File permission bits
+ * @uid: user id of owner
+ * @gid: group id
+ * @size: File size
+ * @atime_sec: Last access time, seconds
+ * @atime_nsec: Last access time, nanoseconds
+ * @mtime_sec: Last modification time, seconds
+ * @mtime_nsec: Last modification time, nanoseconds
+ */
+
+struct p9_iattr_dotl {
+ u32 valid;
+ u32 mode;
+ u32 uid;
+ u32 gid;
+ u64 size;
+ u64 atime_sec;
+ u64 atime_nsec;
+ u64 mtime_sec;
+ u64 mtime_nsec;
+};
+
/* Structures for Protocol Operations */
struct p9_tstatfs {
u32 fid;
@@ -485,6 +538,18 @@ struct p9_rwrite {
u32 count;
};
+struct p9_treaddir {
+ u32 fid;
+ u64 offset;
+ u32 count;
+};
+
+struct p9_rreaddir {
+ u32 count;
+ u8 *data;
+};
+
+
struct p9_tclunk {
u32 fid;
};
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index 7dd3ed85c782..d6a01870199a 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -195,6 +195,21 @@ struct p9_fid {
struct list_head dlist; /* list of all fids attached to a dentry */
};
+/**
+ * struct p9_dirent - directory entry structure
+ * @qid: The p9 server qid for this dirent
+ * @d_off: offset to the next dirent
+ * @d_type: type of file
+ * @d_name: file name
+ */
+
+struct p9_dirent {
+ struct p9_qid qid;
+ u64 d_off;
+ unsigned char d_type;
+ char d_name[256];
+};
+
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb);
int p9_client_rename(struct p9_fid *fid, struct p9_fid *newdirfid, char *name);
int p9_client_version(struct p9_client *);
@@ -217,8 +232,14 @@ int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
u64 offset, u32 count);
int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
u64 offset, u32 count);
+int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset);
+int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
+ int proto_version);
struct p9_wstat *p9_client_stat(struct p9_fid *fid);
int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
+int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr);
+
+struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid);
struct p9_req_t *p9_tag_lookup(struct p9_client *, u16);
void p9_client_cb(struct p9_client *c, struct p9_req_t *req);
diff --git a/include/video/mipi_display.h b/include/video/mipi_display.h
new file mode 100644
index 000000000000..ddcc8ca7316b
--- /dev/null
+++ b/include/video/mipi_display.h
@@ -0,0 +1,130 @@
+/*
+ * Defines for Mobile Industry Processor Interface (MIPI(R))
+ * Display Working Group standards: DSI, DCS, DBI, DPI
+ *
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ * Copyright (C) 2006 Nokia Corporation
+ * Author: Imre Deak <imre.deak@nokia.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 MIPI_DISPLAY_H
+#define MIPI_DISPLAY_H
+
+/* MIPI DSI Processor-to-Peripheral transaction types */
+enum {
+ MIPI_DSI_V_SYNC_START = 0x01,
+ MIPI_DSI_V_SYNC_END = 0x11,
+ MIPI_DSI_H_SYNC_START = 0x21,
+ MIPI_DSI_H_SYNC_END = 0x31,
+
+ MIPI_DSI_COLOR_MODE_OFF = 0x02,
+ MIPI_DSI_COLOR_MODE_ON = 0x12,
+ MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22,
+ MIPI_DSI_TURN_ON_PERIPHERAL = 0x32,
+
+ MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03,
+ MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13,
+ MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23,
+
+ MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04,
+ MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14,
+ MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24,
+
+ MIPI_DSI_DCS_SHORT_WRITE = 0x05,
+ MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15,
+
+ MIPI_DSI_DCS_READ = 0x06,
+
+ MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37,
+
+ MIPI_DSI_END_OF_TRANSMISSION = 0x08,
+
+ MIPI_DSI_NULL_PACKET = 0x09,
+ MIPI_DSI_BLANKING_PACKET = 0x19,
+ MIPI_DSI_GENERIC_LONG_WRITE = 0x29,
+ MIPI_DSI_DCS_LONG_WRITE = 0x39,
+
+ MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c,
+ MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c,
+ MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c,
+
+ MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d,
+ MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d,
+ MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d,
+
+ MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e,
+ MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e,
+ MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e,
+ MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e,
+};
+
+/* MIPI DSI Peripheral-to-Processor transaction types */
+enum {
+ MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02,
+ MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08,
+ MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11,
+ MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12,
+ MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a,
+ MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c,
+ MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21,
+ MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22,
+};
+
+/* MIPI DCS commands */
+enum {
+ MIPI_DCS_NOP = 0x00,
+ MIPI_DCS_SOFT_RESET = 0x01,
+ MIPI_DCS_GET_DISPLAY_ID = 0x04,
+ MIPI_DCS_GET_RED_CHANNEL = 0x06,
+ MIPI_DCS_GET_GREEN_CHANNEL = 0x07,
+ MIPI_DCS_GET_BLUE_CHANNEL = 0x08,
+ MIPI_DCS_GET_DISPLAY_STATUS = 0x09,
+ MIPI_DCS_GET_POWER_MODE = 0x0A,
+ MIPI_DCS_GET_ADDRESS_MODE = 0x0B,
+ MIPI_DCS_GET_PIXEL_FORMAT = 0x0C,
+ MIPI_DCS_GET_DISPLAY_MODE = 0x0D,
+ MIPI_DCS_GET_SIGNAL_MODE = 0x0E,
+ MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F,
+ MIPI_DCS_ENTER_SLEEP_MODE = 0x10,
+ MIPI_DCS_EXIT_SLEEP_MODE = 0x11,
+ MIPI_DCS_ENTER_PARTIAL_MODE = 0x12,
+ MIPI_DCS_ENTER_NORMAL_MODE = 0x13,
+ MIPI_DCS_EXIT_INVERT_MODE = 0x20,
+ MIPI_DCS_ENTER_INVERT_MODE = 0x21,
+ MIPI_DCS_SET_GAMMA_CURVE = 0x26,
+ MIPI_DCS_SET_DISPLAY_OFF = 0x28,
+ MIPI_DCS_SET_DISPLAY_ON = 0x29,
+ MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A,
+ MIPI_DCS_SET_PAGE_ADDRESS = 0x2B,
+ MIPI_DCS_WRITE_MEMORY_START = 0x2C,
+ MIPI_DCS_WRITE_LUT = 0x2D,
+ MIPI_DCS_READ_MEMORY_START = 0x2E,
+ MIPI_DCS_SET_PARTIAL_AREA = 0x30,
+ MIPI_DCS_SET_SCROLL_AREA = 0x33,
+ MIPI_DCS_SET_TEAR_OFF = 0x34,
+ MIPI_DCS_SET_TEAR_ON = 0x35,
+ MIPI_DCS_SET_ADDRESS_MODE = 0x36,
+ MIPI_DCS_SET_SCROLL_START = 0x37,
+ MIPI_DCS_EXIT_IDLE_MODE = 0x38,
+ MIPI_DCS_ENTER_IDLE_MODE = 0x39,
+ MIPI_DCS_SET_PIXEL_FORMAT = 0x3A,
+ MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C,
+ MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E,
+ MIPI_DCS_SET_TEAR_SCANLINE = 0x44,
+ MIPI_DCS_GET_SCANLINE = 0x45,
+ MIPI_DCS_READ_DDB_START = 0xA1,
+ MIPI_DCS_READ_DDB_CONTINUE = 0xA8,
+};
+
+/* MIPI DCS pixel formats */
+#define MIPI_DCS_PIXEL_FMT_24BIT 7
+#define MIPI_DCS_PIXEL_FMT_18BIT 6
+#define MIPI_DCS_PIXEL_FMT_16BIT 5
+#define MIPI_DCS_PIXEL_FMT_12BIT 3
+#define MIPI_DCS_PIXEL_FMT_8BIT 2
+#define MIPI_DCS_PIXEL_FMT_3BIT 1
+
+#endif
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
new file mode 100644
index 000000000000..18bca08f9f59
--- /dev/null
+++ b/include/video/sh_mipi_dsi.h
@@ -0,0 +1,35 @@
+/*
+ * Public SH-mobile MIPI DSI header
+ *
+ * Copyright (C) 2010 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 VIDEO_SH_MIPI_DSI_H
+#define VIDEO_SH_MIPI_DSI_H
+
+enum sh_mipi_dsi_data_fmt {
+ MIPI_RGB888,
+ MIPI_RGB565,
+ MIPI_RGB666_LP,
+ MIPI_RGB666,
+ MIPI_BGR888,
+ MIPI_BGR565,
+ MIPI_BGR666_LP,
+ MIPI_BGR666,
+ MIPI_YUYV,
+ MIPI_UYVY,
+ MIPI_YUV420_L,
+ MIPI_YUV420,
+};
+
+struct sh_mobile_lcdc_chan_cfg;
+
+struct sh_mipi_dsi_info {
+ enum sh_mipi_dsi_data_fmt data_format;
+ struct sh_mobile_lcdc_chan_cfg *lcd_chan;
+};
+
+#endif
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 288205457713..24393449960f 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -3,24 +3,27 @@
#include <linux/fb.h>
-enum { RGB8, /* 24bpp, 8:8:8 */
- RGB9, /* 18bpp, 9:9 */
- RGB12A, /* 24bpp, 12:12 */
- RGB12B, /* 12bpp */
- RGB16, /* 16bpp */
- RGB18, /* 18bpp */
- RGB24, /* 24bpp */
- SYS8A, /* 24bpp, 8:8:8 */
- SYS8B, /* 18bpp, 8:8:2 */
- SYS8C, /* 18bpp, 2:8:8 */
- SYS8D, /* 16bpp, 8:8 */
- SYS9, /* 18bpp, 9:9 */
- SYS12, /* 24bpp, 12:12 */
- SYS16A, /* 16bpp */
- SYS16B, /* 18bpp, 16:2 */
- SYS16C, /* 18bpp, 2:16 */
- SYS18, /* 18bpp */
- SYS24 };/* 24bpp */
+enum {
+ RGB8, /* 24bpp, 8:8:8 */
+ RGB9, /* 18bpp, 9:9 */
+ RGB12A, /* 24bpp, 12:12 */
+ RGB12B, /* 12bpp */
+ RGB16, /* 16bpp */
+ RGB18, /* 18bpp */
+ RGB24, /* 24bpp */
+ YUV422, /* 16bpp */
+ SYS8A, /* 24bpp, 8:8:8 */
+ SYS8B, /* 18bpp, 8:8:2 */
+ SYS8C, /* 18bpp, 2:8:8 */
+ SYS8D, /* 16bpp, 8:8 */
+ SYS9, /* 18bpp, 9:9 */
+ SYS12, /* 24bpp, 12:12 */
+ SYS16A, /* 16bpp */
+ SYS16B, /* 18bpp, 16:2 */
+ SYS16C, /* 18bpp, 2:16 */
+ SYS18, /* 18bpp */
+ SYS24, /* 24bpp */
+};
enum { LCDC_CHAN_DISABLED = 0,
LCDC_CHAN_MAINLCD,
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index c93fd3faac2d..c60e519e2917 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -158,7 +158,7 @@ static struct inode *mqueue_get_inode(struct super_block *sb,
u->mq_bytes + mq_bytes >
task_rlimit(p, RLIMIT_MSGQUEUE)) {
spin_unlock(&mq_lock);
- /* mqueue_delete_inode() releases info->messages */
+ /* mqueue_evict_inode() releases info->messages */
goto out_inode;
}
u->mq_bytes += mq_bytes;
@@ -241,7 +241,7 @@ static void mqueue_destroy_inode(struct inode *inode)
kmem_cache_free(mqueue_inode_cachep, MQUEUE_I(inode));
}
-static void mqueue_delete_inode(struct inode *inode)
+static void mqueue_evict_inode(struct inode *inode)
{
struct mqueue_inode_info *info;
struct user_struct *user;
@@ -249,10 +249,11 @@ static void mqueue_delete_inode(struct inode *inode)
int i;
struct ipc_namespace *ipc_ns;
- if (S_ISDIR(inode->i_mode)) {
- clear_inode(inode);
+ end_writeback(inode);
+
+ if (S_ISDIR(inode->i_mode))
return;
- }
+
ipc_ns = get_ns_from_inode(inode);
info = MQUEUE_I(inode);
spin_lock(&info->lock);
@@ -261,8 +262,6 @@ static void mqueue_delete_inode(struct inode *inode)
kfree(info->messages);
spin_unlock(&info->lock);
- clear_inode(inode);
-
/* Total amount of bytes accounted for the mqueue */
mq_bytes = info->attr.mq_maxmsg * (sizeof(struct msg_msg *)
+ info->attr.mq_msgsize);
@@ -1225,9 +1224,8 @@ static const struct file_operations mqueue_file_operations = {
static const struct super_operations mqueue_super_ops = {
.alloc_inode = mqueue_alloc_inode,
.destroy_inode = mqueue_destroy_inode,
+ .evict_inode = mqueue_evict_inode,
.statfs = simple_statfs,
- .delete_inode = mqueue_delete_inode,
- .drop_inode = generic_delete_inode,
};
static struct file_system_type mqueue_fs_type = {
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 7a56b22e0602..71ed3ce29e12 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -242,6 +242,17 @@ toggle_bp_slot(struct perf_event *bp, bool enable, enum bp_type_idx type,
}
/*
+ * Function to perform processor-specific cleanup during unregistration
+ */
+__weak void arch_unregister_hw_breakpoint(struct perf_event *bp)
+{
+ /*
+ * A weak stub function here for those archs that don't define
+ * it inside arch/.../kernel/hw_breakpoint.c
+ */
+}
+
+/*
* Contraints to check before allowing this new breakpoint counter:
*
* == Non-pinned counter == (Considered as pinned for now)
@@ -339,6 +350,7 @@ void release_bp_slot(struct perf_event *bp)
{
mutex_lock(&nr_bp_mutex);
+ arch_unregister_hw_breakpoint(bp);
__release_bp_slot(bp);
mutex_unlock(&nr_bp_mutex);
diff --git a/kernel/printk.c b/kernel/printk.c
index 444b770c9595..569a7c2489b1 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -37,6 +37,8 @@
#include <linux/ratelimit.h>
#include <linux/kmsg_dump.h>
#include <linux/syslog.h>
+#include <linux/cpu.h>
+#include <linux/notifier.h>
#include <asm/uaccess.h>
@@ -985,6 +987,29 @@ void resume_console(void)
}
/**
+ * console_cpu_notify - print deferred console messages after CPU hotplug
+ * @self: notifier struct
+ * @action: CPU hotplug event
+ * @hcpu: unused
+ *
+ * If printk() is called from a CPU that is not online yet, the messages
+ * will be spooled but will not show up on the console. This function is
+ * called when a new CPU comes online (or fails to come up), and ensures
+ * that any such output gets printed.
+ */
+static int __cpuinit console_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_UP_CANCELED:
+ acquire_console_sem();
+ release_console_sem();
+ }
+ return NOTIFY_OK;
+}
+
+/**
* acquire_console_sem - lock the console system for exclusive use.
*
* Acquires a semaphore which guarantees that the caller has
@@ -1371,7 +1396,7 @@ int unregister_console(struct console *console)
}
EXPORT_SYMBOL(unregister_console);
-static int __init disable_boot_consoles(void)
+static int __init printk_late_init(void)
{
struct console *con;
@@ -1382,9 +1407,10 @@ static int __init disable_boot_consoles(void)
unregister_console(con);
}
}
+ hotcpu_notifier(console_cpu_notify, 0);
return 0;
}
-late_initcall(disable_boot_consoles);
+late_initcall(printk_late_init);
#if defined CONFIG_PRINTK
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index e722e9d62221..30a515f1e4ee 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -528,7 +528,7 @@ config LOCKDEP
bool
depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT
select STACKTRACE
- select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390
+ select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE
select KALLSYMS
select KALLSYMS_ALL
@@ -628,6 +628,19 @@ config DEBUG_INFO
If unsure, say N.
+config DEBUG_INFO_REDUCED
+ bool "Reduce debugging information"
+ depends on DEBUG_INFO
+ help
+ If you say Y here gcc is instructed to generate less debugging
+ information for structure types. This means that tools that
+ need full debugging information (like kgdb or systemtap) won't
+ be happy. But if you merely need debugging information to
+ resolve line numbers there is no loss. Advantage is that
+ build directory object sizes shrink dramatically over a full
+ DEBUG_INFO build and compile times are reduced too.
+ Only works with newer gcc versions.
+
config DEBUG_VM
bool "Debug VM"
depends on DEBUG_KERNEL
@@ -958,13 +971,13 @@ config FAULT_INJECTION_STACKTRACE_FILTER
depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT
depends on !X86_64
select STACKTRACE
- select FRAME_POINTER if !PPC && !S390
+ select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE
help
Provide stacktrace filter for fault-injection capabilities
config LATENCYTOP
bool "Latency measuring infrastructure"
- select FRAME_POINTER if !MIPS && !PPC && !S390
+ select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE
select KALLSYMS
select KALLSYMS_ALL
select STACKTRACE
diff --git a/mm/shmem.c b/mm/shmem.c
index f65f84062db5..1529d8fdc23f 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -767,6 +767,10 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
loff_t newsize = attr->ia_size;
int error;
+ error = inode_change_ok(inode, attr);
+ if (error)
+ return error;
+
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)
&& newsize != inode->i_size) {
struct page *page = NULL;
@@ -801,25 +805,22 @@ static int shmem_notify_change(struct dentry *dentry, struct iattr *attr)
}
}
- error = simple_setsize(inode, newsize);
+ /* XXX(truncate): truncate_setsize should be called last */
+ truncate_setsize(inode, newsize);
if (page)
page_cache_release(page);
- if (error)
- return error;
shmem_truncate_range(inode, newsize, (loff_t)-1);
}
- error = inode_change_ok(inode, attr);
- if (!error)
- generic_setattr(inode, attr);
+ setattr_copy(inode, attr);
#ifdef CONFIG_TMPFS_POSIX_ACL
- if (!error && (attr->ia_valid & ATTR_MODE))
+ if (attr->ia_valid & ATTR_MODE)
error = generic_acl_chmod(inode);
#endif
return error;
}
-static void shmem_delete_inode(struct inode *inode)
+static void shmem_evict_inode(struct inode *inode)
{
struct shmem_inode_info *info = SHMEM_I(inode);
@@ -836,7 +837,7 @@ static void shmem_delete_inode(struct inode *inode)
}
BUG_ON(inode->i_blocks);
shmem_free_inode(inode->i_sb);
- clear_inode(inode);
+ end_writeback(inode);
}
static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir)
@@ -933,7 +934,7 @@ found:
/*
* Move _head_ to start search for next from here.
- * But be careful: shmem_delete_inode checks list_empty without taking
+ * But be careful: shmem_evict_inode checks list_empty without taking
* mutex, and there's an instant in list_move_tail when info->swaplist
* would appear empty, if it were the only one on shmem_swaplist. We
* could avoid doing it if inode NULL; or use this minor optimization.
@@ -2496,7 +2497,7 @@ static const struct super_operations shmem_ops = {
.remount_fs = shmem_remount_fs,
.show_options = shmem_show_options,
#endif
- .delete_inode = shmem_delete_inode,
+ .evict_inode = shmem_evict_inode,
.drop_inode = generic_delete_inode,
.put_super = shmem_put_super,
};
diff --git a/mm/truncate.c b/mm/truncate.c
index 937571b8b233..ba887bff48c5 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -541,28 +541,48 @@ void truncate_pagecache(struct inode *inode, loff_t old, loff_t new)
EXPORT_SYMBOL(truncate_pagecache);
/**
+ * truncate_setsize - update inode and pagecache for a new file size
+ * @inode: inode
+ * @newsize: new file size
+ *
+ * truncate_setsize updastes i_size update and performs pagecache
+ * truncation (if necessary) for a file size updates. It will be
+ * typically be called from the filesystem's setattr function when
+ * ATTR_SIZE is passed in.
+ *
+ * Must be called with inode_mutex held and after all filesystem
+ * specific block truncation has been performed.
+ */
+void truncate_setsize(struct inode *inode, loff_t newsize)
+{
+ loff_t oldsize;
+
+ oldsize = inode->i_size;
+ i_size_write(inode, newsize);
+
+ truncate_pagecache(inode, oldsize, newsize);
+}
+EXPORT_SYMBOL(truncate_setsize);
+
+/**
* vmtruncate - unmap mappings "freed" by truncate() syscall
* @inode: inode of the file used
* @offset: file offset to start truncating
*
- * NOTE! We have to be ready to update the memory sharing
- * between the file and the memory map for a potential last
- * incomplete page. Ugly, but necessary.
- *
- * This function is deprecated and simple_setsize or truncate_pagecache
- * should be used instead.
+ * This function is deprecated and truncate_setsize or truncate_pagecache
+ * should be used instead, together with filesystem specific block truncation.
*/
int vmtruncate(struct inode *inode, loff_t offset)
{
int error;
- error = simple_setsize(inode, offset);
+ error = inode_newsize_ok(inode, offset);
if (error)
return error;
+ truncate_setsize(inode, offset);
if (inode->i_op->truncate)
inode->i_op->truncate(inode);
-
- return error;
+ return 0;
}
EXPORT_SYMBOL(vmtruncate);
diff --git a/net/9p/client.c b/net/9p/client.c
index 37c8da07a80b..47a994bae04e 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -460,7 +460,8 @@ static int p9_check_errors(struct p9_client *c, struct p9_req_t *req)
return err;
}
- if (p9_is_proto_dotu(c))
+ if (p9_is_proto_dotu(c) ||
+ p9_is_proto_dotl(c))
err = -ecode;
if (!err || !IS_ERR_VALUE(err))
@@ -1302,6 +1303,57 @@ error:
}
EXPORT_SYMBOL(p9_client_stat);
+struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid)
+{
+ int err;
+ struct p9_client *clnt;
+ struct p9_stat_dotl *ret = kmalloc(sizeof(struct p9_stat_dotl),
+ GFP_KERNEL);
+ struct p9_req_t *req;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TGETATTR fid %d\n", fid->fid);
+
+ if (!ret)
+ return ERR_PTR(-ENOMEM);
+
+ err = 0;
+ clnt = fid->clnt;
+
+ req = p9_client_rpc(clnt, P9_TGETATTR, "d", fid->fid);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
+
+ err = p9pdu_readf(req->rc, clnt->proto_version, "A", ret);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ p9_free_req(clnt, req);
+ goto error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P,
+ "<<< RGETATTR qid=%x.%llx.%x st_mode=%8.8x\n"
+ "<<< st_nlink=%llu st_uid=%d st_gid=%d st_rdev=%llx\n"
+ "<<< st_size=%llx st_blksize=%llu st_blocks=%llu\n"
+ "<<< st_atime_sec=%lld st_atime_nsec=%lld\n"
+ "<<< st_mtime_sec=%lld st_mtime_nsec=%lld\n"
+ "<<< st_ctime_sec=%lld st_ctime_nsec=%lld\n",
+ ret->qid.type, ret->qid.path, ret->qid.version,
+ ret->st_mode, ret->st_nlink, ret->st_uid, ret->st_gid,
+ ret->st_rdev, ret->st_size, ret->st_blksize, ret->st_blocks,
+ ret->st_atime_sec, ret->st_atime_nsec, ret->st_mtime_sec,
+ ret->st_mtime_nsec, ret->st_ctime_sec, ret->st_ctime_nsec);
+
+ p9_free_req(clnt, req);
+ return ret;
+
+error:
+ kfree(ret);
+ return ERR_PTR(err);
+}
+EXPORT_SYMBOL(p9_client_getattr_dotl);
+
static int p9_client_statsize(struct p9_wstat *wst, int proto_version)
{
int ret;
@@ -1366,6 +1418,36 @@ error:
}
EXPORT_SYMBOL(p9_client_wstat);
+int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *p9attr)
+{
+ int err;
+ struct p9_req_t *req;
+ struct p9_client *clnt;
+
+ err = 0;
+ clnt = fid->clnt;
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TSETATTR fid %d\n", fid->fid);
+ P9_DPRINTK(P9_DEBUG_9P,
+ " valid=%x mode=%x uid=%d gid=%d size=%lld\n"
+ " atime_sec=%lld atime_nsec=%lld\n"
+ " mtime_sec=%lld mtime_nsec=%lld\n",
+ p9attr->valid, p9attr->mode, p9attr->uid, p9attr->gid,
+ p9attr->size, p9attr->atime_sec, p9attr->atime_nsec,
+ p9attr->mtime_sec, p9attr->mtime_nsec);
+
+ req = p9_client_rpc(clnt, P9_TSETATTR, "dI", fid->fid, p9attr);
+
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RSETATTR fid %d\n", fid->fid);
+ p9_free_req(clnt, req);
+error:
+ return err;
+}
+EXPORT_SYMBOL(p9_client_setattr);
+
int p9_client_statfs(struct p9_fid *fid, struct p9_rstatfs *sb)
{
int err;
@@ -1432,3 +1514,50 @@ error:
}
EXPORT_SYMBOL(p9_client_rename);
+int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
+{
+ int err, rsize, total;
+ struct p9_client *clnt;
+ struct p9_req_t *req;
+ char *dataptr;
+
+ P9_DPRINTK(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n",
+ fid->fid, (long long unsigned) offset, count);
+
+ err = 0;
+ clnt = fid->clnt;
+ total = 0;
+
+ rsize = fid->iounit;
+ if (!rsize || rsize > clnt->msize-P9_READDIRHDRSZ)
+ rsize = clnt->msize - P9_READDIRHDRSZ;
+
+ if (count < rsize)
+ rsize = count;
+
+ req = p9_client_rpc(clnt, P9_TREADDIR, "dqd", fid->fid, offset, rsize);
+ if (IS_ERR(req)) {
+ err = PTR_ERR(req);
+ goto error;
+ }
+
+ err = p9pdu_readf(req->rc, clnt->proto_version, "D", &count, &dataptr);
+ if (err) {
+ p9pdu_dump(1, req->rc);
+ goto free_and_error;
+ }
+
+ P9_DPRINTK(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count);
+
+ if (data)
+ memmove(data, dataptr, count);
+
+ p9_free_req(clnt, req);
+ return count;
+
+free_and_error:
+ p9_free_req(clnt, req);
+error:
+ return err;
+}
+EXPORT_SYMBOL(p9_client_readdir);
diff --git a/net/9p/protocol.c b/net/9p/protocol.c
index 149f82160130..4dba08f5f3aa 100644
--- a/net/9p/protocol.c
+++ b/net/9p/protocol.c
@@ -141,6 +141,7 @@ pdu_write_u(struct p9_fcall *pdu, const char __user *udata, size_t size)
D - data blob (int32_t size followed by void *, results are not freed)
T - array of strings (int16_t count, followed by strings)
R - array of qids (int16_t count, followed by qids)
+ A - stat for 9p2000.L (p9_stat_dotl)
? - if optional = 1, continue parsing
*/
@@ -340,6 +341,27 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
}
}
break;
+ case 'A': {
+ struct p9_stat_dotl *stbuf =
+ va_arg(ap, struct p9_stat_dotl *);
+
+ memset(stbuf, 0, sizeof(struct p9_stat_dotl));
+ errcode =
+ p9pdu_readf(pdu, proto_version,
+ "Qdqddqqqqqqqqqq",
+ &stbuf->qid,
+ &stbuf->st_mode, &stbuf->st_nlink,
+ &stbuf->st_uid, &stbuf->st_gid,
+ &stbuf->st_rdev, &stbuf->st_size,
+ &stbuf->st_blksize, &stbuf->st_blocks,
+ &stbuf->st_atime_sec,
+ &stbuf->st_atime_nsec,
+ &stbuf->st_mtime_sec,
+ &stbuf->st_mtime_nsec,
+ &stbuf->st_ctime_sec,
+ &stbuf->st_ctime_nsec);
+ }
+ break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
@@ -488,6 +510,23 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
}
}
break;
+ case 'I':{
+ struct p9_iattr_dotl *p9attr = va_arg(ap,
+ struct p9_iattr_dotl *);
+
+ errcode = p9pdu_writef(pdu, proto_version,
+ "ddddqqqqq",
+ p9attr->valid,
+ p9attr->mode,
+ p9attr->uid,
+ p9attr->gid,
+ p9attr->size,
+ p9attr->atime_sec,
+ p9attr->atime_nsec,
+ p9attr->mtime_sec,
+ p9attr->mtime_nsec);
+ }
+ break;
case '?':
if ((proto_version != p9_proto_2000u) &&
(proto_version != p9_proto_2000L))
@@ -580,3 +619,30 @@ void p9pdu_reset(struct p9_fcall *pdu)
pdu->offset = 0;
pdu->size = 0;
}
+
+int p9dirent_read(char *buf, int len, struct p9_dirent *dirent,
+ int proto_version)
+{
+ struct p9_fcall fake_pdu;
+ int ret;
+ char *nameptr;
+
+ fake_pdu.size = len;
+ fake_pdu.capacity = len;
+ fake_pdu.sdata = buf;
+ fake_pdu.offset = 0;
+
+ ret = p9pdu_readf(&fake_pdu, proto_version, "Qqbs", &dirent->qid,
+ &dirent->d_off, &dirent->d_type, &nameptr);
+ if (ret) {
+ P9_DPRINTK(P9_DEBUG_9P, "<<< p9dirent_read failed: %d\n", ret);
+ p9pdu_dump(1, &fake_pdu);
+ goto out;
+ }
+
+ strcpy(dirent->d_name, nameptr);
+
+out:
+ return fake_pdu.offset;
+}
+EXPORT_SYMBOL(p9dirent_read);
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index 98ce9bcb0e15..c85109d809ca 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -948,7 +948,7 @@ p9_fd_create_unix(struct p9_client *client, const char *addr, char *args)
csocket = NULL;
- if (strlen(addr) > UNIX_PATH_MAX) {
+ if (strlen(addr) >= UNIX_PATH_MAX) {
P9_EPRINTK(KERN_ERR, "p9_trans_unix: address too long: %s\n",
addr);
return -ENAMETOOLONG;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b10e3cdb08f8..800b6b9fbbae 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -358,6 +358,11 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8
acl->sec_level = sec_level;
acl->auth_type = auth_type;
hci_acl_connect(acl);
+ } else {
+ if (acl->sec_level < sec_level)
+ acl->sec_level = sec_level;
+ if (acl->auth_type < auth_type)
+ acl->auth_type = auth_type;
}
if (type == ACL_LINK)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 6c57fc71c7e2..786b5de0bac4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1049,6 +1049,8 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (conn) {
if (!ev->status)
conn->link_mode |= HCI_LM_AUTH;
+ else
+ conn->sec_level = BT_SECURITY_LOW;
clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 1b682a5aa061..cf3c4073a8a6 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -401,6 +401,11 @@ static inline void l2cap_send_rr_or_rnr(struct l2cap_pinfo *pi, u16 control)
l2cap_send_sframe(pi, control);
}
+static inline int __l2cap_no_conn_pending(struct sock *sk)
+{
+ return !(l2cap_pi(sk)->conf_state & L2CAP_CONF_CONNECT_PEND);
+}
+
static void l2cap_do_start(struct sock *sk)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
@@ -409,12 +414,13 @@ static void l2cap_do_start(struct sock *sk)
if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE))
return;
- if (l2cap_check_security(sk)) {
+ if (l2cap_check_security(sk) && __l2cap_no_conn_pending(sk)) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
@@ -464,12 +470,14 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
}
if (sk->sk_state == BT_CONNECT) {
- if (l2cap_check_security(sk)) {
+ if (l2cap_check_security(sk) &&
+ __l2cap_no_conn_pending(sk)) {
struct l2cap_conn_req req;
req.scid = cpu_to_le16(l2cap_pi(sk)->scid);
req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
@@ -2912,7 +2920,6 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
l2cap_pi(sk)->ident = 0;
l2cap_pi(sk)->dcid = dcid;
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
-
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_CONF_REQ,
@@ -4404,6 +4411,7 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
req.psm = l2cap_pi(sk)->psm;
l2cap_pi(sk)->ident = l2cap_get_ident(conn);
+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_CONNECT_PEND;
l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_REQ, sizeof(req), &req);
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index c51b55400dc5..11201784d29a 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -1,7 +1,7 @@
menuconfig NET_DSA
bool "Distributed Switch Architecture support"
default n
- depends on EXPERIMENTAL && !S390
+ depends on EXPERIMENTAL && NET_ETHERNET && !S390
select PHYLIB
---help---
This allows you to use hardware switch chips that use
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6596b4feeddc..65afeaec15b7 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -608,6 +608,7 @@ ssize_t tcp_splice_read(struct socket *sock, loff_t *ppos,
ssize_t spliced;
int ret;
+ sock_rps_record_flow(sk);
/*
* We can't seek on a socket input
*/
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
index 94d72e85a475..b2a3ae6cad78 100644
--- a/net/phonet/pep.c
+++ b/net/phonet/pep.c
@@ -698,6 +698,7 @@ static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
newsk = NULL;
goto out;
}
+ kfree_skb(oskb);
sock_hold(sk);
pep_sk(newsk)->listener = sk;
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index 570949417f38..724553e8ed7b 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -205,7 +205,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
{
struct icmphdr *icmph;
- if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph)))
+ if (!pskb_may_pull(skb, ihl + sizeof(*icmph)))
goto drop;
icmph = (void *)(skb_network_header(skb) + ihl);
@@ -215,6 +215,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
(icmph->type != ICMP_PARAMETERPROB))
break;
+ if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph)))
+ goto drop;
+
iph = (void *)(icmph + 1);
if (egress)
addr = iph->daddr;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 58de76c8540c..939d048ef92b 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -320,7 +320,7 @@ static struct cache_detail *current_detail;
static int current_index;
static void do_cache_clean(struct work_struct *work);
-static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean);
+static struct delayed_work cache_cleaner;
static void sunrpc_init_cache_detail(struct cache_detail *cd)
{
@@ -1504,6 +1504,11 @@ static int create_cache_proc_entries(struct cache_detail *cd)
}
#endif
+void __init cache_initialize(void)
+{
+ INIT_DELAYED_WORK_DEFERRABLE(&cache_cleaner, do_cache_clean);
+}
+
int cache_register(struct cache_detail *cd)
{
int ret;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index f438347d817b..c52b18489149 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -43,6 +43,7 @@ init_sunrpc(void)
#ifdef CONFIG_PROC_FS
rpc_proc_init();
#endif
+ cache_initialize();
cache_register(&ip_map_cache);
cache_register(&unix_gid_cache);
svc_init_xprt_sock(); /* svc sock transport */
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af1c173be4ad..a7ec5a8a2380 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1594,8 +1594,8 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols,
/* Try to instantiate a bundle */
err = xfrm_tmpl_resolve(pols, num_pols, fl, xfrm, family);
- if (err < 0) {
- if (err != -EAGAIN)
+ if (err <= 0) {
+ if (err != 0 && err != -EAGAIN)
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTPOLERROR);
return ERR_PTR(err);
}
@@ -1678,6 +1678,13 @@ xfrm_bundle_lookup(struct net *net, struct flowi *fl, u16 family, u8 dir,
goto make_dummy_bundle;
dst_hold(&xdst->u.dst);
return oldflo;
+ } else if (new_xdst == NULL) {
+ num_xfrms = 0;
+ if (oldflo == NULL)
+ goto make_dummy_bundle;
+ xdst->num_xfrms = 0;
+ dst_hold(&xdst->u.dst);
+ return oldflo;
}
/* Kill the previous bundle */
@@ -1760,6 +1767,10 @@ restart:
xfrm_pols_put(pols, num_pols);
err = PTR_ERR(xdst);
goto dropdst;
+ } else if (xdst == NULL) {
+ num_xfrms = 0;
+ drop_pols = num_pols;
+ goto no_transform;
}
spin_lock_bh(&xfrm_policy_sk_bundle_lock);
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index e4deb73e9a84..390aae4bb222 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -156,14 +156,14 @@ $(obj)/%.i: $(src)/%.c FORCE
cmd_gensymtypes = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
- $(GENKSYMS) -T $@ -a $(ARCH) \
+ $(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \
$(if $(KBUILD_PRESERVE),-p) \
- $(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
+ -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \
set -e; \
- $(call cmd_gensymtypes, true) >/dev/null; \
+ $(call cmd_gensymtypes,true,$@) >/dev/null; \
test -s $@ || rm -f $@
$(obj)/%.symtypes : $(src)/%.c FORCE
@@ -192,16 +192,16 @@ else
# the actual value of the checksum generated by genksyms
cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
-cmd_modversions = \
- if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
- $(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
- else \
- mv -f $(@D)/.tmp_$(@F) $@; \
+cmd_modversions = \
+ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
+ $(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
+ > $(@D)/.tmp_$(@F:.o=.ver); \
+ \
+ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
+ -T $(@D)/.tmp_$(@F:.o=.ver); \
+ rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
+ else \
+ mv -f $(@D)/.tmp_$(@F) $@; \
fi;
endif
diff --git a/scripts/Makefile.help b/scripts/Makefile.help
new file mode 100644
index 000000000000..d03608f5db04
--- /dev/null
+++ b/scripts/Makefile.help
@@ -0,0 +1,3 @@
+
+checker-help:
+ @echo ' coccicheck - Check with Coccinelle.'
diff --git a/scripts/checkkconfigsymbols.sh b/scripts/checkkconfigsymbols.sh
index 46be3c5a62b7..2ca49bb31efc 100755
--- a/scripts/checkkconfigsymbols.sh
+++ b/scripts/checkkconfigsymbols.sh
@@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while
do
# Output the bare Kconfig variable and the filename; the _MODULE part at
# the end is not removed here (would need perl an not-hungry regexp for that).
- sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i
+ sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i
done | \
# Smart "sort|uniq" implemented in awk and tuned to collect the names of all
# files which use a given symbol
diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh
index 66ad375612f2..6bb42e72e0e5 100755
--- a/scripts/checksyscalls.sh
+++ b/scripts/checksyscalls.sh
@@ -183,7 +183,6 @@ cat << EOF
#define __IGNORE_ustat /* statfs */
#define __IGNORE_utime /* utimes */
#define __IGNORE_vfork /* clone */
-#define __IGNORE_wait4 /* waitid */
/* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */
#ifdef __NR_sync_file_range2
diff --git a/scripts/coccicheck b/scripts/coccicheck
new file mode 100755
index 000000000000..b8bcf1f7bed7
--- /dev/null
+++ b/scripts/coccicheck
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+SPATCH="`which ${SPATCH:=spatch}`"
+
+if [ "$C" = "1" -o "$C" = "2" ]; then
+ ONLINE=1
+
+# This requires Coccinelle >= 0.2.3
+# FLAGS="-ignore_unknown_options -very_quiet"
+# OPTIONS=$*
+
+# Workaround for Coccinelle < 0.2.3
+ FLAGS="-I $srctree/include -very_quiet"
+ shift $(( $# - 1 ))
+ OPTIONS=$1
+else
+ ONLINE=0
+ FLAGS="-very_quiet"
+fi
+
+if [ ! -x "$SPATCH" ]; then
+ echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
+ exit 1
+fi
+
+if [ "$MODE" = "" ] ; then
+ if [ "$ONLINE" = "0" ] ; then
+ echo 'You have not explicitly specify the mode to use. Fallback to "report".'
+ echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
+ echo 'Available modes are: report, patch, context, org'
+ fi
+ MODE="report"
+fi
+
+if [ "$ONLINE" = "0" ] ; then
+ echo ''
+ echo 'Please check for false positives in the output before submitting a patch.'
+ echo 'When using "patch" mode, carefully review the patch before submitting it.'
+ echo ''
+fi
+
+coccinelle () {
+ COCCI="$1"
+
+ OPT=`grep "Option" $COCCI | cut -d':' -f2`
+
+# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
+#
+# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
+
+ if [ "$ONLINE" = "0" ] ; then
+
+ FILE=`echo $COCCI | sed "s|$srctree/||"`
+
+ echo "Processing `basename $COCCI` with option(s) \"$OPT\""
+ echo 'Message example to submit a patch:'
+
+ sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
+
+ echo ' The semantic patch that makes this change is available'
+ echo " in $FILE."
+ echo ''
+ echo ' More information about semantic patching is available at'
+ echo ' http://coccinelle.lip6.fr/'
+ echo ''
+
+ $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1
+ else
+ $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
+ fi
+
+}
+
+if [ "$COCCI" = "" ] ; then
+ for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
+ coccinelle $f
+ done
+else
+ coccinelle $COCCI
+fi
diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
new file mode 100644
index 000000000000..7d4771d449c3
--- /dev/null
+++ b/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
@@ -0,0 +1,67 @@
+///
+/// Casting (void *) value returned by kmalloc is useless
+/// as mentioned in Documentation/CodingStyle, Chap 14.
+///
+// Confidence: High
+// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options: -no_includes -include_headers
+//
+// Keywords: kmalloc, kzalloc, kcalloc
+// Version min: < 2.6.12 kmalloc
+// Version min: < 2.6.12 kcalloc
+// Version min: 2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T;
+@@
+
+* (T *)
+ \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T;
+@@
+
+- (T *)
+ \(kmalloc\|kzalloc\|kcalloc\)(...)
+
+//----------------------------------------------------------
+// For org and report mode
+//----------------------------------------------------------
+
+@r depends on org || report@
+type T;
+position p;
+@@
+
+ (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
+
+@script:python depends on org@
+p << r.p;
+t << r.T;
+@@
+
+coccilib.org.print_safe_todo(p[0], t)
+
+@script:python depends on report@
+p << r.p;
+t << r.T;
+@@
+
+msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/alloc/kzalloc-simple.cocci
new file mode 100644
index 000000000000..2eae828fc657
--- /dev/null
+++ b/scripts/coccinelle/alloc/kzalloc-simple.cocci
@@ -0,0 +1,82 @@
+///
+/// kzalloc should be used rather than kmalloc followed by memset 0
+///
+// Confidence: High
+// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
+// Options: -no_includes -include_headers
+//
+// Keywords: kmalloc, kzalloc
+// Version min: < 2.6.12 kmalloc
+// Version min: 2.6.14 kzalloc
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@depends on context@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+* x = (T)kmalloc(E1,E2);
+ if ((x==NULL) || ...) S
+* memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@depends on patch@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+@@
+
+- x = (T)kmalloc(E1,E2);
++ x = kzalloc(E1,E2);
+ if ((x==NULL) || ...) S
+- memset((T2)x,0,E1);
+
+//----------------------------------------------------------
+// For org mode
+//----------------------------------------------------------
+
+@r depends on org || report@
+type T, T2;
+expression x;
+expression E1,E2;
+statement S;
+position p;
+@@
+
+ x = (T)kmalloc@p(E1,E2);
+ if ((x==NULL) || ...) S
+ memset((T2)x,0,E1);
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="%s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/deref_null.cocci
new file mode 100644
index 000000000000..9969d76d0f4b
--- /dev/null
+++ b/scripts/coccinelle/deref_null.cocci
@@ -0,0 +1,293 @@
+///
+/// A variable is dereference under a NULL test.
+/// Even though it is know to be NULL.
+///
+// Confidence: Moderate
+// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Comments: -I ... -all_includes can give more complete results
+// Options:
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+@initialize:python depends on !context && patch && !org && !report@
+
+import sys
+print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
+
+@depends on patch@
+@@
+
+this_rule_should_never_matches();
+
+@ifm depends on !patch@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+// The following two rules are separate, because both can match a single
+// expression in different ways
+@pr1 depends on !patch expression@
+expression *ifm.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr2 depends on !patch expression@
+expression *ifm.E;
+identifier f;
+position p2;
+@@
+
+(
+ (E != NULL) && ... && <+...E->f@p2...+>
+|
+ (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+// For org and report modes
+
+@r depends on !context && !patch && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+ ... when any
+ return ...;
+}
+else S3
+
+@script:python depends on !context && !patch && !org && report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+cocci.include_match(False)
+
+@script:python depends on !context && !patch && org && !report@
+p << r.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+cocci.include_match(False)
+
+@s depends on !context && !patch && (org || report) exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+ E->f@p // bad use
+)
+ ... when any
+}
+else S3
+
+@script:python depends on !context && !patch && !org && report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+coccilib.report.print_report(p[0], msg)
+
+@script:python depends on !context && !patch && org && !report@
+p << s.p;
+p1 << ifm.p1;
+x << ifm.E;
+@@
+
+msg="ERROR: %s is NULL but dereferenced." % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+cocci.print_main(msg_safe,p)
+
+// For context mode
+
+@depends on context && !patch && !org && !report exists@
+expression subE <= ifm.E;
+expression *ifm.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr1.p1,pr2.p2};
+position ifm.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+ ... when any
+ return ...;
+}
+else S3
+
+// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
+// It is need because the previous rule as already made a "change".
+
+@ifm1 depends on !patch@
+expression *E;
+statement S1,S2;
+position p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...) S1 else S2
+
+@pr11 depends on !patch expression@
+expression *ifm1.E;
+identifier f;
+position p1;
+@@
+
+ (E != NULL && ...) ? <+...E->f@p1...+> : ...
+
+@pr12 depends on !patch expression@
+expression *ifm1.E;
+identifier f;
+position p2;
+@@
+
+(
+ (E != NULL) && ... && <+...E->f@p2...+>
+|
+ (E == NULL) || ... || <+...E->f@p2...+>
+|
+ sizeof(<+...E->f@p2...+>)
+)
+
+@depends on context && !patch && !org && !report exists@
+expression subE <= ifm1.E;
+expression *ifm1.E;
+expression E1,E2;
+identifier f;
+statement S1,S2,S3,S4;
+iterator iter;
+position p!={pr11.p1,pr12.p2};
+position ifm1.p1;
+@@
+
+if@p1 ((E == NULL && ...) || ...)
+{
+ ... when != if (...) S1 else S2
+(
+ iter(subE,...) S4 // no use
+|
+ list_remove_head(E2,subE,...)
+|
+ subE = E1
+|
+ for(subE = E1;...;...) S4
+|
+ subE++
+|
+ ++subE
+|
+ --subE
+|
+ subE--
+|
+ &subE
+|
+* E->f@p // bad use
+)
+ ... when any
+}
+else S3
diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/err_cast.cocci
new file mode 100644
index 000000000000..2ce115000af6
--- /dev/null
+++ b/scripts/coccinelle/err_cast.cocci
@@ -0,0 +1,56 @@
+///
+/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
+///
+// Confidence: High
+// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options:
+//
+// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
+// Version min: 2.6.25
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+
+@ depends on context && !patch && !org && !report@
+expression x;
+@@
+
+* ERR_PTR(PTR_ERR(x))
+
+@ depends on !context && patch && !org && !report @
+expression x;
+@@
+
+- ERR_PTR(PTR_ERR(x))
++ ERR_CAST(x)
+
+@r depends on !context && !patch && (org || report)@
+expression x;
+position p;
+@@
+
+ ERR_PTR@p(PTR_ERR(x))
+
+@script:python depends on org@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING ERR_CAST can be used with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r.p;
+x << r.x;
+@@
+
+msg="WARNING: ERR_CAST can be used with %s" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/resource_size.cocci
new file mode 100644
index 000000000000..1935a58b39d9
--- /dev/null
+++ b/scripts/coccinelle/resource_size.cocci
@@ -0,0 +1,93 @@
+///
+/// Use resource_size function on resource object
+/// instead of explicit computation.
+///
+// Confidence: High
+// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
+// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
+// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
+// URL: http://coccinelle.lip6.fr/
+// Options:
+//
+// Keywords: resource_size
+// Version min: 2.6.27 resource_size
+//
+
+virtual context
+virtual patch
+virtual org
+virtual report
+
+//----------------------------------------------------------
+// For context mode
+//----------------------------------------------------------
+
+@r_context depends on context && !patch && !org@
+struct resource *res;
+@@
+
+* (res->end - res->start) + 1
+
+//----------------------------------------------------------
+// For patch mode
+//----------------------------------------------------------
+
+@r_patch depends on !context && patch && !org@
+struct resource *res;
+@@
+
+- (res->end - res->start) + 1
++ resource_size(res)
+
+//----------------------------------------------------------
+// For org mode
+//----------------------------------------------------------
+
+
+@r_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p;
+@@
+
+ (res->end@p - res->start) + 1
+
+@rbad_org depends on !context && !patch && (org || report)@
+struct resource *res;
+position p != r_org.p;
+@@
+
+ res->end@p - res->start
+
+@script:python depends on org@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << r_org.p;
+x << r_org.res;
+@@
+
+msg="ERROR: Missing resource_size with %s" % (x)
+coccilib.report.print_report(p[0], msg)
+
+@script:python depends on org@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING with %s" % (x)
+msg_safe=msg.replace("[","@(").replace("]",")")
+coccilib.org.print_todo(p[0], msg_safe)
+
+@script:python depends on report@
+p << rbad_org.p;
+x << rbad_org.res;
+@@
+
+msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
+coccilib.report.print_report(p[0], msg)
diff --git a/scripts/decodecode b/scripts/decodecode
index 8b30cc36744f..18ba881c3415 100755
--- a/scripts/decodecode
+++ b/scripts/decodecode
@@ -40,7 +40,7 @@ echo $code
code=`echo $code | sed -e 's/.*Code: //'`
width=`expr index "$code" ' '`
-width=$[($width-1)/2]
+width=$((($width-1)/2))
case $width in
1) type=byte ;;
2) type=2byte ;;
@@ -48,10 +48,10 @@ case $width in
esac
disas() {
- ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
+ ${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
- if [ "$ARCH" == "arm" ]; then
- if [ $width == 2 ]; then
+ if [ "$ARCH" = "arm" ]; then
+ if [ $width -eq 2 ]; then
OBJDUMPFLAGS="-M force-thumb"
fi
@@ -59,7 +59,7 @@ disas() {
fi
${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
- grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
+ grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
}
marker=`expr index "$code" "\<"`
diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
index 766b2694d935..8fe1bdf239f0 100644
--- a/scripts/dtc/fstree.c
+++ b/scripts/dtc/fstree.c
@@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname)
free(tmpnam);
}
+ closedir(d);
return tree;
}
diff --git a/scripts/kconfig/.gitignore b/scripts/kconfig/.gitignore
index 6a36a76e6606..624f6502e03e 100644
--- a/scripts/kconfig/.gitignore
+++ b/scripts/kconfig/.gitignore
@@ -17,6 +17,7 @@ gconf.glade.h
#
conf
mconf
+nconf
qconf
gconf
kxgettext
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 7ea649da1940..0a34335bf0f9 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -72,6 +72,12 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
fi
$(Q)rm -f .tmp.config
+nonint_oldconfig: $(obj)/conf
+ $< -b $(Kconfig)
+
+loose_nonint_oldconfig: $(obj)/conf
+ $< -B $(Kconfig)
+
# Create new linux.pot file
# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
# The symlink is used to repair a deficiency in arch/um
@@ -136,6 +142,10 @@ help:
@echo ' allmodconfig - New config selecting modules when possible'
@echo ' allyesconfig - New config where all options are accepted with yes'
@echo ' allnoconfig - New config where all options are answered with no'
+ @echo ' nonint_oldconfig - Checks the current configuration and fails if an option is '
+ @echo ' not set'
+ @echo ' loose_nonint_oldconfig - Same as nonint_oldconfig, but updates the config file with '
+ @echo ' missing config options as unset'
# lxdialog stuff
check-lxdialog := $(srctree)/$(src)/lxdialog/check-lxdialog.sh
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c
index 9960d1c303f8..bde01b4200ee 100644
--- a/scripts/kconfig/conf.c
+++ b/scripts/kconfig/conf.c
@@ -16,6 +16,10 @@
#define LKC_DIRECT_LINK
#include "lkc.h"
+/* Return codes */
+#define EUNSETOPT 2 /* if -B and -b are used and unset config
+ * options were found */
+
static void conf(struct menu *menu);
static void check_conf(struct menu *menu);
@@ -23,6 +27,8 @@ enum {
ask_all,
ask_new,
ask_silent,
+ dont_ask,
+ dont_ask_dont_tell,
set_default,
set_yes,
set_mod,
@@ -37,6 +43,7 @@ static int sync_kconfig;
static int conf_cnt;
static char line[128];
static struct menu *rootEntry;
+static int unset_variables;
static void print_help(struct menu *menu)
{
@@ -156,14 +163,12 @@ static int conf_string(struct menu *menu)
static int conf_sym(struct menu *menu)
{
struct symbol *sym = menu->sym;
- int type;
tristate oldval, newval;
while (1) {
printf("%*s%s ", indent - 1, "", _(menu->prompt->text));
if (sym->name)
printf("(%s) ", sym->name);
- type = sym_get_type(sym);
putchar('[');
oldval = sym_get_tristate_value(sym);
switch (oldval) {
@@ -228,11 +233,9 @@ static int conf_choice(struct menu *menu)
{
struct symbol *sym, *def_sym;
struct menu *child;
- int type;
bool is_new;
sym = menu->sym;
- type = sym_get_type(sym);
is_new = !sym_has_value(sym);
if (sym_is_changable(sym)) {
conf_sym(menu);
@@ -360,7 +363,10 @@ static void conf(struct menu *menu)
switch (prop->type) {
case P_MENU:
- if (input_mode == ask_silent && rootEntry != menu) {
+ if ((input_mode == ask_silent ||
+ input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) &&
+ rootEntry != menu) {
check_conf(menu);
return;
}
@@ -418,10 +424,23 @@ static void check_conf(struct menu *menu)
if (sym && !sym_has_value(sym)) {
if (sym_is_changable(sym) ||
(sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)) {
- if (!conf_cnt++)
- printf(_("*\n* Restart config...\n*\n"));
- rootEntry = menu_get_parent_menu(menu);
- conf(rootEntry);
+ if (input_mode == dont_ask ||
+ input_mode == dont_ask_dont_tell) {
+ if (input_mode == dont_ask &&
+ sym->name && !sym_is_choice_value(sym)) {
+ if (!unset_variables)
+ fprintf(stderr, "The following"
+ " variables are not set:\n");
+ fprintf(stderr, "CONFIG_%s\n",
+ sym->name);
+ unset_variables++;
+ }
+ } else {
+ if (!conf_cnt++)
+ printf(_("*\n* Restart config...\n*\n"));
+ rootEntry = menu_get_parent_menu(menu);
+ conf(rootEntry);
+ }
}
}
@@ -439,7 +458,7 @@ int main(int ac, char **av)
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
+ while ((opt = getopt(ac, av, "osbBdD:nmyrh")) != -1) {
switch (opt) {
case 'o':
input_mode = ask_silent;
@@ -448,6 +467,12 @@ int main(int ac, char **av)
input_mode = ask_silent;
sync_kconfig = 1;
break;
+ case 'b':
+ input_mode = dont_ask;
+ break;
+ case 'B':
+ input_mode = dont_ask_dont_tell;
+ break;
case 'd':
input_mode = set_default;
break;
@@ -525,6 +550,8 @@ int main(int ac, char **av)
case ask_silent:
case ask_all:
case ask_new:
+ case dont_ask:
+ case dont_ask_dont_tell:
conf_read(NULL);
break;
case set_no:
@@ -586,12 +613,16 @@ int main(int ac, char **av)
conf(&rootmenu);
input_mode = ask_silent;
/* fall through */
+ case dont_ask:
+ case dont_ask_dont_tell:
case ask_silent:
/* Update until a loop caused no more changes */
do {
conf_cnt = 0;
check_conf(&rootmenu);
- } while (conf_cnt);
+ } while (conf_cnt &&
+ (input_mode != dont_ask &&
+ input_mode != dont_ask_dont_tell));
break;
}
@@ -607,11 +638,11 @@ int main(int ac, char **av)
fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
return 1;
}
- } else {
+ } else if (!unset_variables || input_mode != dont_ask) {
if (conf_write(NULL)) {
fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
exit(1);
}
}
- return 0;
+ return unset_variables ? EUNSETOPT : 0;
}
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index d83f2322893a..8f18e37892cb 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1121,7 +1121,7 @@ static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *s
}
str_append(gs, str);
- if (sym)
+ if (sym && sym->type != S_UNKNOWN)
str_printf(gs, " [=%s]", sym_str);
}
diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h
index 891cd9ce9ba2..75a31e4552f3 100644
--- a/scripts/kconfig/expr.h
+++ b/scripts/kconfig/expr.h
@@ -83,6 +83,7 @@ struct symbol {
tristate visible;
int flags;
struct property *prop;
+ struct expr_value dir_dep;
struct expr_value rev_dep;
};
@@ -163,6 +164,7 @@ struct menu {
struct symbol *sym;
struct property *prompt;
struct expr *dep;
+ struct expr *dir_dep;
unsigned int flags;
char *help;
struct file *file;
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c
index bef10411837f..d66988265f89 100644
--- a/scripts/kconfig/gconf.c
+++ b/scripts/kconfig/gconf.c
@@ -1114,7 +1114,7 @@ static gchar **fill_row(struct menu *menu)
row[COL_OPTION] =
g_strdup_printf("%s %s", _(menu_get_prompt(menu)),
- sym && sym_has_value(sym) ? "(NEW)" : "");
+ sym && !sym_has_value(sym) ? "(NEW)" : "");
if (opt_mode == OPT_ALL && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray");
@@ -1343,7 +1343,8 @@ static void update_tree(struct menu *src, GtkTreeIter * dst)
#endif
if ((opt_mode == OPT_NORMAL && !menu_is_visible(child1)) ||
- (opt_mode == OPT_PROMPT && !menu_has_prompt(child1))) {
+ (opt_mode == OPT_PROMPT && !menu_has_prompt(child1)) ||
+ (opt_mode == OPT_ALL && !menu_get_prompt(child1))) {
/* remove node */
if (gtktree_iter_find_node(dst, menu1) != NULL) {
@@ -1425,7 +1426,7 @@ static void display_tree(struct menu *menu)
if ((opt_mode == OPT_NORMAL && menu_is_visible(child)) ||
(opt_mode == OPT_PROMPT && menu_has_prompt(child)) ||
- (opt_mode == OPT_ALL))
+ (opt_mode == OPT_ALL && menu_get_prompt(child)))
place_node(child, fill_row(child));
#ifdef DEBUG
printf("%*c%s: ", indent, ' ', menu_get_prompt(child));
diff --git a/scripts/kconfig/lxdialog/checklist.c b/scripts/kconfig/lxdialog/checklist.c
index bcc6f19c3a35..a2eb80fbc896 100644
--- a/scripts/kconfig/lxdialog/checklist.c
+++ b/scripts/kconfig/lxdialog/checklist.c
@@ -31,6 +31,10 @@ static int list_width, check_x, item_x;
static void print_item(WINDOW * win, int choice, int selected)
{
int i;
+ char *list_item = malloc(list_width + 1);
+
+ strncpy(list_item, item_str(), list_width - item_x);
+ list_item[list_width - item_x] = '\0';
/* Clear 'residue' of last item */
wattrset(win, dlg.menubox.atr);
@@ -45,13 +49,14 @@ static void print_item(WINDOW * win, int choice, int selected)
wprintw(win, "(%c)", item_is_tag('X') ? 'X' : ' ');
wattrset(win, selected ? dlg.tag_selected.atr : dlg.tag.atr);
- mvwaddch(win, choice, item_x, item_str()[0]);
+ mvwaddch(win, choice, item_x, list_item[0]);
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
- waddstr(win, (char *)item_str() + 1);
+ waddstr(win, list_item + 1);
if (selected) {
wmove(win, choice, check_x + 1);
wrefresh(win);
}
+ free(list_item);
}
/*
@@ -175,6 +180,7 @@ do_resize:
check_x = 0;
item_foreach()
check_x = MAX(check_x, strlen(item_str()) + 4);
+ check_x = MIN(check_x, list_width);
check_x = (list_width - check_x) / 2;
item_x = check_x + 4;
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c
index 2c83d3234d30..d2f6e056c058 100644
--- a/scripts/kconfig/mconf.c
+++ b/scripts/kconfig/mconf.c
@@ -74,7 +74,7 @@ static const char mconf_readme[] = N_(
"\n"
" Shortcut: Press <H> or <?>.\n"
"\n"
-"o To show hidden options, press <Z>.\n"
+"o To toggle the display of hidden options, press <Z>.\n"
"\n"
"\n"
"Radiolists (Choice lists)\n"
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 203632cc30bd..11799894f3bd 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -105,6 +105,7 @@ static struct expr *menu_check_dep(struct expr *e)
void menu_add_dep(struct expr *dep)
{
current_entry->dep = expr_alloc_and(current_entry->dep, menu_check_dep(dep));
+ current_entry->dir_dep = current_entry->dep;
}
void menu_set_type(int type)
@@ -288,6 +289,10 @@ void menu_finalize(struct menu *parent)
for (menu = parent->list; menu; menu = menu->next)
menu_finalize(menu);
} else if (sym) {
+ /* ignore inherited dependencies for dir_dep */
+ sym->dir_dep.expr = expr_transform(expr_copy(parent->dir_dep));
+ sym->dir_dep.expr = expr_eliminate_dups(sym->dir_dep.expr);
+
basedep = parent->prompt ? parent->prompt->visible.expr : NULL;
basedep = expr_trans_compare(basedep, E_UNEQUAL, &symbol_no);
basedep = expr_eliminate_dups(expr_transform(basedep));
@@ -419,9 +424,13 @@ bool menu_is_visible(struct menu *menu)
if (!sym || sym_get_tristate_value(menu->sym) == no)
return false;
- for (child = menu->list; child; child = child->next)
- if (menu_is_visible(child))
+ for (child = menu->list; child; child = child->next) {
+ if (menu_is_visible(child)) {
+ if (sym)
+ sym->flags |= SYMBOL_DEF_USER;
return true;
+ }
+ }
return false;
}
@@ -501,9 +510,19 @@ void get_symbol_str(struct gstr *r, struct symbol *sym)
bool hit;
struct property *prop;
- if (sym && sym->name)
+ if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name,
sym_get_string_value(sym));
+ str_printf(r, "Type : %s\n", sym_type_name(sym->type));
+ if (sym->type == S_INT || sym->type == S_HEX) {
+ prop = sym_get_range_prop(sym);
+ if (prop) {
+ str_printf(r, "Range : ");
+ expr_gstr_print(prop->expr, r);
+ str_append(r, "\n");
+ }
+ }
+ }
for_all_prompts(sym, prop)
get_prompt_str(r, prop);
hit = false;
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 00c51507cfcc..820df2d1217b 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -58,11 +58,10 @@ QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
{
QValueList<int> result;
QStringList entryList = readListEntry(key, ok);
- if (ok) {
- QStringList::Iterator it;
- for (it = entryList.begin(); it != entryList.end(); ++it)
- result.push_back((*it).toInt());
- }
+ QStringList::Iterator it;
+
+ for (it = entryList.begin(); it != entryList.end(); ++it)
+ result.push_back((*it).toInt());
return result;
}
@@ -149,7 +148,7 @@ void ConfigItem::updateMenu(void)
case S_TRISTATE:
char ch;
- if (!sym_is_changable(sym) && !list->showAll) {
+ if (!sym_is_changable(sym) && list->optMode == normalOpt) {
setPixmap(promptColIdx, 0);
setText(noColIdx, QString::null);
setText(modColIdx, QString::null);
@@ -320,7 +319,7 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
- showAll(false), showName(false), showRange(false), showData(false),
+ showName(false), showRange(false), showData(false), optMode(normalOpt),
rootEntry(0), headerPopup(0)
{
int i;
@@ -337,10 +336,10 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
if (name) {
configSettings->beginGroup(name);
- showAll = configSettings->readBoolEntry("/showAll", false);
showName = configSettings->readBoolEntry("/showName", false);
showRange = configSettings->readBoolEntry("/showRange", false);
showData = configSettings->readBoolEntry("/showData", false);
+ optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
configSettings->endGroup();
connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
}
@@ -352,6 +351,17 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
reinit();
}
+bool ConfigList::menuSkip(struct menu *menu)
+{
+ if (optMode == normalOpt && menu_is_visible(menu))
+ return false;
+ if (optMode == promptOpt && menu_has_prompt(menu))
+ return false;
+ if (optMode == allOpt)
+ return false;
+ return true;
+}
+
void ConfigList::reinit(void)
{
removeColumn(dataColIdx);
@@ -380,7 +390,7 @@ void ConfigList::saveSettings(void)
configSettings->writeEntry("/showName", showName);
configSettings->writeEntry("/showRange", showRange);
configSettings->writeEntry("/showData", showData);
- configSettings->writeEntry("/showAll", showAll);
+ configSettings->writeEntry("/optionMode", (int)optMode);
configSettings->endGroup();
}
}
@@ -606,7 +616,7 @@ void ConfigList::updateMenuList(P* parent, struct menu* menu)
}
visible = menu_is_visible(child);
- if (showAll || visible) {
+ if (!menuSkip(child)) {
if (!child->sym && !child->list && !child->prompt)
continue;
if (!item || item->menu != child)
@@ -835,7 +845,10 @@ void ConfigList::contextMenuEvent(QContextMenuEvent *e)
e->ignore();
}
-ConfigView* ConfigView::viewList;
+ConfigView*ConfigView::viewList;
+QAction *ConfigView::showNormalAction;
+QAction *ConfigView::showAllAction;
+QAction *ConfigView::showPromptAction;
ConfigView::ConfigView(QWidget* parent, const char *name)
: Parent(parent, name)
@@ -860,13 +873,16 @@ ConfigView::~ConfigView(void)
}
}
-void ConfigView::setShowAll(bool b)
+void ConfigView::setOptionMode(QAction *act)
{
- if (list->showAll != b) {
- list->showAll = b;
- list->updateListAll();
- emit showAllChanged(b);
- }
+ if (act == showNormalAction)
+ list->optMode = normalOpt;
+ else if (act == showAllAction)
+ list->optMode = allOpt;
+ else
+ list->optMode = promptOpt;
+
+ list->updateListAll();
}
void ConfigView::setShowName(bool b)
@@ -964,34 +980,6 @@ void ConfigInfoView::setInfo(struct menu *m)
menuInfo();
}
-void ConfigInfoView::setSource(const QString& name)
-{
- const char *p = name.latin1();
-
- menu = NULL;
- sym = NULL;
-
- switch (p[0]) {
- case 'm':
- struct menu *m;
-
- if (sscanf(p, "m%p", &m) == 1 && menu != m) {
- menu = m;
- menuInfo();
- emit menuSelected(menu);
- }
- break;
- case 's':
- struct symbol *s;
-
- if (sscanf(p, "s%p", &s) == 1 && sym != s) {
- sym = s;
- symbolInfo();
- }
- break;
- }
-}
-
void ConfigInfoView::symbolInfo(void)
{
QString str;
@@ -1349,11 +1337,24 @@ ConfigMainWindow::ConfigMainWindow(void)
connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
showDataAction->setOn(configList->showData);
- QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
- showAllAction->setToggleAction(TRUE);
- connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
- connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
- showAllAction->setOn(configList->showAll);
+
+ QActionGroup *optGroup = new QActionGroup(this);
+ optGroup->setExclusive(TRUE);
+ connect(optGroup, SIGNAL(selected(QAction *)), configView,
+ SLOT(setOptionMode(QAction *)));
+ connect(optGroup, SIGNAL(selected(QAction *)), menuView,
+ SLOT(setOptionMode(QAction *)));
+
+ configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
+ configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
+ configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
+ configView->showNormalAction->setToggleAction(TRUE);
+ configView->showNormalAction->setOn(configList->optMode == normalOpt);
+ configView->showAllAction->setToggleAction(TRUE);
+ configView->showAllAction->setOn(configList->optMode == allOpt);
+ configView->showPromptAction->setToggleAction(TRUE);
+ configView->showPromptAction->setOn(configList->optMode == promptOpt);
+
QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
showDebugAction->setToggleAction(TRUE);
connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
@@ -1396,7 +1397,8 @@ ConfigMainWindow::ConfigMainWindow(void)
showRangeAction->addTo(optionMenu);
showDataAction->addTo(optionMenu);
optionMenu->insertSeparator();
- showAllAction->addTo(optionMenu);
+ optGroup->addTo(optionMenu);
+ optionMenu->insertSeparator();
showDebugAction->addTo(optionMenu);
// create help menu
@@ -1491,7 +1493,7 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
ConfigList* list = NULL;
ConfigItem* item;
- if (!menu_is_visible(menu) && !configView->showAll())
+ if (configList->menuSkip(menu))
return;
switch (configList->mode) {
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index b3b5657b6b35..636a74b23bf9 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -44,6 +44,9 @@ enum colIdx {
enum listMode {
singleMode, menuMode, symbolMode, fullMode, listMode
};
+enum optionMode {
+ normalOpt = 0, allOpt, promptOpt
+};
class ConfigList : public QListView {
Q_OBJECT
@@ -115,6 +118,8 @@ public:
void setAllOpen(bool open);
void setParentMenu(void);
+ bool menuSkip(struct menu *);
+
template <class P>
void updateMenuList(P*, struct menu*);
@@ -124,8 +129,9 @@ public:
QPixmap choiceYesPix, choiceNoPix;
QPixmap menuPix, menuInvPix, menuBackPix, voidPix;
- bool showAll, showName, showRange, showData;
+ bool showName, showRange, showData;
enum listMode mode;
+ enum optionMode optMode;
struct menu *rootEntry;
QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup;
@@ -222,17 +228,15 @@ public:
static void updateList(ConfigItem* item);
static void updateListAll(void);
- bool showAll(void) const { return list->showAll; }
bool showName(void) const { return list->showName; }
bool showRange(void) const { return list->showRange; }
bool showData(void) const { return list->showData; }
public slots:
- void setShowAll(bool);
void setShowName(bool);
void setShowRange(bool);
void setShowData(bool);
+ void setOptionMode(QAction *);
signals:
- void showAllChanged(bool);
void showNameChanged(bool);
void showRangeChanged(bool);
void showDataChanged(bool);
@@ -242,6 +246,10 @@ public:
static ConfigView* viewList;
ConfigView* nextView;
+
+ static QAction *showNormalAction;
+ static QAction *showAllAction;
+ static QAction *showPromptAction;
};
class ConfigInfoView : public QTextBrowser {
@@ -254,7 +262,6 @@ public:
public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
- void setSource(const QString& name);
void setShowDebug(bool);
signals:
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 2e7a048e0cfc..c127fa342f1d 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -205,6 +205,16 @@ static void sym_calc_visibility(struct symbol *sym)
}
if (sym_is_choice_value(sym))
return;
+ /* defaulting to "yes" if no explicit "depends on" are given */
+ tri = yes;
+ if (sym->dir_dep.expr)
+ tri = expr_calc_value(sym->dir_dep.expr);
+ if (tri == mod)
+ tri = yes;
+ if (sym->dir_dep.tri != tri) {
+ sym->dir_dep.tri = tri;
+ sym_set_changed(sym);
+ }
tri = no;
if (sym->rev_dep.expr)
tri = expr_calc_value(sym->rev_dep.expr);
@@ -222,13 +232,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
struct property *prop;
struct expr *e;
+ /* first calculate all choice values' visibilities */
+ prop = sym_get_choice_prop(sym);
+ expr_list_for_each_sym(prop->expr, e, def_sym)
+ sym_calc_visibility(def_sym);
+
/* is the user choice visible? */
def_sym = sym->def[S_DEF_USER].val;
- if (def_sym) {
- sym_calc_visibility(def_sym);
- if (def_sym->visible != no)
- return def_sym;
- }
+ if (def_sym && def_sym->visible != no)
+ return def_sym;
/* any of the defaults visible? */
for_all_defaults(sym, prop) {
@@ -236,18 +248,15 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
if (prop->visible.tri == no)
continue;
def_sym = prop_get_symbol(prop);
- sym_calc_visibility(def_sym);
if (def_sym->visible != no)
return def_sym;
}
/* just get the first visible value */
prop = sym_get_choice_prop(sym);
- expr_list_for_each_sym(prop->expr, e, def_sym) {
- sym_calc_visibility(def_sym);
+ expr_list_for_each_sym(prop->expr, e, def_sym)
if (def_sym->visible != no)
return def_sym;
- }
/* no choice? reset tristate value */
sym->curr.tri = no;
@@ -321,6 +330,14 @@ void sym_calc_value(struct symbol *sym)
}
}
calc_newval:
+ if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) {
+ fprintf(stderr, "warning: (");
+ expr_fprint(sym->rev_dep.expr, stderr);
+ fprintf(stderr, ") selects %s which has unmet direct dependencies (",
+ sym->name);
+ expr_fprint(sym->dir_dep.expr, stderr);
+ fprintf(stderr, ")\n");
+ }
newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri);
}
if (newval.tri == mod && sym_get_type(sym) == S_BOOLEAN)
@@ -365,12 +382,13 @@ void sym_calc_value(struct symbol *sym)
if (sym_is_choice(sym)) {
struct symbol *choice_sym;
- int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
prop = sym_get_choice_prop(sym);
expr_list_for_each_sym(prop->expr, e, choice_sym) {
- choice_sym->flags |= flags;
- if (flags & SYMBOL_CHANGED)
+ if ((sym->flags & SYMBOL_WRITE) &&
+ choice_sym->visible != no)
+ choice_sym->flags |= SYMBOL_WRITE;
+ if (sym->flags & SYMBOL_CHANGED)
sym_set_changed(choice_sym);
}
}
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index 07f2fbde2abf..5f1e2fc7f171 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -148,10 +148,11 @@ EOF
# Generate a control file
cat <<EOF > debian/control
Source: linux-upstream
-Section: admin
+Section: kernel
Priority: optional
Maintainer: $maintainer
-Standards-Version: 3.8.1
+Standards-Version: 3.8.4
+Homepage: http://www.kernel.org/
EOF
if [ "$ARCH" = "um" ]; then
diff --git a/tools/perf/arch/arm/Makefile b/tools/perf/arch/arm/Makefile
new file mode 100644
index 000000000000..15130b50dfe3
--- /dev/null
+++ b/tools/perf/arch/arm/Makefile
@@ -0,0 +1,4 @@
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
+endif
diff --git a/tools/perf/arch/arm/util/dwarf-regs.c b/tools/perf/arch/arm/util/dwarf-regs.c
new file mode 100644
index 000000000000..fff6450c8c99
--- /dev/null
+++ b/tools/perf/arch/arm/util/dwarf-regs.c
@@ -0,0 +1,64 @@
+/*
+ * Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2010 Will Deacon, ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <libio.h>
+#include <dwarf-regs.h>
+
+struct pt_regs_dwarfnum {
+ const char *name;
+ unsigned int dwarfnum;
+};
+
+#define STR(s) #s
+#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
+#define GPR_DWARFNUM_NAME(num) \
+ {.name = STR(%r##num), .dwarfnum = num}
+#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
+
+/*
+ * Reference:
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
+ */
+static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
+ GPR_DWARFNUM_NAME(0),
+ GPR_DWARFNUM_NAME(1),
+ GPR_DWARFNUM_NAME(2),
+ GPR_DWARFNUM_NAME(3),
+ GPR_DWARFNUM_NAME(4),
+ GPR_DWARFNUM_NAME(5),
+ GPR_DWARFNUM_NAME(6),
+ GPR_DWARFNUM_NAME(7),
+ GPR_DWARFNUM_NAME(8),
+ GPR_DWARFNUM_NAME(9),
+ GPR_DWARFNUM_NAME(10),
+ REG_DWARFNUM_NAME("%fp", 11),
+ REG_DWARFNUM_NAME("%ip", 12),
+ REG_DWARFNUM_NAME("%sp", 13),
+ REG_DWARFNUM_NAME("%lr", 14),
+ REG_DWARFNUM_NAME("%pc", 15),
+ REG_DWARFNUM_END,
+};
+
+/**
+ * get_arch_regstr() - lookup register name from it's DWARF register number
+ * @n: the DWARF register number
+ *
+ * get_arch_regstr() returns the name of the register in struct
+ * regdwarfnum_table from it's DWARF register number. If the register is not
+ * found in the table, this returns NULL;
+ */
+const char *get_arch_regstr(unsigned int n)
+{
+ const struct pt_regs_dwarfnum *roff;
+ for (roff = regdwarfnum_table; roff->name != NULL; roff++)
+ if (roff->dwarfnum == n)
+ return roff->name;
+ return NULL;
+}